Code: Select all
lda #29
Moderator: Moderators
Code: Select all
lda #29
Code: Select all
dex
stx t2
bne --
Code: Select all
dex
stx t2
bpl --
I know you aren't magic. Thank you for noticing bne-to-bpl that fixed part of it! I kept thinking of other code needing to be updated and found two things that probably fixed the other part of it before reading your response. My brain is working today!Kasumi wrote:You would also need to change this:to thisCode: Select all
dex stx t2 bne --
Otherwise it never actually does 0. Whether or not that will fix the falling issue, I don't know. You've never posted that code, and I'm not magic. Does the movement routine use what's in RAMbuffer2? Because you've just changed how it works, and any other code that uses it also needs to updated to reflect that.Code: Select all
dex stx t2 bpl --
Code: Select all
0C06A 58 cli
0C06B ;----------------------------END OF RESET----------------------------------
0C06B ; Transfer control to the GAME LOGIC routines.
0C06B
0C06B
0C06B ;initialize the flag to "false"
0C06B A9 00 lda #$00
0C06D 85 21 sta FrameReady
0C06F
0C06F MainLoop:
0C06F
0C06F ;DO THE GAME LOGIC HERE (i.e. movement, collisions, etc.)
0C06F 20 2F C1 jsr react_to_input
0C072 20 91 C3 jsr collisionU
0C075
0C075 A6 0F ldx aFrame
0C077 20 05 C4 jsr draw_sprite
0C07A ; hope this will be some good cement. :) tested... works good so far :D
0C07A EA nop
0C07B EA nop ;ldx #$02
0C07C EA nop ;ldy #$00
0C07D EA nop
0C07E 20 41 C4 jsr draw_RAMbuffers ;left & right column
0C081
0C081 ;indicate that the frame calculations are done
0C081 C6 21 dec FrameReady
0C083
0C083 WaitForUpdates:
0C083 ;wait for the flag to change
0C083 24 21 bit FrameReady
0C085 30 FC bmi WaitForUpdates
0C087
0C087 4C 6F C0 jmp MainLoop
Code: Select all
0C441 ;*******************************************************
0C441 ; uses x for load_screen input... send value of screen to load in x
0C441 ; uses y to pick a column (1 16x16 metatile wide).
0C441 ;*******************************************************
0C441 draw_RAMbuffers:
0C441 ;"Prepare the (new nametable) writes in a RAM buffer during draw time..." tepples pg 59
0C441
0C441 85 FF sta $ff
0C443 A2 02 ldx #$02
0C445 20 24 C1 jsr load_screen
0C448
0C448 A9 1D lda #29
0C44A 85 31 sta t2
0C44C
0C44C ;tya
0C44C ;pha ;------->
0C44C A0 03 ldy #$03
0C44E ;---
0C44E ;
0C44E B1 10 -- lda ($10), y
0C450 AA tax
0C451 ;29 lda MetatileTile2, x
0C451 BD 52 C7 lda MetatileTile2, x
0C454 48 pha ;--->
0C455 ;30 lda MetatileTile0, x
0C455 BD 94 C5 lda MetatileTile0, x
0C458 A6 31 ldx t2
0C45A 95 33 sta RAMbuffer1, x
0C45C CA dex
0C45D 68 pla ;<---
0C45E 95 33 sta RAMbuffer1, x
0C460
0C460 98 tya
0C461 18 clc
0C462 69 10 adc #$10 ;increment y by 16!!!!
0C464 A8 tay
0C465
0C465 CA dex
0C466 86 31 stx t2
0C468 10 E4 bpl --
0C46A
0C46A
0C46A A9 1D lda #29 ;need to reset t2 back up to #29
0C46C 85 31 sta t2
0C46E
0C46E ;pla ;<--------
0C46E ;tay
0C46E A0 03 ldy #$03
0C470 ;---
0C470 B1 10 -- lda ($10), y
0C472 AA tax
0C473 ;29 lda MetatileTile3, x
0C473 BD 31 C8 lda MetatileTile3, x
0C476 48 pha ;--->
0C477 ;30 lda MetatileTile1, x
0C477 BD 73 C6 lda MetatileTile1, x
0C47A A6 31 ldx t2
0C47C 95 51 sta RAMbuffer2, x
0C47E CA dex
0C47F 68 pla ;<---
0C480 95 51 sta RAMbuffer2, x
0C482
0C482 98 tya
0C483 18 clc
0C484 69 10 adc #$10 ;increment y by 16!!!!
0C486 A8 tay
0C487
0C487 CA dex
0C488 86 31 stx t2
0C48A 10 E4 bpl --
0C48C
0C48C
0C48C 60 rts ;end of draw_RAMbuffers
Code: Select all
vblank: inc FRAME_CNT
;skip the video updates if the frame calculations aren't over yet
bit FrameReady
bpl SkipUpdates
;PERFORM VIDEO UPDATES HERE
jsr update_sprite
jsr update_vram
;modify the flag
inc FrameReady
SkipUpdates:
;PERFORM TASKS THAT MUST BE PERFORMED EVEN
;WHEN THE FRAME IS NOT READY, SUCH AS UPDATING
;THE MUSIC OR DRAWING A STATUS BAR
jsr FamiToneUpdate
;"Setting the scroll should ALWAYS be the very last thing in your VBlank handler." -tokumaru pg 43
jsr scroll_screen
;return from the NMI (vblank)
rti
;^ that's the end of my vblank: procedure... what follows are some vblank-type procedures...
update_sprite:
lda #>sprite
sta $4014 ;OAM_DMA register ; Jam sprite page ($200-$2FF) into SPR-RAM
;takes 513 cycles.
rts
.enum LocalVariables4vblank
tE .dsb 2
.ende
update_vram: ;testing... works grandly :)
lda my_copy_of_last_write_to_PPUCTRL
ora #00000100b ;change $2007 increment to +32
sta PPUCTRL0
sta my_copy_of_last_write_to_PPUCTRL
lda #$20
sta PPUADDR6
lda #$00
sta tE
sta PPUADDR6
ldx #29 ;should hold last spot written to RAMbuffer. each column is always full so #29 1XNJJ8WY
- lda RAMbuffer1, x
sta PPUDATA7
dex
bpl -
;this part should hold the increase +1 (moves over to next column) for tE, I think...
inc tE
lda #$20
sta PPUADDR6
lda tE
sta PPUADDR6
ldx #29
- lda RAMbuffer2, x
sta PPUDATA7
dex
bpl -
rts ;end of update_vram.
.include "daprg-scrolllandiii.asm"
Code: Select all
vblank:
pha
tya
pha
txa
pha
inc FRAME_CNT
;skip the video updates if the frame calculations aren't over yet
bit FrameReady
bpl SkipUpdates
Code: Select all
;return from the NMI (vblank)
pla
tax
pla
tay
pla
rti
Woah, ok, yes!!! Thank you 500 percent Kasumi! You are very wise and thank you for sharing your wisdom with me.Kasumi wrote:Beats me. My guess is it's because you're not saving your registers in the NMI routine?
The NMI can interrupt your code at any time. If it changes the value in a register, the "wrong" value (i.e. a value that the code the NMI interrupted doesn't expect) will be there when it returns. To avoid this, just push the values of all the registers to the stack right at the beginning, and then pull them all at the end of the interrupt before the RTI.
Like this:And at the end...Code: Select all
vblank: pha tya pha txa pha inc FRAME_CNT ;skip the video updates if the frame calculations aren't over yet bit FrameReady bpl SkipUpdates
If that's not it, I'm not sure I can find anything else.Code: Select all
;return from the NMI (vblank) pla tax pla tay pla rti
Not bad at all. Look at this example from "PPU scrolling" on the wiki:unregistered wrote:I should make sure to draw columns at the beginning of nametable 0 nearing the end of nametable 1 so that it appears to scroll the screen to the right into a new nametable (nametable 0). Is thinking like this bad?
You don't need to draw more than one column at a time. I just showed four because it makes the GIF clearer. SMB1 actually draws four columns, one at a time, and then fills the attributes for those columns.unregistered wrote:I will try to make it work like that... have to draw four columns at a time
Actually, the number of columns you need to draw depends on how much you scroll each frame. Most games don't scroll any faster than 8 pixels at a time, so they can get away with updating only 1 column at a time. To scroll up to 16 pixels from one frame to the next, you need to update 2 columns, and so on.tepples wrote:You don't need to draw more than one column at a time.
Code: Select all
set 2006 to 23C0
Write to 23C0...
and to 23E0
set 2006 to 23C8
write to 23C8...
and to 23E8
set 2006 to 23D0
write to 23D0...
and to 23F0
set 2006 to 23D8
write to 23D8...
and to 23F8
Code: Select all
lda $2007
and #11001100b
ora tileA
ora tileC
sta $2007
Code: Select all
lda $2007
and #00110011b
ora tileB
ora tileD
sta $2007