This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

SMB1/MMC3 - Status bar IRQ routine and more needed for hack

SMB1/MMC3 - Status bar IRQ routine and more needed for hack
by on (#30373)
How do i create an IRQ routine, I am creating a status bar for SMB1 NES and not use sprite 0 just like SMB2j. It is possible, Just needed some help!

Also. I should use Sprite 0 for eyes like Super mario 2 (USA). and I could probrably need some help making (or rewrite) the SMB player engine to use 32x32 using 8x16 tilesize instead of using 16x32 using 8x8 tilesize, but using the same bounding box.

But what I really need, Most notably is the SMB1/MMC3 IRQ setup for the Status bar and Sprite 0 setup to be a free sprite space.

by on (#30376)
If you make the player use 8x16 pixel sprites, you'll have to do the same for the enemies, like in SMB3. Then you'll probably have to go and make the squid of 2-2 smaller like they are in SMB3 too. At this rate, wouldn't it be easier to port SMB1's maps to the SMB3 engine?

by on (#30384)
tepples wrote:
If you make the player use 8x16 pixel sprites, you'll have to do the same for the enemies, like in SMB3. Then you'll probably have to go and make the squid of 2-2 smaller like they are in SMB3 too. At this rate, wouldn't it be easier to port SMB1's maps to the SMB3 engine?


Yes, I was going to say the same for the enemies.

And I could do it in SMB3, But the problem is that I cannot do a full disassembly for SMB3. as opposed to the currently used SMB1 disassembly. So probably scratch the sprites part,

I also tried to make SMB1 use different music (something in the size of 0000-3fff (the size of Hebereke.NSF without the Header and DPCM data) in a hex editor), But I could not. It is something in the line of ''SMB2 and 3 uses a very hard-to-do techniqe to put music in a hidden place in the unknown'' (Possibly a case of Program Bankswitching with $8000-$BFFF during Initialization?)
Re: SMB1/MMC3 - Status bar IRQ routine and more needed for h
by on (#30389)
Hamtaro126 wrote:
How do i create an IRQ routine, I am creating a status bar for SMB1 NES and not use sprite 0 just like SMB2j. It is possible, Just needed some help!


Mapper 0 has no way to generate IRQs for raster effects (at least -- none that would allow you to remove sprite 0 hit -- you could use DMC IRQs for a rough timing, but sprite 0 hit would still need to be there so you can get the time right)

SMB2j was for the FDS, which had an additional CPU cycle counting IRQ generator (why they didn't put something this simple on the NES, I'll never understand).

Anyway -- to do this you'd need to switch to a mapper that has IRQs (like mapper 4). But this involves other headaches in the form of rerouting the reset vector so it lands in the fixed page, and prepping a bunch of mapper regs at system startup.

Doesn't sound like much work, but with how little free space SMB has... additional code means you'll either have to gut and remove an exising routine or two... or you'll have to expand the ROM.

by on (#30392)
Hamtaro126 wrote:
And I could do it in SMB3, But the problem is that I cannot do a full disassembly for SMB3. as opposed to the currently used SMB1 disassembly.

If you are disassembling the program, editing large parts of the source code, and reassembling it, how are you going to distribute the result? For patches that do not relocate subroutines, such as fan translations, binary diff formats such as .ips are popular, but as far as I can tell, these formats can't handle relocating subroutines. You'd have to distribute a symbol table for the disassembly along with a source code patch, and then require the end user to disassemble an existing ROM (obtained "elsewhere") using your symbol table, apply your patch, and then reassemble the result.

Quote:
So probably scratch the sprites part

Case in point: SMB1 in Super Mario All-Stars still uses the 8x8 pixel sprites.

Quote:
I also tried to make SMB1 use different music (something in the size of 0000-3fff (the size of Hebereke.NSF without the Header and DPCM data) in a hex editor), But I could not. It is something in the line of ''SMB2 and 3 uses a very hard-to-do techniqe to put music in a hidden place in the unknown'' (Possibly a case of Program Bankswitching with $8000-$BFFF during Initialization?)

Yes, the bigger games bankswitch the music code and data.

by on (#30394)
tepples wrote:
Case in point: SMB1 in Super Mario All-Stars still uses the 8x8 pixel sprites.

I would expect that all of the SMAS games utilize the SNES much more like an NES than other games written specifically for the SNES since they're basically source-level ports, and much of the game logic is identical.

by on (#30399)
Tepples posts:

tepples wrote:
Hamtaro126 wrote:
And I could do it in SMB3, But the problem is that I cannot do a full disassembly for SMB3. as opposed to the currently used SMB1 disassembly.

If you are disassembling the program, editing large parts of the source code, and reassembling it, how are you going to distribute the result? For patches that do not relocate subroutines, such as fan translations, binary diff formats such as .ips are popular, but as far as I can tell, these formats can't handle relocating subroutines. You'd have to distribute a symbol table for the disassembly along with a source code patch, and then require the end user to disassemble an existing ROM (obtained "elsewhere") using your symbol table, apply your patch, and then reassemble the result.



That sounds like a good idea, Since that is supported in X816, In which I use mostly

Quote:
Quote:
So probably scratch the sprites part

Case in point: SMB1 in Super Mario All-Stars still uses the 8x8 pixel sprites.



I know, Just wanted to scratch it because it might require a engine rewrite, I think.

Quote:
Quote:
I also tried to make SMB1 use different music (something in the size of 0000-3fff (the size of Hebereke.NSF without the Header and DPCM data) in a hex editor), But I could not. It is something in the line of ''SMB2 and 3 uses a very hard-to-do techniqe to put music in a hidden place in the unknown'' (Possibly a case of Program Bankswitching with $8000-$BFFF during Initialization?)

Yes, the bigger games bankswitch the music code and data.


If you or anyone is interested in helping me with the music bankswitching
stuff, PM me please.

Disch's posts:

Disch wrote:
Hamtaro126 wrote:
How do i create an IRQ routine, I am creating a status bar for SMB1 NES and not use sprite 0 just like SMB2j. It is possible, Just needed some help!


Quote:
Mapper 0 has no way to generate IRQs for raster effects (at least -- none that would allow you to remove sprite 0 hit -- you could use DMC IRQs for a rough timing, but sprite 0 hit would still need to be there so you can get the time right)


Quote:
SMB2j was for the FDS, which had an additional CPU cycle counting IRQ generator (why they didn't put something this simple on the NES, I'll never understand).


I know mapper 0 does not support it, That is why I'm using MMC3 or some other mapper/variant

Quote:
Anyway -- to do this you'd need to switch to a mapper that has IRQs (like mapper 4). But this involves other headaches in the form of rerouting the reset vector so it lands in the fixed page, and prepping a bunch of mapper regs at system startup.


You also mentioned the rerouting thing in the post, I knew that

Quote:
Doesn't sound like much work, but with how little free space SMB has... additional code means you'll either have to gut and remove an exising routine or two... or you'll have to expand the ROM.


I am thinking about editing and useing the E000.asm included with Loopy's SMB2J-NES project. and remove the code I will not need (Will use the leftover space that I deleted, I also deleted SMB1's music).
Re: SMB1/MMC3 - Status bar IRQ routine and more needed for h
by on (#30402)
Hamtaro126 wrote:
How do i create an IRQ routine, I am creating a status bar for SMB1 NES and not use sprite 0 just like SMB2j. It is possible, Just needed some help!

Also. I should use Sprite 0 for eyes like Super mario 2 (USA). and I could probrably need some help making (or rewrite) the SMB player engine to use 32x32 using 8x16 tilesize instead of using 16x32 using 8x8 tilesize, but using the same bounding box.

But what I really need, Most notably is the SMB1/MMC3 IRQ setup for the Status bar and Sprite 0 setup to be a free sprite space.


Nobody knows for sure, though you have the chance to hack a MMC3 game and study its IRQ subroutine. Depending of what you want to do, it won't be so much different. An IRQ is merely a "branch" to a subroutine. Usually, you can take advantage of score bars or raster effects.

You're asking this because you *probably* have played SMB1 hacks that do NOT use mapper 0, right? Try asking some rom hacker...

by on (#30404)
Oh blah... I'm sorry Hamtaro -- I feel kind of dumb. For some reason my brain blocked out all the times you mentioned MMC3 (it's even in the thread title)

My apologies.

Anyway setting up an IRQ is pretty simple on MMC3, but there is a big caveat:

All sprites must use right-hand pattern table & BG must use lefthand pattern table.

I believe this is the opposite of how SMB does it. *checks* Yeah it is. You technically can get away with SMB as it is now -- but it's ill advised. Especially if you plan to move to 8x16 sprites -- in which case the BG MUST be using the left pattern table.

To make this change, simply flip around the CHR in the ROM and change what gets written to $2000 (specifically, you'll need to switch bits 3 and 4). Make sure you catch and fix every $2000 write SMB does -- there probably aren't too many of them.


That caveat aside.. IRQs are pretty simple. You'll need to set up the IRQ counter in VBlank so that it fires on the desired scanline. Then when it fires, you just split the screen's scroll and acknowlege/disable the IRQ:

To enable/set up the IRQs (done in VBlank):
1) Write N to $C000, where 'N' is the number of scanlines you want the IRQ to fire after minus 1. (This sets the reload value)

2) write any value to $C001 (this clears the actual IRQ counter)

3) write any value to $E000 (this enables IRQs)

4) clear the I flag with a CLI instruction

also) I don't think SMB has other IRQ sources enabled, but if it does you may have to disable them. The only one that's a concern really is APU frame IRQs. Just make sure that whenever SMB writes to $4017, bit 6 is set.


To acknowledge/disable IRQs (do in your IRQ routine):

1) write any value to $E001


For example -- if you want the IRQ to happen after 32 ($20) scanlines, you'd do the following:

Code:
;  in VBlank (probably in NMI)
  LDA #$1F
  STA $C000  ; write $20 - 1
  STA $C001
  STA $E000

; IRQs now up and running
; make sure the CPU doesn't mask them
  CLI


;  in your IRQ routine, you need to acknowledge the IRQ:
  STA $E001   ; that's it!

by on (#30407)
Hamtaro126 wrote:
tepples wrote:
Hamtaro126 wrote:
And I could do it in SMB3, But the problem is that I cannot do a full disassembly for SMB3. as opposed to the currently used SMB1 disassembly.

You'd have to distribute a symbol table for the disassembly along with a source code patch

That sounds like a good idea, Since that is supported in X816, In which I use mostly

If you are using a proprietary disassembler and assembler designed to run on MS-DOS, then you won't have much of an audience unless you also distribute instructions to 1. get x816 and 2. get x816 working on the most popular operating systems that are still in print. (MS-DOS and Windows 9x are not.) This leaves Windows XP, Windows Vista, Mac OS X, and Ubuntu. Does x816 work in DOSBox?

by on (#30418)
tepples wrote:
Hamtaro126 wrote:
tepples wrote:
Hamtaro126 wrote:
And I could do it in SMB3, But the problem is that I cannot do a full disassembly for SMB3. as opposed to the currently used SMB1 disassembly.

You'd have to distribute a symbol table for the disassembly along with a source code patch

That sounds like a good idea, Since that is supported in X816, In which I use mostly

If you are using a proprietary disassembler and assembler designed to run on MS-DOS, then you won't have much of an audience unless you also distribute instructions to 1. get x816 and 2. get x816 working on the most popular operating systems that are still in print. (MS-DOS and Windows 9x are not.) This leaves Windows XP, Windows Vista, Mac OS X, and Ubuntu. Does x816 work in DOSBox?


It should, But now I should put a notice for X816 to ASM6/CA65 ASM file conversion for every ASM file I make for now on, Just to insure
compatibility with OSes.

Note that using I am using Windows 2000 right now, and it works, unless you have XP or above (I think).

Disch: Thanks for the help, One thing though, Can you please add the ''caveat'' stuff to your MMC3 document, unless it is already mentioned.

By the way: I might need Blargg's MMC3 document(s) to understand things properly,

by on (#30423)
Hamtaro126 wrote:
Disch: Thanks for the help, One thing though, Can you please add the ''caveat'' stuff to your MMC3 document, unless it is already mentioned.


It is already mentioned.

See "Basic IRQ Operation"... "Therefore, you must follow these rules:" -- it's rule 4. And explanation further of why it must be that way is explained near the end of "Detailed IRQ Operation"