It is currently Mon Dec 11, 2017 9:28 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: Craziest 2$#% I Ever Saw
PostPosted: Tue Jul 12, 2005 8:50 am 
When, in Kirby's Adventure, I saw that the IRQ vector was 0029, I thought, No way. I then checked a trace of a split-screen scrolling operation and saw that indeed, the IRQ vector is at 0029! I guess it writes brand new code into the RAM and then executes it from there. :shock: Then again, I sorta knew it was possible.

Code:
$0029:48        PHA                        A:00 X:FF Y:00 P:nvUbdIZC
$002A:A9 00     LDA #$00                   A:00 X:FF Y:00 P:nvUbdIZC
$002C:8D 00 E0  STA $E000 = #$6E           A:00 X:FF Y:00 P:nvUbdIZC
$002F:8D 00 E0  STA $E000 = #$6E           A:00 X:FF Y:00 P:nvUbdIZC
$0032:4C BF FB  JMP $FBBF                  A:00 X:FF Y:00 P:nvUbdIZC


Top
  
 
 Post subject:
PostPosted: Tue Jul 12, 2005 8:55 am 
Here's the rest of that particular IRQ routine (my guess is that the code starting at 0029 is subject to change). Note the NOP and that weird loop that decrements repeatedly y by 1 until it reaches zero. There seems to be a timing reason for it, probably. Perhaps somebody could explain why. Also, why two writes to E000 (MMC3)?

