Mikes360 Posted April 21, 2015 Share Posted April 21, 2015 Hi Guys, I have written a bank switching scheme similar to many others around that use brk followed by the address of a routine. Here is the macro I created MAC BSR // takes routine address as argument BSR_ORIGIN_BANK SET CURRENT_BANK ldx #BANK_{1} brk .word {1} ENDM To make this work you need to make the interrupt vector point to a hotspot bankswitch routine and this is my version. MAC BANK_HOTSPOT ORG BANK_ORIGIN + $FD3 RORG $FFD3 Hotspot dec $FE ldy #1 lda ($FE),y pha dey lda ($FE),y pha dec $FB sta hotspot,x rts ReturnSpot sta hotspot,x rti BYTE_COUNT Hotspot, "Hotspot" ENDM For completeness here is the macro for retuning from a bankswitch routine MAC RBS ldx #BSR_ORIGIN_BANK jmp ReturnSpot ENDM I have found that when using this my code is very sensitive to the address of the routine after the brk instruction for example a brk .word{$F0F4} works fine and brk .word{$F0EF} does not. The difference is the lower byte $EF gets resolved to the following 3 byte illegal opcode: EF *ISC abs 6 $EF: bytes: 3 cycles: 6 A___P=>A___P RW abs and $F4 gets resolved to a two byte illegal opcode: F4 *NOP zpx 4 $F4: bytes: 2 cycles: 4 _____=>_____ R_ zpx Now from looking at stella in the case where it works then I return to the origin bank the program counter gets incremented by two so the next inscription after the brk .word{$F0F4} is executed correctly and everything is fine. However in the case where it is not working brk .word{$F0EF} the program counter is getting incremented by three so subsequent instructions are not executed correctly. Can someone look at my macros and see what I might be doing wrong to cause this behaviour? I hope I have given enough detail to describe the issue I am getting. Thanks, Mike Quote Link to comment Share on other sites More sharing options...
ZackAttack Posted April 22, 2015 Share Posted April 22, 2015 I think what's confusing you is that stella is trying to disassemble the 2 data bytes after the BRK instruction. That's probably not relevant to your issue. It should always be executing the instruction that follow that macro and once it does, the disassembly will fix itself. I think the real problem is the RBS macro. BSR_ORIGIN_BANK will most likely be set to the bank you're already in instead of the bank you just came from. You should try this instead. (NOT TESTED) Basically just keep track of the origin back in a variable. If you call through multiple banks you may need to refactor it to use the stack or allocate an array instead of a single variable. Hope that helps! -Zack MAC BSR // takes routine address as argument ldx #BANK_{1} brk .word {1} ENDM MAC BANK_HOTSPOT ORG BANK_ORIGIN + $FD3 RORG $FFD3 Hotspot LDA #CURRENT_BANK ;Save the current bank in ram so we know what it was later STA originBank ;<-- declare a variable for this dec $FE ldy #1 lda ($FE),y pha dey lda ($FE),y pha dec $FB sta hotspot,x rts ReturnSpot sta hotspot,x rti BYTE_COUNT Hotspot, "Hotspot" ENDM MAC RBS ldx originBank ;can't use the macro here because this will vary at runtime depending on which bank called into this one jmp ReturnSpot ENDM Quote Link to comment Share on other sites More sharing options...
Mikes360 Posted April 22, 2015 Author Share Posted April 22, 2015 (edited) Hi ZackAttack, That is a valid point I was aware of this. In my case I always want to jump back to the first bank so its not been a problem I should just replace the return logic with a ldx #0 for my needs. However the problem I am describing is different and its all to do with how the program counter is being incremented by two of three bytes depending on the contents of the address after brk Here is the failed brk in stella (notice the program counter is being incremented by three which is causing it to go wrong) PC = F0A6 PC = F0A9 And here is the successful brk (program counter being incremented by two PC = F0A6 PC = F0A8 So am I modifying the return address in my hotspot code incorrectly? Edited April 22, 2015 by Mikes360 Quote Link to comment Share on other sites More sharing options...
ZackAttack Posted April 22, 2015 Share Posted April 22, 2015 Yes, the return address should have been F0A8 instead of F0A6. The 2 bytes after the BRK instruction are data and should not be executed. Try incrementing FE twice before RTI Quote Link to comment Share on other sites More sharing options...
Mikes360 Posted April 24, 2015 Author Share Posted April 24, 2015 Hi ZackAttack, Thanks for your recommendation that now works ok now. Nice 3 sprite demo by the way! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.