;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ;º º ;º Routine to take the GAMEBOY Tetris source code (or a close approximation º ;º from the Amiga Gameboy emulator and emulate the gameboy by modifying the º ;º code to give a playable version of TETRIS with minimum effort... º ;º º ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ORG 0 DUMP 1,0 DI ;store BASIC and run the game LD (sp.store+&8001),SP IN A,(&FA) LD (low.page+&8001),A IN A,(&FC) LD (scr.page+&8001),A LD A,33 OUT (&FA),A LD A,16 OUT (&F9),A JP here ORG &0038 ;interrupt handler -- plays music DUMP 1,&38 PUSH AF IN A,(&F9) RRA JR C,exit.int PUSH BC PUSH DE PUSH HL PUSH IX PUSH IY CALL 10006 ;music playback routine POP IY POP IX POP HL POP DE POP BC exit.int: POP AF EI RET here: LD SP,&8000 ;set stack, page in screen, set palette LD A,4 OUT (&FB),A LD A,4+96 OUT (&FC),A LD HL,&8000+24576+15 LD BC,&10F8 OTDR CALL 10000 ;initialise music LD HL,&9F5D ;move the NINTENDO logo up the screen as with LD B,72 ;the GAMEBOY on switch on ;) nint.loop: PUSH HL PUSH BC CALL put.nintendo CALL wait.frame LD B,200 DJNZ $ CALL wait.frame POP BC POP HL DEC H DJNZ nint.loop LD B,250 wait.loop: IN A,(&F9) ;wait for a vblank BIT 3,A JR NZ,wait.loop PUSH BC LD B,0 pause: NOP NOP NOP DJNZ pause POP BC DJNZ wait.loop EI JP start_game exit_game: DI XOR A ;clear soundchip, reset line interrupt, LD BC,511 ;return to basic LD D,28 OUT (C),D DEC B OUT (C),A LD A,255 OUT (&F9),A LD A,1 OUT (&FB),A JP here2+&8000 here2: sp.store: LD SP,&0000 low.page: LD A,&00 OUT (&FA),A scr.page: LD A,&00 OUT (&FC),A EI RET ;START of gameboy code... modified by ME to work on the SAM's Z80 ;lines beginning with a ;* are my comments. Code commented out is stuff ;I removed because it wasn't needed. ; modifications for z80 argasm: ; ; even command ; dw's ; out (n),a ; cnops SIZE_Y: EQU 18 SIZE_X: EQU 20 start_game: ; LD A,char_set/256 ; LD (60003),A ; LD A,char_set\256 ; LD (60002),A ; LD A,char_map/256 ; LD (60001),A ; LD A,char_map\256 ; LD (60000),A ;*On the Gameboy, it appears that address &EA62 is written to for ;*setting the character set used on the screen, and ;*&EA60 is written to to set the screen map address... LD HL,char_map XOR A LD BC,SIZE_Y*SIZE_X loop: LD (HL),0; clear the map PUSH AF ;* XOR A ;* CALL write.map ;*do same on screen POP AF ;* INC HL DEC BC LD A,B OR C JR NZ,loop LD HL,char_map CALL draw_wall LD HL,char_map+11 CALL draw_wall LD HL,score.text LD DE,&010D LD (xpos+1),DE CALL put.text LD HL,lines.text LD DE,&060D LD (xpos+1),DE CALL put.text LD HL,shape.text LD DE,&0B0D LD (xpos+1),DE CALL put.text CALL random AND 3 LD (next_shape),A LD A,35 LD (tetris_speed),A LD B,7 rep_loop: XOR A LD (rotation),A LD (new_rot),A LD (char),A LD A,15 LD (shape_x),A LD A,14 LD (shape_y),A CALL draw_nextshape LD A,(next_shape) LD (new_shape),A LD (current_shape),A get_another: CALL random AND 7 JR Z,get_another DEC A LD (next_shape),A LD A,2 LD (char),A CALL draw_nextshape LD A,5 LD (shape_x),A LD (newshape_x),A LD A,1 LD (shape_y),A LD (newshape_y),A CALL display_score main_loop: ;* HALT CALL wait.frame ;* better than a HALT LD A,&F7 IN A,(&F9) RLA RLA RLA JP NC,exit_game LD A,(speed_count) AND 3 JP NZ,no_moving LD A,(newshape_x) LD C,A PUSH BC LD BC,&EFFE IN A,(C) CPL POP BC ;* LD A,(60004) AND 24 JR NZ,xmove_it XOR A LD (lastmove),A JR no_xmove xmove_it: LD B,A LD A,(lastmove) CP B JR NZ,move_active LD A,(move_count) INC A AND 7 JR NZ,xwait CALL inc_seed BIT 4,B JR Z,noqleft DEC C JR x_fin noqleft: INC C JR x_fin xwait: LD (move_count),A JR NZ,no_xmove BIT 4,B JR Z,norepleft DEC C JR x_fin norepleft: INC C JR x_fin move_active: LD A,B LD (lastmove),A XOR A LD (move_count),A BIT 4,B JR Z,noleft DEC C JR x_fin noleft: INC C x_fin: LD A,C LD (newshape_x),A CALL check_shape JR NC,no_xmove LD A,(shape_x) LD (newshape_x),A no_xmove: LD A,(lastfire) OR A JR Z,fire_con XOR A LD (lastfire),A JP no_fire fire_con: PUSH BC LD BC,&EFFE IN A,(C) CPL POP BC ;* LD A,(60004) BIT 0,A JR Z,no_fire LD A,1 LD (lastfire),A LD A,(new_rot) DEC A AND 3 LD (new_rot),A CALL check_shape JR NC,no_fire LD A,(rotation) LD (new_rot),A no_fire: no_moving: CALL update_shape PUSH BC LD BC,&EFFE IN A,(C) CPL POP BC ;* LD A,(60004) LD C,A LD A,(tetris_speed) LD B,A BIT 2,C JR Z,no_down ;*! LD B,3 no_down: LD HL,speed_count INC (HL) LD A,(HL) CP B JP C,main_loop LD (HL),0 LD A,(newshape_y) INC A LD (newshape_y),A CALL check_shape JP NC,main_loop le_fin: LD A,(shape_y) CP 2 JR C,dead_meat LD A,3 LD (char),A CALL draw_shape CALL scan_rows JR Z,none_completed PUSH HL CALL flash_rows CALL remove_rows POP HL LD A,L ADD A,A LD L,A ADD A,A ADD A,A ADD A,L LD C,A LD B,0 CALL add_score LD A,(tetris_speed) DEC A JR Z,none_completed LD (tetris_speed),A none_completed: JP rep_loop dead_meat: CALL game_over LD HL,SIZE_X*SIZE_Y-1+char_map LD C,SIZE_Y splaty: ;HALT CALL wait.frame LD B,SIZE_X splatx: LD (HL),1 LD A,1 CALL write.map DEC HL DJNZ splatx DEC C JR NZ,splaty JP exit_game ;* DEFB &D3 ;is this a special opcode for gameboy??? I think so. display_score: LD HL,score LD DE,3*SIZE_X+13+char_map LD B,5 copy_byte: LD A,(HL) LD (DE),A EX DE,HL CALL write.map EX DE,HL INC HL INC DE DJNZ copy_byte RET random: inc_seed: PUSH HL PUSH BC LD HL,(seed1) LD BC,(seed2) LD A,L RLA RL H RLA RL H RLA RL H SUB 7 XOR C LD L,A LD (seed2),A LD A,H LD (seed2+1),A LD A,C LD (seed1),A LD A,B LD (seed1+1),A LD A,L POP BC POP HL RET draw_wall: LD DE,SIZE_X LD B,SIZE_Y LD A,4 next_part: LD (HL),A CALL write.map ;* ADD HL,DE DJNZ next_part RET scan_rows: LD DE,rowstoremove+3 XOR A LD (DE),A DEC DE LD (DE),A DEC DE LD (DE),A DEC DE LD (DE),A PUSH DE LD C,A LD HL,char_map+1 LD B,SIZE_Y do_nextrow: PUSH BC PUSH HL LD B,10 XOR A chk_nextbyte: CP (HL) JR Z,chk_nextrow INC HL DJNZ chk_nextbyte ; now remove the row LD A,C LD (DE),A INC DE chk_nextrow: POP HL LD BC,SIZE_X ADD HL,BC POP BC INC C DJNZ do_nextrow POP HL XOR A EX DE,HL SBC HL,DE RET remove_rows: LD HL,rowstoremove LD B,4 remove_next: LD A,(HL) CALL remove_a_row INC HL DJNZ remove_next RET remove_a_row: ; a = number of row to remove PUSH BC PUSH HL OR A JR Z,row_0 ADD A,A ADD A,A LD C,A LD L,A LD H,0 LD B,H ADD HL,HL ADD HL,HL ADD HL,BC LD DE,char_map-SIZE_X+10 ADD HL,DE LD E,L LD D,H LD BC,SIZE_X ADD HL,BC SRL A SRL A LD C,A next_row: LD B,10 next_column: LD A,(DE) LD (HL),A CALL write.map DEC HL DEC DE DJNZ next_column LD A,E SUB SIZE_X-10 LD E,A LD A,D SBC A,0 LD D,A LD A,L SUB SIZE_X-10 LD L,A LD A,H SBC A,0 LD H,A DEC C JR NZ,next_row XOR A ; clear top row row_0: CALL clear_row POP HL POP BC RET flash_rows: ; this routine flashes any full lines (if any exist) LD HL,rowstoremove LD DE,temp_store LD A,(HL) INC HL CALL store_row LD A,(HL) INC HL CALL store_row LD A,(HL) INC HL CALL store_row LD A,(HL) INC HL CALL store_row LD C,3 next_flash: LD B,8 pause1: ;* HALT CALL wait.frame ;* PUSH BC LD B,20 DJNZ $ POP BC DJNZ pause1 LD HL,rowstoremove LD A,(HL) INC HL CALL clear_row LD A,(HL) INC HL CALL clear_row LD A,(HL) INC HL CALL clear_row LD A,(HL) INC HL CALL clear_row LD B,8 pause2: ;* HALT CALL wait.frame ;* PUSH BC LD B,20 DJNZ $ POP BC DJNZ pause2 LD HL,rowstoremove LD DE,temp_store LD A,(HL) INC HL CALL restore_row LD A,(HL) INC HL CALL restore_row LD A,(HL) INC HL CALL restore_row LD A,(HL) INC HL CALL restore_row DEC C JR NZ,next_flash fr_exit: RET ;My routine -- wait.frame. Waits for end of gameboy "screen" refresh and ;displays the data. wait.frame: PUSH AF w2: LD A,1 IN A,(&F8) CP 160 JR NZ,w2 POP AF RET store_row: PUSH HL PUSH BC ADD A,A ADD A,A LD C,A LD L,A LD H,0 LD B,H ADD HL,HL ADD HL,HL ADD HL,BC LD BC,char_map+1 ADD HL,BC LD B,10 next_copy: LD A,(HL) LD (DE),A ;* EX DE,HL ;* CALL write.map ;* EX DE,HL INC HL INC DE DJNZ next_copy POP BC POP HL RET restore_row: PUSH HL PUSH BC ADD A,A ADD A,A LD C,A LD L,A LD H,0 LD B,H ADD HL,HL ADD HL,HL ADD HL,BC LD BC,char_map+1 ADD HL,BC LD B,10 next_copy2: LD A,(DE) LD (HL),A CALL write.map ;* INC HL INC DE DJNZ next_copy2 POP BC POP HL RET clear_row: PUSH HL PUSH BC ADD A,A ADD A,A LD C,A LD L,A LD H,0 LD B,H ADD HL,HL ADD HL,HL ADD HL,BC LD BC,char_map+1 ADD HL,BC LD B,10 XOR A next_clear: LD (HL),A CALL write.map ;* INC HL DJNZ next_clear POP BC POP HL RET check_shape: LD A,(new_rot) LD B,A LD A,(new_shape) CALL calc_addr LD B,4 ; 4 blocks ; hl now points to the shape offsets check_it: LD DE,(newshape_x) LD A,(HL) ADD A,E CP SIZE_X JR NC,check_error; off limits LD E,A INC HL LD A,(HL) ADD A,D CP SIZE_Y JR NC,check_error LD D,A INC HL PUSH HL PUSH BC LD A,D ADD A,A ADD A,A LD C,A LD L,A LD H,0 LD B,H ADD HL,HL ADD HL,HL ADD HL,BC LD A,L ADD A,E LD L,A LD A,H ADC A,0 LD H,A LD DE,char_map ADD HL,DE LD A,(HL) POP BC POP HL CP 2 JR Z,no_check OR A ; overwriting something JR NZ,check_error no_check: DJNZ check_it XOR A RET check_error: SCF RET calc_addr: ADD A,A ADD A,A ADD A,A ADD A,A ADD A,A LD E,A LD D,0 LD HL,shapes ADD HL,DE LD A,B ADD A,A ADD A,A ADD A,A ADD A,L LD L,A LD A,H ADC A,0 LD H,A RET draw_nextshape: XOR A LD B,A LD A,(next_shape) JP drawnext draw_shape: LD A,(rotation) LD B,A LD A,(current_shape) drawnext: CALL calc_addr LD B,4 ; 4 blocks ; hl now points to the shape offsets loop_it: LD DE,(shape_x) LD A,(HL) ADD A,E LD E,A INC HL LD A,(HL) ADD A,D LD D,A INC HL CALL draw_square DJNZ loop_it RET draw_square: ; de = y,x PUSH BC PUSH HL LD A,D ADD A,A ADD A,A LD C,A LD L,A LD H,0 LD B,H ADD HL,HL ADD HL,HL ADD HL,BC LD BC,char_map ADD HL,BC LD A,E ADD A,L LD L,A LD A,H ADC A,0 LD H,A LD A,(char) LD (HL),A CALL write.map ;* POP HL POP BC RET put_letter: EX AF,AF' xpos: LD DE,&0000 PUSH BC PUSH HL LD A,D ADD A,A ADD A,A LD C,A LD L,A LD H,0 LD B,H ADD HL,HL ADD HL,HL ADD HL,BC LD BC,char_map ADD HL,BC LD A,E ADD A,L LD L,A LD A,H ADC A,0 LD H,A EX AF,AF' LD (HL),A CALL write.map POP HL POP BC INC E LD A,E CP 20 JR NZ,not.overf LD E,0 INC D LD A,D CP 18 JR NZ,not.overf LD D,0 not.overf: LD (xpos+1),DE RET update_shape: XOR A LD (char),A LD HL,(newshape_x) LD DE,(shape_x) SBC HL,DE JR NZ,has_changed LD A,(new_rot) LD B,A LD A,(rotation) CP B RET Z has_changed: CALL draw_shape; delete old shape LD A,(newshape_x) LD (shape_x),A LD A,(newshape_y) LD (shape_y),A LD A,(new_shape) LD (current_shape),A LD A,(new_rot) LD (rotation),A LD A,2 LD (char),A CALL draw_shape RET inc_score: LD HL,score+4 inc_next: INC (HL) LD A,(HL) CP 5+10 RET C LD (HL),5 DEC HL JP inc_next add_score: CALL inc_score DEC BC LD A,B OR C JP NZ,add_score RET ;My routine to write to screen for the character map. write.map: PUSH BC PUSH DE PUSH AF PUSH HL PUSH HL LD H,0 LD L,A ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,HL LD DE,font ADD HL,DE EX DE,HL POP HL RES 6,H ADD HL,HL PUSH DE LD DE,addresses ADD HL,DE LD E,(HL) INC HL LD D,(HL) EX DE,HL SET 7,H POP BC LD D,8 main.char: PUSH DE LD A,(BC) LD (HL),A INC L INC BC LD A,(BC) LD (HL),A INC L INC BC LD A,(BC) LD (HL),A INC L INC BC LD A,(BC) INC BC LD (HL),A LD DE,125 ADD HL,DE POP DE DEC D JR NZ,main.char POP HL POP AF POP DE POP BC RET put.text: LD A,(HL) INC HL CP 255 RET Z PUSH HL LD L,A LD H,0 LD DE,font.conv ADD HL,DE LD A,(HL) POP HL CALL put_letter JR put.text temp_store: DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 rowstoremove: DEFB 0,0,0,0,0 move_count: DEFB 0 lastmove: DEFB 0 lastfire: DEFB 0 shape_x: DEFB 0 shape_y: DEFB 0 current_shape: DEFB 0 rotation: DEFB 0 char: DEFB 0 next_shape: DEFB 0 newshape_x: DEFB 0 newshape_y: DEFB 0 new_shape: DEFB 0 new_rot: DEFB 0 tetris_speed: DEFB 0 speed_count: DEFB 0 seed1: DEFW 3 seed2: DEFW 4 score: DEFB 5,5,5,5,5 shapes: shape1: ; long DEFB -1,0,0,0,1,0,2,0 DEFB 0,-1,0,0,0,1,0,2 DEFB 1,0,0,0,-1,0,-2,0 DEFB 0,1,0,0,0,-1,0,-2 shape2: ; square DEFB 0,0,0,1,1,1,1,0 DEFB 0,0,0,1,1,1,1,0 DEFB 0,0,0,1,1,1,1,0 DEFB 0,0,0,1,1,1,1,0 shape3: ; s-shape 1 DEFB -1,1,0,1,0,0,1,0 DEFB -1,-1,-1,0,0,0,0,1 DEFB -1,1,0,1,0,0,1,0 DEFB -1,-1,-1,0,0,0,0,1 shape4: ; s-shape 2 DEFB -1,-1,0,-1,0,0,1,0 DEFB 1,-1,1,0,0,0,0,1 DEFB -1,-1,0,-1,0,0,1,0 DEFB 1,-1,1,0,0,0,0,1 shape5: ; l-shape 1 DEFB 0,-1,0,0,0,1,1,1 DEFB -1,1,-1,0,0,0,1,0 DEFB -1,-1,0,-1,0,0,0,1 DEFB -1,0,0,0,1,0,1,-1 shape6: ; l-shape 2 DEFB -1,0,0,0,1,0,1,1 DEFB 0,-1,0,0,0,1,-1,1 DEFB -1,-1,-1,0,0,0,1,0 DEFB 1,-1,0,-1,0,0,0,1 shape7: ; t-shape DEFB -1,0,0,0,1,0,0,1 DEFB 0,-1,0,0,0,1,-1,0 DEFB -1,0,0,0,1,0,0,-1 DEFB 0,-1,0,0,0,1,1,0 ;My copy routines and NINTENDO logo put routines... put.nintendo: LD A,1 IN A,(&F8) CP 160 JR NZ,put.nintendo LD A,160 SUB H CP 8 JR C,okay LD A,8 okay: SCF RR H RR L LD DE,nintendo.logo EX DE,HL copy.stuff: PUSH AF PUSH DE LD BC,35 LDIR POP DE PUSH HL LD HL,128 ADD HL,DE EX DE,HL POP HL POP AF DEC A JR NZ,copy.stuff RET ;My GAMEOVER routine game.mess: DEFM "GAMEOVER" game_over: LD DE,temp_store LD HL,game.mess LD B,8 conv.loop: LD A,(HL) INC HL PUSH HL PUSH DE LD L,A LD H,0 LD DE,font.conv ADD HL,DE LD A,(HL) POP DE POP HL LD (DE),A INC DE DJNZ conv.loop LD HL,8*SIZE_X+4+char_map LD BC,4 LDIR LD HL,9*SIZE_X+4+char_map LD BC,4 LDIR LD B,15 over.loop: PUSH BC CALL wait.frame LD DE,temp_store CALL put.game.line CALL pause.delay CALL wait.frame CALL put.game.line CALL pause.delay POP BC DJNZ over.loop RET pause.delay: LD B,25 pause.d2: PUSH BC pause.d1: LD A,1 IN A,(&F8) CP 160 JR NZ,pause.d1 LD B,40 DJNZ $ POP BC DJNZ pause.d2 RET put.game.line: LD HL,8*SIZE_X+4+char_map LD A,(DE) CALL write.map INC DE INC HL LD A,(DE) CALL write.map INC DE INC HL LD A,(DE) CALL write.map INC DE INC HL LD A,(DE) INC DE CALL write.map LD HL,9*SIZE_X+4+char_map LD A,(DE) CALL write.map INC DE INC HL LD A,(DE) CALL write.map INC DE INC HL LD A,(DE) CALL write.map INC DE INC HL LD A,(DE) INC DE CALL write.map RET lines.text: DEFM "LINES" DEFB 255 score.text: DEFM "SCORE" DEFB 255 shape.text: DEFM "NEXT" DEFB 255 nintendo.logo: MDAT "ninten.lgo" font: MDAT "ninfnt.dat" font.conv: MDAT "font.tbl" ;This was the original numbers font and blocks for the game. ;Not needed now I've patched the character set... char_set: ; DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; DEFB 170,0,85,0,170,0,85,0 ; DEFB 170,0,85,0,170,0,85,0 ; DEFB 255,0,129,36,129,126,129,36 ; DEFB 129,36,129,126,129,36,255,0 ; DEFB 255,0,129,36,129,126,129,36 ; DEFB 129,36,129,126,129,36,255,0 ; DEFB 255,255,16,255,16,255,16,255 ; DEFB 255,255,66,255,66,255,66,255 ; ; DEFB %00000000,0 ; DEFB %01111100,0 ; DEFB %11001110,0 ; DEFB %11011110,0 ; DEFB %11110110,0 ; DEFB %11100110,0 ; DEFB %11000110,0 ; DEFB %01111100,0 ; ; DEFB %00000000,0 ; DEFB %00110000,0 ; DEFB %01110000,0 ; DEFB %11110000,0 ; DEFB %00110000,0 ; DEFB %00110000,0 ; DEFB %00110000,0 ; DEFB %11111100,0 ; ; DEFB %00000000,0 ; DEFB %01111000,0 ; DEFB %11000110,0 ; DEFB %00001100,0 ; DEFB %00011000,0 ; DEFB %01100000,0 ; DEFB %11000000,0 ; DEFB %11111110,0 ; ; DEFB %00000000,0 ; DEFB %11111110,0 ;DEFB %00001100,0 ;DEFB %00011000,0 ;DEFB %00000110,0 ; DEFB %00000110,0 ; DEFB %11000110,0 ; DEFB %01111100,0 ; ; DEFB %00000000,0 ; DEFB %00001100,0 ; DEFB %00011100,0 ; DEFB %00111100,0 ; DEFB %01101100,0 ; DEFB %11001100,0 ; DEFB %11111110,0 ; DEFB %00001100,0 ; DEFB %00000000,0 ; DEFB %11111110,0 ; DEFB %11000000,0 ; DEFB %11111100,0 ; DEFB %00000110,0 ; DEFB %00000110,0 ; DEFB %11000110,0 ; DEFB %01111100,0 ; ; DEFB %00000000,0 ; DEFB %01110000,0 ; DEFB %11000000,0 ; DEFB %11111100,0 ; DEFB %11000110,0 ; DEFB %11000110,0 ; DEFB %11000110,0 ; DEFB %01111100,0 ; ; DEFB %00000000,0 ; DEFB %11111110,0 ; DEFB %00000110,0 ; DEFB %00001100,0 ; DEFB %00011000,0 ; DEFB %00011000,0 ; DEFB %00011000,0 ; DEFB %00011000,0 ; ; DEFB %00000000,0 ; DEFB %01111100,0 ; DEFB %11000110,0 ; DEFB %01111100,0 ; DEFB %11000110,0 ; DEFB %11000110,0 ; DEFB %11000110,0 ; DEFB %01111100,0 ; ; DEFB %00000000,0 ; DEFB %01111110,0 ; DEFB %11000110,0 ; DEFB %11000110,0 ; DEFB %00111110,0 ; DEFB %00000110,0 ; DEFB %00000110,0 ; DEFB %00000110,0 ; ORG 10000 DUMP 1,10000 MDAT "music" ORG &4000 DUMP 2,0 char_map: DEFS 20*18 ; DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; addresses: MDAT "addrtable" ORG &8000 DUMP 4,0 MDAT "gameboy" ;gameboy screen surrounds...