Question 1:
I did actually try using .logical but I only got errors as I was already using sections and stuff. Besides NMI is not at $8000 but rather somewhere after that. I also tried doing .logical $808000+_fast but it would produce another error ("can't figure out stable address for _fast" or something like that).Oziphantom wrote: ↑Sat Nov 14, 2020 12:47 amMultiple ways to do this.Pokun wrote: ↑Fri Nov 13, 2020 9:56 amNow there is just how to do a dummy long jump to bank $80 so that the SNES high-speed mode benefits kicks in.How would I make this label "fast" have the bank byte $80? In WLA-DX it's as easy as sticking in ".base $80" before the label, but I see no such option in 64tass.Code: Select all
NMI: ;in bank $00 jml fast fast: ;in bank $80 ...
Edit: Answering my own question, after trying out various things this appears to work:This assembles to 5C xx 80 80 (long jump to $8080xx) instead of 5C xx 80 00 (long jump to $0080xx).Code: Select all
NMI: jml fast+$800000 ;long jump to bank $80 fast: ...
Too simple! No need for a .base directive.
as you discovered adding $80000 works, but not really the right way.
the proper way would beThis way all code will be treated and encoded as if it is in bank 80. Maybe something else will jump to a label and this way all labels here after will be in bank $80 as seen by the assembler.Code: Select all
NMI jml _fast .logical $808000 _fast ... .here
However ; for a snes project the linear map of the ROM doesn't always match the memory map. LoROM for example so I would expect you have a "map" header where you do something along the lines ofIf the earlier code thinks it is in $008000 vs $808000 that is fine as the vectors will be taking a <>NMI which is only 16 bits, and if the assembler puts the INIT code where it thinks it is 808000 not 008000 it doesn't matter.Code: Select all
.logical $808000 .dsection BANK00 .here ; maybe put vectors here? .align $8000 ; fill up empty bank space .logical $818000 .dsection BANK01 .here ....
Something I didn't do however, was putting ROM bank 0 in "65816 bank"* $80, but rather in bank $00. I did this because I thought the vector table must be in bank $00, but didn't realize that I can put only that part in bank $00. Now I did just this by moving the code/data section of the first ROM bank into bank $80. This produced a lot of errors first, but they where fixed by using the low-word operator <> on label references to make them 16-bit. Although the program works, this move made the errors I defined using .cerror (like in the examples in the manual) to stop working, even if I try exceeding the section limit. Errors for the RAM map do work as they should however.
BTW I was only using one ROM bank at first (I think anything more than 32 kB ROM is overkill for a hello world or other small program), but increased this to two ROM banks just to make sure multiple ROM banks works.
Here is the shell of my program, which show its structure. The code inside isn't important for this question.
Code: Select all
;=============================================================================
;ROM Size: 64 kB (2 banks of 32 kB each)
;Mapping: Mode 20 (LoROM)
;Device Speed: Normal (SlowROM)
;Region: NTSC
.cpu "65816" ;set CPU to 65816
.mansiz ;set manual register sizes
.proff ;disable source listing
.enc "ascii" ;define and set encoding "ascii"
.cdef " ~",32 ;include all printable characters
;Address space map:
;Internal WRAM (LowRAM $000000~$001FFF and HighRAM $7E2000~$7FFFFF, 128 kB):
*=$000000 ;Zero Page RAM
.dsection zp ;$000000~$0000FF (256 B)
.cerror * > $000100,"Out of ZP RAM!"
*=$000100 ;LowRAM bss
.dsection bss_lo ;$000100~$001EFF (7 680 B)
.cerror * > $001F00,"Out of LowRAM!"
*=$001F00 ;stack page
.dsection stackpage ;$001F00~$001FFF (256 B)
.cerror * > $002000,"Out of stack RAM!"
*=$7E2000 ;HighRAM bss
.dsection bss_hi ;$7E2000~$7FFFFF (120 kB)
.cerror * > $800000,"Out of HighRAM!"
;ROM bank 0 (808000~$80FFAF and $00FFB0~$00FFFF, 32 kB):
*=$000000
.logical $808000 ;ROM bank 0 program ($80+ mirror)
.dsection rom0_prg ;$808000~$80FFAF (32 688 B)
.cerror * > $80FFB0,"Out of ROM 0!"
.here
*=$007FB0
.logical $00FFB0 ;header and vectors ROM area
.dsection rom0_vector ;$00FFB0~$00FFFF (80 B)
.here
;ROM bank 1 (818000~$81FFFF, 32 kB):
*=$008000
.logical $818000 ;ROM bank 1 start ($80+ mirror)
.dsection rom1 ;$818000~$81FFFF (32 kB)
.cerror * > $81FFFF,"Out of ROM 1!"
.here
;[FIXME] "Out of ROM x" error messages stopped working since ROM banks where
;moved into the $8x banks.
;=============================================================================
; Constants
;=============================================================================
[defines here]
;=============================================================================
; Variables
;=============================================================================
;Internal WRAM definitions:
.section zp ;Zero page ($000000~$0000FF, 256 B)
temp0 .fill 8 ;general-purpose work register
temp1 .fill 8 ;general-purpose work register
pointer0 .fill 2 ;general-purpose pointer
pointer1 .fill 2 ;general-purpose pointer
.send
.section bss_lo ;LowRAM bss ($000100~$001EFF, 7 680 B)
.send
.section stackpage ;Stack page ($001F00~$001FFF, 256 B)
stack .fill 256 ;top of LowRAM reserved for stack
.send
.section bss_hi ;HighRAM bss ($7E2000~$7FFFFF, 120 kB)
.send
;=============================================================================
; ROM Bank 0 ($808000~$80FFAF and $00FFB0~$00FFFF)
;=============================================================================
.pron ;enable source listing
.section rom0_prg ;ROM bank 0 program area ($808000~$80FFAF, 32 688 B)
RESET:
[init code here]
jml _fast
_fast: ;jump to mirrored bank $80 to allow high-speed mode
;-----------------------------------------------------------------------------
main:
wai
jmp main
;-----------------------------------------------------------------------------
NMIn:
jml _fast
_fast:
rti
;-----------------------------------------------------------------------------
BRKn:
jml _fast
_fast:
rti
;-----------------------------------------------------------------------------
IRQn:
jml _fast
_fast:
rti
;-----------------------------------------------------------------------------
;Unused interrupt handlers:
COPn:
ABORTn:
COPe:
ABORTe:
NMIe:
IRQ_BRKe:
jml _fast
_fast:
rti
;-----------------------------------------------------------------------------
;Data:
[data here]
.send
;=============================================================================
; Header ($00FFB0~$00FFDF) and CPU Exception Vectors ($00FFE0~$00FFFF)
;=============================================================================
.section rom0_vector ;headers and vectors ($00FFB0~$00FFFF, 80 B)
;Header:
[header here]
;Native mode vectors (65816 mode):
.byte $00,$00,$00,$00
.word <>COPn ;COP opcode interrupt, unused on Super Famicom/NES
.word <>BRKn ;BRK opcode interrupt
.word <>ABORTn ;unused on Super Famicom/NES
.word <>NMIn ;Vertical blanking interrupt
.byte $00,$00 ;65816 mode has no RESET vector
.word <>IRQn ;H/V-Timer or external interrupt
;Emulation mode vectors (6502 mode):
.byte $00,$00,$00,$00
.word <>COPe ;emulation mode version of COP
.byte $00,$00 ;6502 mode has no separate BRK vector
.word <>ABORTe ;unused on Super Famicom/NES
.word <>NMIe ;NMI vector for 6502 mode
.word <>RESET ;CPU is always in 6502 mode on boot/reset
.word <>IRQ_BRKe ;emulation mode IRQ/BRK vector
.send
;=============================================================================
;ROM bank 1 (818000~$81FFFF)
;=============================================================================
.section rom1 ;ROM bank 1 (818000~$81FFFF, 32 kB)
rom1:
nop
.align $8000,$00 ;0-pad to end of ROM bank
.send
;-----------------------------------------------------------------------------
Question 2:
Do interrupts work if I jump to ROM bank 1 ($818000)? I don't need another vector table in that bank right?
*Rant: Why do we use the same word "bank" for two different things anyway? This is probably one reason SNES dev was such a headache to get into in the past before I realized that ROM banks and 65816 banks are two different concepts.