Refactor to use .defines for many memory locations.

This commit is contained in:
Colin McMillen 2015-05-25 14:28:00 -04:00
parent 7b6cd3f583
commit a0532f0429

View File

@ -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 ldx JOY1L
sta $10 stx joy1
lda JOY1H ldx JOY2L
sta $11 stx joy2
lda JOY2L
sta $12
lda JOY2H
sta $13
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 playerY
dec $21 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 playerY
inc $21 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 playerX
dec $20 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 playerX
inc $20 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 sta shotData
lda $20 lda playerX
sta $31 sta shotData + 1
lda $21 lda playerY
sta $32 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. ; Disable it by setting x-position to 1 and setting the high x-bit.
stz $104 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 inc vBlankCounter
lda $14 lda vBlankCounter
cmp #$00 cmp #$00
bne VBlankCounterDone bne VBlankCounterDone
inc $15 inc vBlankCounter + 1
lda $15 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