; skeleton Gameboy 1.0 ; September 3, 2001 ; John Harrison INCLUDE "gbhw.inc" ; hardware definitions INCLUDE "ibmpc1.inc" ; ASCII character set INCLUDE "my_defs.inc" ; my specific definitions (variables, end_byte markers, etc.) ; IRQs SECTION "Vblank",HOME[$0040] jp DMACODELOC ; update sprites SECTION "LCDC",HOME[$0048] reti SECTION "Timer_Overflow",HOME[$0050] reti SECTION "Serial",HOME[$0058] reti SECTION "p1thru4",HOME[$0060] reti ; starting place SECTION "start",HOME[$0100] nop jp begin ; ROM header ROM_HEADER ROM_NOMBC, ROM_SIZE_32KBYTE, RAM_SIZE_0KBYTE INCLUDE "memory.asm" INCLUDE "mymem.asm" ; MY OWN MEMORY ROUTINES INCLUDE "eyeoh.asm" ; MY OWN INPUT/OUTPUT ROUTINES INCLUDE "pvoice.asm" ; MY OWN POCKETVOICE ROUTINES INCLUDE "strings.asm" ; ALL OF THE STRINGS USED INCLUDE "debug.asm" ; DEBUGGING ROUTINES MAY BE ELIMINATED ON COMPLETED PROJECT TileData: chr_IBMPC1 1,8 ; LOAD ENTIRE CHARACTER SET ; ************************************************************** ; ; CODE BEGINS HERE: STANDARD INITIALIZATION ; ; ************************************************************** begin: nop di ld sp, $fff4 call initdma ; move routine to HRAM ld a, IEF_VBLANK ld [rIE],a ; ENABLE ONLY VBLANK INTERRUPT ei ; LET THE INTS FLY call initpv ; INITIALIZE POCKET VOICE call loadflashcode ; LOAD FLASH ROM ROUTINES INTO RAM init: ld a, $e4 ld [rBGP], a ; CLEAR THE SCREEN ld a,0 ld [rSCX], a ld [rSCY], a ; SET TO UPPER RIGHT HAND CORNER call StopLCD ; YOU CAN NOT LOAD $8000 WITH LCD ON ld hl, TileData ld de, $8000 ld bc, 8*256 call mem_CopyMono ; load tile data ld a, LCDCF_ON|LCDCF_BG8000|LCDCF_BG9800|LCDCF_BGON|LCDCF_OBJ16|LCDCF_OBJOFF LD [rLCDC], a ld a, 32 ; BLANK SPACE ld hl, $9800 ld bc, SCRN_VX_B * SCRN_VY_B call mem_SetVRAM ; *** MARKS THE END OF INITIALIZATION FOR A TYPICAL PROGRAM *** start: xor a ld [end_of_buffer], a ld [end_of_buffer+1], a ld hl, MainTitle ld d, 1 ; LINE TO PRINT TO ld e, 1 ; COLUMN TO PRINT TO call print ; SCROLLING PRINT ROUTINE ld hl, Play1L5 ld d, 5 ld e, 1 call print ld d,8 ld e,1 ld hl, Play1L7 call print ld hl, Play1L8 ld e,1 ld d,9 call print P1start: ld hl, Play1L10 ld e,1 ld d,11 call print ld hl, Play1L3 ld d, 3 ld e, 1 call print MainLoopP1: call keywait bit A_KEY, a call nz, RecMain bit UP_KEY, a call nz, PlayMain bit DOWN_KEY, a call nz, RevPlayMain bit SELECT_KEY, a jr z, MainLoopP1 ; SWITCH TO PLAYER 2. call check_for_recording jr nz, GotoP2 call cutloop jr MainLoopP1 GotoP2: call CopyToFlash call geneop ; WITHOUT THIS GB WON'T PLAY FIRST TIME???? ld a, [end_of_buffer] ld [end_of_fbuffer], a ; MOVE LENGTH OF BUFFER TO FLASH LENGTH OF BUFFER VAR ld a, [end_of_buffer+1] ld [end_of_fbuffer+1], a xor a ld [end_of_buffer], a ld [end_of_buffer+1], a ld hl, Play2L3 ld d, 3 ld e, 1 call print ld hl, Play2L6 ld d,6 ld e,1 call print ld hl, Play2L11 ld d,11 ld e,1 call print MainLoopP2: xor a call keywait bit A_KEY, a call nz, RecMain bit UP_KEY, a call nz, PlayMain bit DOWN_KEY, a call nz, RevPlayMain bit B_KEY, a call nz, RevPlayPlayer1 bit START_KEY, a jp nz, GotoP1 jr MainLoopP2 GotoP1: ld hl, FLASHRECBUFFER ld de, RECBUFFER ld a, [end_of_buffer] ld c, a ld a, [end_of_buffer+1] ld b, a call mem_Copy ; COPY CONTENTS OF FLASH BUFFER INTO RAM BUFFER ld a, [end_of_fbuffer] ld [end_of_buffer], a ; MOVE LENGTH OF BUFFER TO RAM LENGTH OF BUFFER VAR ld a, [end_of_fbuffer+1] ld [end_of_buffer+1], a xor a ld [end_of_fbuffer], a ; 0 OUT FLASH BUFFER ld [end_of_fbuffer+1], a ld hl, EraseCmd ld d, 6 ld e,1 call print jp P1start ; COPY BUFFER FROM RAM TO FLASH MEMORY CopyToFlash: ld a, 0 ld [$a003], a ld a, $ff ld [selectmode], a ;DO NOT RECORD AT THE SAME TIME ld a, BANKNUMBER ld [bankno], a ; CHOOSE BANK ld hl, RECBUFFER ld de, FLASHRECBUFFER ld a, [end_of_buffer+1] ld b,a inc b CtoFLoop: push bc call writepage - beginpvflashroutines + RAMLOC ; write 256 bytes pop bc dec b jr nz, CtoFLoop ret RecMain: ld hl, RecordMenu ld d, CMDLINE ld e, 1 call print call rec ld a, l ld [end_of_buffer], a ld a, h ld [end_of_buffer+1], a cutloop: ld hl, EraseCmd ld d, CMDLINE ld e, 1 call print xor a ret PlayMain: call check_for_recording jr z, cutloop ld hl, PlayMenu ld d, CMDLINE ld e, 1 call print ld de, RECBUFFER ld a, [end_of_buffer] ld l, a ld a, [end_of_buffer+1] ld h, a call play ld hl, EraseCmd ld d, CMDLINE ld e, 1 call print xor a ret RevPlayMain: call check_for_recording jr z, cutloop ld hl, RevPlayMenu ld d, CMDLINE ld e, 1 call print ld de, RECBUFFER ld a, [end_of_buffer] ld l, a ld a, [end_of_buffer+1] ld h, a call revplay ld hl, EraseCmd ld d, CMDLINE ld e, 1 call print xor a ret RevPlayPlayer1: ld hl, RevPlayMenu ld d, CMDLINE ld e, 1 call print ld de, FLASHRECBUFFER ld a, [end_of_fbuffer] ld l, a ld a, [end_of_fbuffer+1] ld h, a call revplay ld hl, EraseCmd ld d, CMDLINE ld e, 1 call print xor a ret ; check_for_recording ; OUTPUT: Z FLAG SET IF NO RECORDING check_for_recording: ld a, [end_of_buffer] cp 0 ret nz ld a, [end_of_buffer+1] cp 0 ret nz ld hl, RecFirstInstr ld d, CMDLINE ld e, 1 call print ld bc, $ffff call loop ld bc, $ffff call loop ld bc, $ffff call loop ; DELAY ROUTINE LEAVES Z FLAG SET ON EXIT ret ; loop routine is a time delay we are not using for key test ; LOOPDELAY delays with loop count ; INPUT: BC - LENGTH OF DELAY LoopDelay: dec b dec c loop: inc b inc c inner: dec c jr nz, inner dec b jr nz, inner ret wait: jr wait initdma: ld de, DMACODELOC ld hl, dmacode ld bc, dmaend-dmacode call mem_CopyVRAM ret dmacode: push af ld a, $c0 ; location $c000 ldh [rDMA], a ; Start DMA ld a, $28 ; 160ns dma_wait: dec a jr nz, dma_wait pop af reti dmaend: StopLCD: ld a,[rLCDC] rlca ; Put the high bit of LCDC into the Carry flag ret nc ; Screen is off already. Exit. ; Loop until we are in VBlank .wait: ld a,[rLY] cp 145 ; Is display on scan line 145 yet? jr nz,.wait ; no, keep waiting ; Turn off the LCD ld a,[rLCDC] res 7,a ; Reset bit 7 of LCDC ld [rLCDC],a ret ; ALL OF THE STRINGS ; PRINT NUMBER ROUTINE: ; PRINTS 16 BIT NUMBER IN HEXADECIMAL ; INPUT: LOWER NIBBLE OF A ; OUTPUT: A = ASCII CHARACTER OF LOWER NIBBLE convrt: and $0f add a, $30 cp $3a ret c add a, $7 ret