Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; to do:
- ; main game loop
- ; sprite movement
- JOYPAD_REGISTER equ $00 ; joypad
- PAD_PORT_DPAD equ %00100000 ; select d-pad buttons
- PAD_PORT_BUTTONS equ %00010000 ; select other buttons
- PAD_OUTPUT_MASK equ %00001111 ; mask for the output buttons
- DPAD_DOWN equ 7 ; down is 7, example: cp 7 is it the down button?
- DPAD_UP equ 6 ; up is 6
- DPAD_LEFT equ 5 ; left is 5
- DPAD_RIGHT equ 4 ; right is 4
- START_BUTTON equ 3
- SELECT_BUTTON equ 2
- B_BUTTON equ 1
- A_BUTTON equ 0 ; down to here
- DPAD_DOWN_MASK equ %10000000 ; masks for the buttons
- DPAD_UP_MASK equ %01000000
- DPAD_LEFT_MASK equ %00100000
- DPAD_RIGHT_MASK equ %00010000
- START_BUTTON_MASK equ %00001000
- SELECT_BUTTON_MASK equ %00000100
- B_BUTTON_MASK equ %00000010
- A_BUTTON_MASK equ %00000001
- DIV_REGISTER equ $04 ; divide timer... read to get time, write to reset it to 0
- TIMA_REGISTER equ $05 ; main timer... freq is set in TAC reg, generates interupt when overflows
- TMA_REGISTER equ $06 ; Timer Modulo... main timer loaded with this value after it overflows
- TAC_REGISTER equ $07 ; Timer Control
- TIMER_STOP equ %00000100 ; timer halt flag... 0=stop, 1=run
- TIMER_FREQ_MASK equ %00000011 ; mask for timer frequency bits
- TIMER_FREQ_4KHz equ %00000000 ; main timer runs at 4.096 KHz
- TIMER_FREQ_262KHz equ %00000001 ; main timer runs at 262.144 KHz
- TIMER_FREQ_65KHZ equ %00000010 ; main timer runs at 65.536 KHz
- TIMER_FREQ_16KHz equ %00000011 ; main timer runs at 15.384 KHz
- IRQ_FLAG_REGISTER equ $0F ; Interrupt Flag
- VBLANK_INT equ %00000001 ; bit 0 = vblank interrupt on/off
- LCDC_INT equ %00000010 ; bit 1 = LCDC interrupt on/off
- TIMER_INT equ %00000100 ; bit 2 = Timer Overflow interrupt on/off
- SERIAL_INT equ %00001000 ; bit 3 = Serial I/O Transfer Completion interrupt on/off
- CONTROLLER_INT equ %00010000 ; bit 4 = ??
- LCDC_CONTROL equ $40 ; LCD (Graphics) Control
- BKG_DISP_FLAG equ %00000001 ; bit 0 = background tile map is on if set
- SPRITE_DISP_FLAG equ %00000010 ; bit 1 = sprites are on if set
- SPRITE_DISP_SIZE equ %00000100 ; bit 2 = sprite size (0=8x8 pixels, 1=16x8)
- BKG_MAP_LOC equ %00001000 ; bit 3 = background tile map location (0=$9800-$9bff, 1=$9c00-$9fff)
- TILES_LOC equ %00010000 ; bit 4 = tile data location (0=$8800-$97ff, 1=$8000-$8fff)
- WINDOW_DISP_FLAG equ %00100000 ; bit 5 = window tile map is on if set
- WINDOW_MAP_LOC equ %01000000 ; bit 6 = window tile map location (0=$9800-$9bff, 1=$9c00-9fff)
- DISPLAY_FLAG equ %10000000 ; bit 7 = LCD display on if set
- LCDC_STATUS equ $41 ; LCDC Status
- DISP_CYCLE_MODE equ %00000011 ; mask for the display cycle mode bits
- VBLANK_MODE equ %00000000 ; system is in vertical blanking interval
- HBLANK_MODE equ %00000001 ; system is in a horizontal blanking interval
- SPRITE_MODE equ %00000010 ; system is reading sprite RAM
- LCD_TRANSFER equ %00000011 ; system is transfering data to the LCD driver
- SCROLL_BKG_Y equ $42 ; vertical scroll position of background tile map
- SCROLL_BKG_X equ $43 ; horizontal scroll position of background tile map
- LCDC_LY_COUNTER equ $44 ; increments every scan line (0..143 = display, 144-153 = vblank)
- LY_COMPARE equ $45 ; ??
- DMA_REGISTER equ $46 ; DMA Transfer and Start Address
- PALETTE_BKG equ $47 ; palette data for background tile map
- PALETTE_SPRITE_0 equ $48 ; sprite palette 0 data
- PALETTE_SPRITE_1 equ $49 ; sprite palette 1 data
- POS_WINDOW_Y equ $4A ; window tile map Y position
- POS_WINDOW_X equ $4B ; window tile map X position
- INTERRUPT_ENABLE equ $ff ; Interrupt Enable
- ; $ff80 to $fffe is 128 bytes of internal RAM
- STACK_TOP equ $fff4 ; put the stack here
- ; video ram display locations
- TILES_MEM_LOC_0 equ $8800 ; tile map tiles only
- TILES_MEM_LOC_1 equ $8000 ; tile maps and sprite tiles
- MAP_MEM_LOC_0 equ $9800 ; background and window tile maps
- MAP_MEM_LOC_1 equ $9c00 ; (select which uses what mem loc in LCDC_CONTROL register)
- SPRITE_ATTRIB_MEM_LOC equ $fe00 ; OAM memory (sprite attributes)
- ; sprite attribute flags
- SPRITE_FLAGS_PAL equ %00010000 ; palette (0=sprite pal 0, 1=sprite pal 1)
- SPRITE_FLAGS_XFLIP equ %00100000 ; sprite is horizontal flipped
- SPRITE_FLAGS_YFLIP equ %01000000 ; sprite is vertical flipped
- SPRITE_FLAGS_PRIORITY equ %10000000 ; sprite display priority (0=on top bkg & win, 1=behind bkg & win)
- SECTION "rst 00", ROM0 [$00]
- rst $38
- SECTION "rst 08", ROM0 [$08]
- rst $38
- SECTION "rst 10", ROM0 [$10]
- rst $38
- SECTION "rst 18", ROM0 [$18]
- rst $38
- SECTION "rst 28", ROM0 [$20]
- rst $38
- SECTION "rst 30", ROM0 [$30]
- rst $38
- SECTION "rst 38", ROM0 [$38]
- rst $38
- ; hardware interrupts
- SECTION "vblank", ROM0 [$40]
- jp VBlank
- SECTION "hblank", ROM0 [$48]
- rst $38
- SECTION "timer", ROM0 [$50]
- reti
- SECTION "serial", ROM0 [$58]
- reti
- SECTION "joypad", ROM0 [$60]
- reti
- SECTION "Entry", ROM0 [$100]
- nop ; one cpu cycle, four clock cycles
- jp Start ; enter the program
- SECTION "Header", ROM0 [$104]
- ds $150 - $104 ; rgbfix
- SECTION "Main", ROM0 [$150]
- Start::
- ld sp, STACK_TOP ; top of sp
- ld a, VBLANK_INT
- ldh [INTERRUPT_ENABLE], a
- sub a
- ldh [LCDC_STATUS], a ; 0
- ldh [LCDC_CONTROL], a ; 0
- ld [vblank_flag], a ; reset the vblank flag
- ; load our tiles
- ld bc, TitleTiles
- call LoadTitleTiles
- ; load title screen data
- ld bc, TitleScreenData
- call LoadTitleScreen
- call InitSprites ; clear sprites
- call InitPalettes ; set palettes
- ld a, DISPLAY_FLAG | BKG_DISP_FLAG | SPRITE_DISP_FLAG | TILES_LOC | WINDOW_MAP_LOC
- ldh [LCDC_CONTROL], a
- jp titleKeyLoop ; wait for key to be pressed
- ; ----------------------------------
- ; START OF ACTUAL GAME
- ; GAME LOOP INCLUDED
- ; ----------------------------------
- gameStart::
- GameLoop::
- ; ----------------------
- ; SECTION FOR LOADING TILES/TILESETS
- ; ----------------------
- ; routine to load tiles into vram
- BYTES_PER_TILE = 16
- LoadTitleTiles::
- ld bc, TitleTiles
- ld hl, TILES_MEM_LOC_0
- ld e, 5
- .tile
- ld d, BYTES_PER_TILE
- .byte
- .wait
- ld a, [LCDC_STATUS]
- and SPRITE_MODE
- jr nz, .wait
- ld a, [bc]
- ld [hli], a
- inc bc
- dec d
- jr nz, .byte
- dec e
- jr nz, .tile
- ret
- ; routine to show title screen
- LoadTitleScreen::
- ld hl, MAP_MEM_LOC_0 ; load the map to map bank 0
- ld e, $04 ; 4 blocks (32x32 tiles, 1024 bytes)
- .tile
- ld d, $00 ; 256 bytes per "block"
- .wait
- ; only write during
- ldh a, [LCDC_STATUS] ; get the status
- and SPRITE_MODE ; don't write during sprite and transfer modes
- jr nz, .wait
- ld a, [bc] ; get the next value from the source
- ld [hli], a ; load the value to the destination, incrementing dest. ptr
- inc bc ; increment the source ptr
- ; now loop de times
- dec d
- jp nz, .byte
- dec e
- jp nz, .tile
- ret
- ; --------------------------
- ; END
- ; --------------------------
- ; hide the sprites
- HideSprites::
- xor a
- ld hl, SPRITE_ATTRIB_MEM_LOC
- ld b, 40 * 4
- .loop
- ld [hli], a
- dec b
- jr nz, .loop
- ret
- ; this routine waits for a key to be pressed
- ; when A is pressed, it jumps to our actual game start
- titleKeyLoop::
- call Joypad ; read joypad
- ld a, [joypad_down] ; get the last button down
- bit A_BUTTON, a ; was it the a button?
- jr z, .key_loop ; if not, keep looping
- jp gameStart
- .key_loop
- jr titleKeyLoop ; loop it
- ; function to read joypad info
- Joypad::
- ld a, PAD_PORT_DPAD ; select dpad
- ldh [JOYPAD_REGISTER], a ; send to joypad
- ldh a, [JOYPAD_REGISTER]
- ldh a, [JOYPAD_REGISTER]
- ldh a, [JOYPAD_REGISTER]
- ldh a, [JOYPAD_REGISTER]
- ldh a, [JOYPAD_REGISTER]
- ldh a, [JOYPAD_REGISTER] ; get result back
- cpl ; bit flip it
- ld b, a
- and PAD_OUTPUT_MASK ; mask out output bits
- swap a
- ld b, a
- ; get a, b, select, and start buttons
- ld a, PAD_PORT_BUTTONS ; buttons
- ldh [JOYPAD_REGISTER], a ; send to joypad
- ldh a, [JOYPAD_REGISTER]
- ldh a, [JOYPAD_REGISTER]
- ldh a, [JOYPAD_REGISTER]
- ldh a, [JOYPAD_REGISTER]
- ldh a, [JOYPAD_REGISTER]
- ldh a, [JOYPAD_REGISTER] ; get result back
- cpl ; bit flip result
- and PAD_OUTPUT_MASK ; mask out output bits
- or b
- ld b, a
- ; calculate buttons that went down since last joypad read
- ld a, [joypad_held] ; get last button bits
- cpl ; invert
- and b
- ld [joypad_down], a
- ld a, b
- ld [joypad_held], a
- ld a, $30 ; reset joypad
- ldh [JOYPAD_REGISTER], a ; send back
- ret ; done
- ; -----------------
- ; Init functions, these routines are called at the beginning of the code.
- ; -----------------
- InitPalettes::
- ld a, %10010011 ; set palette colors
- ; load to all the palettes
- ldh [PALETTE_BKG], a
- ldh [PALETTE_SPRITE_0], a
- ldh [PALETTE_SPRITE_1], a
- InitSprites::
- ld hl, $c000
- ld b, 40*4
- ld a, $ff
- .init_sprites_loop
- ld [hli], a
- dec b
- jr init_sprites_loop
- ret
- ; ----------------------
- ; copy block of data
- ; de = destination
- ; hl = source
- ; b = number of bytes to copy
- ; -----------------------
- CopyData::
- push af
- .copy_block_loop
- ld a, [hli]
- ld [de], a
- inc de
- dec b
- jr nz, copy_block_loop
- pop af
- ret
- ; ---------------
- ; vblank function
- ; ---------------
- VBlank::
- di
- push af
- ld a, $c0 ; dma from $c000
- ldh [DMA_REGISTER], a ; start DMA
- ld a, $28 ; wait for 160 microseconds
- .vblank_dma_wait
- dec a
- jr nz, .vblank_dma_wait
- ld hl, $fe00 ; sprite memo
- ld a, 1
- ld [vblank_flag], a
- pop af
- ei
- reti
- TitleTiles::
- INCLUDE "titleTiles.z80" ; title screen tileset
- TitleScreenData::
- INCLUDE "titleScreen.z80" ; title screen
- SECTION "RAMSprites",BSS[$C000]
- playerx:
- ds 1
- playery:
- ds 1
- playerTile:
- ds 1
- playerFlags:
- ds 1
- SECTION "RAM",BSS[$C0A0]
- joypad_held:
- ds 1
- joypad_down:
- ds 1
- vblank_flag:
- ds 1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement