// assembler: bass v17 // command: `bass -o gb-test.gb gb-test.bass.txt` architecture gb.cpu // Jump to any arbitrary location in ROM macro seek(variable bank, variable offset) { origin (bank * $4000) + (offset % $4000) base offset } // Calls code in another bank macro farcall(variable bank, variable location) { ld a, bank ld hl, location rst 00h } // Attempt to define some WRAM variables namespace wram { variable i = $c000 // start here constant current_bank = i;i=i+ 1 // current_bank is 1 bytes long constant test_var = i;i=i+ 2 // test_var is 2 bytes long // etc. } namespace hram { variable i = $ff80 // start here constant buffer = i;i=i+ 1 // buffer is 1 bytes long // etc. } namespace hardware { constant rombank = $2000 } ///////// home bank /////////////// namespace home { // interrupt and rst's seek(0, $00); jp Bankswitch // rst 00 seek(0, $08); reti // rst 08 seek(0, $10); reti // rst 10 seek(0, $18); reti // rst 18 seek(0, $20); reti // rst 20 seek(0, $28); reti // rst 28 seek(0, $30); reti // rst 30 seek(0, $38); reti // rst 38 seek(0, $40); jp VBlank // VBlank seek(0, $48); reti // LCDC seek(0, $50); reti // Timer seek(0, $58); reti // Serial seek(0, $60); reti // HiLo // header seek(0, $100) nop jp Init // jump to init // nintendo logo db $CE,$ED,$66,$66,$CC,$0D,$00,$0B,$03,$73,$00,$83,$00,$0C,$00,$0D db $00,$08,$11,$1F,$88,$89,$00,$0E,$DC,$CC,$6E,$E6,$DD,$DD,$D9,$99 db $BB,$BB,$67,$63,$6E,$0E,$EC,$CC,$DD,$DC,$99,$9F,$BB,$B9,$33,$3E // meta db "TEST ROM " // title db $00 // cgb enabled db "ZU" // new licensee code db $00 // sgb enable db $12 // cart type db $00 // rom size db $00 // ram size db $01 // international db $33 // use new code db $00 // rom version db 0 // header chksum (use another tool?) dw 0 // global chksum (use another tool?) // routines function Init { // which bank is loaded by default ld a, 1 ld (wram.current_bank),a // do stuff call bank1.routine purgatory: halt nop jr purgatory } function VBlank { reti } // a = bank // hl = location function Bankswitch { ldh ((hram.buffer & $ff)),a // take the low byte of hram.buffer ld a,(wram.current_bank) push af ldh a,((hram.buffer & $ff)) ld (wram.current_bank),a ld (hardware.rombank),a call + pop af ld (wram.current_bank),a ld (hardware.rombank),a ret +; jp hl } } ///////// bank 1 /////////////// seek(1, $4000); namespace bank1 { function routine { farcall(2, bank2.routine) ret } } ///////// bank 2 /////////////// seek(2, $4000); namespace bank2 { function routine { variable x = 0 ld a, 0 while (x < 5) { ld (wram.test_var),a inc a x = x+1 } ret } }