ScumSoft, on Sat Apr 30, 2011 1:46 AM, said:
Since I've switched over to using the DPC+ for now, I've run into a whole slew of new issues

I mean fun challenges to overcome.
How do I run a subroutine from another bank? I've looked around but don't understand the procedure.
Switch banks then jump to routine you need? and to switch banks I have to just access the $1FFx slot the bank table has it set to?
Does the bank start at the beginning, or does it continue on the same instruction count as when it was switched, e.g on PC#00E2 -> switch bank -> PC#00E2 ?
Or will the PC reset to 00 and start at the top of the bank.
I'm confused!
[edit]Hmm found
This Link which seems to have explained it pretty well.
So if I wanted to access a 2k table from another bank, how would that work? Would I have to switch banks to read from it?
DPC+ switches the cart's entire 4K memory space, so you'll need one or more bankswitching routines, and they'll need to be replicated at the same locations in all banks.
I know Fred (batari) likes to use a stack/RTS method to switch banks. If you look at the "banksw.asm" code (shown below), you can see how he does it.
; every bank has this stuff at the same place
; this code can switch to/from any bank at any entry point
; and can preserve register values
; note: lines not starting with a space are not placed in all banks
;
; line below tells the compiler how long this is - do not remove
;size=32
begin_bscode
ldx #$ff
ifconst FASTFETCH ; using DPC+
stx FASTFETCH
endif
txs
lda #>(start-1)
pha
lda #<(start-1)
pha
BS_return
pha
txa
pha
tsx
lda 4,x ; get high byte of return address
rol
rol
rol
rol
and #bs_mask ;1 3 or 7 for F8/F6/F4
tax
inx
BS_jsr
lda bankswitch_hotspot-1,x
pla
tax
pla
rts
if ((* & $1FFF) > ((bankswitch_hotspot & $1FFF) - 1))
echo "WARNING: size parameter in banksw.asm too small - the program probably will not work."
echo "Change to",[(*-begin_bscode+1)&$FF]d,"and try again."
endif
I like to use a simpler approach, and I recently created some macros to simplify the process of calling my routines:
MAC SKIP
REPEAT {1}
HEX 00
REPEND
ENDM
MAC GOTO
LDY #[(>{0} & $F0) - $10] / $20
LDX #<{0}
LDA #>{0}
JMP Switch_and_Go
ENDM
MAC GOSUB
LDY #[(>. & $F0) - $10] / $20
STY Return_Bank
LDY #[(>{0} & $F0) - $10] / $20
LDX #<{0}
LDA #>{0}
JSR Switch_and_Go
ENDM
MAC RETURN
JMP Switch_and_Return
ENDM
ORG $6FE6
RORG $BFE6
Switch_and_Go
STX Target_Lo
STA Target_Hi
LDA Select_Bank,Y
JMP (Target)
Switch_and_Return
LDY Return_Bank
LDA Select_Bank,Y
RTS
"Target" is a two-byte variable in zero-page RAM. "Target_Lo" and "Target_Hi" simply redefine the two bytes of "Target."
"Return_Bank" is a one-byte variable in zero-page RAM.
So if I want to switch banks, and the routine I'm jumping to does *not* need to return to where it was called from, I can use "GOTO routine" to switch banks and jump to that routine.
But if I want to switch banks and *return* later, I can use "GOSUB routine" to do that, and then use "RETURN" when I'm ready to return.
The macro code assumes you've got each bank defined with its own logical address space as follows:
ORG $0400
RORG $0000
INCBIN DPCplus.arm
ORG $1000
RORG $1000
SKIP 128
Bank_0 ; User Code
ORG $2000
RORG $3000
SKIP 128
Bank_1 ; User Code
ORG $3000
RORG $5000
SKIP 128
Bank_2 ; User Code
ORG $4000
RORG $7000
SKIP 128
Bank_3 ; User Code
ORG $5000
RORG $9000
SKIP 128
Bank_4 ; User Code
ORG $6000
RORG $B000
SKIP 128
Bank_5 ; User Code
ORG $7000
RORG $D000
SKIP 128
Bank_6 ; DPC+ Display Data
ORG $8000
RORG $1000
Bank_7 ; DPC+ Frequency Table
; Goes up through $83FF
(The "SKIP 128" statement after each "RORG" uses the "SKIP" macro to set aside the first 128 bytes of each user ROM bank, since those bytes are used for the DPC+ registers.)
Note that when you use my method, the original values of the A, X, and Y registers will be lost, so be sure to store them first if you want to get them back later. However, my "Switch_and_Return" routine leaves the X register untouched, so you could "GOSUB" to some subroutine in a given bank, store some return value in the X register, and "RETURN" to the calling location with the return value intact.
Michael