Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 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)
- ;-------------------------------------------------------------------------
- ; start of the game rom (address 0000)
- ;-------------------------------------------------------------------------
- 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 20", ROM0 [$20]
- rst $38
- SECTION "rst 28", ROM0 [$28]
- rst $38
- SECTION "rst 30", ROM0 [$30]
- rst $38
- SECTION "rst 38", ROM0 [$38]
- rst $38
- ; NOTE: the hardware requires the interrupt jumps to be at these addresses
- SECTION "VBlank_IRQ_Jump",HOME[$0040]
- ; Vertical Blanking interrupt
- jp VBlankFunc
- SECTION "LCDC_IRQ_Jump",HOME[$0048]
- ; LCDC Status interrupt (can be set for H-Blanking interrupt)
- rst $38
- SECTION "Timer_Overflow_IRQ_Jump",HOME[$0050]
- ; Main Timer Overflow interrupt
- reti
- SECTION "Serial_IRQ_Jump",HOME[$0058]
- ; Serial Transfer Completion interrupt
- reti
- SECTION "Joypad_IRQ_Jump",HOME[$0060]
- ; Joypad Button Interrupt
- reti
- SECTION "Entry",HOME[$0100]
- nop ; one cpu cycle (four clock cycles)
- jp title_stuff ; jump to our code
- SECTION "GameBoy_Header_Start",HOME[$0104]
- ds $150 - $104 ; rgbfix
- SECTION "Game_Code_Start",HOME[$0150]
- ; begining of game code
- ; this routine sets up some registers and values, and starts the game
- title_stuff::
- ld sp, STACK_TOP ; put stack where it wants it
- ld a, VBLANK_INT ; get the vblank int
- ldh [INTERRUPT_ENABLE], a ; load it into the interrupt enable
- sub a ; default accumulator value is 1, apparently
- ldh [LCDC_STATUS], a ; 0
- ldh [LCDC_CONTROL], a ; 0
- ld [vblank_flag], a ; reset vblank flag
- ; load the tiles
- ld bc, TitleTiles ; black and white tiles for our title screen
- call LoadTitleTiles
- ld bc, TitleScreenData ; our title screen map, is supported by our tile set which was loaded above.
- call LoadTitleScreen
- call InitSprites ; clear sprites
- call InitPalettes ; init the palettes
- ; setup the screen and other formats
- ld a, DISPLAY_FLAG | BKG_DISP_FLAG | SPRITE_DISP_FLAG | TILES_LOC | WINDOW_MAP_LOC ; load this
- ldh [LCDC_CONTROL], a ; into the LCD control
- call wait_for_key ; wait for a key to be pressed
- ; this routine loads our title screen and shows it.
- LoadTitleScreen::
- ld hl, MAP_MEM_LOC_0 ; lcdc control must be 0
- ld de, 4 * 16
- ld d, $10 ; 16 bytes per tile
- ld e, $05 ; number of tiles to load
- .load_title_loop
- ; only write during
- ldh a, [LCDC_STATUS] ; get the status
- and SPRITE_MODE ; don't write during sprite and transfer modes
- jr nz, .load_title_loop ; ^ loop
- 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
- ; eli5 wait for d/e = 0
- dec d
- jp nz, .load_title_loop ; is d = 0?
- dec e
- jp nz, .load_title_loop ; is e = 0?
- ret ; make sure we return back
- ; this function waits for A to be pressed
- ; when A is pressed, it starts the game, loads the sprites, and the main stuff
- wait_for_key::
- call ReadJoypad ; read the joypad
- ld a, [joypad_down] ; get the button pressed
- bit A_BUTTON, a ; did the player press the a button?
- jr z, .key_loop ; if not, keep looping
- jp start ; otherwise, if the a button was pressed, start the game
- .key_loop
- jr wait_for_key ; loop
- WaitVBL::
- ld a, [vblank_flag]
- cp 0 ; are we in vblank
- jr WaitVBL ; keep looping......
- ;;;;;;;;;
- ; functions below load the title screen tiles, which are blank, white tiles and black tiles
- ;;;;;;;;
- ; note: first load tiles into bc before calling this routine
- LoadTitleTiles::
- ld hl, TILES_MEM_LOC_0 ; load the tiles to tiles bank 0
- ld de, 4 * 16
- ld d, $10 ; 16 bytes per tile
- ld e, $05 ; number of tiles to load
- .load_tilestitle_loop
- ; only write during
- ldh a, [LCDC_STATUS] ; get the status
- and SPRITE_MODE ; don't write during sprite and transfer modes
- jr nz, .load_tilestitle_loop
- 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 til de = 0
- dec d
- jp nz, .load_tilestitle_loop
- dec e
- jp nz, .load_tilestitle_loop
- ret
- start::
- ld a, 1
- ld [LCDC_CONTROL], a ; tiles/map must be loaded into "1" bank
- xor a
- ld a, 16
- ldh [SCROLL_BKG_X], a ; background map will start at 16,16
- ldh [SCROLL_BKG_Y], a
- ld bc, TileData ; our overworld tileset
- call LoadTiles
- ; load the background map
- ld bc, BkgMapData ; our world map, supported by tileset loaded above
- call LoadMapToBkg
- ; init player sprite
- ld a, $40
- ld [spaceship_xpos], a
- ld [spaceship_ypos], a
- ld a, 2
- ld [spaceship_tile], a
- ld a, 0
- ld [spaceship_flags], a
- ; allow interrupts to start occuring
- ei
- jp Game_Loop
- ; main game loop
- Game_Loop::
- ; don't do a frame update unless we have had a vblank
- ld a, [vblank_flag]
- cp 0
- jp z, .end_game_loop
- ; get this frame's joypad info
- call ReadJoypad
- ; adjust sprite due to d-pad presses
- call MoveSpaceship ; yeah I know, I'm dumb
- ; reset vblank flag
- ld a, 0
- ld [vblank_flag], a
- .end_game_loop
- ; time to loop!
- jp Game_Loop
- ;-----------------------------------------------------------------------
- ; copy a block of data
- ;
- ; in: de - destination ptr
- ; hl - source ptr
- ; b - number of bytes to copy
- ;-----------------------------------------------------------------------
- CopyBlock::
- push af ; save af
- .copy_block_loop
- ld a, [hli] ; inc hl
- ld [de], a ; load it into de
- inc de ; inc that
- dec b ; dec that
- jr nz, .copy_block_loop ; then loop
- pop af ; restore af and return
- ret ;
- ;------------------------------------------
- ; init the local copy of the sprites
- ;------------------------------------------
- InitSprites::
- ld hl, $c000 ; my sprites are at $c000
- ld b, 40*4 ; 40 sprites, 4 bytes per sprite
- ld a, $ff
- .init_sprites_loop
- ld [hli], a
- dec b
- jr nz, .init_sprites_loop
- ret
- ;----------------------------------------------------
- ; load the tiles from ROM into the tile video memory
- ;
- ; IN: bc = address of tile data to load
- ;----------------------------------------------------
- LoadTiles::
- ld hl, TILES_MEM_LOC_1 ; load the tiles to tiles bank 1
- ld de, 4 * 16
- ld d, $10 ; 16 bytes per tile
- ld e, $05 ; number of tiles to load
- .load_tiles_loop
- ; only write during
- ldh a, [LCDC_STATUS] ; get the status
- and SPRITE_MODE ; don't write during sprite and transfer modes
- jr nz, .load_tiles_loop
- 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, .load_tiles_loop
- dec e
- jp nz, .load_tiles_loop
- ret
- ;----------------------------------------------------
- ; load the tile map to the background
- ;
- ; IN: bc = address of map to load
- ;----------------------------------------------------
- LoadMapToBkg::
- ld hl, MAP_MEM_LOC_1 ; load the map to map bank 1
- ld d, $00 ; 256 bytes per "block"
- ld e, $04 ; 4 blocks (32x32 tiles, 1024 bytes)
- .load_map_loop
- ; only write during
- ldh a, [LCDC_STATUS] ; get the status
- and SPRITE_MODE ; don't write during sprite and transfer modes
- jr nz, .load_map_loop
- 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, .load_map_loop
- dec e
- jp nz, .load_map_loop
- ret
- ;----------------------------------------------------
- ; init the palettes to basic
- ;----------------------------------------------------
- InitPalettes::
- ld a, %10010011 ; set palette colors
- ; load it to all the palettes
- ldh [PALETTE_BKG], a
- ldh [PALETTE_SPRITE_0], a
- ldh [PALETTE_SPRITE_1], a
- ret
- ;-----------------------------------------------------------------------
- ; read the joypad
- ;
- ; output:
- ; This loads two variables:
- ; joypad_held - what buttons are currently held
- ; joypad_down - what buttons went down since last joypad read
- ;-----------------------------------------------------------------------
- ReadJoypad::
- ; get the d-pad buttons
- ld a, PAD_PORT_DPAD ; select d-pad
- ldh [JOYPAD_REGISTER], a ; send it to the 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 the result back (takes a few cycles)
- cpl ; bit-flip the result
- ; ld b, a
- and PAD_OUTPUT_MASK ; mask out the output bits
- swap a ; put the d-pad button results to top nibble
- ld b, a ; and store it
- ; get A / B / SELECT / START buttons
- ld a, PAD_PORT_BUTTONS ; select buttons
- ldh [JOYPAD_REGISTER], a ; send it to the 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 the result back (takes even more cycles?)
- cpl ; bit-flip the result
- and PAD_OUTPUT_MASK ; mask out the output bits
- or b ; add it to the other button bits
- ld b, a ; put it back in c
- ; calculate the buttons that went down since last joypad read
- ld a, [joypad_held] ; grab last button bits
- cpl ; invert them
- and b ; combine the bits with current bits
- ld [joypad_down], a ; store just-went-down button bits
- ld a, b
- ld [joypad_held], a ; store the held down button bits
- ld a, $30 ; reset joypad
- ldh [JOYPAD_REGISTER],A
- ret ; done
- ;---------------------------------------------------
- ; my vblank routine - do all graphical changes here
- ; while the display is not drawing
- ;---------------------------------------------------
- VBlankFunc::
- di ; disable interrupts
- push af
- ; increment my little timer
- ld a, [ScrollTimer] ; get the scroll timer
- inc a ; increment it
- ld [ScrollTimer], a
- ; load the sprite attrib table to OAM memory
- .vblank_sprite_DMA
- ld a, $c0 ; dma from $c000 (where I have my local copy of the attrib table)
- ldh [DMA_REGISTER], a ; start the dma
- ld a, $28 ; wait for 160 microsec (using a loop)
- .vblank_dma_wait
- dec a
- jr nz, .vblank_dma_wait
- ld hl, SPRITE_ATTRIB_MEM_LOC
- ; set the vblank occured flag
- ld a, 1
- ld [vblank_flag], a
- pop af
- ei ; enable interrupts
- reti ; and done
- MoveSpaceship::
- push af
- ; check buttons for d-pad presses
- .check_for_up
- ld a, [joypad_held]
- bit DPAD_UP, a
- jp z, .check_for_down ; if button not pressed then done
- ; up was held down
- .check_for_upright
- ; is right also held?
- ld a, [joypad_held]
- bit DPAD_RIGHT, a
- jp z, .check_for_upleft
- ; up + right held, so sprite needs to be diagonal
- ld a, 1 ; diagonal sprite is tile 1
- ld [spaceship_tile], a
- ld a, 0 ; flags are no x or y flip
- ld [spaceship_flags], a
- jp .adjust_up_pos
- .check_for_upleft
- ; is left also held?
- ld a, [joypad_held]
- bit DPAD_LEFT, a
- jp z, .set_up_only
- ; up + left held, so sprite needs to be diagonal
- ld a, 1 ; diagonal sprite is tile 1
- ld [spaceship_tile], a
- ld a, SPRITE_FLAGS_XFLIP ; sprite should be x flipped
- ld [spaceship_flags], a
- jp .adjust_up_pos
- .set_up_only
- ; only up was held, so sprite needs to be up
- ld a, 0 ; vertical sprite is tile 0
- ld [spaceship_tile], a
- ld a, 0
- ld [spaceship_flags], a
- .adjust_up_pos
- ; adjust the sprite's position
- ld a, [ScrollTimer] ; only move sprite every 2nd vblank
- and %00000001
- jr nz, .check_for_left
- ; move sprite up a pixel
- ld a, [spaceship_ypos]
- dec a
- ld [spaceship_ypos], a
- ; don't check down, since up + down should never occur
- jp .check_for_left
- .check_for_down
- ld a, [joypad_held]
- bit DPAD_DOWN, a
- jp z, .check_for_left ; if button not pressed then done
- ; down was held down
- .check_for_downright
- ; is right also held?
- ld a, [joypad_held]
- bit DPAD_RIGHT, a
- jp z, .check_for_downleft
- ; down + right held, so sprite needs to be diagonal
- ld a, 1 ; diagonal sprite is tile 1
- ld [spaceship_tile], a
- ld a, SPRITE_FLAGS_YFLIP ; y flip the sprite
- ld [spaceship_flags], a
- jp .adjust_down_pos
- .check_for_downleft
- ; is left also held?
- ld a, [joypad_held]
- bit DPAD_LEFT, a
- jp z, .set_down_only
- ; down + left held, so sprite needs to be diagonal
- ld a, 1 ; diagonal sprite is tile 1
- ld [spaceship_tile], a
- ld a, SPRITE_FLAGS_XFLIP + SPRITE_FLAGS_YFLIP ; sprite should be x and y flipped
- ld [spaceship_flags], a
- jp .adjust_down_pos
- .set_down_only
- ; only down was held, so sprite needs to be down
- ld a, 0 ; vertical sprite is tile 0
- ld [spaceship_tile], a
- ld a, SPRITE_FLAGS_YFLIP
- ld [spaceship_flags], a
- .adjust_down_pos
- ; adjust the sprite's position
- ld a, [ScrollTimer] ; only move sprite every 2nd vblank
- and %00000001
- jr nz, .check_for_left
- ; move sprite up a pixel
- ld a, [spaceship_ypos]
- inc a
- ld [spaceship_ypos], a
- .check_for_left
- ld a, [joypad_held]
- bit DPAD_LEFT, a
- jp z, .check_for_right ; if button not pressed then done
- ; left was pressed
- .check_left_andUpOrDown
- ld a, [joypad_held]
- and DPAD_UP_MASK + DPAD_DOWN_MASK
- jp nz, .adjust_left_pos ; if up or down was pressed, then we already set the sprite attribs
- ; sprite needs to be horizontal
- ld a, 2 ; horizontal sprite is tile 2
- ld [spaceship_tile], a
- ld a, SPRITE_FLAGS_XFLIP
- ld [spaceship_flags], a
- .adjust_left_pos
- ld a, [ScrollTimer] ; only move sprite every 2nd vblank
- and %00000001
- jr nz, .done_checking_dpad
- ; move sprite left one pixel
- ld a, [spaceship_xpos]
- dec a
- ld [spaceship_xpos], a
- jp .done_checking_dpad ; if left was pressed, don't check right
- .check_for_right
- ld a, [joypad_held]
- bit DPAD_RIGHT, a
- jp z, .done_checking_dpad ; if button not pressed then done
- ; right was pressed
- .check_right_andUpOrDown
- ld a, [joypad_held]
- and DPAD_UP_MASK + DPAD_DOWN_MASK
- jp nz, .adjust_right_pos ; if up or down was pressed, then we already set the sprite attribs
- ; sprite needs to be horizontal
- ld a, 2 ; horizontal sprite is tile 2
- ld [spaceship_tile], a
- ld a, 0
- ld [spaceship_flags], a
- .adjust_right_pos
- ld a, [ScrollTimer] ; only move sprite every 2nd vblank
- and %00000001
- jr nz, .done_checking_dpad
- ; move sprite left one pixel
- ld a, [spaceship_xpos]
- inc a
- ld [spaceship_xpos], a
- jp .done_checking_dpad ; if left was pressed, don't check right
- .done_checking_dpad
- ld a, [joypad_down]
- bit A_BUTTON, a
- jr z, .check_b_button
- .check_b_button
- ld a, [joypad_down]
- bit B_BUTTON, a
- jr z, .done_move_ship
- ld a, [scrl_dir_flag]
- xor 1
- ld [scrl_dir_flag], a ; toggle the scroll direction flag
- .done_move_ship
- pop af
- ret
- TitleTiles:
- INCLUDE "titleSet.dat" ; title screen tileset
- TitleScreenData:
- INCLUDE "titleScreen.dat" ; title screen map
- ; tiles are here
- TileData:
- INCLUDE "tgTiles.dat"
- ; map is here
- WorldMap:
- BkgMapData:
- INCLUDE "tgMap.dat"
- ;-------------------------------------------------------------------------
- ; Internal RAM... store dynamic data here
- ;-------------------------------------------------------------------------
- SECTION "RAM_Start_Sprites",BSS[$C000]
- ; local version of sprite attrib table
- spaceship_ypos:
- ds 1
- spaceship_xpos:
- ds 1
- spaceship_tile:
- ds 1
- spaceship_flags:
- ds 1
- SECTION "RAM_Other_Variables",BSS[$C0A0]
- ; other variables
- ; joypad values
- joypad_held:
- ds 1 ; what buttons are currently held
- joypad_down:
- ds 1 ; what buttons went down since last joypad read
- ; scroll values
- world_x:
- ds 2
- world_y:
- ds 2
- x_scrl_accum:
- ds 1
- y_scrl_accum:
- ds 1
- ; bullets (16 of them, 2 bytes for each)
- ; 1st byte = orientation (3 bits) - if $ff, this bullet is unused
- ; 2nd byte = time left to live (in vblanks)
- bullet_data:
- ds 32
- ; frame timing
- vblank_flag:
- ds 1 ; set if a vblank occured since last pass through game loop
- ; scroll direction flag
- scrl_dir_flag:
- ds 1
- ; temp variables
- ScrollTimer:
- ds 1 ; temp variable for slowing down scroll speed
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement