cant get NMI to start after reset vector completion

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

Post Reply
infidelity
Posts: 486
Joined: Fri Mar 01, 2013 4:46 am

cant get NMI to start after reset vector completion

Post by infidelity »

Im wondering, if this is because what I have going on in my reset vector is too big?

This is my first time trying to setup a rom on my own from scratch. If I use an RTS at the end of my reset vector, the game will crash. But if end up using a JMP to where the NMI starts, my NMI code will run, but the NMI pointer is not logging, it's the IRQ pointer that is logging.

So am I only supposed to have a certain amount of code within the reset vector? I'm trying to prep a lot of stuff for the rom, but I'm assuming maybe it's too much?

Code: Select all

SEI
CLD
LDA #$00
STA $2001 
STA $2000
LDX #$FF
TXS
LDA $2002
AND #$80
BEQ $2002
LDA $2002
AND #$80
BEQ $2002

;it is at this point, where if I throw an rts here, the nmi will load up. but, if I continue to have large amounts of code to prep the rom, then use an rts, it doesn't work.
The CPU Cycle in FCEUX says 235915 when I reach the end of what I have in my reset vector.

This is what I have...

Code: Select all

 01:FF00:78        SEI
 01:FF01:D8        CLD
 01:FF02:A9 00     LDA #$00
>01:FF04:8D 01 20  STA $2001 = #$00
 01:FF07:8D 00 20  STA $2000 = #$00
 01:FF0A:A2 FF     LDX #$FF
 01:FF0C:9A        TXS
 01:FF0D:AD 02 20  LDA $2002 = #$00
 01:FF10:29 80     AND #$80
 01:FF12:F0 F9     BEQ $FF0D
 01:FF14:AD 02 20  LDA $2002 = #$00
 01:FF17:29 80     AND #$80
 01:FF19:F0 F9     BEQ $FF14
 01:FF1B:A2 05     LDX #$05
 01:FF1D:8E 00 80  STX $8000 = #$FF
 01:FF20:BD F4 FF  LDA $FFF4,X @ $FFF4 = #$00
 01:FF23:8D 01 80  STA $8001 = #$FF
 01:FF26:CA        DEX
 01:FF27:10 F4     BPL $FF1D
 01:FF29:A9 7F     LDA #$7F
 01:FF2B:85 01     STA $0001 = #$00
 01:FF2D:A9 00     LDA #$00
 01:FF2F:91 00     STA ($00),Y @ $0000 = #$00
 01:FF31:88        DEY
 01:FF32:D0 F9     BNE $FF2D
 01:FF34:C6 01     DEC $0001 = #$00
 01:FF36:A5 01     LDA $0001 = #$00
 01:FF38:C9 5F     CMP #$5F
 01:FF3A:D0 F1     BNE $FF2D
 01:FF3C:A9 07     LDA #$07
 01:FF3E:A0 FE     LDY #$FE
 01:FF40:85 01     STA $0001 = #$00
 01:FF42:A9 00     LDA #$00
 01:FF44:85 00     STA $0000 = #$00
 01:FF46:A9 00     LDA #$00
 01:FF48:91 00     STA ($00),Y @ $0000 = #$00
 01:FF4A:88        DEY
 01:FF4B:C0 FF     CPY #$FF
 01:FF4D:D0 F7     BNE $FF46
 01:FF4F:C6 01     DEC $0001 = #$00
 01:FF51:A5 01     LDA $0001 = #$00
 01:FF53:C9 03     CMP #$03
 01:FF55:B0 EF     BCS $FF46
 01:FF57:A2 FF     LDX #$FF
 01:FF59:A9 00     LDA #$00
 01:FF5B:95 00     STA $00,X @ $0000 = #$00
 01:FF5D:9D 00 02  STA $0200,X @ $0200 = #$00
 01:FF60:CA        DEX
 01:FF61:D0 F6     BNE $FF59
 01:FF63:A0 00     LDY #$00
 01:FF65:A2 40     LDX #$40
 01:FF67:A9 F8     LDA #$F8
 01:FF69:99 00 02  STA $0200,Y @ $0200 = #$00
 01:FF6C:C8        INY
 01:FF6D:C8        INY
 01:FF6E:C8        INY
 01:FF6F:C8        INY
 01:FF70:CA        DEX
 01:FF71:D0 F4     BNE $FF67
 01:FF73:A9 00     LDA #$00
 01:FF75:8D 00 A0  STA $A000 = #$02
 01:FF78:A9 04     LDA #$04
 01:FF7A:85 14     STA $0014 = #$FF
 01:FF7C:A9 00     LDA #$00
 01:FF7E:20 DA FF  JSR $FFDA
 01:FF81:20 80 A0  JSR $A080
 01:FF84:A9 02     LDA #$02
 01:FF86:85 14     STA $0014 = #$FF

;it is at this point, if I use a JMP to where my NMI starts, the code will run, but it's running as an IRQ, cause $FFFE-$FFFF is highlighted and not $FFFA-$FFFB.
User avatar
Disch
Posts: 1848
Joined: Wed Nov 10, 2004 6:47 pm

Re: cant get NMI to start after reset vector completion

Post by Disch »