Code:
$0029:48        PHA                        A:00 X:FF Y:00 P:nvUbdIZC
$002A:A9 00     LDA #$00                   A:00 X:FF Y:00 P:nvUbdIZC
$002C:8D 00 E0  STA $E000 = #$6E           A:00 X:FF Y:00 P:nvUbdIZC
$002F:8D 00 E0  STA $E000 = #$6E           A:00 X:FF Y:00 P:nvUbdIZC
$0032:4C BF FB  JMP $FBBF                  A:00 X:FF Y:00 P:nvUbdIZC
$FBBF:EA        NOP                        A:00 X:FF Y:00 P:nvUbdIZC
$FBC0:98        TYA                        A:00 X:FF Y:00 P:nvUbdIZC
$FBC1:48        PHA                        A:00 X:FF Y:00 P:nvUbdIZC
$FBC2:A0 0F     LDY #$0F                   A:00 X:FF Y:00 P:nvUbdIZC
$FBC4:88        DEY                        A:00 X:FF Y:0F P:nvUbdIzC
$FBC5:D0 FD     BNE $FBC4                  A:00 X:FF Y:0E P:nvUbdIzC
$FBC4:88        DEY                        A:00 X:FF Y:0E P:nvUbdIzC
$FBC5:D0 FD     BNE $FBC4                  A:00 X:FF Y:0D P:nvUbdIzC
$FBC4:88        DEY                        A:00 X:FF Y:0D P:nvUbdIzC
$FBC5:D0 FD     BNE $FBC4                  A:00 X:FF Y:0C P:nvUbdIzC
$FBC4:88        DEY                        A:00 X:FF Y:0C P:nvUbdIzC
$FBC5:D0 FD     BNE $FBC4                  A:00 X:FF Y:0B P:nvUbdIzC
$FBC4:88        DEY                        A:00 X:FF Y:0B P:nvUbdIzC
$FBC5:D0 FD     BNE $FBC4                  A:00 X:FF Y:0A P:nvUbdIzC
$FBC4:88        DEY                        A:00 X:FF Y:0A P:nvUbdIzC
$FBC5:D0 FD     BNE $FBC4                  A:00 X:FF Y:09 P:nvUbdIzC
$FBC4:88        DEY                        A:00 X:FF Y:09 P:nvUbdIzC
$FBC5:D0 FD     BNE $FBC4                  A:00 X:FF Y:08 P:nvUbdIzC
$FBC4:88        DEY                        A:00 X:FF Y:08 P:nvUbdIzC
$FBC5:D0 FD     BNE $FBC4                  A:00 X:FF Y:07 P:nvUbdIzC
$FBC4:88        DEY                        A:00 X:FF Y:07 P:nvUbdIzC
$FBC5:D0 FD     BNE $FBC4                  A:00 X:FF Y:06 P:nvUbdIzC
$FBC4:88        DEY                        A:00 X:FF Y:06 P:nvUbdIzC
$FBC5:D0 FD     BNE $FBC4                  A:00 X:FF Y:05 P:nvUbdIzC
$FBC4:88        DEY                        A:00 X:FF Y:05 P:nvUbdIzC
$FBC5:D0 FD     BNE $FBC4                  A:00 X:FF Y:04 P:nvUbdIzC
$FBC4:88        DEY                        A:00 X:FF Y:04 P:nvUbdIzC
$FBC5:D0 FD     BNE $FBC4                  A:00 X:FF Y:03 P:nvUbdIzC
$FBC4:88        DEY                        A:00 X:FF Y:03 P:nvUbdIzC
$FBC5:D0 FD     BNE $FBC4                  A:00 X:FF Y:02 P:nvUbdIzC
$FBC4:88        DEY                        A:00 X:FF Y:02 P:nvUbdIzC
$FBC5:D0 FD     BNE $FBC4                  A:00 X:FF Y:01 P:nvUbdIzC
$FBC4:88        DEY                        A:00 X:FF Y:01 P:nvUbdIzC
$FBC5:D0 FD     BNE $FBC4                  A:00 X:FF Y:00 P:nvUbdIZC
$FBC7:A9 00     LDA #$00                   A:00 X:FF Y:00 P:nvUbdIZC
$FBC9:8D 06 20  STA $2006 = #$A2           A:00 X:FF Y:00 P:nvUbdIZC
$FBCC:8D 06 20  STA $2006 = #$A0           A:00 X:FF Y:00 P:nvUbdIZC
$FBCF:8D 05 20  STA $2005 = #$00           A:00 X:FF Y:00 P:nvUbdIZC
$FBD2:8D 05 20  STA $2005 = #$00           A:00 X:FF Y:00 P:nvUbdIZC
$FBD5:A9 82     LDA #$82                   A:00 X:FF Y:00 P:nvUbdIZC
$FBD7:8D 00 80  STA $8000 = #$3A           A:82 X:FF Y:00 P:NvUbdIzC
$FBDA:A9 DA     LDA #$DA                   A:82 X:FF Y:00 P:NvUbdIzC
$FBDC:8D 01 80  STA $8001 = #$80           A:DA X:FF Y:00 P:NvUbdIzC
$FBDF:A9 83     LDA #$83                   A:DA X:FF Y:00 P:NvUbdIzC
$FBE1:8D 00 80  STA $8000 = #$3A           A:83 X:FF Y:00 P:NvUbdIzC
$FBE4:A9 DB     LDA #$DB                   A:83 X:FF Y:00 P:NvUbdIzC
$FBE6:8D 01 80  STA $8001 = #$80           A:DB X:FF Y:00 P:NvUbdIzC
$FBE9:A9 84     LDA #$84                   A:DB X:FF Y:00 P:NvUbdIzC
$FBEB:8D 00 80  STA $8000 = #$3A           A:84 X:FF Y:00 P:NvUbdIzC
$FBEE:A9 3F     LDA #$3F                   A:84 X:FF Y:00 P:NvUbdIzC
$FBF0:8D 01 80  STA $8001 = #$80           A:3F X:FF Y:00 P:nvUbdIzC
$FBF3:A9 85     LDA #$85                   A:3F X:FF Y:00 P:nvUbdIzC
$FBF5:8D 00 80  STA $8000 = #$3A           A:85 X:FF Y:00 P:NvUbdIzC
$FBF8:A9 DA     LDA #$DA                   A:85 X:FF Y:00 P:NvUbdIzC
$FBFA:8D 01 80  STA $8001 = #$80           A:DA X:FF Y:00 P:NvUbdIzC
$FBFD:4C 22 FB  JMP $FB22                  A:DA X:FF Y:00 P:NvUbdIzC
$FB22:68        PLA                        A:DA X:FF Y:00 P:NvUbdIzC
$FB23:A8        TAY                        A:00 X:FF Y:00 P:nvUbdIZC
$FB24:A5 38     LDA $38 = #$86             A:00 X:FF Y:00 P:nvUbdIZC
$FB26:8D 00 80  STA $8000 = #$3A           A:86 X:FF Y:00 P:NvUbdIzC
$FB29:68        PLA                        A:86 X:FF Y:00 P:NvUbdIzC
$FB2A:40        RTI                        A:00 X:FF Y:00 P:nvUbdIZC


Top
  
 
 Post subject:
PostPosted: Tue Jul 12, 2005 10:39 am 
Offline
Site Admin
User avatar

