Yes, It is another wierd-arse question, but in order to use banks for SNES, we need to use long jumps,
We need to figure out a myth concerning conversions, at least with some compare routines, using the rom and extra SNES RAM for the bankswitch emulation.
Games like Hebereke and SMB2 have bankswitching, I just turned the banks into 32k (16k combined with Fixed Bank).
In short: Can/Did anyone solve this big myth?
EDIT: Tables are also what I am talking about, Can't always do it without a way to find the bank switching tables.
Hebereke uses some sort of them. But I do not know...
NES to SNES - JML/JSL/Bankswitching - Myth Help/Assistance!
Moderator: Moderators
Forum rules
- For making cartridges of your Super NES games, see Reproduction.
- Hamtaro126
- Posts: 783
- Joined: Thu Jan 19, 2006 5:08 pm
NES to SNES - JML/JSL/Bankswitching - Myth Help/Assistance!
AKA SmilyMZX/AtariHacker.
The way you stated your question is vague and I don't really get what the myth you're talking about might be.
Here's how I understand it:
You want to port NES games to the SNES and you have a problem rewriting the PRG-ROM bankswitching parts to work on the SNES.
I started to port a NES game myself a while ago (just to check out how much work would be involved), and found that the hardest/most tedious parts were getting a 100% accurate disassembly (which i consider imperative) and rewriting PPU register accesses.
The game I worked on used 8kb CHR-RAM, which spared me the trouble of CHR-bankswitching, which (depending on the game) could obviously implicate heavy rewrites.
Didn't have a single problem rewriting the bankswitching code to use long jumps instead.
Please elaborate on what exactly is causing you trouble.
Code examples would help.
Here's how I understand it:
You want to port NES games to the SNES and you have a problem rewriting the PRG-ROM bankswitching parts to work on the SNES.
I started to port a NES game myself a while ago (just to check out how much work would be involved), and found that the hardest/most tedious parts were getting a 100% accurate disassembly (which i consider imperative) and rewriting PPU register accesses.
The game I worked on used 8kb CHR-RAM, which spared me the trouble of CHR-bankswitching, which (depending on the game) could obviously implicate heavy rewrites.
Didn't have a single problem rewriting the bankswitching code to use long jumps instead.
Please elaborate on what exactly is causing you trouble.
Code examples would help.
- Hamtaro126
- Posts: 783
- Joined: Thu Jan 19, 2006 5:08 pm
I changed my mind... I was going to do SMB2, But appearently it's not that good to do it!d4s wrote:The way you stated your question is vague and I don't really get what the myth you're talking about might be.
Here's how I understand it:
You want to port NES games to the SNES and you have a problem rewriting the PRG-ROM bankswitching parts to work on the SNES.
I started to port a NES game myself a while ago (just to check out how much work would be involved), and found that the hardest/most tedious parts were getting a 100% accurate disassembly (which i consider imperative) and rewriting PPU register accesses.
The game I worked on used 8kb CHR-RAM, which spared me the trouble of CHR-bankswitching, which (depending on the game) could obviously implicate heavy rewrites.
Didn't have a single problem rewriting the bankswitching code to use long jumps instead.
Please elaborate on what exactly is causing you trouble.
Code examples would help.
I guess I'll create a new SMBDIS package (Easier).
Since no CA65 SNES code for GFX and other stuff exists, I had to try to create a new NES Emulation method. (Sound is at least MSU1 Only for now.)
I already know how to disable sprite 0 for it, as the SNES PPU cannot use it.
the SMB Disassembly is by Doppleganger and can be found in RomHacking.Net.
EDIT: If you have the code for your NES Port, Can you please share? (Without the actual game code, of course.)
AKA SmilyMZX/AtariHacker.
Yeah, in case this ever yields something presentable, I'll release the full sourcecode.Hamtaro126 wrote: EDIT: If you have the code for your NES Port, Can you please share? (Without the actual game code, of course.)
Regarding the topic of bankswitching and long jumps:
IMHO, the only correct way to do this is to replace all instances of bankswitching with native long jumps, i.e. remove all traces of the bankswitching interface.
This requires quite some effort, mainly because you'd not only have to modify all callers, but all callees aswell.
If, for some reason, you'd want to take the route of least possible modification,
preserving the bankswitching interface, possibly using static patches even (which probably would be a gigantic nightmare to maintain), the following would be one possible way to do that.
It's far from pretty though:
original nes bankswitching code, AOROM game:
Code: Select all
/**
* switch bank, jump to subroutine
*
* @param a return bank with mirror flag
* @param x (target routine number + 1) * 3
* @param y target bank with mirror flag
*/
Lbl_00_ffcd:
ora #$00
sta $2d
lda $13
pha
stx $13
lda.w AOROM_BANK_PPU_MIRROR_2000,y
sta.w AOROM_BANK_PPU_MIRROR_2000,y
jsr Lbl_00_8000
ldy $2d
pla
sta $13
lda.w AOROM_BANK_PPU_MIRROR_2000,y
sta.w AOROM_BANK_PPU_MIRROR_2000,y
rts
/**
* bank LUT (avoids bus conflict on bank select), also with/out ppu mirroring flag
*/
AOROM_BANK_PPU_MIRROR_2000:
.byte $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a,$0b,$0c,$0d,$0e,$0f
AOROM_BANK_PPU_MIRROR_2400:
.byte $10,$11,$12,$13,$14,$15,$16,$17
/**
* trampoline bank 0
*/
Lbl_00_8000:
jmp ($0013)
/**
* jump table bank 0
*/
Lbl_00_8003:
jmp Lbl_00_e7b2
Lbl_00_8006:
jmp Lbl_00_8326
etc.
/**
* trampoline bank 1
*/
Lbl_01_8000:
jmp ($0013)
/**
* jump table bank 1
*/
Lbl_01_8003:
jmp Lbl_01_80a2
Lbl_01_8006:
jmp Lbl_01_8719
etc.
/**
* sample routine, bank 1
*/
Lbl_01_8719:
lda #$17
sta $b3
lda #$d0
sta $b4
lda #$86
sta $95
lda $b5
ror a
ror a
ror a
and #$c0
tay
ldx #$60
Lbl_01_872f:
lda.w Lbl_01_8619,y
sta $0100,x
iny
inx
cpx #$a0
bne Lbl_01_872f
rts
relevant routines modified to use long jumps instead while preserving interface (minus ppu mirror flags, which would probably best be handled in the graphics subsystem instead):
Code: Select all
/**
* jump to subroutine, long (no ppu mirror flag handling here)
*
* @param x (target routine number + 1) * 3
* @param y target bank
*/
Lbl_00_ffcd:
;save previous jump target for whatever reason
php
pei ($13)
;prepare pointer to target bank
rep #$30
lda #Lbl_00_8000
sta $13
sep #$20
tya
sta $15
;execute jump
jsl longJump
;restore previous jump target
rep #$30
pla
sta $13
plp
rts
longJump:
jml [$13]
/**
* trampoline bank 0
*/
Lbl_00_8000:
dex
dex
jsr (Lbl_00_8003,x)
rtl
/**
* jump table bank 0
*/
Lbl_00_8003:
jmp Lbl_00_e7b2
Lbl_00_8006:
jmp Lbl_00_8326
etc.
/**
* trampoline bank 1
*/
Lbl_01_8000:
dex
dex
jsr (Lbl_01_8003,x)
rtl
/**
* jump table bank 1
*/
Lbl_01_8003:
jmp Lbl_01_80a2
Lbl_01_8006:
jmp Lbl_01_8719
etc.
As already hinted at earlier, I'm not actually using the above code snippet, because it feels hackish and not very maintainable to me.
Last edited by d4s on Fri Sep 02, 2011 11:54 am, edited 2 times in total.
- Hamtaro126
- Posts: 783
- Joined: Thu Jan 19, 2006 5:08 pm