You do not "exit" your reset vector. RTI or RTSing out of it is wrong. The reset vector is where your program starts. The code that gets executed from there must keep running for as long as you want your program to run (ie: until the user quits... so it should run forever).


Typically the reset vector initializes things.. then enters a loop. The loop will get interrupted by NMIs every frame, so you can drive your logic.

You also should not JMP to your NMI code... since the NMI code should typically only be called when there's an NMI. So instead... enable NMIs, then spin in a loop waiting for an NMI to happen.
infidelity
Posts: 486
Joined: Fri Mar 01, 2013 4:46 am

Re: cant get NMI to start after reset vector completion

Post by infidelity »

ok, so how do I enable an nmi? I figured sei would take care of that, being set interrupts. :-/

I took a look at super Mario bros, and I see that it loops itself on a jmp. I tried doing that with my work, but the NMI still does not kick in. I noticed The Legend of Zelda does the same thing, it will loop itself on a jmp...
User avatar
rainwarrior
Posts: 8062
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: cant get NMI to start after reset vector completion

Post by rainwarrior »

SEI actually disables interrupts. It sets the flag that masks IRQs, preventing them from taking effect.

However, SEI and CLI are not related to the NMI. The NMI is the "non-maskable interrupt", meaning it's separate from the regular IRQ line and not affected by that flag.

The high bit written to $2000 will enable the NMI, if set. What happens when this is enabled is that whenever vblank begins, execution of your code (wherever you've reached starting from your reset vector) will be interrupted in the middle of what it's doing and jump to the routine specified in your NMI vector. When finished with your NMI routine, use RTI (return from interrupt) to return to the previously running code.

So... to enable the NMI, write $80 to $2000. Don't do this until you're finished setting everything up in your reset code.

Other IRQs will use the IRQ vector instead, and are effected by SEI and CLI, but I expect you don't have a use for them yet, so you should leave SEI enabled. The reason standard startup code has an SEI is to prevent any interrupts from trying to execute code before your program has had time to set itself up.


Also, I saw the line BEQ $2002 in your posted source. That's not really what you have there, is it? BEQ should be followed by a label. It can't jump to an absolute address like that, and even if it could, it certainly shouldn't jump to $2002, where there is no code to be run. Also, you might consider this common alternative for the vblank wait:

Code: Select all

:
bit $2002
bpl :-
BIT is a strange instruction, but one of the things it can do is test the high bit of the address specified (goes into the sign flag). This saves you the trouble of an extra AND instruction. Probably not too important here, but in situations where timing is more critical this will get you a more accurate timing.
infidelity
Posts: 486
Joined: Fri Mar 01, 2013 4:46 am

Re: cant get NMI to start after reset vector completion

Post by infidelity »

I don't write code, I code via hex.

And thank you very much for the info on the enabling of nmi! I threw in LDA #$80, STA $2000, then I perform a JMP over that area, and the NMI pointer is firing up now. :-)
User avatar
Disch
Posts: 1848
Joined: Wed Nov 10, 2004 6:47 pm

Re: cant get NMI to start after reset vector completion

Post by Disch »

I don't write code, I code via hex.
That's insane. Get an assembler.
infidelity
Posts: 486
Joined: Fri Mar 01, 2013 4:46 am

Re: cant get NMI to start after reset vector completion

Post by infidelity »

That's how I've been coding for almost 10 years. May be insane to others, but that's how I work. I use the FCEUX debugger, and I have no issues.

Also, that NMI enable seems to have fixed my control push bit issue. The register that shows a button held down was fine, but the register that shows you pressed a button, never reset itself, sometimes would throw random values into it. But that's all been fixed now, so my P1/P2 controls are working properly. :-)
User avatar
Disch
Posts: 1848
Joined: Wed Nov 10, 2004 6:47 pm

Re: cant get NMI to start after reset vector completion

Post by Disch »

*shrug* Alright. I'm not going to tell you how to live your life. =P

Glad to hear it's working now.
User avatar
Movax12
Posts: 529
Joined: Sun Jan 02, 2011 11:50 am

Re: cant get NMI to start after reset vector completion

Post by Movax12 »

Disch wrote:
I don't write code, I code via hex.
That's insane. Get an assembler.
+1

If you only had access to a simple hex monitor, sure, but .. there are a number of decent cross-assemblers.
User avatar
Jarhmander
Formerly ~J-@D!~
Posts: 521
Joined: Sun Mar 12, 2006 12:36 am
Location: Rive nord de Montréal

Re: cant get NMI to start after reset vector completion

Post by Jarhmander »

Image
((λ (x) (x x)) (λ (x) (x x)))
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: cant get NMI to start after reset vector completion

Post by tepples »

Perhaps someone has to go through some formality with the computer's administrator to install each program. Getting ca65+ld65 onto a machine might be a pain. And even then, the assemblers for creating an executable from scratch ("homebrew") and for modifying an existing executable created by someone else ("ROM hacking") are often different.
User avatar
rainwarrior
Posts: 8062
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: cant get NMI to start after reset vector completion

Post by rainwarrior »

I found ca65 to be quite well suited for romhacking once I figured out how to place code via the linker config.
Post Reply