Code: Select all
Main:
; Some code
JMP Main
In my main loop I have:
Code: Select all
LDA Timer
BEQ MainDone
In the NMI I have:
Code: Select all
LDA #$01
STA Timer
Moderator: Moderators
Code: Select all
Main:
; Some code
JMP Main
Code: Select all
LDA Timer
BEQ MainDone
Code: Select all
LDA #$01
STA Timer
That looks strange... if your NMI routine sets the flag, your waiting loop should be waiting for it to get set, like this:67726e wrote:In the NMI I have:Code: Select all
LDA Timer BEQ MainDone
Code: Select all
LDA #$01 STA Timer
Code: Select all
Wait:
lda Timer
beq Wait
dec Timer
jmp Main
Code: Select all
Main:
LDA Timer
BEQ Main
Code: Select all
LDA counter
AND $#03 ; EDIT: Changed this to AND, originally I had it as ORA (Oops!)
BNE notThisFrame
;this happens every 4th frame
notThisFrame:
One of the alternative methods is to run the whole game logic inside the NMI, so at the end of the game code, instead of waiting for a flag to change you just RTS to the main loop, which is just an empty "Forever: JMP Forever" loop. When the next NMI fires, the next frame will be processed.67726e wrote:I was just wondering about possible alternate methods.
Ah, I see... Yeah, I guess you could to that without problems. It's just my preference to do the waiting at the end, because by that time the frame is already processed and the buffers with all PPU updates are already to be used when the NMI fires.67726e wrote:However, couldn't I just start of the main loop with:
Code: Select all
Main: LDA Timer BEQ Main
Do you mean "AND #$03"? What you have there will ALWAYS branch since whatever counter is, it's just going to get two bits set which is always non zero.cartlemmy wrote:Code: Select all
LDA counter ORA $#03 BNE notThisFrame ;this happens every 4th frame notThisFrame:
Code: Select all
NMI:
dec framecount
rti
Main:
lda framecount
bmi droppedframes
bne main
beq start
droppedframes:
sta skiplogic;Will be nonzero
bne start2
start:
lda #$00
sta skiplogic
start2:
lda #$01
sta framecount
;Other stuff
;Check $2002?
jmp Main
Not it wouldn't... That flag only stays up during VBlank, and since VBlank doesn't last very long, if your logic took longer than a frame to complete, the chances that it also goes over the time of VBlank are pretty high...Kasumi wrote:I suppose you could check bit 7 of $2002 at the beginning and end of the main loop which would detect a CPU loop that took more than one frame in most cases.
Code: Select all
Nmi:
lda isGameLogicCompleted
beq dropFrame
//do frame stuff
lda #0
sta isGameLogicCompleted
jmp end
dropFrame: inc droppedFrames
end:rti
Main:
lda droppedFrames
bne droppedFrameLogic
//do frame logic
...
jmp endMain
droppedFrameLogic:
//do droppedFrameLogic
...
endMain:
inc isGameLogicCompleted
lda #0
sta droppedFrames
OH MY! Shame on me for not proof reading code. I have a really nasty habit of mixing AND and OR without giving a thought.Kasumi wrote:Do you mean "AND #$03"? What you have there will ALWAYS branch since whatever counter is, it's just going to get two bits set which is always non zero.cartlemmy wrote:Code: Select all
LDA counter AND $#03 ; EDIT: Was ORA BNE notThisFrame ;this happens every 4th frame notThisFrame:
...and status bar, if you have one, don't for get that. If you don't set up the IRQ or wait for the sprite 0 hit necessary to properly position it, it will jump/disappear, and those are very unpleasant effects to look at.MottZilla wrote:Your NMI if it saw no update was ready for the PPU could just skip over that but still update your sound engine.