|
@ -4,19 +4,53 @@ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; Assumes 16-bit X & 8-bit A. |
|
|
|
|
|
|
|
|
; Memory layout: |
|
|
|
|
|
; 0000-000F: scratch space for functions. |
|
|
|
|
|
; 0010-0011: controller state of joypad #1. |
|
|
|
|
|
; 0012-0013: controller state of joypad #2. |
|
|
|
|
|
; 0014-0016: 24-bit counter of vblanks. |
|
|
|
|
|
; 0017-0019: RGB color values to use for background color, from [0-31]. |
|
|
|
|
|
; 001A-001B: 16-bit pointer to next random byte. |
|
|
|
|
|
; [gap] |
|
|
|
|
|
; 0020-0021: (x, y) coordinates of player. |
|
|
|
|
|
; 0022: shot cooldown timer. |
|
|
|
|
|
; 0030-0032: enable / x / y of shot. |
|
|
|
|
|
; |
|
|
|
|
|
; Sprite table buffers -- copied each frame to OAM during VBlank, using DMA. |
|
|
|
|
|
; 0100-02FF: table 1 (4 bytes each: x/y coord, tile #, flip/priority/palette) |
|
|
|
|
|
; 0300-031F: table 2 (2 bits each: high x-coord bit, size) |
|
|
|
|
|
.define joy1 $10 |
|
|
|
|
|
.define joy2 $12 |
|
|
|
|
|
.define vBlankCounter $14 |
|
|
|
|
|
.define backgroundRed $17 |
|
|
|
|
|
.define backgroundGreen $18 |
|
|
|
|
|
.define backgroundBlue $19 |
|
|
|
|
|
.define randomBytePtr $1A |
|
|
|
|
|
.define playerX $40 |
|
|
|
|
|
.define playerY $41 |
|
|
|
|
|
.define shotCooldown $42 |
|
|
|
|
|
.define shotData $50 |
|
|
|
|
|
|
|
|
|
|
|
; TODO(mcmillen): verify that we can relocate these without messing things up. |
|
|
|
|
|
.define spriteTableStart $100 |
|
|
|
|
|
.define spriteTable1Size $200 |
|
|
|
|
|
.define spriteTable2Start $300 ; TODO(mcmillen): use this. |
|
|
|
|
|
.define spriteTableSize $220 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; Stores result to A. |
|
|
; Stores result to A. |
|
|
|
|
|
; Assumes 16-bit X & 8-bit A. |
|
|
; Modifies X. |
|
|
; Modifies X. |
|
|
; Updates $0018-$0019 to point at the next available random byte. |
|
|
|
|
|
|
|
|
; Updates randomBytePtr. |
|
|
.MACRO GetRandomByte |
|
|
.MACRO GetRandomByte |
|
|
ldx $18 |
|
|
|
|
|
|
|
|
ldx randomBytePtr |
|
|
lda $028000, X ; $028000: beginning of ROM bank 2. |
|
|
lda $028000, X ; $028000: beginning of ROM bank 2. |
|
|
inx |
|
|
inx |
|
|
cpx #$8000 ; This is the size of the entire ROM bank. |
|
|
cpx #$8000 ; This is the size of the entire ROM bank. |
|
|
bne + |
|
|
bne + |
|
|
ldx #0 |
|
|
ldx #0 |
|
|
+ |
|
|
+ |
|
|
stx $18 |
|
|
|
|
|
|
|
|
stx randomBytePtr |
|
|
.ENDM |
|
|
.ENDM |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -26,25 +60,16 @@ |
|
|
.SECTION "MainCode" |
|
|
.SECTION "MainCode" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; Memory layout: |
|
|
|
|
|
; 0000-000F: scratch space for functions. |
|
|
|
|
|
; 0010-0011: controller state of joypad #1. |
|
|
|
|
|
; 0012-0013: controller state of joypad #2. |
|
|
|
|
|
; 0014-0016: 24-bit counter of vblanks. |
|
|
|
|
|
; 0018-0019: 16-bit pointer to next random byte. |
|
|
|
|
|
; 0020-0021: (x, y) coordinates of player. |
|
|
|
|
|
; 0022-0024: RGB color values to use for background color, from [0-31]. |
|
|
|
|
|
; 0025: shot cooldown timer. |
|
|
|
|
|
; 0030-0032: enable / x / y of shot. |
|
|
|
|
|
; |
|
|
|
|
|
; Sprite table buffers -- copied each frame to OAM during VBlank, using DMA. |
|
|
|
|
|
; 0100-02FF: table 1 (4 bytes each: x/y coord, tile #, flip/priority/palette) |
|
|
|
|
|
; 0300-031F: table 2 (2 bits each: high x-coord bit, size) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Start: |
|
|
Start: |
|
|
InitializeSNES |
|
|
InitializeSNES |
|
|
|
|
|
|
|
|
|
|
|
; By default we assume 16-bit X/Y and 8-bit A. |
|
|
|
|
|
; If any code wants to change this, it's expected to do so itself, |
|
|
|
|
|
; and to change them back to the defaults before returning. |
|
|
|
|
|
rep #%00010000 ; 16-bit X/Y. |
|
|
|
|
|
sep #%00100000 ; 8-bit A/B. |
|
|
|
|
|
|
|
|
; Store zeroes to the controller status registers. |
|
|
; Store zeroes to the controller status registers. |
|
|
; TODO(mcmillen): is this needed? I think the system will overwrite these |
|
|
; TODO(mcmillen): is this needed? I think the system will overwrite these |
|
|
; automatically. |
|
|
; automatically. |
|
@ -96,12 +121,6 @@ LoadPaletteAndTileData: |
|
|
; quite helpful with palette / sprites / DMA, especially starting at |
|
|
; quite helpful with palette / sprites / DMA, especially starting at |
|
|
; http://wiki.superfamicom.org/snes/show/Working+with+VRAM+-+Loading+the+Palette |
|
|
; http://wiki.superfamicom.org/snes/show/Working+with+VRAM+-+Loading+the+Palette |
|
|
|
|
|
|
|
|
; 16-bit X/Y registers. Used for DMA source address & transfer size, both of |
|
|
|
|
|
; which want 16-bit values. |
|
|
|
|
|
rep #%00010000 |
|
|
|
|
|
; 8-bit A/B registers. Used for DMA source bank & destination address. |
|
|
|
|
|
sep #%00100000 |
|
|
|
|
|
|
|
|
|
|
|
; Initialize the palette memory in a loop. |
|
|
; Initialize the palette memory in a loop. |
|
|
; We could also do this with a DMA transfer (like we do with the tile data |
|
|
; We could also do this with a DMA transfer (like we do with the tile data |
|
|
; below), but it seems overkill for just a few bytes. :) |
|
|
; below), but it seems overkill for just a few bytes. :) |
|
@ -225,7 +244,7 @@ InitializeSpriteTables: |
|
|
; It uses the same approach we're using, in which we keep a buffer of the |
|
|
; It uses the same approach we're using, in which we keep a buffer of the |
|
|
; sprite tables in RAM, and DMA the sprite tables to the system's OAM |
|
|
; sprite tables in RAM, and DMA the sprite tables to the system's OAM |
|
|
; during VBlank. |
|
|
; during VBlank. |
|
|
rep #%00110000 ; 16-bit A/X/Y. |
|
|
|
|
|
|
|
|
rep #%00100000 ; 16-bit A. |
|
|
|
|
|
|
|
|
ldx #$0000 |
|
|
ldx #$0000 |
|
|
; Fill sprite table 1. 4 bytes per sprite, laid out as follows: |
|
|
; Fill sprite table 1. 4 bytes per sprite, laid out as follows: |
|
@ -236,12 +255,12 @@ InitializeSpriteTables: |
|
|
; p: palette # |
|
|
; p: palette # |
|
|
lda #$01 |
|
|
lda #$01 |
|
|
- |
|
|
- |
|
|
sta $0100, X ; We keep our sprite table at $0100 and DMA it to OAM later. |
|
|
|
|
|
|
|
|
sta spriteTableStart, X |
|
|
inx |
|
|
inx |
|
|
inx |
|
|
inx |
|
|
inx |
|
|
inx |
|
|
inx |
|
|
inx |
|
|
cpx #$0200 |
|
|
|
|
|
|
|
|
cpx #spriteTable1Size |
|
|
bne - |
|
|
bne - |
|
|
|
|
|
|
|
|
; Fill sprite table 2. 2 bits per sprite, like so: |
|
|
; Fill sprite table 2. 2 bits per sprite, like so: |
|
@ -250,10 +269,10 @@ InitializeSpriteTables: |
|
|
; Setting all the high bits keeps the sprites offscreen. |
|
|
; Setting all the high bits keeps the sprites offscreen. |
|
|
lda #%0101010101010101 |
|
|
lda #%0101010101010101 |
|
|
- |
|
|
- |
|
|
sta $0100, X |
|
|
|
|
|
|
|
|
sta spriteTableStart, X |
|
|
inx |
|
|
inx |
|
|
inx |
|
|
inx |
|
|
cpx #$0220 |
|
|
|
|
|
|
|
|
cpx #spriteTableSize |
|
|
bne - |
|
|
bne - |
|
|
|
|
|
|
|
|
sep #%00100000 ; 8-bit A. |
|
|
sep #%00100000 ; 8-bit A. |
|
@ -268,9 +287,9 @@ InitializeWorld: |
|
|
|
|
|
|
|
|
; Player's initial starting location. |
|
|
; Player's initial starting location. |
|
|
lda #(256 / 4) |
|
|
lda #(256 / 4) |
|
|
sta $20 |
|
|
|
|
|
|
|
|
sta playerX |
|
|
lda #((224 - 32) / 2) |
|
|
lda #((224 - 32) / 2) |
|
|
sta $21 |
|
|
|
|
|
|
|
|
sta playerY |
|
|
rts |
|
|
rts |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -287,14 +306,10 @@ MainLoop: |
|
|
|
|
|
|
|
|
JoypadDebug: |
|
|
JoypadDebug: |
|
|
; Load joypad registers into RAM for easier inspection. |
|
|
; Load joypad registers into RAM for easier inspection. |
|
|
lda JOY1L |
|
|
|
|
|
sta $10 |
|
|
|
|
|
lda JOY1H |
|
|
|
|
|
sta $11 |
|
|
|
|
|
lda JOY2L |
|
|
|
|
|
sta $12 |
|
|
|
|
|
lda JOY2H |
|
|
|
|
|
sta $13 |
|
|
|
|
|
|
|
|
ldx JOY1L |
|
|
|
|
|
stx joy1 |
|
|
|
|
|
ldx JOY2L |
|
|
|
|
|
stx joy2 |
|
|
rts |
|
|
rts |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -306,104 +321,104 @@ JoypadUp: |
|
|
and #$08 ; Up |
|
|
and #$08 ; Up |
|
|
cmp #$08 |
|
|
cmp #$08 |
|
|
bne JoypadDown ; Button not pressed. |
|
|
bne JoypadDown ; Button not pressed. |
|
|
lda $21 |
|
|
|
|
|
|
|
|
lda playerY |
|
|
cmp #0 |
|
|
cmp #0 |
|
|
beq JoypadDown ; Value saturated. |
|
|
beq JoypadDown ; Value saturated. |
|
|
dec $21 |
|
|
|
|
|
dec $21 |
|
|
|
|
|
|
|
|
dec playerY |
|
|
|
|
|
dec playerY |
|
|
|
|
|
|
|
|
JoypadDown: |
|
|
JoypadDown: |
|
|
lda JOY1H |
|
|
lda JOY1H |
|
|
and #$04 |
|
|
and #$04 |
|
|
cmp #$04 |
|
|
cmp #$04 |
|
|
bne JoypadLeft ; Button not pressed. |
|
|
bne JoypadLeft ; Button not pressed. |
|
|
lda $21 |
|
|
|
|
|
|
|
|
lda playerY |
|
|
cmp #(224 - 32) |
|
|
cmp #(224 - 32) |
|
|
beq JoypadLeft ; Value saturated. |
|
|
beq JoypadLeft ; Value saturated. |
|
|
inc $21 |
|
|
|
|
|
inc $21 |
|
|
|
|
|
|
|
|
inc playerY |
|
|
|
|
|
inc playerY |
|
|
|
|
|
|
|
|
JoypadLeft: |
|
|
JoypadLeft: |
|
|
lda JOY1H |
|
|
lda JOY1H |
|
|
and #$02 ; Left |
|
|
and #$02 ; Left |
|
|
cmp #$02 |
|
|
cmp #$02 |
|
|
bne JoypadRight ; Button not pressed. |
|
|
bne JoypadRight ; Button not pressed. |
|
|
lda $20 |
|
|
|
|
|
|
|
|
lda playerX |
|
|
cmp #0 |
|
|
cmp #0 |
|
|
beq JoypadRight ; Value saturated. |
|
|
beq JoypadRight ; Value saturated. |
|
|
dec $20 |
|
|
|
|
|
dec $20 |
|
|
|
|
|
|
|
|
dec playerX |
|
|
|
|
|
dec playerX |
|
|
|
|
|
|
|
|
JoypadRight: |
|
|
JoypadRight: |
|
|
lda JOY1H |
|
|
lda JOY1H |
|
|
and #$01 |
|
|
and #$01 |
|
|
cmp #$01 ; Right |
|
|
cmp #$01 ; Right |
|
|
bne JoypadStart ; Button not pressed. |
|
|
bne JoypadStart ; Button not pressed. |
|
|
lda $20 |
|
|
|
|
|
|
|
|
lda playerX |
|
|
cmp #(256 - 32) |
|
|
cmp #(256 - 32) |
|
|
beq JoypadStart ; Value saturated. |
|
|
beq JoypadStart ; Value saturated. |
|
|
inc $20 |
|
|
|
|
|
inc $20 |
|
|
|
|
|
|
|
|
inc playerX |
|
|
|
|
|
inc playerX |
|
|
|
|
|
|
|
|
JoypadStart: |
|
|
JoypadStart: |
|
|
lda JOY1H |
|
|
lda JOY1H |
|
|
and #$10 ; Start |
|
|
and #$10 ; Start |
|
|
cmp #$10 |
|
|
cmp #$10 |
|
|
bne JoypadSelect ; Button not pressed. |
|
|
bne JoypadSelect ; Button not pressed. |
|
|
lda $22 |
|
|
|
|
|
|
|
|
lda backgroundRed |
|
|
cmp #0 |
|
|
cmp #0 |
|
|
beq JoypadSelect ; Value saturated. |
|
|
beq JoypadSelect ; Value saturated. |
|
|
dec $22 |
|
|
|
|
|
|
|
|
dec backgroundRed |
|
|
|
|
|
|
|
|
JoypadSelect: |
|
|
JoypadSelect: |
|
|
lda JOY1H |
|
|
lda JOY1H |
|
|
and #$20 ; Select |
|
|
and #$20 ; Select |
|
|
cmp #$20 |
|
|
cmp #$20 |
|
|
bne JoypadY ; Button not pressed. |
|
|
bne JoypadY ; Button not pressed. |
|
|
lda $22 |
|
|
|
|
|
|
|
|
lda backgroundRed |
|
|
cmp #31 |
|
|
cmp #31 |
|
|
beq JoypadY ; Value saturated. |
|
|
beq JoypadY ; Value saturated. |
|
|
inc $22 |
|
|
|
|
|
|
|
|
inc backgroundRed |
|
|
|
|
|
|
|
|
JoypadY: |
|
|
JoypadY: |
|
|
lda JOY1H |
|
|
lda JOY1H |
|
|
and #$40 ; Y |
|
|
and #$40 ; Y |
|
|
cmp #$40 |
|
|
cmp #$40 |
|
|
bne JoypadX ; Button not pressed. |
|
|
bne JoypadX ; Button not pressed. |
|
|
lda $23 |
|
|
|
|
|
|
|
|
lda backgroundGreen |
|
|
cmp #0 |
|
|
cmp #0 |
|
|
beq JoypadX ; Value saturated. |
|
|
beq JoypadX ; Value saturated. |
|
|
dec $23 |
|
|
|
|
|
|
|
|
dec backgroundGreen |
|
|
|
|
|
|
|
|
JoypadX: |
|
|
JoypadX: |
|
|
lda JOY1L |
|
|
lda JOY1L |
|
|
and #$40 ; X |
|
|
and #$40 ; X |
|
|
cmp #$40 |
|
|
cmp #$40 |
|
|
bne JoypadL ; Button not pressed. |
|
|
bne JoypadL ; Button not pressed. |
|
|
lda $23 |
|
|
|
|
|
|
|
|
lda backgroundGreen |
|
|
cmp #31 |
|
|
cmp #31 |
|
|
beq JoypadL ; Value saturated. |
|
|
beq JoypadL ; Value saturated. |
|
|
inc $23 |
|
|
|
|
|
|
|
|
inc backgroundGreen |
|
|
|
|
|
|
|
|
JoypadL: |
|
|
JoypadL: |
|
|
lda JOY1L |
|
|
lda JOY1L |
|
|
and #$20 ; L |
|
|
and #$20 ; L |
|
|
cmp #$20 |
|
|
cmp #$20 |
|
|
bne JoypadR ; Button not pressed. |
|
|
bne JoypadR ; Button not pressed. |
|
|
lda $24 |
|
|
|
|
|
|
|
|
lda backgroundBlue |
|
|
cmp #0 |
|
|
cmp #0 |
|
|
beq JoypadR ; Value saturated. |
|
|
beq JoypadR ; Value saturated. |
|
|
dec $24 |
|
|
|
|
|
|
|
|
dec backgroundBlue |
|
|
|
|
|
|
|
|
JoypadR: |
|
|
JoypadR: |
|
|
lda JOY1L |
|
|
lda JOY1L |
|
|
and #$10 ; R |
|
|
and #$10 ; R |
|
|
cmp #$10 |
|
|
cmp #$10 |
|
|
bne JoypadB ; Button not pressed. |
|
|
bne JoypadB ; Button not pressed. |
|
|
lda $24 |
|
|
|
|
|
|
|
|
lda backgroundBlue |
|
|
cmp #31 |
|
|
cmp #31 |
|
|
beq JoypadB ; Value saturated. |
|
|
beq JoypadB ; Value saturated. |
|
|
inc $24 |
|
|
|
|
|
|
|
|
inc backgroundBlue |
|
|
|
|
|
|
|
|
JoypadB: |
|
|
JoypadB: |
|
|
lda JOY1H |
|
|
lda JOY1H |
|
@ -419,19 +434,19 @@ JoypadDone: |
|
|
|
|
|
|
|
|
MaybeShoot: |
|
|
MaybeShoot: |
|
|
; If the cooldown timer is non-zero, don't shoot. |
|
|
; If the cooldown timer is non-zero, don't shoot. |
|
|
lda $25 |
|
|
|
|
|
|
|
|
lda shotCooldown |
|
|
cmp #0 |
|
|
cmp #0 |
|
|
bne + |
|
|
bne + |
|
|
; Enable shot; set its position to player position. |
|
|
; Enable shot; set its position to player position. |
|
|
lda #1 |
|
|
lda #1 |
|
|
sta $30 |
|
|
|
|
|
lda $20 |
|
|
|
|
|
sta $31 |
|
|
|
|
|
lda $21 |
|
|
|
|
|
sta $32 |
|
|
|
|
|
|
|
|
sta shotData |
|
|
|
|
|
lda playerX |
|
|
|
|
|
sta shotData + 1 |
|
|
|
|
|
lda playerY |
|
|
|
|
|
sta shotData + 2 |
|
|
; Set cooldown timer. |
|
|
; Set cooldown timer. |
|
|
lda #16 |
|
|
lda #16 |
|
|
sta $25 |
|
|
|
|
|
|
|
|
sta shotCooldown |
|
|
+ |
|
|
+ |
|
|
rts |
|
|
rts |
|
|
|
|
|
|
|
@ -439,17 +454,17 @@ MaybeShoot: |
|
|
|
|
|
|
|
|
UpdateWorld: |
|
|
UpdateWorld: |
|
|
; Update shot cooldown. |
|
|
; Update shot cooldown. |
|
|
lda $0025 |
|
|
|
|
|
|
|
|
lda shotCooldown |
|
|
cmp #0 |
|
|
cmp #0 |
|
|
beq + |
|
|
beq + |
|
|
dea |
|
|
dea |
|
|
sta $0025 |
|
|
|
|
|
|
|
|
sta shotCooldown |
|
|
+ |
|
|
+ |
|
|
|
|
|
|
|
|
; Copy player coords into sprite table. |
|
|
; Copy player coords into sprite table. |
|
|
lda $0020 |
|
|
|
|
|
|
|
|
lda playerX |
|
|
sta $0100 |
|
|
sta $0100 |
|
|
lda $0021 |
|
|
|
|
|
|
|
|
lda playerY |
|
|
sta $0101 |
|
|
sta $0101 |
|
|
; Set the sprite. |
|
|
; Set the sprite. |
|
|
lda #0 |
|
|
lda #0 |
|
@ -458,37 +473,37 @@ UpdateWorld: |
|
|
lda #%00110000 |
|
|
lda #%00110000 |
|
|
sta $0103 |
|
|
sta $0103 |
|
|
; Clear x-MSB so that the sprite is displayed. |
|
|
; Clear x-MSB so that the sprite is displayed. |
|
|
lda $0300 |
|
|
|
|
|
|
|
|
lda spriteTable2Start |
|
|
and #%11111110 |
|
|
and #%11111110 |
|
|
ora #%00000010 ; ... and make it the large size. (32x32) |
|
|
ora #%00000010 ; ... and make it the large size. (32x32) |
|
|
sta $0300 |
|
|
|
|
|
|
|
|
sta spriteTable2Start |
|
|
|
|
|
|
|
|
; Move shot coords. |
|
|
; Move shot coords. |
|
|
ldx $0 |
|
|
ldx $0 |
|
|
lda $30 |
|
|
|
|
|
|
|
|
lda shotData |
|
|
cmp #1 |
|
|
cmp #1 |
|
|
bne DisableShot |
|
|
bne DisableShot |
|
|
|
|
|
|
|
|
lda $31 |
|
|
|
|
|
|
|
|
lda shotData + 1 |
|
|
; TODO(mcmillen): do this with an add, then check the carry bit? |
|
|
; TODO(mcmillen): do this with an add, then check the carry bit? |
|
|
.rept 6 |
|
|
.rept 6 |
|
|
ina |
|
|
ina |
|
|
cmp #$00 ; If it wraps around, disable it. |
|
|
cmp #$00 ; If it wraps around, disable it. |
|
|
bne + |
|
|
bne + |
|
|
stz $30 |
|
|
|
|
|
|
|
|
stz shotData |
|
|
+ |
|
|
+ |
|
|
.endr |
|
|
.endr |
|
|
sta $0031 ; Store new x-coord. |
|
|
|
|
|
|
|
|
sta shotData + 1 ; Store new x-coord. |
|
|
|
|
|
|
|
|
; See if sprite is still enabled after move. |
|
|
; See if sprite is still enabled after move. |
|
|
lda $0030 |
|
|
|
|
|
|
|
|
lda shotData |
|
|
cmp #1 |
|
|
cmp #1 |
|
|
bne DisableShot |
|
|
bne DisableShot |
|
|
|
|
|
|
|
|
; Set up shot sprite. |
|
|
; Set up shot sprite. |
|
|
lda $0031 ; x |
|
|
|
|
|
|
|
|
lda shotData + 1 ; x |
|
|
sta $0104 |
|
|
sta $0104 |
|
|
lda $0032 ; y |
|
|
|
|
|
|
|
|
lda shotData + 2 ; y |
|
|
sta $0105 |
|
|
sta $0105 |
|
|
lda #8 ; which sprite |
|
|
lda #8 ; which sprite |
|
|
sta $0106 |
|
|
sta $0106 |
|
@ -500,8 +515,9 @@ UpdateWorld: |
|
|
jmp ShotDone |
|
|
jmp ShotDone |
|
|
|
|
|
|
|
|
DisableShot: |
|
|
DisableShot: |
|
|
; Disable it by setting x-position to zero and setting the high x-bit. |
|
|
|
|
|
stz $104 |
|
|
|
|
|
|
|
|
; Disable it by setting x-position to 1 and setting the high x-bit. |
|
|
|
|
|
lda #1 |
|
|
|
|
|
sta $104 |
|
|
lda $0300 |
|
|
lda $0300 |
|
|
ora #%00000100 |
|
|
ora #%00000100 |
|
|
sta $0300 |
|
|
sta $0300 |
|
@ -509,11 +525,11 @@ DisableShot: |
|
|
ShotDone: |
|
|
ShotDone: |
|
|
; Make the background scroll. Horizontal over time; vertical depending on |
|
|
; Make the background scroll. Horizontal over time; vertical depending on |
|
|
; player's y-coordinate. |
|
|
; player's y-coordinate. |
|
|
lda $14 |
|
|
|
|
|
|
|
|
lda vBlankCounter |
|
|
sta BG3HOFS |
|
|
sta BG3HOFS |
|
|
lda $15 |
|
|
|
|
|
|
|
|
lda vBlankCounter + 1 |
|
|
sta BG3HOFS |
|
|
sta BG3HOFS |
|
|
lda $21 |
|
|
|
|
|
|
|
|
lda playerY |
|
|
.rept 3 |
|
|
.rept 3 |
|
|
lsr |
|
|
lsr |
|
|
.endr |
|
|
.endr |
|
@ -525,7 +541,7 @@ ShotDone: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SetBackgroundColor: |
|
|
SetBackgroundColor: |
|
|
; $22 $23 $24 are (R, G, B), each ranging from [0-31]. |
|
|
|
|
|
|
|
|
; The background-color bytes are (R, G, B), each ranging from [0-31]. |
|
|
; The palette color format is 15-bit: [0bbbbbgg][gggrrrrr] |
|
|
; The palette color format is 15-bit: [0bbbbbgg][gggrrrrr] |
|
|
|
|
|
|
|
|
; Set the background color. |
|
|
; Set the background color. |
|
@ -533,20 +549,20 @@ SetBackgroundColor: |
|
|
stz CGADDR |
|
|
stz CGADDR |
|
|
|
|
|
|
|
|
; Compute and the low-order byte and store it in CGDATA. |
|
|
; Compute and the low-order byte and store it in CGDATA. |
|
|
lda $23 ; Green. |
|
|
|
|
|
|
|
|
lda backgroundGreen |
|
|
.rept 5 |
|
|
.rept 5 |
|
|
asl |
|
|
asl |
|
|
.endr |
|
|
.endr |
|
|
ora $22 ; Red. |
|
|
|
|
|
|
|
|
ora backgroundRed |
|
|
sta CGDATA |
|
|
sta CGDATA |
|
|
|
|
|
|
|
|
; Compute the high-order byte and store it in CGDATA. |
|
|
; Compute the high-order byte and store it in CGDATA. |
|
|
lda $24 ; Blue. |
|
|
|
|
|
|
|
|
lda backgroundBlue |
|
|
.rept 2 |
|
|
.rept 2 |
|
|
asl |
|
|
asl |
|
|
.endr |
|
|
.endr |
|
|
sta $00 |
|
|
sta $00 |
|
|
lda $23 ; Green. |
|
|
|
|
|
|
|
|
lda backgroundGreen |
|
|
.rept 3 |
|
|
.rept 3 |
|
|
lsr |
|
|
lsr |
|
|
.endr |
|
|
.endr |
|
@ -565,25 +581,23 @@ VBlankHandler: |
|
|
|
|
|
|
|
|
VBlankCounter: |
|
|
VBlankCounter: |
|
|
; Increment a counter of how many VBlanks we've done. |
|
|
; Increment a counter of how many VBlanks we've done. |
|
|
; This is a 24-bit counter. At 60 vblanks/second, this will take over |
|
|
|
|
|
|
|
|
; This is a 24-bit counter. At 60 vblanks/second, this will take |
|
|
; 77 hours to wrap around; that's good enough for me :) |
|
|
; 77 hours to wrap around; that's good enough for me :) |
|
|
inc $14 |
|
|
|
|
|
lda $14 |
|
|
|
|
|
|
|
|
inc vBlankCounter |
|
|
|
|
|
lda vBlankCounter |
|
|
cmp #$00 |
|
|
cmp #$00 |
|
|
bne VBlankCounterDone |
|
|
bne VBlankCounterDone |
|
|
inc $15 |
|
|
|
|
|
lda $15 |
|
|
|
|
|
|
|
|
inc vBlankCounter + 1 |
|
|
|
|
|
lda vBlankCounter + 1 |
|
|
cmp #$00 |
|
|
cmp #$00 |
|
|
bne VBlankCounterDone |
|
|
bne VBlankCounterDone |
|
|
inc $16 |
|
|
|
|
|
|
|
|
inc vBlankCounter + 2 |
|
|
VBlankCounterDone: |
|
|
VBlankCounterDone: |
|
|
rts |
|
|
rts |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DMASpriteTables: |
|
|
DMASpriteTables: |
|
|
rep #%00010000 ; 16-bit X/Y. |
|
|
|
|
|
sep #%00100000 ; 8-bit A. |
|
|
|
|
|
; Store at the base OAM address. |
|
|
; Store at the base OAM address. |
|
|
ldx #$0000 |
|
|
ldx #$0000 |
|
|
stx OAMADDR |
|
|
stx OAMADDR |
|
@ -592,10 +606,10 @@ DMASpriteTables: |
|
|
lda #$04 |
|
|
lda #$04 |
|
|
sta DMA0DST |
|
|
sta DMA0DST |
|
|
; Our sprites start at $0100 in bank 0 and are #$220 bytes long. |
|
|
; Our sprites start at $0100 in bank 0 and are #$220 bytes long. |
|
|
ldx #$0100 |
|
|
|
|
|
|
|
|
ldx #spriteTableStart |
|
|
stx DMA0SRC |
|
|
stx DMA0SRC |
|
|
stz DMA0SRCBANK |
|
|
stz DMA0SRCBANK |
|
|
ldx #$0220 |
|
|
|
|
|
|
|
|
ldx #spriteTableSize |
|
|
stx DMA0SIZE |
|
|
stx DMA0SIZE |
|
|
; Kick off the DMA transfer. |
|
|
; Kick off the DMA transfer. |
|
|
lda #%00000001 |
|
|
lda #%00000001 |
|
|