Joined: Mon Sep 20, 2004 6:04 am
Posts: 3487
Location: Indianapolis
Yeah, that's definitely a timing loop. Probably to kill the time between IRQ trigger and the end of the scanline. I dunno why it writes twice to the MMC3 register though.

Actually, since my Squeedo BIOS has so much IRQ code I thought about doing something similar. But not jumping to zeropage, just normal RAM (I don't see much advantage in using the ZP like that, heh). But I'm sticking with ROM for now.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 12, 2005 11:03 am 
Memblers wrote:
Yeah, that's definitely a timing loop. Probably to kill the time between IRQ trigger and the end of the scanline. I dunno why it writes twice to the MMC3 register though.

Actually, since my Squeedo BIOS has so much IRQ code I thought about doing something similar. But not jumping to zeropage, just normal RAM (I don't see much advantage in using the ZP like that, heh). But I'm sticking with ROM for now.


From looking at the RAM while it's running, I think that second write to E000 is just as a filler. This was traced while it was on the title page and scrolling that save data select table up. I looked at the RAM while it was running: before it started scrolling up the save data select table, it has a write to 2001 instead of a second write to E000. Then it just changes the code. That was probably why the IRQ vector is in such a weird place to begin with; they didn't want to waste time and memory with flags and branch statements.


Top
  
 
 Post subject:
PostPosted: Tue Jul 12, 2005 11:06 am 
beneficii wrote:
Memblers wrote:
Yeah, that's definitely a timing loop. Probably to kill the time between IRQ trigger and the end of the scanline. I dunno why it writes twice to the MMC3 register though.

Actually, since my Squeedo BIOS has so much IRQ code I thought about doing something similar. But not jumping to zeropage, just normal RAM (I don't see much advantage in using the ZP like that, heh). But I'm sticking with ROM for now.


From looking at the RAM while it's running, I think that second write to E000 is just as a filler. This was traced while it was on the title page and scrolling that save data select table up. I looked at the RAM while it was running: before it started scrolling up the save data select table, it has a write to 2001 instead of a second write to E000. Then it just changes the code. That was probably why the IRQ vector is in such a weird place to begin with; they didn't want to waste time and memory with flags and branch statements.


Then again, they could have just used indirect addressing. It would have taken less memory space. Perhaps they did it so that the IRQ would not take so long? That's my best guess now.


Top
  
 
 Post subject:
PostPosted: Tue Jul 12, 2005 11:09 am 
beneficii wrote:
beneficii wrote:
Memblers wrote:
Yeah, that's definitely a timing loop. Probably to kill the time between IRQ trigger and the end of the scanline. I dunno why it writes twice to the MMC3 register though.

Actually, since my Squeedo BIOS has so much IRQ code I thought about doing something similar. But not jumping to zeropage, just normal RAM (I don't see much advantage in using the ZP like that, heh). But I'm sticking with ROM for now.


From looking at the RAM while it's running, I think that second write to E000 is just as a filler. This was traced while it was on the title page and scrolling that save data select table up. I looked at the RAM while it was running: before it started scrolling up the save data select table, it has a write to 2001 instead of a second write to E000. Then it just changes the code. That was probably why the IRQ vector is in such a weird place to begin with; they didn't want to waste time and memory with flags and branch statements.


Then again, they could have just used indirect addressing. It would have taken less memory space. Perhaps they did it so that the IRQ would not take so long? That's my best guess now.


Or, better, so it will not take so long from the start of the IRQ to that weird loop so they could control the timing better?


Top
  
 
 Post subject:
PostPosted: Tue Jul 12, 2005 12:28 pm 
Offline
Site Admin
User avatar

Joined: Mon Sep 20, 2004 6:04 am
Posts: 3487
Location: Indianapolis
beneficii wrote:
beneficii wrote:
Then again, they could have just used indirect addressing. It would have taken less memory space. Perhaps they did it so that the IRQ would not take so long? That's my best guess now.


Or, better, so it will not take so long from the start of the IRQ to that weird loop so they could control the timing better?


Yeah, both those reasons. IRQs are usually for something time-dependant, but it can be for different reasons. So if they have a case where the delay would be unwanted, they could JMP to code without it. On Squeedo I currently do that with a BPL that's not taken if it's a sound IRQ, so that only costs 2 cycles in that case. It does an indirect JMP in all other cases. I can get away with that though since I'm controlling every bit returned from the mapper read, heheh.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group