Fix absolute address issue in rom
This commit is contained in:
parent
310c3487ca
commit
64f7106143
|
@ -0,0 +1,105 @@
|
|||
HexToChar dfb '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
|
||||
|
||||
; Convert a byte (Acc) into a string and store at (Y)
|
||||
ByteToString and #$00FF
|
||||
sep #$20
|
||||
pha
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
and #$0F
|
||||
tax
|
||||
ldal HexToChar,x
|
||||
sta: $0000,y
|
||||
|
||||
pla
|
||||
and #$0F
|
||||
tax
|
||||
ldal HexToChar,x
|
||||
sta: $0001,y
|
||||
|
||||
rep #$20
|
||||
rts
|
||||
|
||||
; Convert a word (Acc) into a hexadecimal string and store at (Y)
|
||||
WordToString pha
|
||||
bra Addr2ToString
|
||||
|
||||
; Pass in Acc = High, X = low
|
||||
Addr3ToString phx
|
||||
jsr ByteToString
|
||||
iny
|
||||
iny
|
||||
lda 1,s
|
||||
Addr2ToString xba
|
||||
jsr ByteToString
|
||||
iny
|
||||
iny
|
||||
pla
|
||||
jsr ByteToString
|
||||
rts
|
||||
|
||||
; A=Value
|
||||
; X=Screen offset
|
||||
DrawWord phx ; Save register value
|
||||
phy
|
||||
ldy #WordBuff+1
|
||||
jsr WordToString
|
||||
ply
|
||||
plx
|
||||
lda #WordBuff
|
||||
jsr DrawString
|
||||
rts
|
||||
|
||||
WordBuff str '0000'
|
||||
Addr3Buff str '000000' ; str adds leading length byte
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
516
demos/smb/Main.s
516
demos/smb/Main.s
|
@ -22,11 +22,20 @@ MyUserId equ 0
|
|||
ROMStk equ 2
|
||||
ROMZeroPg equ 4
|
||||
LastScroll equ 6
|
||||
RenderCtr equ 8
|
||||
TileX equ 10 ; GTE tile store coordinates that correspond to the PPUSCROLL edge
|
||||
TileY equ 12
|
||||
ROMScreenEdge equ 14
|
||||
ROMScrollEdge equ 16
|
||||
ROMScrollDelta equ 18
|
||||
OldROMScrollEdge equ 20
|
||||
CurrScrollEdge equ 22
|
||||
|
||||
Tmp0 equ 240
|
||||
Tmp1 equ 242
|
||||
Tmp2 equ 244
|
||||
Tmp3 equ 246
|
||||
Tmp4 equ 248
|
||||
Tmp5 equ 250
|
||||
|
||||
phk
|
||||
plb
|
||||
|
@ -34,7 +43,12 @@ Tmp3 equ 246
|
|||
_MTStartUp ; GTE requires the miscellaneous toolset to be running
|
||||
|
||||
stz LastScroll
|
||||
stz RenderCtr
|
||||
stz TileX
|
||||
stz TileY
|
||||
stz ROMScreenEdge
|
||||
stz ROMScrollEdge
|
||||
stz ROMScrollDelta
|
||||
stz OldROMScrollEdge
|
||||
|
||||
; The next two direct pages will be used by GTE, so get another 2 pages beyond that for the ROM. We get
|
||||
; 4K of DP/Stack space by default, so there is plenty to share
|
||||
|
@ -79,6 +93,12 @@ Tmp3 equ 246
|
|||
pea #drawOAMSprites
|
||||
_GTESetAddress
|
||||
|
||||
; Install a custom callback to update the tile store as the screen scrolls
|
||||
pea extBG0TileUpdate
|
||||
pea #^UpdateFromPPU
|
||||
pea #UpdateFromPPU
|
||||
_GTESetAddress
|
||||
|
||||
; Get the address of a low-level routine that can be used to draw a tile directly to the graphics screen
|
||||
pea rawDrawTile
|
||||
_GTEGetAddress
|
||||
|
@ -133,42 +153,6 @@ Tmp3 equ 246
|
|||
cpx #512*16
|
||||
bcc :tloop
|
||||
|
||||
; Put the tile set on the screen
|
||||
|
||||
* lda #0
|
||||
* stz Tmp1
|
||||
* :yloop stz Tmp0
|
||||
* :xloop
|
||||
* pha
|
||||
* pei Tmp0
|
||||
* pei Tmp1
|
||||
* pha
|
||||
* _GTESetTile
|
||||
* pla
|
||||
* inc
|
||||
|
||||
* inc Tmp0
|
||||
* ldx Tmp0
|
||||
* cpx #32
|
||||
* bcc :xloop
|
||||
|
||||
* inc Tmp1
|
||||
* ldx Tmp1
|
||||
* cpx #20
|
||||
* bcc :yloop
|
||||
|
||||
* ; Render and wait for the user to continue
|
||||
* pea $0000
|
||||
* _GTERender
|
||||
|
||||
* :wait1
|
||||
* pha
|
||||
* _GTEReadControl
|
||||
* pla
|
||||
* and #$007F
|
||||
* cmp #' '
|
||||
* bne :wait1
|
||||
|
||||
; Set an internal flag to tell the VBL interrupt handler that it is
|
||||
; ok to start invoking the game logic. The ROM code has to be run
|
||||
; at 60 Hz because it controls the audio. Bad audio is way worse
|
||||
|
@ -184,38 +168,60 @@ EvtLoop
|
|||
beq :spin
|
||||
stz nmiCount
|
||||
|
||||
; lda ppustatus ; Set the bit that the VBL has started
|
||||
; bit #$80
|
||||
; beq :spin
|
||||
; and #$FF7F
|
||||
; sta ppustatus
|
||||
; The GTE playfield is 41 tiles wide, but the NES is 32 tiles wide. Fortunately, the game
|
||||
; keeps track of the global coordinates of each level at
|
||||
;
|
||||
; ScreenEdge_PageLoc = $071a
|
||||
; ScreenEdge_X_Pos = $071c
|
||||
;
|
||||
; So we can keep our scrolling in sync with the game. In order to efficiently update the
|
||||
; GTE tile store, we handle this in two stages
|
||||
;
|
||||
; 1. When new column(s) are exposed, set the tiles directly from the PPU nametable memory
|
||||
; 2. When the PPU nametable memory is updated in an area that is already on-screen, set the tile
|
||||
|
||||
; jsr triggerNMI
|
||||
; Get the current global coordinates
|
||||
|
||||
; lda RenderCtr
|
||||
; bne :no_render
|
||||
sei
|
||||
lda ROMScrollEdge ; This is set in the VBL IRQ
|
||||
sta CurrScrollEdge ; Freeze it, then we can let the IRQs continue
|
||||
cli
|
||||
|
||||
; lda #5
|
||||
; sta RenderCtr
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
sta ROMScreenEdge
|
||||
|
||||
jsr CopyNametable
|
||||
; Calculate how many blocks have been scrolled into view
|
||||
|
||||
lda ppuscroll+1
|
||||
and #$00FF
|
||||
lda CurrScrollEdge
|
||||
sec
|
||||
sbc OldROMScrollEdge
|
||||
sta Tmp1 ; This is the raw number of pixels moved
|
||||
|
||||
lda OldROMScrollEdge ; This is the number of partial pixels the old scroll position occupied
|
||||
and #7
|
||||
sta Tmp0
|
||||
lda #7
|
||||
sec
|
||||
sbc Tmp0 ; This account for situations where going from 8 -> 9 reveals a new column
|
||||
clc
|
||||
adc Tmp1
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
sta ROMScrollDelta ; This many columns have been revealed
|
||||
|
||||
lda CurrScrollEdge
|
||||
sta OldROMScrollEdge ; Stash a copy for the next round through
|
||||
lsr
|
||||
pha
|
||||
sta LastScroll
|
||||
lda ppuscroll
|
||||
and #$00FF
|
||||
pha
|
||||
pea $0000
|
||||
_GTESetBG0Origin
|
||||
|
||||
pea $FFFF ; NES mode
|
||||
_GTERender
|
||||
|
||||
:no_render
|
||||
dec RenderCtr
|
||||
|
||||
pha
|
||||
_GTEReadControl
|
||||
pla
|
||||
|
@ -226,7 +232,8 @@ EvtLoop
|
|||
and #PAD_BUTTON_A+PAD_BUTTON_B ; bits 0x200 and 0x100
|
||||
lsr
|
||||
lsr
|
||||
sta native_joy
|
||||
sta native_joy ; Put inputs on both controllers
|
||||
sta native_joy+1
|
||||
lda 1,s
|
||||
and #$00FF
|
||||
cmp #'n'
|
||||
|
@ -254,6 +261,7 @@ EvtLoop
|
|||
lda #$0001
|
||||
:nes_merge ora native_joy
|
||||
sta native_joy
|
||||
sta native_joy+1
|
||||
:nes_done
|
||||
pla
|
||||
; bit #PAD_KEY_DOWN
|
||||
|
@ -262,23 +270,51 @@ EvtLoop
|
|||
|
||||
and #$007F
|
||||
|
||||
cmp #'1' ; Copy nametable 1
|
||||
cmp #'r' ; Refresh
|
||||
bne :not_1
|
||||
lda #$2000
|
||||
jsr CopyStatus
|
||||
|
||||
lda ROMScreenEdge ; global tile index
|
||||
and #$003F ; mod the mirrored nametable size
|
||||
ldx #33
|
||||
ldy #0
|
||||
jsr CopyNametable
|
||||
brl EvtLoop
|
||||
:not_1
|
||||
|
||||
cmp #'2'
|
||||
bne :not_2
|
||||
lda #$2400
|
||||
cmp #'1'
|
||||
bne :not_v
|
||||
lda ROMScreenEdge
|
||||
clc
|
||||
adc #33
|
||||
and #$003F
|
||||
ldx #1
|
||||
ldy #33
|
||||
jsr CopyNametable
|
||||
:not_2
|
||||
brl EvtLoop
|
||||
|
||||
cmp #'s' ; next step
|
||||
bne :not_n
|
||||
jsr triggerNMI
|
||||
:not_n
|
||||
:not_v
|
||||
|
||||
cmp #'t' ; test by placing markers on screen
|
||||
bne :not_t
|
||||
pea 0
|
||||
pea #3
|
||||
pea $0150
|
||||
_GTESetTile
|
||||
pea #31
|
||||
pea #3
|
||||
pea $0150
|
||||
_GTESetTile
|
||||
pea #32
|
||||
pea #3
|
||||
pea $0150
|
||||
_GTESetTile
|
||||
pea #39
|
||||
pea #3
|
||||
pea $0150
|
||||
_GTESetTile
|
||||
|
||||
brl EvtLoop
|
||||
:not_t
|
||||
|
||||
cmp #'q'
|
||||
beq Exit
|
||||
|
@ -298,46 +334,234 @@ Greyscale dw $0000,$5555,$AAAA,$FFFF
|
|||
nmiCount dw 0
|
||||
DPSave dw 0
|
||||
|
||||
; Copy the tile and attribute bytes into the GTE buffer
|
||||
; Take a PPU address and convert it to a tile store coordinate
|
||||
;
|
||||
; A = Nametable address ($2000, $2400, $2800, or $2C00)
|
||||
CopyNametable
|
||||
lda ppuctrl
|
||||
and #$0003 ; nametable select bits
|
||||
xba
|
||||
asl
|
||||
asl
|
||||
; Inputs
|
||||
; A = PPU address
|
||||
; X = Global Address in GTE bytes
|
||||
|
||||
; Outputs
|
||||
; X = relative tile store column
|
||||
; Y = relative tile store row
|
||||
PPUAddrToTileStore
|
||||
:PPUAddr equ Tmp0
|
||||
:PPUTopLeft equ Tmp1
|
||||
|
||||
sta :PPUAddr
|
||||
|
||||
; Based on the global coordiate, figure out whhat the left column in the PPU RAM is
|
||||
txa
|
||||
lsr ; Convert from bytes to tiles
|
||||
lsr
|
||||
and #$003F ; Logically there are 64 tiles in the mirrored PPU RAM
|
||||
sta :PPUTopLeft
|
||||
|
||||
; Now we have the PPU address of the column that corresponds to the left edge of the GTE
|
||||
; playfield. Now, calculate the relative coordinates of the passed PPU address
|
||||
|
||||
; The y-coordinate is easy. Since the top-left address is always on the top row (row = 0),
|
||||
; we just have to extract the row that the PPU address occupies.
|
||||
|
||||
lda :PPUAddr
|
||||
and #$03E0 ; Take the middle 5 bits (ignore nametable)
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
tay ; Save the y-index here
|
||||
|
||||
; The GTE playfield is positioned with the third PPU row as it's origin and is 25 tiles high.
|
||||
; If the PPU tile is in rows 0, 1, 27, 28 or 29 then we can ignore it
|
||||
|
||||
cpy #2
|
||||
bcc :outOfRange
|
||||
cpy #27
|
||||
bcs :outOfRange
|
||||
|
||||
; Adjust the relative position down by 2
|
||||
|
||||
dey
|
||||
dey
|
||||
|
||||
; The horizontal coordinate is a bit trickier. We need to add 32 to the horizontal
|
||||
; coordinate in it's in the second nametable
|
||||
|
||||
lda :PPUAddr
|
||||
and #$041F ; Project it to the top row
|
||||
bit #$0400
|
||||
beq *+5
|
||||
ora #$0020 ; Add 32
|
||||
and #$003F ; Clamp to range of 0 - 63
|
||||
|
||||
; If we're in the top two row, they don't scroll, so skip the displacement
|
||||
cpy #2
|
||||
bcc :noshift
|
||||
|
||||
; Now calculate the difference between the PPUTopLeft index and this value
|
||||
|
||||
cmp :PPUTopLeft
|
||||
bcs :ahead ; If the provided address is > than the origin, just calc the difference
|
||||
adc #64 ; Else distance is (a - 0) + (64 - b) = a + 64 - b
|
||||
sec
|
||||
:ahead sbc :PPUTopLeft
|
||||
:noshift
|
||||
|
||||
; If this value is larger than the payfield + 1, then we have the carry set or clear
|
||||
|
||||
tax
|
||||
cmp #33
|
||||
rts
|
||||
|
||||
:outOfRange
|
||||
sec
|
||||
rts
|
||||
|
||||
; If there is some other reason to draw the full screen, this will empty the queue
|
||||
ClearNTQueue
|
||||
stz nt_queue_front
|
||||
stz nt_queue_end
|
||||
rts
|
||||
|
||||
; Scan through the queue of tiles that need to be updated before applying the scroll change
|
||||
DrainNTQueue
|
||||
:GTELeftEdge equ Tmp3
|
||||
:PPUAddr equ Tmp4
|
||||
|
||||
; Prep item -- get the logical block of the left edge of the scroll window
|
||||
|
||||
lda CurrScrollEdge ; Global position that the GTE playfield was set to
|
||||
lsr
|
||||
sta :GTELeftEdge
|
||||
|
||||
lda nt_queue_front
|
||||
cmp nt_queue_end
|
||||
beq :out
|
||||
|
||||
:loop
|
||||
tax
|
||||
phx ; Save the x register
|
||||
|
||||
lda nt_queue,x ; get the PPU address that was stored
|
||||
sta :PPUAddr ; save for later if we draw this tile
|
||||
|
||||
ldx :GTELeftEdge ; get the global coordinate
|
||||
jsr PPUAddrToTileStore ; convert the PPU address to realtive tile store coordinates
|
||||
bcs :skip ; if it's offscreen, no reason to draw it
|
||||
|
||||
; Now we have the relative position from the left edge of the tile. Add the origin
|
||||
; tile to it (uless we're in rows 0 or 1)
|
||||
|
||||
txa
|
||||
cpy #2
|
||||
bcc :toprow
|
||||
clc
|
||||
adc #2*32
|
||||
sta Tmp0 ; base address offset into nametable memory
|
||||
adc TileX
|
||||
cmp #41
|
||||
bcc *+5
|
||||
sbc #41
|
||||
:toprow
|
||||
pha ; Tile Store horizontal tile coordinate
|
||||
|
||||
; ora #$2000
|
||||
; clc
|
||||
; adc #PPU_MEM
|
||||
; clc
|
||||
; adc #2*32
|
||||
; sta Tmp0 ; base address
|
||||
phy ; No translation needed for y
|
||||
|
||||
; NES RAM $6D = page, $86 = player_x_in_page can be used to get a global position in the level, then subtracting the
|
||||
; player's x coordinate will give us the global coordinate of the left edge of the screen and allow us to map between
|
||||
; the GTE tile buffer and the PPU nametables
|
||||
ldx :PPUAddr
|
||||
lda PPU_MEM,x
|
||||
and #$00FF
|
||||
ora #$0100
|
||||
pha
|
||||
_GTESetTile
|
||||
|
||||
lda ppuscroll+1
|
||||
:skip
|
||||
pla ; Pop the saved x-register into the accumulator
|
||||
inc
|
||||
inc
|
||||
and #{2*1024}-1
|
||||
cmp nt_queue_end
|
||||
bne :loop
|
||||
|
||||
:out
|
||||
sta nt_queue_front
|
||||
rts
|
||||
|
||||
; Copy the necessary columns into the TileStore when setting a new scroll position
|
||||
UpdateFromPPU
|
||||
:StartXMod164 equ 36
|
||||
|
||||
phb
|
||||
phd
|
||||
|
||||
; Snag the StartXmod164 value from the GTE direct page so we can calulate the tile origin
|
||||
; ourselves
|
||||
|
||||
ldx :StartXMod164
|
||||
|
||||
phk
|
||||
plb
|
||||
lda DPSave
|
||||
tcd
|
||||
|
||||
txa
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
and #$001F
|
||||
sta Tmp1 ; starting offset
|
||||
sta TileX ; Tile column of playfield origin
|
||||
|
||||
; Check the scroll delta, if it's negative or just large enough, do a whole copy of the current PPU
|
||||
; memory into the TileStore
|
||||
|
||||
lda ROMScrollDelta
|
||||
beq :queue
|
||||
|
||||
cmp #32
|
||||
bcc :partial
|
||||
|
||||
jsr ClearNTQueue ; kill any pending updates
|
||||
lda ROMScreenEdge ; global tile index
|
||||
and #$003F ; mod the mirrored nametable size
|
||||
ldx #33 ; do the full width
|
||||
ldy #0
|
||||
jsr CopyNametable
|
||||
bra :done
|
||||
|
||||
; Calculate the difference between the old and new
|
||||
:partial
|
||||
jsr DrainNTQueue
|
||||
|
||||
lda #33
|
||||
sec
|
||||
sbc ROMScrollDelta
|
||||
tay
|
||||
|
||||
ldx ROMScrollDelta
|
||||
inx
|
||||
inx
|
||||
|
||||
lda ROMScreenEdge
|
||||
clc
|
||||
adc #33
|
||||
sec
|
||||
sbc ROMScrollDelta
|
||||
and #$003F
|
||||
|
||||
jsr CopyNametable
|
||||
:done
|
||||
pld
|
||||
plb
|
||||
rtl
|
||||
|
||||
; Just drain the queue of any on-screen changes and then exit
|
||||
:queue
|
||||
jsr DrainNTQueue
|
||||
pld
|
||||
plb
|
||||
rtl
|
||||
|
||||
CopyStatus
|
||||
; Copy the first two rows from $2400 because they don't scroll
|
||||
|
||||
ldy #0
|
||||
:yloop
|
||||
ldx #0
|
||||
|
||||
cpy #2
|
||||
bcs :offset
|
||||
|
||||
tya
|
||||
clc
|
||||
adc #2
|
||||
|
@ -346,19 +570,84 @@ CopyNametable
|
|||
asl
|
||||
asl
|
||||
asl
|
||||
|
||||
sta Tmp2
|
||||
lda #0
|
||||
sta Tmp3
|
||||
bra :xloop
|
||||
stz Tmp3
|
||||
:xloop
|
||||
phx ; Save X and Y
|
||||
phy
|
||||
|
||||
:offset
|
||||
lda Tmp0 ; Get the base address for this line
|
||||
ora Tmp1 ; Move over to the first horizontal tile
|
||||
phx ; x = GTE tile index = PPU tile index
|
||||
phy ; No vertical scroll, so screen_y = tile_y
|
||||
|
||||
ldx Tmp2 ; Nametable address
|
||||
lda PPU_MEM+$2000,x
|
||||
and #$00FF
|
||||
ora #$0100
|
||||
pha
|
||||
|
||||
; Advance to the next tile (no wrapping needed)
|
||||
|
||||
inx
|
||||
stx Tmp2
|
||||
|
||||
_GTESetTile
|
||||
|
||||
ply
|
||||
plx
|
||||
|
||||
inx
|
||||
cpx #33
|
||||
bcc :xloop
|
||||
|
||||
iny
|
||||
cpy #2
|
||||
bcc :yloop
|
||||
rts
|
||||
|
||||
; Copy the tile and attribute bytes into the GTE buffer
|
||||
;
|
||||
; A = logical column in mirrored PPU memory (0 - 63)
|
||||
; X = number of columns to copy
|
||||
; Y = number of GTE tiles to offset
|
||||
CopyNametable
|
||||
; cmp #5
|
||||
; bcc *+4
|
||||
; brk $88
|
||||
sta Tmp2
|
||||
bit #$0020 ; Is it >32?
|
||||
beq *+5
|
||||
ora #$0400 ; Move to the next nametable
|
||||
and #$041F ; Mask to the top of a valid column
|
||||
|
||||
clc ; Add in the offset since we only copy rows 2 - 27
|
||||
adc #4*32
|
||||
sta Tmp0 ; base address offset into nametable memory
|
||||
|
||||
stx Tmp4
|
||||
|
||||
tya
|
||||
clc
|
||||
adc TileX
|
||||
cmp #41
|
||||
bcc *+5
|
||||
sbc #41
|
||||
sta Tmp5
|
||||
|
||||
; NES RAM $6D = page, $86 = player_x_in_page can be used to get a global position in the level, then subtracting the
|
||||
; player's x coordinate will give us the global coordinate of the left edge of the screen and allow us to map between
|
||||
; the GTE tile buffer and the PPU nametables
|
||||
|
||||
; Skip the first two rows -- call CopyStatus to get those
|
||||
|
||||
ldy #2
|
||||
:yloop
|
||||
ldx #0
|
||||
|
||||
lda Tmp0 ; Get the base address for this row
|
||||
sta Tmp2 ; coarse x-scroll
|
||||
|
||||
lda Tmp1
|
||||
sta Tmp3 ; Keep a separate count for the GTE tile position
|
||||
lda Tmp5
|
||||
sta Tmp3 ; Keep a separate variable for the GTE tile position
|
||||
:xloop
|
||||
phx ; Save X and Y
|
||||
phy
|
||||
|
@ -401,7 +690,7 @@ CopyNametable
|
|||
sta Tmp3
|
||||
|
||||
inx
|
||||
cpx #33
|
||||
cpx Tmp4
|
||||
bcc :xloop
|
||||
|
||||
lda Tmp0
|
||||
|
@ -766,12 +1055,25 @@ nmiTask
|
|||
|
||||
jsr triggerNMI
|
||||
|
||||
; Immediately after the NMI returns, freeze some of the global state variables so we can sync up with this frame when
|
||||
; we render the next frame. Since we're in an interrupt handler here, sno change of the variables changing under
|
||||
; our nose
|
||||
|
||||
sep #$20
|
||||
ldal ROMBase+$071a
|
||||
xba
|
||||
ldal ROMBase+$071c
|
||||
rep #$20
|
||||
sta ROMScrollEdge
|
||||
|
||||
pld
|
||||
plb
|
||||
plp
|
||||
:skip
|
||||
rtl
|
||||
mx %00
|
||||
put App.Msg.s
|
||||
put font.s
|
||||
put palette.s
|
||||
put ppu.s
|
||||
|
||||
|
|
|
@ -1,3 +1,25 @@
|
|||
; 8 * 8 * 2 (2 bits to codify color) = 128 bits = 16 bytes to codify a single tile
|
||||
;
|
||||
; Surprisingly, 2 bits of a pixel are not codified in the same byte. A tile is
|
||||
; described using 16 bytes. And each row is encoded using 2 bytes that stand 8
|
||||
; bytes apart from each other. To figure out the color index of the top-left pixel,
|
||||
; we need to read the 7th bit of byte 0x0000 and the 7th bit of byte 0x0008, to get
|
||||
; the next pixel in the same row we would need to read 6th bits in the same bytes, etc.
|
||||
;
|
||||
; Decode the first row which is the back of mario's head
|
||||
;
|
||||
; ADDR VAL BITS ADDR VAL BITS
|
||||
;
|
||||
; 0x00 $03 00000011 0x08 $00 00000000 00 00 00 00 00 00 01 01 0 0 0 0 0 0 1 1
|
||||
; 0x01 $0F 00001111 0x09 $00 00000000 00 00 00 00 01 01 01 01 0 0 0 0 1 1 1 1
|
||||
; 0x02 $1F 00011111 0x0A $00 00000000 00 00 00 01 01 01 01 01 0 0 0 1 1 1 1 1
|
||||
; 0x03 $1F 00011111 0x0B $00 00000000 = 00 00 00 01 01 01 01 01 = 0 0 0 1 1 1 1 1
|
||||
; 0x04 $1C 00011100 0x0C $1F 00011111 00 00 00 11 11 11 10 10 0 0 0 3 3 3 2 2
|
||||
; 0x05 $24 00100100 0x0D $3F 00111111 00 00 11 10 10 11 10 10 0 0 3 2 2 3 2 2
|
||||
; 0x06 $26 00100110 0x0E $3F 00111111 00 00 11 10 10 11 11 10 0 0 3 2 2 3 3 2
|
||||
; 0x07 $66 01100110 0x0F $7F 11111111 10 11 11 10 10 11 11 10 2 3 3 2 2 3 3 2
|
||||
|
||||
; Begin Bank 0
|
||||
db $03,$0f,$1f,$1f,$1c,$24,$26,$66,$00,$00,$00,$00,$1f,$3f,$3f,$7f
|
||||
db $e0,$c0,$80,$fc,$80,$c0,$00,$20,$00,$20,$60,$00,$f0,$fc,$fe,$fe
|
||||
db $60,$70,$18,$07,$0f,$1f,$3f,$7f,$7f,$7f,$1f,$07,$00,$1e,$3f,$7f
|
||||
|
@ -254,6 +276,9 @@
|
|||
db $00,$00,$00,$00,$00,$00,$00,$00,$66,$e6,$66,$66,$66,$67,$f3,$00
|
||||
db $00,$00,$00,$00,$00,$00,$00,$00,$5e,$59,$59,$59,$5e,$d8,$98,$00
|
||||
db $00,$00,$00,$00,$00,$7c,$38,$00,$00,$00,$00,$00,$00,$04,$08,$00
|
||||
|
||||
; Begin Bank 1
|
||||
; Tiles 0 - 15
|
||||
db $38,$4c,$c6,$c6,$c6,$64,$38,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $18,$38,$18,$18,$18,$18,$7e,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $7c,$c6,$0e,$3c,$78,$e0,$fe,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
|
@ -270,6 +295,8 @@
|
|||
db $f8,$cc,$c6,$c6,$c6,$cc,$f8,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $fe,$c0,$c0,$fc,$c0,$c0,$fe,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $fe,$c0,$c0,$fc,$c0,$c0,$c0,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
|
||||
; Tiles 16 - 31
|
||||
db $3e,$60,$c0,$ce,$c6,$66,$3e,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $c6,$c6,$c6,$fe,$c6,$c6,$c6,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $7e,$18,$18,$18,$18,$18,$7e,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
|
@ -286,6 +313,8 @@
|
|||
db $7e,$18,$18,$18,$18,$18,$18,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $c6,$c6,$c6,$c6,$c6,$c6,$7c,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $c6,$c6,$c6,$ee,$7c,$38,$10,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
|
||||
; Tiles 32 - 47
|
||||
db $c6,$c6,$d6,$fe,$fe,$ee,$c6,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $c6,$ee,$7c,$38,$7c,$ee,$c6,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $66,$66,$66,$3c,$18,$18,$18,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
|
@ -302,6 +331,8 @@
|
|||
db $80,$80,$80,$c1,$e3,$ff,$ff,$ff,$7f,$7f,$7f,$3e,$1c,$00,$00,$ff
|
||||
db $38,$7c,$7c,$7c,$7c,$7c,$38,$00,$08,$04,$04,$04,$04,$04,$08,$00
|
||||
db $03,$06,$0c,$0c,$08,$08,$04,$03,$03,$05,$0b,$0b,$0f,$0f,$07,$03
|
||||
|
||||
; Tiles 48 - 63
|
||||
db $01,$02,$04,$08,$10,$20,$40,$80,$01,$03,$07,$0f,$1f,$3f,$7f,$ff
|
||||
db $00,$00,$00,$00,$00,$07,$38,$c0,$00,$00,$00,$00,$00,$07,$3f,$ff
|
||||
db $00,$00,$00,$00,$00,$e0,$1c,$03,$00,$00,$00,$00,$00,$e0,$fc,$ff
|
||||
|
@ -318,6 +349,8 @@
|
|||
db $c0,$20,$10,$10,$10,$10,$20,$c0,$c0,$e0,$f0,$f0,$f0,$f0,$e0,$c0
|
||||
db $00,$00,$00,$00,$3f,$7f,$e0,$c0,$00,$00,$00,$00,$00,$00,$1c,$3e
|
||||
db $88,$9c,$88,$80,$80,$80,$80,$80,$7f,$7f,$7f,$3e,$1c,$00,$00,$00
|
||||
|
||||
; Tiles 64 - 79
|
||||
db $fe,$fe,$fe,$fe,$fe,$fe,$fe,$fe,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $08,$14,$24,$c4,$03,$40,$a1,$26,$00,$08,$18,$38,$fc,$bf,$5e,$d9
|
||||
db $ff,$ff,$ff,$ff,$7f,$7f,$7f,$7f,$81,$81,$81,$81,$81,$81,$81,$81
|
||||
|
@ -334,6 +367,8 @@
|
|||
db $ff,$ff,$ff,$ff,$ff,$ff,$7e,$3c,$80,$80,$80,$80,$80,$81,$42,$3c
|
||||
db $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$00,$00,$00,$00,$00,$00,$00
|
||||
db $ff,$ff,$ff,$ff,$ff,$ff,$fe,$7c,$00,$00,$00,$00,$00,$01,$82,$7c
|
||||
|
||||
; Tiles 80 - 95
|
||||
db $ff,$ff,$ff,$ff,$ff,$ff,$fe,$7c,$00,$00,$00,$00,$00,$01,$83,$ff
|
||||
db $f8,$fc,$fe,$fe,$ff,$ff,$ff,$ff,$f8,$04,$02,$02,$01,$01,$01,$01
|
||||
db $ff,$ff,$ff,$ff,$ff,$ff,$7e,$3c,$01,$01,$01,$01,$01,$81,$42,$3c
|
||||
|
@ -350,6 +385,8 @@
|
|||
db $11,$39,$11,$01,$01,$01,$01,$01,$fe,$fe,$fe,$7c,$38,$00,$00,$00
|
||||
db $ef,$28,$28,$28,$28,$28,$ef,$00,$20,$e7,$e7,$e7,$e7,$e7,$ef,$00
|
||||
db $fe,$82,$82,$82,$82,$82,$fe,$00,$02,$7e,$7e,$7e,$7e,$7e,$fe,$00
|
||||
|
||||
; Tiles 96 - 111
|
||||
db $80,$80,$80,$98,$9c,$8c,$80,$7f,$7f,$7f,$7f,$67,$67,$7f,$7f,$7f
|
||||
db $ff,$ff,$83,$f3,$f3,$f3,$f3,$f3,$ff,$80,$fc,$8c,$8c,$8c,$8c,$8c
|
||||
db $ff,$ff,$f0,$f6,$f6,$f6,$f6,$f6,$ff,$00,$0f,$09,$09,$09,$09,$09
|
||||
|
@ -366,6 +403,8 @@
|
|||
db $ff,$80,$80,$c0,$ff,$ff,$fe,$fe,$ff,$7f,$7f,$3f,$00,$00,$01,$01
|
||||
db $ff,$7f,$7f,$ff,$ff,$07,$03,$03,$ff,$80,$80,$00,$00,$f8,$fc,$fc
|
||||
db $ff,$00,$00,$00,$00,$81,$c3,$ff,$ff,$ff,$ff,$ff,$ff,$7e,$3c,$00
|
||||
|
||||
; Tiles 112 - 127
|
||||
db $f8,$fc,$fe,$fe,$e3,$c1,$81,$81,$f8,$04,$02,$02,$1d,$3f,$7f,$7f
|
||||
db $83,$ff,$ff,$ff,$ff,$ff,$7f,$1f,$fc,$80,$80,$80,$80,$80,$60,$1f
|
||||
db $fc,$fc,$fc,$fc,$fe,$fe,$ff,$ff,$03,$03,$03,$03,$01,$01,$00,$ff
|
||||
|
@ -382,6 +421,8 @@
|
|||
db $04,$9a,$fa,$fd,$fd,$fd,$fd,$fd,$00,$80,$80,$80,$80,$80,$80,$80
|
||||
db $7e,$38,$21,$00,$01,$00,$01,$00,$21,$21,$01,$01,$01,$01,$01,$01
|
||||
db $fa,$8a,$84,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80
|
||||
|
||||
; Tiles 128 - 143
|
||||
db $02,$04,$00,$10,$00,$40,$80,$00,$01,$01,$06,$08,$18,$20,$20,$c0
|
||||
db $0b,$0b,$3b,$0b,$fb,$0b,$0b,$0a,$04,$04,$c4,$f4,$f4,$04,$04,$05
|
||||
db $90,$10,$1f,$10,$1f,$10,$10,$90,$70,$f0,$f0,$ff,$ff,$f0,$f0,$70
|
||||
|
@ -398,6 +439,8 @@
|
|||
db $ff,$ff,$ff,$ff,$ff,$00,$ff,$ff,$00,$00,$00,$00,$00,$ff,$00,$00
|
||||
db $fc,$fc,$fe,$fe,$fe,$02,$fe,$fe,$07,$07,$03,$03,$03,$ff,$03,$03
|
||||
db $ff,$80,$80,$80,$80,$80,$80,$80,$80,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
|
||||
; Tiles 144 - 159
|
||||
db $ff,$03,$03,$03,$03,$03,$03,$03,$03,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $02,$02,$02,$02,$02,$02,$04,$04,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $80,$80,$aa,$d5,$aa,$ff,$ff,$ff,$ff,$ff,$d5,$aa,$d5,$80,$80,$ff
|
||||
|
@ -414,6 +457,8 @@
|
|||
db $e1,$f9,$fd,$ff,$fe,$fe,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $f0,$10,$10,$10,$10,$10,$10,$ff,$00,$e0,$e0,$e0,$e0,$e0,$e0,$e0
|
||||
db $1f,$10,$10,$10,$10,$10,$10,$ff,$00,$0f,$0f,$0f,$0f,$0f,$0f,$0f
|
||||
|
||||
; Tiles 160 - 175
|
||||
db $92,$92,$92,$fe,$fe,$00,$00,$00,$48,$48,$6c,$00,$00,$00,$fe,$00
|
||||
db $0a,$0a,$3a,$0a,$fb,$0b,$0b,$0b,$05,$05,$c5,$f5,$f4,$04,$04,$04
|
||||
db $90,$90,$9f,$90,$9f,$90,$90,$90,$70,$70,$70,$7f,$7f,$70,$70,$70
|
||||
|
@ -426,10 +471,12 @@
|
|||
db $f8,$f8,$f8,$f8,$f8,$f0,$f0,$e0,$98,$98,$98,$98,$98,$30,$30,$60
|
||||
db $f1,$11,$11,$1f,$10,$10,$10,$ff,$0f,$ef,$ef,$ef,$ef,$ef,$ef,$e0
|
||||
db $1f,$10,$10,$f0,$10,$10,$10,$ff,$e0,$ef,$ef,$ef,$ef,$ef,$ef,$0f
|
||||
db $7f,$bf,$df,$ef,$f0,$f0,$f0,$f0,$80,$40,$20,$10,$0f,$0f,$0f,$0f
|
||||
; db $7f,$bf,$df,$ef,$f0,$f0,$f0,$f0,$80,$40,$20,$10,$0f,$0f,$0f,$0f
|
||||
db $f0,$f0,$f0,$f0,$ff,$ff,$ff,$ff,$0f,$0f,$0f,$0f,$1f,$3f,$7f,$ff
|
||||
db $ff,$ff,$ff,$ff,$0f,$0f,$0f,$0f,$01,$03,$07,$0f,$ff,$ff,$ff,$ff
|
||||
db $0f,$0f,$0f,$0f,$f7,$fb,$fd,$fe,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
|
||||
; Tiles 176 - 191
|
||||
db $00,$00,$00,$00,$00,$00,$18,$18,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $1f,$3f,$7f,$7f,$7f,$ff,$ff,$ff,$1f,$20,$40,$40,$40,$80,$82,$82
|
||||
db $ff,$ff,$ff,$7f,$7f,$7f,$3f,$1e,$82,$80,$a0,$44,$43,$40,$21,$1e
|
||||
|
@ -446,6 +493,8 @@
|
|||
db $7f,$7f,$7f,$3f,$3f,$1f,$0f,$07,$40,$40,$40,$20,$30,$1c,$0f,$07
|
||||
db $fe,$fe,$fe,$fc,$fc,$f8,$f0,$f0,$02,$02,$02,$04,$0c,$38,$f0,$f0
|
||||
db $0f,$0f,$0f,$0f,$0f,$0f,$07,$0f,$08,$08,$08,$08,$08,$0c,$05,$0a
|
||||
|
||||
; Tiles 192 - 207
|
||||
db $f0,$f0,$f0,$f0,$f0,$f0,$e0,$f0,$10,$50,$50,$50,$50,$30,$a0,$50
|
||||
db $81,$c1,$a3,$a3,$9d,$81,$81,$81,$00,$41,$22,$22,$1c,$00,$00,$00
|
||||
db $e3,$f7,$c1,$c1,$c1,$c1,$f7,$e3,$e3,$14,$3e,$3e,$3e,$3e,$14,$e3
|
||||
|
@ -462,6 +511,8 @@
|
|||
db $e9,$e9,$e9,$ef,$e2,$e3,$f0,$ff,$76,$76,$76,$70,$7d,$7c,$7f,$7f
|
||||
db $96,$96,$96,$f6,$46,$c6,$0e,$fe,$6f,$6f,$6f,$0f,$bf,$3f,$ff,$ff
|
||||
db $00,$00,$00,$00,$00,$00,$7e,$3c,$3c,$7e,$7e,$ff,$ff,$ff,$42,$00
|
||||
|
||||
; Tiles 208 - 223
|
||||
db $3c,$42,$99,$a1,$a1,$99,$42,$3c,$00,$00,$00,$00,$00,$00,$00,$00
|
||||
db $0f,$1f,$1f,$3f,$3f,$7f,$7f,$7f,$f0,$e0,$e0,$c0,$c0,$80,$80,$80
|
||||
db $f0,$f8,$f8,$fc,$fc,$fe,$fe,$fe,$0f,$07,$07,$03,$03,$01,$01,$01
|
||||
|
@ -478,6 +529,8 @@
|
|||
db $ff,$ff,$ff,$ff,$fc,$fe,$fe,$7e,$ff,$03,$03,$03,$03,$03,$03,$ff
|
||||
db $ff,$ff,$ff,$ff,$00,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
db $7f,$7f,$7f,$7f,$7f,$7f,$7f,$7f,$80,$80,$80,$80,$80,$80,$80,$80
|
||||
|
||||
; Tiles 224 - 239
|
||||
db $ff,$ff,$ff,$ff,$ff,$ff,$ff,$fe,$01,$01,$01,$03,$07,$03,$01,$01
|
||||
db $7e,$7e,$7f,$7f,$7f,$7f,$7f,$7f,$81,$81,$81,$81,$81,$81,$81,$81
|
||||
db $3f,$3f,$3f,$3f,$00,$00,$00,$00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
|
||||
|
@ -494,6 +547,8 @@
|
|||
db $20,$a6,$54,$26,$20,$c6,$54,$26,$20,$e6,$54,$26,$21,$06,$54,$26
|
||||
db $20,$85,$01,$44,$20,$86,$54,$48,$20,$9a,$01,$49,$20,$a5,$c9,$46
|
||||
db $20,$ba,$c9,$4a,$20,$a6,$0a,$d0,$d1,$d8,$d8,$de,$d1,$d0,$da,$de
|
||||
|
||||
; Tiles 240 - 255
|
||||
db $d1,$20,$c6,$0a,$d2,$d3,$db,$db,$db,$d9,$db,$dc,$db,$df,$20,$e6
|
||||
db $0a,$d4,$d5,$d4,$d9,$db,$e2,$d4,$da,$db,$e0,$21,$06,$0a,$d6,$d7
|
||||
db $d6,$d7,$e1,$26,$d6,$dd,$e1,$e1,$21,$26,$14,$d0,$e8,$d1,$d0,$d1
|
||||
|
@ -510,3 +565,5 @@
|
|||
db $0a,$16,$0e,$22,$8b,$0d,$02,$24,$19,$15,$0a,$22,$0e,$1b,$24,$10
|
||||
db $0a,$16,$0e,$22,$ec,$04,$1d,$18,$19,$28,$22,$f6,$01,$00,$23,$c9
|
||||
db $56,$55,$23,$e2,$04,$99,$aa,$aa,$aa,$23,$ea,$04,$99,$aa,$aa,$aa
|
||||
|
||||
db $7f,$bf,$df,$ef,$f0,$f0,$f0,$f0,$80,$40,$20,$10,$0f,$0f,$0f,$0f
|
||||
|
|
|
@ -0,0 +1,668 @@
|
|||
****************************************
|
||||
* FONT ENGINE (v3?) *
|
||||
* *
|
||||
* Dagen Brock <dagenbrock@gmail.com> *
|
||||
* 2013-07-20 *
|
||||
****************************************
|
||||
* A= ptr to string preceded by length *
|
||||
* X= screen location *
|
||||
****************************************
|
||||
; each char:
|
||||
; draw char at loc
|
||||
; update loc
|
||||
; see if length hit - no? back to draw char
|
||||
rel
|
||||
mx %00
|
||||
]F_Length ds 2 ;length of string (only one byte currently used)
|
||||
]F_CharIdx ds 2 ;index of current character
|
||||
]F_CurrentPos ds 2 ;current top left char position
|
||||
]F_StrPtr equ $01 ;pointer to string (including length byte) / DP
|
||||
]F_StrClr equ $03
|
||||
|
||||
DrawString
|
||||
pha ; local variable space
|
||||
pha
|
||||
tsc
|
||||
phd
|
||||
tcd
|
||||
|
||||
; sta ]F_StrPtr ; (done in pha init above) store at dp 0 ($00) for indirect loads
|
||||
stx ]F_CurrentPos
|
||||
sty ]F_StrClr
|
||||
stz ]F_CharIdx
|
||||
lda (]F_StrPtr)
|
||||
and #$00ff ;strip off first char (len is only one byte)
|
||||
sta ]F_Length ;get our length byte
|
||||
|
||||
NextChar lda ]F_CharIdx
|
||||
cmp ]F_Length
|
||||
bne :notDone
|
||||
ldy ]F_StrClr ;restore the color pattern
|
||||
pld
|
||||
pla
|
||||
pla
|
||||
rts ;DONE! Return to caller
|
||||
|
||||
:notDone inc ]F_CharIdx
|
||||
ldy ]F_CharIdx
|
||||
lda (]F_StrPtr),y ;get next char!
|
||||
and #$00FF ;mask high byte
|
||||
sec
|
||||
sbc #' ' ;our table starts with space ' '
|
||||
asl ;*2
|
||||
tay
|
||||
ldx ]F_CurrentPos
|
||||
jsr :drawChar
|
||||
inc ]F_CurrentPos ;compare to addition time (?)
|
||||
inc ]F_CurrentPos
|
||||
inc ]F_CurrentPos
|
||||
inc ]F_CurrentPos ;update screen pos (2 words=8 pixels)
|
||||
bra NextChar
|
||||
|
||||
;x = TopLeft screen pos
|
||||
;y = char table offset
|
||||
:drawChar lda FontTable,y ;get real address of char data
|
||||
sec
|
||||
sbc #FontData ;pivot offset - now a is offset of fontdata
|
||||
tay ;so we'll index with that
|
||||
|
||||
lda FontData,y
|
||||
and ]F_StrClr
|
||||
stal $E12000,x
|
||||
|
||||
lda FontData+2,y
|
||||
and ]F_StrClr
|
||||
stal $E12000+2,x
|
||||
|
||||
lda FontData+4,y
|
||||
and ]F_StrClr
|
||||
stal $E12000+160,x
|
||||
|
||||
lda FontData+6,y
|
||||
and ]F_StrClr
|
||||
stal $E12000+160+2,x
|
||||
|
||||
lda FontData+8,y
|
||||
and ]F_StrClr
|
||||
stal {$E12000+160*2},x
|
||||
|
||||
lda FontData+10,y
|
||||
and ]F_StrClr
|
||||
stal {$E12000+160*2+2},x
|
||||
|
||||
lda FontData+12,y
|
||||
and ]F_StrClr
|
||||
stal {$E12000+160*3},x
|
||||
|
||||
lda FontData+14,y
|
||||
and ]F_StrClr
|
||||
stal {$E12000+160*3+2},x
|
||||
|
||||
lda FontData+16,y
|
||||
and ]F_StrClr
|
||||
stal {$E12000+160*4},x
|
||||
|
||||
lda FontData+18,y
|
||||
and ]F_StrClr
|
||||
stal {$E12000+160*4+2},x
|
||||
|
||||
lda FontData+20,y
|
||||
and ]F_StrClr
|
||||
stal {$E12000+160*5},x
|
||||
|
||||
lda FontData+22,y
|
||||
and ]F_StrClr
|
||||
stal {$E12000+160*5+2},x
|
||||
rts
|
||||
|
||||
FontTable dw s_Space
|
||||
dw s_Exclaim
|
||||
dw s_Quote
|
||||
dw s_Number
|
||||
dw s_Dollar
|
||||
dw s_Percent
|
||||
dw s_Amper
|
||||
dw s_Single
|
||||
dw s_OpenParen
|
||||
dw s_CloseParen
|
||||
dw s_Asterix
|
||||
dw s_Plus
|
||||
dw s_Comma
|
||||
dw s_Minus
|
||||
dw s_Period
|
||||
dw s_Slash
|
||||
dw s_N0
|
||||
dw s_N1
|
||||
dw s_N2
|
||||
dw s_N3
|
||||
dw s_N4
|
||||
dw s_N5
|
||||
dw s_N6
|
||||
dw s_N7
|
||||
dw s_N8
|
||||
dw s_N9
|
||||
dw s_Colon
|
||||
dw s_Semi
|
||||
dw s_LAngle
|
||||
dw s_Equal
|
||||
dw s_RAngle
|
||||
dw s_Question
|
||||
dw s_At
|
||||
dw s_A
|
||||
dw s_B
|
||||
dw s_C
|
||||
dw s_D
|
||||
dw s_E
|
||||
dw s_F
|
||||
dw s_G
|
||||
dw s_H
|
||||
dw s_I
|
||||
dw s_J
|
||||
dw s_K
|
||||
dw s_L
|
||||
dw s_M
|
||||
dw s_N
|
||||
dw s_O
|
||||
dw s_P
|
||||
dw s_Q
|
||||
dw s_R
|
||||
dw s_S
|
||||
dw s_T
|
||||
dw s_U
|
||||
dw s_V
|
||||
dw s_W
|
||||
dw s_X
|
||||
dw s_Y
|
||||
dw s_Z
|
||||
dw s_LBracket
|
||||
dw s_BackSlash
|
||||
dw s_RBracket
|
||||
dw s_Carot
|
||||
dw s_UnderLine
|
||||
|
||||
FontData = *
|
||||
s_Space hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
|
||||
s_Exclaim hex 000FF000
|
||||
hex 000FF000
|
||||
hex 000FF000
|
||||
hex 000FF000
|
||||
hex 00000000
|
||||
hex 000FF000
|
||||
|
||||
s_Quote hex 0FF00FF0
|
||||
hex 00F000F0
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
|
||||
s_Number hex 00000000
|
||||
hex 00F00F00
|
||||
hex 0FFFFFF0
|
||||
hex 00F00F00
|
||||
hex 0FFFFFF0
|
||||
hex 00F00F00
|
||||
|
||||
s_Dollar hex 000F0F00
|
||||
hex 00FFFFF0
|
||||
hex 0F0F0F00
|
||||
hex 00FFFF00
|
||||
hex 000F0FF0
|
||||
hex 0FFFFF00
|
||||
|
||||
s_Percent hex 0FF000F0
|
||||
hex 00000F00
|
||||
hex 0000F000
|
||||
hex 000F0000
|
||||
hex 00F00000
|
||||
hex 0F000FF0
|
||||
|
||||
s_Amper hex 000FF000
|
||||
hex 00F00F00
|
||||
hex 0F00F000
|
||||
hex 00F000F0
|
||||
hex 0F0FFF00
|
||||
hex 00F0F000
|
||||
|
||||
s_Single hex 000FF000
|
||||
hex 0000F000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
|
||||
s_OpenParen hex 000FF000
|
||||
hex 00FF0000
|
||||
hex 0FF00000
|
||||
hex 0FF00000
|
||||
hex 00FF0000
|
||||
hex 000FF000
|
||||
|
||||
s_CloseParen hex 000FF000
|
||||
hex 0000FF00
|
||||
hex 00000FF0
|
||||
hex 00000FF0
|
||||
hex 0000FF00
|
||||
hex 000FF000
|
||||
|
||||
|
||||
s_Asterix hex 00000000
|
||||
hex 00F0F0F0
|
||||
hex 000FFF00
|
||||
hex 00FFFFF0
|
||||
hex 000FFF00
|
||||
hex 00F0F0F0
|
||||
|
||||
s_Plus hex 000F0000
|
||||
hex 000F0000
|
||||
hex 0FFFFF00
|
||||
hex 000F0000
|
||||
hex 000F0000
|
||||
hex 00000000
|
||||
|
||||
s_Comma hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 0000FF00
|
||||
hex 0000F000
|
||||
|
||||
s_Minus hex 00000000
|
||||
hex 00000000
|
||||
hex 0FFFFF00
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
|
||||
|
||||
s_Period hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 0000FF00
|
||||
hex 0000FF00
|
||||
|
||||
s_Slash hex 000000F0
|
||||
hex 00000F00
|
||||
hex 0000F000
|
||||
hex 000F0000
|
||||
hex 00F00000
|
||||
hex 0F000000
|
||||
|
||||
s_N0 hex 00FFFF00
|
||||
hex 0F000FF0
|
||||
hex 0F00F0F0
|
||||
hex 0F0F00F0
|
||||
hex 0FF000F0
|
||||
hex 00FFFF00
|
||||
|
||||
s_N1 hex 000F0000
|
||||
hex 00FF0000
|
||||
hex 000F0000
|
||||
hex 000F0000
|
||||
hex 000F0000
|
||||
hex 00FFF000
|
||||
|
||||
s_N2 hex 00FFFF00
|
||||
hex 0F0000F0
|
||||
hex 00000F00
|
||||
hex 000FF000
|
||||
hex 00F00000
|
||||
hex 0FFFFFF0
|
||||
|
||||
s_N3 hex 00FFFF00
|
||||
hex 000000F0
|
||||
hex 000FFF00
|
||||
hex 000000F0
|
||||
hex 000000F0
|
||||
hex 00FFFF00
|
||||
|
||||
s_N4 hex 0000FF00
|
||||
hex 000F0F00
|
||||
hex 00F00F00
|
||||
hex 0FFFFFF0
|
||||
hex 00000F00
|
||||
hex 00000F00
|
||||
|
||||
s_N5 hex 0FFFFFF0
|
||||
hex 0F000000
|
||||
hex 0FFFFF00
|
||||
hex 000000F0
|
||||
hex 0F0000F0
|
||||
hex 00FFFF00
|
||||
|
||||
s_N6 hex 000FFF00
|
||||
hex 00F00000
|
||||
hex 0F000000
|
||||
hex 0FFFFF00
|
||||
hex 0F0000F0
|
||||
hex 00FFFFF0
|
||||
|
||||
s_N7 hex 0FFFFFF0
|
||||
hex 000000F0
|
||||
hex 00000F00
|
||||
hex 0000F000
|
||||
hex 000F0000
|
||||
hex 000F0000
|
||||
|
||||
s_N8 hex 00FFFF00
|
||||
hex 0F0000F0
|
||||
hex 00FFFF00
|
||||
hex 0F0000F0
|
||||
hex 0F0000F0
|
||||
hex 00FFFF00
|
||||
|
||||
s_N9 hex 00FFFF00
|
||||
hex 0F0000F0
|
||||
hex 00FFFF00
|
||||
hex 0000F000
|
||||
hex 000F0000
|
||||
hex 00F00000
|
||||
|
||||
s_Colon hex 000FF000
|
||||
hex 000FF000
|
||||
hex 00000000
|
||||
hex 000FF000
|
||||
hex 000FF000
|
||||
hex 00000000
|
||||
|
||||
s_Semi hex 00000000
|
||||
hex 000FF000
|
||||
hex 000FF000
|
||||
hex 00000000
|
||||
hex 000FF000
|
||||
hex 000F0000
|
||||
|
||||
s_LAngle hex 0000F000
|
||||
hex 000F0000
|
||||
hex 00F00000
|
||||
hex 000F0000
|
||||
hex 0000F000
|
||||
hex 00000000
|
||||
|
||||
s_Equal hex 00000000
|
||||
hex 00000000
|
||||
hex 0FFFFF00
|
||||
hex 00000000
|
||||
hex 0FFFFF00
|
||||
hex 00000000
|
||||
|
||||
s_RAngle hex 0000F000
|
||||
hex 00000F00
|
||||
hex 000000F0
|
||||
hex 00000F00
|
||||
hex 0000F000
|
||||
hex 00000000
|
||||
|
||||
s_Question hex 00FFF000
|
||||
hex 0F000F00
|
||||
hex 00000F00
|
||||
hex 000FF000
|
||||
hex 00000000
|
||||
hex 000FF000
|
||||
|
||||
s_At hex 00FFFF00
|
||||
hex 0F0000F0
|
||||
hex 0F00F0F0
|
||||
hex 0FFFF0F0
|
||||
hex 000000F0
|
||||
hex 0FFFFF00
|
||||
|
||||
s_A hex 000FF000
|
||||
hex 00F00F00
|
||||
hex 0F0000F0
|
||||
hex 0FFFFFF0
|
||||
hex 0F0000F0
|
||||
hex 0F0000F0
|
||||
|
||||
s_B hex 0FFFFF00
|
||||
hex 0F0000F0
|
||||
hex 0FFFFF00
|
||||
hex 0F0000F0
|
||||
hex 0F0000F0
|
||||
hex 0FFFFF00
|
||||
|
||||
s_C hex 00FFFFF0
|
||||
hex 0F000000
|
||||
hex 0F000000
|
||||
hex 0F000000
|
||||
hex 0F000000
|
||||
hex 00FFFFF0
|
||||
|
||||
s_D hex 0FFFFF00
|
||||
hex 0F0000F0
|
||||
hex 0F0000F0
|
||||
hex 0F0000F0
|
||||
hex 0F0000F0
|
||||
hex 0FFFFF00
|
||||
|
||||
s_E hex 0FFFFFF0
|
||||
hex 0F000000
|
||||
hex 0FFFF000
|
||||
hex 0F000000
|
||||
hex 0F000000
|
||||
hex 0FFFFFF0
|
||||
|
||||
s_F hex 0FFFFFF0
|
||||
hex 0F000000
|
||||
hex 0FFFF000
|
||||
hex 0F000000
|
||||
hex 0F000000
|
||||
hex 0F000000
|
||||
|
||||
s_G hex 00FFFFF0
|
||||
hex 0F000000
|
||||
hex 0F000000
|
||||
hex 0F00FFF0
|
||||
hex 0F0000F0
|
||||
hex 00FFFF00
|
||||
|
||||
s_H hex 0F0000F0
|
||||
hex 0F0000F0
|
||||
hex 0FFFFFF0
|
||||
hex 0F0000F0
|
||||
hex 0F0000F0
|
||||
hex 0F0000F0
|
||||
|
||||
s_I hex 0FFFFF00
|
||||
hex 000F0000
|
||||
hex 000F0000
|
||||
hex 000F0000
|
||||
hex 000F0000
|
||||
hex 0FFFFF00
|
||||
|
||||
s_J hex 000000F0
|
||||
hex 000000F0
|
||||
hex 000000F0
|
||||
hex 0F0000F0
|
||||
hex 0F0000F0
|
||||
hex 00FFFF00
|
||||
|
||||
s_K hex 0F000F00
|
||||
hex 0F00F000
|
||||
hex 0FFF0000
|
||||
hex 0F00F000
|
||||
hex 0F000F00
|
||||
hex 0F000F00
|
||||
|
||||
s_L hex 0F000000
|
||||
hex 0F000000
|
||||
hex 0F000000
|
||||
hex 0F000000
|
||||
hex 0F000000
|
||||
hex 0FFFFFF0
|
||||
|
||||
s_M hex 0F0000F0
|
||||
hex 0FF00FF0
|
||||
hex 0F0FF0F0
|
||||
hex 0F0000F0
|
||||
hex 0F0000F0
|
||||
hex 0F0000F0
|
||||
|
||||
s_N hex 0F0000F0
|
||||
hex 0FF000F0
|
||||
hex 0F0F00F0
|
||||
hex 0F00F0F0
|
||||
hex 0F000FF0
|
||||
hex 0F0000F0
|
||||
|
||||
s_O hex 00FFFF00
|
||||
hex 0F0000F0
|
||||
hex 0F0000F0
|
||||
hex 0F0000F0
|
||||
hex 0F0000F0
|
||||
hex 00FFFF00
|
||||
|
||||
s_P hex 0FFFFF00
|
||||
hex 0F0000F0
|
||||
hex 0FFFFF00
|
||||
hex 0F000000
|
||||
hex 0F000000
|
||||
hex 0F000000
|
||||
|
||||
s_Q hex 00FFFF00
|
||||
hex 0F0000F0
|
||||
hex 0F0000F0
|
||||
hex 0F00F0F0
|
||||
hex 0F000FF0
|
||||
hex 00FFFFF0
|
||||
|
||||
s_R hex 0FFFFF00
|
||||
hex 0F0000F0
|
||||
hex 0FFFFF00
|
||||
hex 0F000F00
|
||||
hex 0F0000F0
|
||||
hex 0F0000F0
|
||||
|
||||
s_S hex 00FFFFF0
|
||||
hex 0F000000
|
||||
hex 00FFFF00
|
||||
hex 000000F0
|
||||
hex 000000F0
|
||||
hex 0FFFFF00
|
||||
|
||||
s_T hex 0FFFFF00
|
||||
hex 000F0000
|
||||
hex 000F0000
|
||||
hex 000F0000
|
||||
hex 000F0000
|
||||
hex 000F0000
|
||||
|
||||
s_U hex 0F0000F0
|
||||
hex 0F0000F0
|
||||
hex 0F0000F0
|
||||
hex 0F0000F0
|
||||
hex 0F0000F0
|
||||
hex 00FFFF00
|
||||
|
||||
s_V hex 0F0000F0
|
||||
hex 0F0000F0
|
||||
hex 0F0000F0
|
||||
hex 0F0000F0
|
||||
hex 00F00F00
|
||||
hex 000FF000
|
||||
|
||||
s_W hex 0F0000F0
|
||||
hex 0F0000F0
|
||||
hex 0F0000F0
|
||||
hex 0F0FF0F0
|
||||
hex 0FF00FF0
|
||||
hex 0F0000F0
|
||||
|
||||
s_X hex 0F0000F0
|
||||
hex 00F00F00
|
||||
hex 000FF000
|
||||
hex 000FF000
|
||||
hex 00F00F00
|
||||
hex 0F0000F0
|
||||
|
||||
s_Y hex F00000F0
|
||||
hex 0F000F00
|
||||
hex 00F0F000
|
||||
hex 000F0000
|
||||
hex 000F0000
|
||||
hex 000F0000
|
||||
|
||||
s_Z hex 0FFFFFF0
|
||||
hex 00000F00
|
||||
hex 0000F000
|
||||
hex 000F0000
|
||||
hex 00F00000
|
||||
hex 0FFFFFF0
|
||||
|
||||
s_LBracket hex 000FFF00
|
||||
hex 000F0000
|
||||
hex 000F0000
|
||||
hex 000F0000
|
||||
hex 000F0000
|
||||
hex 000FFF00
|
||||
|
||||
s_BackSlash hex 0F000000
|
||||
hex 00F00000
|
||||
hex 000F0000
|
||||
hex 0000F000
|
||||
hex 00000F00
|
||||
hex 000000F0
|
||||
|
||||
s_RBracket hex 00FFF000
|
||||
hex 0000F000
|
||||
hex 0000F000
|
||||
hex 0000F000
|
||||
hex 0000F000
|
||||
hex 00FFF000
|
||||
|
||||
s_Carot hex 0000F000
|
||||
hex 000F0F00
|
||||
hex 00F000F0
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
|
||||
s_UnderLine hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex FFFFFFF0
|
||||
|
||||
s_Template hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
hex 00000000
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -168,6 +168,7 @@ PPUADDR_WRITE ENT
|
|||
plp
|
||||
rtl
|
||||
|
||||
|
||||
; 2007 - PPUDATA (Read/Write)
|
||||
;
|
||||
; If reading from the $0000 - $3EFF range, the value from vram_buff is returned and the actual data is loaded
|
||||
|
@ -212,6 +213,10 @@ PPUDATA_READ ENT
|
|||
pla
|
||||
rtl
|
||||
|
||||
nt_queue_front dw 0
|
||||
nt_queue_end dw 0
|
||||
nt_queue ds 2*{1024}
|
||||
|
||||
PPUDATA_WRITE ENT
|
||||
php
|
||||
phb
|
||||
|
@ -230,16 +235,43 @@ PPUDATA_WRITE ENT
|
|||
adc ppuincr
|
||||
sta ppuaddr
|
||||
|
||||
; Anything between $2000 and $3000, we need to add to the queue. We can't reject updates here because we may not
|
||||
; actually update the GTE tile store for several game frames and the position of the tile within the tile store
|
||||
; may change if the screen is scrolling
|
||||
|
||||
cpx #$3000
|
||||
bcs :nocache
|
||||
cpx #$2000
|
||||
bcc :nocache
|
||||
|
||||
phy
|
||||
lda nt_queue_end
|
||||
tay
|
||||
inc
|
||||
inc
|
||||
and #{2*1024}-1
|
||||
cmp nt_queue_front
|
||||
beq :full
|
||||
|
||||
sta nt_queue_end
|
||||
txa
|
||||
sta nt_queue,y
|
||||
|
||||
:full
|
||||
ply
|
||||
|
||||
:nocache
|
||||
cpx #$3F00
|
||||
bcs :extra
|
||||
|
||||
:done
|
||||
sep #$30
|
||||
plx
|
||||
pla
|
||||
plb
|
||||
plp
|
||||
rtl
|
||||
|
||||
|
||||
; Do some extra work to keep palette data in sync
|
||||
;
|
||||
; Based on the palette data that SMB uses, we map the NES palette entries as
|
||||
|
@ -526,7 +558,7 @@ drawOAMSprites
|
|||
bra :noflip
|
||||
|
||||
:hflip
|
||||
lda PPU_OAM,x ; Loda the tile index into the high byte (x256)
|
||||
lda PPU_OAM,x ; Load the tile index into the high byte (x256)
|
||||
and #$FF00
|
||||
lsr ; multiple by 128
|
||||
adc #64 ; horizontal flip
|
||||
|
|
625
demos/smb/rom.s
625
demos/smb/rom.s
|
@ -30,19 +30,20 @@ PPU_SCROLL_REG = $2005
|
|||
PPU_ADDRESS = $2006
|
||||
PPU_DATA = $2007
|
||||
|
||||
SND_REGISTER = $4000
|
||||
SND_SQUARE1_REG = $4000
|
||||
SND_SQUARE2_REG = $4004
|
||||
SND_TRIANGLE_REG = $4008
|
||||
SND_NOISE_REG = $400c
|
||||
SND_DELTA_REG = $4010
|
||||
SND_MASTERCTRL_REG = $4015
|
||||
SND_REGISTER = $4000 ; Only accessed via abs,x addressing
|
||||
SND_SQUARE1_REG = $4000 ; Only accessed via abs addressing; sta, sty and stx
|
||||
SND_SQUARE2_REG = $4004 ; Only accessed via abs addressing; sta, sty and stx
|
||||
SND_TRIANGLE_REG = $4008 ; Only accessed via abs addressing; sta
|
||||
SND_NOISE_REG = $400c ; Only accessed via abs addressing; sta, sty and stx
|
||||
SND_DELTA_REG = $4010 ; Only accessed via abs addressing; sta, sty
|
||||
SND_MASTERCTRL_REG = $4015 ; Only accessed via abs addressing; sta, stx
|
||||
|
||||
SPR_DMA = $4014
|
||||
JOYPAD_PORT = $4016
|
||||
JOYPAD_PORT1 = $4016
|
||||
JOYPAD_PORT2 = $4017
|
||||
|
||||
GTE_TMP = $10 ; No zero page references in the assembly to this location
|
||||
; GAME SPECIFIC DEFINES
|
||||
|
||||
ObjectOffset = $08
|
||||
|
@ -271,13 +272,13 @@ Misc_SprDataOffset = $06f3
|
|||
SprDataOffset_Ctrl = $03ee
|
||||
|
||||
Player_State = $1d
|
||||
Enemy_State = $1e
|
||||
Enemy_State = $1e ; (11) Lots of ,y indexing on this variable
|
||||
Fireball_State = $24
|
||||
Block_State = $26
|
||||
Misc_State = $2a
|
||||
Misc_State = $2a ; (4) Lots of ,y indexing on this variable
|
||||
|
||||
Player_MovingDir = $45
|
||||
Enemy_MovingDir = $46
|
||||
Enemy_MovingDir = $46 ; (1)
|
||||
|
||||
SprObject_X_Speed = $57
|
||||
Player_X_Speed = $57
|
||||
|
@ -292,41 +293,41 @@ JumpspringForce = $06db
|
|||
|
||||
SprObject_PageLoc = $6d
|
||||
Player_PageLoc = $6d
|
||||
Enemy_PageLoc = $6e
|
||||
Enemy_PageLoc = $6e ; (6)
|
||||
Fireball_PageLoc = $74
|
||||
Block_PageLoc = $76
|
||||
Misc_PageLoc = $7a
|
||||
Block_PageLoc = $76 ; (1)
|
||||
Misc_PageLoc = $7a ; (2)
|
||||
Bubble_PageLoc = $83
|
||||
|
||||
SprObject_X_Position = $86
|
||||
Player_X_Position = $86
|
||||
Enemy_X_Position = $87
|
||||
Enemy_X_Position = $87 ; Fix ,y indexing (7)
|
||||
Fireball_X_Position = $8d
|
||||
Block_X_Position = $8f
|
||||
Misc_X_Position = $93
|
||||
Block_X_Position = $8f ; (1)
|
||||
Misc_X_Position = $93 ; (2)
|
||||
Bubble_X_Position = $9c
|
||||
|
||||
SprObject_Y_Speed = $9f
|
||||
Player_Y_Speed = $9f
|
||||
Enemy_Y_Speed = $a0
|
||||
Enemy_Y_Speed = $a0 ; (4)
|
||||
Fireball_Y_Speed = $a6
|
||||
Block_Y_Speed = $a8
|
||||
Misc_Y_Speed = $ac
|
||||
Misc_Y_Speed = $ac ; (1)
|
||||
|
||||
SprObject_Y_HighPos = $b5
|
||||
Player_Y_HighPos = $b5
|
||||
Enemy_Y_HighPos = $b6
|
||||
Enemy_Y_HighPos = $b6 ; (1)
|
||||
Fireball_Y_HighPos = $bc
|
||||
Block_Y_HighPos = $be
|
||||
Misc_Y_HighPos = $c2
|
||||
Misc_Y_HighPos = $c2 ; (1)
|
||||
Bubble_Y_HighPos = $cb
|
||||
|
||||
SprObject_Y_Position = $ce
|
||||
Player_Y_Position = $ce
|
||||
Enemy_Y_Position = $cf
|
||||
Enemy_Y_Position = $cf ; (11)
|
||||
Fireball_Y_Position = $d5
|
||||
Block_Y_Position = $d7
|
||||
Misc_Y_Position = $db
|
||||
Block_Y_Position = $d7 ; (1)
|
||||
Misc_Y_Position = $db ; (2)
|
||||
Bubble_Y_Position = $e4
|
||||
|
||||
SprObject_Rel_XPos = $03ad
|
||||
|
@ -374,8 +375,8 @@ Misc_BoundBoxCtrl = $04a2
|
|||
|
||||
EnemyFrenzyBuffer = $06cb
|
||||
EnemyFrenzyQueue = $06cd
|
||||
Enemy_Flag = $0f
|
||||
Enemy_ID = $16
|
||||
Enemy_Flag = $0f ; (4)
|
||||
Enemy_ID = $16 ; (7)
|
||||
|
||||
PlayerGfxOffset = $06d5
|
||||
Player_XSpeedAbsolute = $0700
|
||||
|
@ -682,7 +683,11 @@ PPUDATA_WRITE EXT
|
|||
PPUDMA_WRITE EXT
|
||||
|
||||
ROMBase ENT
|
||||
ds $8000-14-50-14
|
||||
ds $7800-14-50-14
|
||||
|
||||
; Macro to replace sta abs,y instructions that access zero page space with direct page
|
||||
; instruction to actually get the correct data on the direct page _and_ bank memory.
|
||||
; That way any lda 00,x or lda 0000,y will
|
||||
|
||||
; Hooks to call back to the GTE harness for PPU memory-mapped accesses
|
||||
mx %11
|
||||
|
@ -3708,12 +3713,23 @@ NoKillE dex ;do this until all
|
|||
FrenzyIDData
|
||||
db FlyCheepCheepFrenzy, BBill_CCheep_Frenzy,
|
||||
|
||||
AreaFrenzy ldx $00 ;use area object identifier bit as offset
|
||||
lda FrenzyIDData-8,x ;note that it starts at 8, thus weird address here
|
||||
ldy #$05
|
||||
FreCompLoop dey ;check regular slots of enemy object buffer
|
||||
;AreaFrenzy ldx $00 ;use area object identifier bit as offset
|
||||
; lda FrenzyIDData-8,x ;note that it starts at 8, thus weird address here
|
||||
; ldy #$05
|
||||
;FreCompLoop dey ;check regular slots of enemy object buffer
|
||||
; bmi ExitAFrenzy ;if all slots checked and enemy object not found, branch to store
|
||||
; cmp Enemy_ID,y ;check for enemy object in buffer versus frenzy object
|
||||
; bne FreCompLoop
|
||||
; lda #$00 ;if enemy object already present, nullify queue and leave
|
||||
;ExitAFrenzy sta EnemyFrenzyQueue ;store enemy into frenzy queue
|
||||
; rts
|
||||
|
||||
AreaFrenzy ldy $00 ;use area object identifier bit as offset
|
||||
lda FrenzyIDData-8,y ;note that it starts at 8, thus weird address here
|
||||
ldx #$05
|
||||
FreCompLoop dex ;check regular slots of enemy object buffer
|
||||
bmi ExitAFrenzy ;if all slots checked and enemy object not found, branch to store
|
||||
cmp Enemy_ID,y ;check for enemy object in buffer versus frenzy object
|
||||
cmp Enemy_ID,x ;check for enemy object in buffer versus frenzy object
|
||||
bne FreCompLoop
|
||||
lda #$00 ;if enemy object already present, nullify queue and leave
|
||||
ExitAFrenzy sta EnemyFrenzyQueue ;store enemy into frenzy queue
|
||||
|
@ -6783,12 +6799,30 @@ Setup_Vine
|
|||
sta Enemy_ID,x ;store in buffer
|
||||
lda #$01
|
||||
sta Enemy_Flag,x ;set flag for enemy object buffer
|
||||
lda Block_PageLoc,y
|
||||
sta Enemy_PageLoc,x ;copy page location from previous object
|
||||
lda Block_X_Position,y
|
||||
sta Enemy_X_Position,x ;copy horizontal coordinate from previous object
|
||||
lda Block_Y_Position,y
|
||||
|
||||
; lda Block_PageLoc,y ; FIXME
|
||||
; sta Enemy_PageLoc,x ;copy page location from previous object
|
||||
; lda Block_X_Position,y ; FIXME
|
||||
; sta Enemy_X_Position,x ;copy horizontal coordinate from previous object
|
||||
; lda Block_Y_Position,y ; FIXME
|
||||
; sta Enemy_Y_Position,x ;copy vertical coordinate from previous object
|
||||
stx GTE_TMP
|
||||
tyx
|
||||
|
||||
lda Block_PageLoc,x ; FIXME
|
||||
pha
|
||||
lda Block_X_Position,x ; FIXME
|
||||
pha
|
||||
lda Block_Y_Position,x ; FIXME
|
||||
|
||||
ldx GTE_TMP
|
||||
sta Enemy_Y_Position,x ;copy vertical coordinate from previous object
|
||||
pla
|
||||
sta Enemy_X_Position,x ;copy horizontal coordinate from previous object
|
||||
pla
|
||||
sta Enemy_PageLoc,x ;copy page location from previous object
|
||||
|
||||
|
||||
ldy VineFlagOffset ;load vine flag/offset to next available vine slot
|
||||
bne NextVO ;if set at all, don't bother to store vertical
|
||||
sta VineStart_Y_Position ;otherwise store vertical coordinate here
|
||||
|
@ -6981,7 +7015,12 @@ SpawnHammerObj
|
|||
lda PseudoRandomBitReg+1
|
||||
and #%00001000 ;get d3 from same part of LSFR
|
||||
SetMOfs tay ;use either d3 or d2-d0 for offset here
|
||||
lda Misc_State,y ;if any values loaded in
|
||||
|
||||
; lda Misc_State,y ;if any values loaded in
|
||||
tyx
|
||||
lda Misc_State,x
|
||||
; x is set immediately on both paths
|
||||
|
||||
bne NoHammer ;$2a-$32 where offset is then leave with carry clear
|
||||
ldx HammerEnemyOfsData,y ;get offset of enemy slot to check using Y as offset
|
||||
lda Enemy_Flag,x ;check enemy buffer flag at offset
|
||||
|
@ -6990,7 +7029,13 @@ SetMOfs tay ;use either d3 or d
|
|||
txa
|
||||
sta HammerEnemyOffset,y ;save here
|
||||
lda #$90
|
||||
sta Misc_State,y ;save hammer's state here
|
||||
|
||||
; sta Misc_State,y ;save hammer's state here
|
||||
phx
|
||||
tyx
|
||||
sta Misc_State,x
|
||||
plx
|
||||
|
||||
lda #$07
|
||||
sta Misc_BoundBoxCtrl,y ;set something else entirely, here
|
||||
sec ;return with carry set
|
||||
|
@ -7030,23 +7075,47 @@ ProcHammerObj
|
|||
jmp RunAllH ;branch to essential subroutines
|
||||
SetHSpd lda #$fe
|
||||
sta Misc_Y_Speed,x ;set hammer's vertical speed
|
||||
lda Enemy_State,y ;get enemy object state
|
||||
|
||||
; No need to preserve x here because it's loaded afterward
|
||||
tyx
|
||||
; lda Enemy_State,y ;get enemy object state
|
||||
lda Enemy_State,x
|
||||
and #%11110111 ;mask out d3
|
||||
sta Enemy_State,y ;store new state
|
||||
; sta Enemy_State,y ;store new state
|
||||
sta Enemy_State,x
|
||||
|
||||
ldx Enemy_MovingDir,y ;get enemy's moving direction
|
||||
dex ;decrement to use as offset
|
||||
lda HammerXSpdData,x ;get proper speed to use based on moving direction
|
||||
ldx ObjectOffset ;reobtain hammer's buffer offset
|
||||
sta Misc_X_Speed,x ;set hammer's horizontal speed
|
||||
|
||||
SetHPos dec Misc_State,x ;decrement hammer's state
|
||||
lda Enemy_X_Position,y ;get enemy's horizontal position
|
||||
|
||||
stx GTE_TMP
|
||||
|
||||
; lda Enemy_X_Position,y ;get enemy's horizontal position
|
||||
tyx
|
||||
lda Enemy_X_Position,x
|
||||
ldx GTE_TMP
|
||||
|
||||
clc
|
||||
adc #$02 ;set position 2 pixels to the right
|
||||
sta Misc_X_Position,x ;store as hammer's horizontal position
|
||||
lda Enemy_PageLoc,y ;get enemy's page location
|
||||
|
||||
; lda Enemy_PageLoc,y ;get enemy's page location
|
||||
tyx
|
||||
lda Enemy_PageLoc,x
|
||||
ldx GTE_TMP
|
||||
|
||||
adc #$00 ;add carry
|
||||
sta Misc_PageLoc,x ;store as hammer's page location
|
||||
lda Enemy_Y_Position,y ;get enemy's vertical position
|
||||
|
||||
; lda Enemy_Y_Position,y ;get enemy's vertical position
|
||||
tyx
|
||||
lda Enemy_Y_Position,x
|
||||
ldx GTE_TMP
|
||||
|
||||
sec
|
||||
sbc #$0a ;move position 10 pixels upward
|
||||
sta Misc_Y_Position,x ;store as hammer's vertical position
|
||||
|
@ -7066,50 +7135,98 @@ RunHSubs jsr GetMiscOffscreenBits ;get offscreen info
|
|||
|
||||
CoinBlock
|
||||
jsr FindEmptyMiscSlot ;set offset for empty or last misc object buffer slot
|
||||
; lda Block_PageLoc,x ;get page location of block object
|
||||
; sta Misc_PageLoc,y ;store as page location of misc object
|
||||
; lda Block_X_Position,x ;get horizontal coordinate of block object
|
||||
; ora #$05 ;add 5 pixels
|
||||
; sta Misc_X_Position,y ;store as horizontal coordinate of misc object
|
||||
; lda Block_Y_Position,x ;get vertical coordinate of block object
|
||||
; sbc #$10 ;subtract 16 pixels
|
||||
; sta Misc_Y_Position,y ;store as vertical coordinate of misc object
|
||||
|
||||
stx GTE_TMP
|
||||
lda Block_PageLoc,x ;get page location of block object
|
||||
sta Misc_PageLoc,y ;store as page location of misc object
|
||||
tyx
|
||||
sta Misc_PageLoc,x ;store as page location of misc object
|
||||
ldx GTE_TMP
|
||||
lda Block_X_Position,x ;get horizontal coordinate of block object
|
||||
ora #$05 ;add 5 pixels
|
||||
sta Misc_X_Position,y ;store as horizontal coordinate of misc object
|
||||
tyx
|
||||
sta Misc_X_Position,x ;store as horizontal coordinate of misc object
|
||||
ldx GTE_TMP
|
||||
lda Block_Y_Position,x ;get vertical coordinate of block object
|
||||
sbc #$10 ;subtract 16 pixels
|
||||
sta Misc_Y_Position,y ;store as vertical coordinate of misc object
|
||||
tyx
|
||||
sta Misc_Y_Position,x ;store as vertical coordinate of misc object
|
||||
ldx GTE_TMP
|
||||
|
||||
jmp JCoinC ;jump to rest of code as applies to this misc object
|
||||
|
||||
SetupJumpCoin
|
||||
jsr FindEmptyMiscSlot ;set offset for empty or last misc object buffer slot
|
||||
lda Block_PageLoc2,x ;get page location saved earlier
|
||||
sta Misc_PageLoc,y ;and save as page location for misc object
|
||||
; sta Misc_PageLoc,y ;and save as page location for misc object
|
||||
phx
|
||||
tyx
|
||||
sta Misc_PageLoc,x
|
||||
|
||||
lda $06 ;get low byte of block buffer offset
|
||||
asl
|
||||
asl ;multiply by 16 to use lower nybble
|
||||
asl
|
||||
asl
|
||||
ora #$05 ;add five pixels
|
||||
sta Misc_X_Position,y ;save as horizontal coordinate for misc object
|
||||
; sta Misc_X_Position,y ;save as horizontal coordinate for misc object
|
||||
sta Misc_X_Position,X
|
||||
|
||||
lda $02 ;get vertical high nybble offset from earlier
|
||||
adc #$20 ;add 32 pixels for the status bar
|
||||
sta Misc_Y_Position,y ;store as vertical coordinate
|
||||
; sta Misc_Y_Position,y ;store as vertical coordinate
|
||||
sta Misc_Y_Position,x
|
||||
plx
|
||||
|
||||
JCoinC lda #$fb
|
||||
sta Misc_Y_Speed,y ;set vertical speed
|
||||
|
||||
; sta Misc_Y_Speed,y ;set vertical speed
|
||||
phx
|
||||
tyx
|
||||
sta Misc_Y_Speed,x
|
||||
|
||||
lda #$01
|
||||
sta Misc_Y_HighPos,y ;set vertical high byte
|
||||
sta Misc_State,y ;set state for misc object
|
||||
; sta Misc_Y_HighPos,y ;set vertical high byte
|
||||
; sta Misc_State,y ;set state for misc object
|
||||
sta Misc_Y_HighPos,x
|
||||
sta Misc_State,x
|
||||
plx
|
||||
|
||||
|
||||
sta Square2SoundQueue ;load coin grab sound
|
||||
stx ObjectOffset ;store current control bit as misc object offset
|
||||
jsr GiveOneCoin ;update coin tally on the screen and coin amount variable
|
||||
inc CoinTallyFor1Ups ;increment coin tally used to activate 1-up block flag
|
||||
|
||||
rts
|
||||
|
||||
FindEmptyMiscSlot
|
||||
ldy #$08 ;start at end of misc objects buffer
|
||||
FMiscLoop lda Misc_State,y ;get misc object state
|
||||
; ldy #$08 ;start at end of misc objects buffer
|
||||
;FMiscLoop lda Misc_State,y ;get misc object state
|
||||
; beq UseMiscS ;branch if none found to use current offset
|
||||
; dey ;decrement offset
|
||||
; cpy #$05 ;do this for three slots
|
||||
; bne FMiscLoop ;do this until all slots are checked
|
||||
; ldy #$08 ;if no empty slots found, use last slot
|
||||
;UseMiscS sty JumpCoinMiscOffset ;store offset of misc object buffer here (residual)
|
||||
phx
|
||||
ldx #$08 ;start at end of misc objects buffer
|
||||
FMiscLoop lda Misc_State,x ;get misc object state
|
||||
beq UseMiscS ;branch if none found to use current offset
|
||||
dey ;decrement offset
|
||||
cpy #$05 ;do this for three slots
|
||||
dex ;decrement offset
|
||||
cpx #$05 ;do this for three slots
|
||||
bne FMiscLoop ;do this until all slots are checked
|
||||
ldy #$08 ;if no empty slots found, use last slot
|
||||
UseMiscS sty JumpCoinMiscOffset ;store offset of misc object buffer here (residual)
|
||||
ldx #$08 ;if no empty slots found, use last slot
|
||||
UseMiscS stx JumpCoinMiscOffset ;store offset of misc object buffer here (residual)
|
||||
txy
|
||||
plx
|
||||
rts
|
||||
|
||||
;-------------------------------------------------------------------------------------
|
||||
|
@ -7130,7 +7247,7 @@ MiscLoop stx ObjectOffset ;store misc object
|
|||
;$02 - used to set maximum speed
|
||||
|
||||
ProcJumpCoin
|
||||
ldy Misc_State,x ;check misc object state
|
||||
ldy Misc_State,x
|
||||
dey ;decrement to see if it's set to 1
|
||||
beq JCoinRun ;if so, branch to handle jumping coin
|
||||
inc Misc_State,x ;otherwise increment state to either start off or as timer
|
||||
|
@ -7880,9 +7997,17 @@ ChkAreaTsk lda AreaParserTaskNum ;check number of ta
|
|||
ChkBowserF pla ;get data from stack
|
||||
and #%00001111 ;mask out high nybble
|
||||
tay
|
||||
lda Enemy_Flag,y ;use as pointer and load same place with different offset
|
||||
bne ExitELCore
|
||||
; lda Enemy_Flag,y ;use as pointer and load same place with different offset
|
||||
; bne ExitELCore
|
||||
stx GTE_TMP
|
||||
tyx
|
||||
lda Enemy_Flag,x
|
||||
bne ExitELCore2
|
||||
|
||||
ldx GTE_TMP
|
||||
sta Enemy_Flag,x ;if second enemy flag not set, also clear first one
|
||||
ExitELCore2 ldx GTE_TMP
|
||||
|
||||
ExitELCore rts
|
||||
|
||||
;--------------------------------
|
||||
|
@ -8384,7 +8509,13 @@ LakituAndSpinyHandler
|
|||
lda #$80 ;set timer
|
||||
sta FrenzyEnemyTimer
|
||||
ldy #$04 ;start with the last enemy slot
|
||||
ChkLak lda Enemy_ID,y ;check all enemy slots to see
|
||||
ChkLak
|
||||
; lda Enemy_ID,y ;check all enemy slots to see
|
||||
phx
|
||||
tyx
|
||||
lda Enemy_ID,x
|
||||
plx
|
||||
|
||||
cmp #Lakitu ;if lakitu is on one of them
|
||||
beq CreateSpiny ;if so, branch out of this loop
|
||||
dey ;otherwise check another slot
|
||||
|
@ -8415,15 +8546,31 @@ CreateSpiny
|
|||
lda Player_Y_Position ;if player above a certain point, branch to leave
|
||||
cmp #$2c
|
||||
bcc ExLSHand
|
||||
lda Enemy_State,y ;if lakitu is not in normal state, branch to leave
|
||||
; lda Enemy_State,y ;if lakitu is not in normal state, branch to leave
|
||||
stx GTE_TMP
|
||||
tyx
|
||||
lda Enemy_State,x
|
||||
ldx GTE_TMP
|
||||
|
||||
bne ExLSHand
|
||||
lda Enemy_PageLoc,y ;store horizontal coordinates (high and low) of lakitu
|
||||
; lda Enemy_PageLoc,y ;store horizontal coordinates (high and low) of lakitu
|
||||
tyx
|
||||
lda Enemy_PageLoc,x
|
||||
ldx GTE_TMP
|
||||
sta Enemy_PageLoc,x ;into the coordinates of the spiny we're going to create
|
||||
lda Enemy_X_Position,y
|
||||
|
||||
; lda Enemy_X_Position,y
|
||||
tyx
|
||||
lda Enemy_X_Position,x
|
||||
ldx GTE_TMP
|
||||
sta Enemy_X_Position,x
|
||||
lda #$01 ;put spiny within vertical screen unit
|
||||
sta Enemy_Y_HighPos,x
|
||||
lda Enemy_Y_Position,y ;put spiny eight pixels above where lakitu is
|
||||
|
||||
; lda Enemy_Y_Position,y ;put spiny eight pixels above where lakitu is
|
||||
tyx
|
||||
lda Enemy_Y_Position,x
|
||||
ldx GTE_TMP
|
||||
sec
|
||||
sbc #$08
|
||||
sta Enemy_Y_Position,x
|
||||
|
@ -8628,23 +8775,64 @@ InitBowser
|
|||
;--------------------------------
|
||||
|
||||
DuplicateEnemyObj
|
||||
ldy #$ff ;start at beginning of enemy slots
|
||||
FSLoop iny ;increment one slot
|
||||
lda Enemy_Flag,y ;check enemy buffer flag for empty slot
|
||||
bne FSLoop ;if set, branch and keep checking
|
||||
sty DuplicateObj_Offset ;otherwise set offset here
|
||||
; ldy #$ff ;start at beginning of enemy slots
|
||||
;:FSLoop iny ;increment one slot
|
||||
; lda Enemy_Flag,y ;check enemy buffer flag for empty slot
|
||||
; bne :FSLoop ;if set, branch and keep checking
|
||||
; sty DuplicateObj_Offset ;otherwise set offset here
|
||||
; txa ;transfer original enemy buffer offset
|
||||
; ora #%10000000 ;store with d7 set as flag in new enemy
|
||||
; sta Enemy_Flag,y ;slot as well as enemy offset
|
||||
; lda Enemy_PageLoc,x
|
||||
; sta Enemy_PageLoc,y ;copy page location and horizontal coordinates
|
||||
; lda Enemy_X_Position,x ;from original enemy to new enemy
|
||||
; sta Enemy_X_Position,y
|
||||
; lda #$01
|
||||
; sta Enemy_Flag,x ;set flag as normal for original enemy
|
||||
; sta Enemy_Y_HighPos,y ;set high vertical byte for new enemy
|
||||
; lda Enemy_Y_Position,x
|
||||
; sta Enemy_Y_Position,y ;copy vertical coordinate from original to new
|
||||
|
||||
stx GTE_TMP
|
||||
ldx #$ff ;start at beginning of enemy slots
|
||||
:FSLoop inx ;increment one slot
|
||||
lda Enemy_Flag,x ;check enemy buffer flag for empty slot
|
||||
bne :FSLoop ;if set, branch and keep checking
|
||||
stx DuplicateObj_Offset ;otherwise set offset here
|
||||
|
||||
ldx GTE_TMP
|
||||
txa ;transfer original enemy buffer offset
|
||||
ora #%10000000 ;store with d7 set as flag in new enemy
|
||||
sta Enemy_Flag,y ;slot as well as enemy offset
|
||||
; sta Enemy_Flag,y ;slot as well as enemy offset
|
||||
pha
|
||||
|
||||
lda Enemy_PageLoc,x
|
||||
sta Enemy_PageLoc,y ;copy page location and horizontal coordinates
|
||||
; sta Enemy_PageLoc,y ;copy page location and horizontal coordinates
|
||||
pha
|
||||
|
||||
lda Enemy_X_Position,x ;from original enemy to new enemy
|
||||
sta Enemy_X_Position,y
|
||||
; sta Enemy_X_Position,y
|
||||
pha
|
||||
|
||||
lda #$01
|
||||
sta Enemy_Flag,x ;set flag as normal for original enemy
|
||||
sta Enemy_Y_HighPos,y ;set high vertical byte for new enemy
|
||||
; sta Enemy_Y_HighPos,y ;set high vertical byte for new enemy
|
||||
|
||||
lda Enemy_Y_Position,x
|
||||
sta Enemy_Y_Position,y ;copy vertical coordinate from original to new
|
||||
; sta Enemy_Y_Position,y ;copy vertical coordinate from original to new
|
||||
|
||||
tyx
|
||||
sta Enemy_Y_Position,x
|
||||
lda #$01
|
||||
sta Enemy_Y_HighPos,x
|
||||
pla
|
||||
sta Enemy_X_Position,x
|
||||
pla
|
||||
sta Enemy_PageLoc,x
|
||||
pla
|
||||
sta Enemy_Flag,x
|
||||
|
||||
ldx GTE_TMP
|
||||
FlmEx rts ;and then leave
|
||||
|
||||
;--------------------------------
|
||||
|
@ -8663,7 +8851,13 @@ InitBowserFlame
|
|||
ora #Sfx_BowserFlame ;load bowser's flame sound into queue
|
||||
sta NoiseSoundQueue
|
||||
ldy BowserFront_Offset ;get bowser's buffer offset
|
||||
lda Enemy_ID,y ;check for bowser
|
||||
|
||||
; lda Enemy_ID,y ;check for bowser
|
||||
phx
|
||||
tyx
|
||||
lda Enemy_ID,x
|
||||
plx
|
||||
|
||||
cmp #Bowser
|
||||
beq SpawnFromMouth ;branch if found
|
||||
jsr SetFlameTimer ;get timer data based on flame counter
|
||||
|
@ -8692,13 +8886,27 @@ PutAtRightExtent
|
|||
jmp FinishFlame ;skip this part to finish setting values
|
||||
|
||||
SpawnFromMouth
|
||||
lda Enemy_X_Position,y ;get bowser's horizontal position
|
||||
; lda Enemy_X_Position,y ;get bowser's horizontal position
|
||||
stx GTE_TMP
|
||||
tyx
|
||||
lda Enemy_X_Position,x
|
||||
ldx GTE_TMP
|
||||
|
||||
sec
|
||||
sbc #$0e ;subtract 14 pixels
|
||||
sta Enemy_X_Position,x ;save as flame's horizontal position
|
||||
lda Enemy_PageLoc,y
|
||||
; lda Enemy_PageLoc,y
|
||||
tyx
|
||||
lda Enemy_PageLoc,x
|
||||
ldx GTE_TMP
|
||||
|
||||
sta Enemy_PageLoc,x ;copy page location from bowser to flame
|
||||
lda Enemy_Y_Position,y
|
||||
|
||||
; lda Enemy_Y_Position,y
|
||||
tyx
|
||||
lda Enemy_Y_Position,x
|
||||
ldx GTE_TMP
|
||||
|
||||
clc ;add 8 pixels to bowser's vertical position
|
||||
adc #$08
|
||||
sta Enemy_Y_Position,x ;save as flame's vertical position
|
||||
|
@ -8741,25 +8949,40 @@ InitFireworks
|
|||
lda #$20 ;otherwise reset timer
|
||||
sta FrenzyEnemyTimer
|
||||
dec FireworksCounter ;decrement for each explosion
|
||||
ldy #$06 ;start at last slot
|
||||
StarFChk dey
|
||||
lda Enemy_ID,y ;check for presence of star flag object
|
||||
; ldy #$06 ;start at last slot
|
||||
;:StarFChk dey
|
||||
; lda Enemy_ID,y ;check for presence of star flag object
|
||||
|
||||
stx GTE_TMP
|
||||
ldx #$06 ;start at last slot
|
||||
:StarFChk dex
|
||||
lda Enemy_ID,x ;check for presence of star flag object
|
||||
|
||||
cmp #StarFlagObject ;if there isn't a star flag object,
|
||||
bne StarFChk ;routine goes into infinite loop = crash
|
||||
lda Enemy_X_Position,y
|
||||
bne :StarFChk ;routine goes into infinite loop = crash
|
||||
|
||||
; lda Enemy_X_Position,y
|
||||
lda Enemy_X_Position,x
|
||||
sec ;get horizontal coordinate of star flag object, then
|
||||
sbc #$30 ;subtract 48 pixels from it and save to
|
||||
pha ;the stack
|
||||
lda Enemy_PageLoc,y
|
||||
|
||||
; lda Enemy_PageLoc,y
|
||||
lda Enemy_PageLoc,x
|
||||
sbc #$00 ;subtract the carry from the page location
|
||||
sta $00 ;of the star flag object
|
||||
lda FireworksCounter ;get fireworks counter
|
||||
clc
|
||||
adc Enemy_State,y ;add state of star flag object (possibly not necessary)
|
||||
|
||||
; adc Enemy_State,y ;add state of star flag object (possibly not necessary)
|
||||
adc Enemy_State,x
|
||||
ldx GTE_TMP
|
||||
|
||||
tay ;use as offset
|
||||
pla ;get saved horizontal coordinate of star flag - 48 pixels
|
||||
clc
|
||||
adc FireworksXPosData,y ;add number based on offset of fireworks counter
|
||||
|
||||
sta Enemy_X_Position,x ;store as the fireworks object horizontal coordinate
|
||||
lda $00
|
||||
adc #$00 ;add carry and store as page location for
|
||||
|
@ -8832,18 +9055,35 @@ AddFBit ora BitMFilter ;add bit to already
|
|||
jmp CheckpointEnemyID ;process our new enemy object
|
||||
|
||||
DoBulletBills
|
||||
ldy #$ff ;start at beginning of enemy slots
|
||||
BB_SLoop iny ;move onto the next slot
|
||||
cpy #$05 ;branch to play sound if we've done all slots
|
||||
; ldy #$ff ;start at beginning of enemy slots
|
||||
;BB_SLoop iny ;move onto the next slot
|
||||
; cpy #$05 ;branch to play sound if we've done all slots
|
||||
; bcs FireBulletBill
|
||||
; lda Enemy_Flag,y ;if enemy buffer flag not set,
|
||||
; beq BB_SLoop ;loop back and check another slot
|
||||
; lda Enemy_ID,y
|
||||
; cmp #BulletBill_FrenzyVar ;check enemy identifier for
|
||||
; bne BB_SLoop ;bullet bill object (frenzy variant)
|
||||
|
||||
stx GTE_TMP
|
||||
ldx #$ff ;start at beginning of enemy slots
|
||||
:BB_SLoop inx ;move onto the next slot
|
||||
cpx #$05 ;branch to play sound if we've done all slots
|
||||
bcs FireBulletBill
|
||||
lda Enemy_Flag,y ;if enemy buffer flag not set,
|
||||
beq BB_SLoop ;loop back and check another slot
|
||||
lda Enemy_ID,y
|
||||
lda Enemy_Flag,x ;if enemy buffer flag not set,
|
||||
beq :BB_SLoop ;loop back and check another slot
|
||||
lda Enemy_ID,x
|
||||
cmp #BulletBill_FrenzyVar ;check enemy identifier for
|
||||
bne BB_SLoop ;bullet bill object (frenzy variant)
|
||||
bne :BB_SLoop ;bullet bill object (frenzy variant)
|
||||
txy
|
||||
stx GTE_TMP
|
||||
|
||||
ExF17 rts ;if found, leave
|
||||
|
||||
FireBulletBill
|
||||
txy
|
||||
stx GTE_TMP
|
||||
|
||||
lda Square2SoundQueue
|
||||
ora #Sfx_Blast ;play fireworks/gunfire sound
|
||||
sta Square2SoundQueue
|
||||
|
@ -8954,14 +9194,23 @@ NoFrenzyCode
|
|||
;--------------------------------
|
||||
|
||||
EndFrenzy
|
||||
ldy #$05 ;start at last slot
|
||||
LakituChk lda Enemy_ID,y ;check enemy identifiers
|
||||
phx
|
||||
; ldy #$05 ;start at last slot
|
||||
;:LakituChk lda Enemy_ID,y ;check enemy identifiers
|
||||
ldx #$05
|
||||
:LakituChk lda Enemy_ID,x ;check enemy identifiers
|
||||
cmp #Lakitu ;for lakitu
|
||||
bne NextFSlot
|
||||
bne :NextFSlot
|
||||
lda #$01 ;if found, set state
|
||||
sta Enemy_State,y
|
||||
NextFSlot dey ;move onto the next slot
|
||||
bpl LakituChk ;do this until all slots are checked
|
||||
; sta Enemy_State,y
|
||||
;:NextFSlot dey ;move onto the next slot
|
||||
sta Enemy_State,x
|
||||
:NextFSlot dex ;move onto the next slot
|
||||
bpl :LakituChk ;do this until all slots are checked
|
||||
|
||||
txy
|
||||
plx
|
||||
|
||||
lda #$00
|
||||
sta EnemyFrenzyBuffer ;empty enemy frenzy buffer
|
||||
sta Enemy_Flag,x ;disable enemy buffer flag for this object
|
||||
|
@ -10083,11 +10332,20 @@ ChkLS lda Enemy_State,x ;if lakitu's enemy
|
|||
bne SetLSpd ;load horizontal speed and do unconditional branch
|
||||
Fr12S lda #Spiny
|
||||
sta EnemyFrenzyBuffer ;set spiny identifier in frenzy buffer
|
||||
ldy #$02
|
||||
LdLDa lda LakituDiffAdj,y ;load values
|
||||
sta $0001,y ;store in zero page
|
||||
dey
|
||||
bpl LdLDa ;do this until all values are stired
|
||||
|
||||
; ldy #$02
|
||||
;:LdLDa lda LakituDiffAdj,y ;load values
|
||||
; sta $0001,y ;store in zero page
|
||||
; dey
|
||||
; bpl :LdLDa ;do this until all values are stired
|
||||
phx
|
||||
ldx #$02
|
||||
:LdLDa lda LakituDiffAdj,x ;load values
|
||||
sta $01,x ;store in zero page
|
||||
dex
|
||||
bpl :LdLDa ;do this until all values are stired
|
||||
plx
|
||||
|
||||
jsr PlayerLakituDiff ;execute sub to set speed and create spinys
|
||||
SetLSpd sta LakituMoveSpeed,x ;set movement speed returned from sub
|
||||
ldy #$01 ;set moving direction to right by default
|
||||
|
@ -10157,7 +10415,13 @@ ChkSpinyO lda Enemy_ID,x ;check for spiny ob
|
|||
ChkEmySpd lda Enemy_Y_Speed,x ;check vertical speed
|
||||
bne SubDifAdj ;branch if nonzero
|
||||
ldy #$00 ;otherwise reinit offset
|
||||
SubDifAdj lda $0001,y ;get one of three saved values from earlier
|
||||
SubDifAdj
|
||||
; lda $0001,y ;get one of three saved values from earlier
|
||||
phx
|
||||
tyx
|
||||
lda $01,x
|
||||
plx
|
||||
|
||||
ldy $00 ;get saved horizontal difference
|
||||
SPixelLak sec ;subtract one for each pixel of horizontal difference
|
||||
sbc #$01 ;from one of three saved values
|
||||
|
@ -10376,15 +10640,36 @@ CopyFToR tya ;move bowser's rear
|
|||
clc
|
||||
adc Enemy_X_Position,x ;add to bowser's front object horizontal coordinate
|
||||
ldy DuplicateObj_Offset ;get bowser's rear object offset
|
||||
sta Enemy_X_Position,y ;store A as bowser's rear horizontal coordinate
|
||||
|
||||
stx GTE_TMP
|
||||
; sta Enemy_X_Position,y ;store A as bowser's rear horizontal coordinate
|
||||
tyx
|
||||
sta Enemy_X_Position,x ;store A as bowser's rear horizontal coordinate
|
||||
ldx GTE_TMP
|
||||
|
||||
lda Enemy_Y_Position,x
|
||||
clc ;add eight pixels to bowser's front object
|
||||
adc #$08 ;vertical coordinate and store as vertical coordinate
|
||||
sta Enemy_Y_Position,y ;for bowser's rear
|
||||
|
||||
; sta Enemy_Y_Position,y ;for bowser's rear
|
||||
tyx
|
||||
sta Enemy_Y_Position,x
|
||||
ldx GTE_TMP
|
||||
|
||||
lda Enemy_State,x
|
||||
sta Enemy_State,y ;copy enemy state directly from front to rear
|
||||
; sta Enemy_State,y ;copy enemy state directly from front to rear
|
||||
tyx
|
||||
sta Enemy_State,x
|
||||
ldx GTE_TMP
|
||||
|
||||
|
||||
lda Enemy_MovingDir,x
|
||||
sta Enemy_MovingDir,y ;copy moving direction also
|
||||
; sta Enemy_MovingDir,y ;copy moving direction also
|
||||
tyx
|
||||
sta Enemy_MovingDir,x
|
||||
ldx GTE_TMP
|
||||
|
||||
|
||||
lda ObjectOffset ;save enemy object offset of front to stack
|
||||
pha
|
||||
ldx DuplicateObj_Offset ;put enemy object offset of rear as current
|
||||
|
@ -10800,13 +11085,23 @@ MakePlatformFall
|
|||
jmp InitPlatformFall ;make platforms fall
|
||||
|
||||
ChkOtherForFall
|
||||
cmp Enemy_Y_Position,y ;check if other platform is above a certain point
|
||||
; cmp Enemy_Y_Position,y ;check if other platform is above a certain point
|
||||
phx
|
||||
tyx
|
||||
cmp Enemy_Y_Position,x
|
||||
plx
|
||||
|
||||
bcc ChkToMoveBalPlat ;if not, branch elsewhere
|
||||
cpx $00 ;if collision flag is set to same value as
|
||||
beq MakePlatformFall ;enemy state, branch to make platforms fall
|
||||
clc
|
||||
adc #$02 ;otherwise add 2 pixels to vertical position
|
||||
sta Enemy_Y_Position,y ;of other platform and branch elsewhere
|
||||
; sta Enemy_Y_Position,y ;of other platform and branch elsewhere
|
||||
phx
|
||||
tyx
|
||||
sta Enemy_Y_Position,x
|
||||
plx
|
||||
|
||||
jmp StopPlatforms ;jump to stop movement and do not return
|
||||
|
||||
ChkToMoveBalPlat
|
||||
|
@ -10840,8 +11135,15 @@ DoOtherPlatform
|
|||
sec
|
||||
sbc Enemy_Y_Position,x ;get difference of old vs. new coordinate
|
||||
clc
|
||||
adc Enemy_Y_Position,y ;add difference to vertical coordinate of other
|
||||
sta Enemy_Y_Position,y ;platform to move it in the opposite direction
|
||||
|
||||
; adc Enemy_Y_Position,y ;add difference to vertical coordinate of other
|
||||
; sta Enemy_Y_Position,y ;platform to move it in the opposite direction
|
||||
phx
|
||||
tyx
|
||||
adc Enemy_Y_Position,x
|
||||
sta Enemy_Y_Position,x
|
||||
plx
|
||||
|
||||
lda PlatformCollisionFlag,x ;if no collision, skip this part here
|
||||
bmi DrawEraseRope
|
||||
tax ;put offset which collision occurred here
|
||||
|
@ -10849,13 +11151,23 @@ DoOtherPlatform
|
|||
|
||||
DrawEraseRope
|
||||
ldy ObjectOffset ;get enemy object offset
|
||||
lda Enemy_Y_Speed,y ;check to see if current platform is
|
||||
; lda Enemy_Y_Speed,y ;check to see if current platform is
|
||||
phx
|
||||
tyx
|
||||
lda Enemy_Y_Speed,x
|
||||
plx
|
||||
|
||||
ora Enemy_Y_MoveForce,y ;moving at all
|
||||
beq ExitRp ;if not, skip all of this and branch to leave
|
||||
ldx VRAM_Buffer1_Offset ;get vram buffer offset
|
||||
cpx #$20 ;if offset beyond a certain point, go ahead
|
||||
bcs ExitRp ;and skip this, branch to leave
|
||||
lda Enemy_Y_Speed,y
|
||||
; lda Enemy_Y_Speed,y
|
||||
phx
|
||||
tyx
|
||||
lda Enemy_Y_Speed,x
|
||||
plx
|
||||
|
||||
pha ;save two copies of vertical speed to stack
|
||||
pha
|
||||
jsr SetupPlatformRope ;do a sub to figure out where to put new bg tiles
|
||||
|
@ -10865,8 +11177,12 @@ DrawEraseRope
|
|||
sta VRAM_Buffer1+1,x
|
||||
lda #$02 ;set length for 2 bytes
|
||||
sta VRAM_Buffer1+2,x
|
||||
lda Enemy_Y_Speed,y ;if platform moving upwards, branch
|
||||
bmi EraseR1 ;to do something else
|
||||
; lda Enemy_Y_Speed,y
|
||||
phx
|
||||
tyx
|
||||
lda Enemy_Y_Speed,x
|
||||
plx
|
||||
bmi EraseR1 ;to do something else
|
||||
lda #$a2
|
||||
sta VRAM_Buffer1+3,x ;otherwise put tile numbers for left
|
||||
lda #$a3 ;and right sides of rope in vram buffer
|
||||
|
@ -10877,7 +11193,12 @@ EraseR1 lda #$24 ;put blank tiles in
|
|||
sta VRAM_Buffer1+4,x
|
||||
|
||||
OtherRope
|
||||
lda Enemy_State,y ;get offset of other platform from state
|
||||
phx
|
||||
; lda Enemy_State,y ;get offset of other platform from state
|
||||
tyx
|
||||
lda Enemy_State,x
|
||||
plx
|
||||
|
||||
tay ;use as Y here
|
||||
pla ;pull second copy of vertical speed from stack
|
||||
eor #$ff ;invert bits to reverse speed
|
||||
|
@ -10909,7 +11230,12 @@ ExitRp ldx ObjectOffset ;get enemy object b
|
|||
|
||||
SetupPlatformRope
|
||||
pha ;save second/third copy to stack
|
||||
lda Enemy_X_Position,y ;get horizontal coordinate
|
||||
; lda Enemy_X_Position,y ;get horizontal coordinate
|
||||
phx
|
||||
tyx
|
||||
lda Enemy_X_Position,x
|
||||
plx
|
||||
|
||||
clc
|
||||
adc #$08 ;add eight pixels
|
||||
ldx SecondaryHardMode ;if secondary hard mode flag set,
|
||||
|
@ -10917,7 +11243,12 @@ SetupPlatformRope
|
|||
clc
|
||||
adc #$10 ;otherwise add sixteen more pixels
|
||||
GetLRp pha ;save modified horizontal coordinate to stack
|
||||
lda Enemy_PageLoc,y
|
||||
; lda Enemy_PageLoc,y
|
||||
phx
|
||||
tyx
|
||||
lda Enemy_PageLoc,x
|
||||
plx
|
||||
|
||||
adc #$00 ;add carry to page location
|
||||
sta $02 ;and save here
|
||||
pla ;pull modified horizontal coordinate
|
||||
|
@ -10953,7 +11284,12 @@ GetHRp txa ;move vertical coor
|
|||
clc
|
||||
adc $00 ;add to horizontal part saved here
|
||||
sta $00 ;save as name table low byte
|
||||
lda Enemy_Y_Position,y
|
||||
; lda Enemy_Y_Position,y
|
||||
phx
|
||||
tyx
|
||||
lda Enemy_Y_Position,x
|
||||
plx
|
||||
|
||||
cmp #$e8 ;if vertical position not below the
|
||||
bcc ExPRp ;bottom of the screen, we're done, branch to leave
|
||||
lda $00
|
||||
|
@ -10976,7 +11312,12 @@ InitPlatformFall
|
|||
|
||||
StopPlatforms
|
||||
jsr InitVStf ;initialize vertical speed and low byte
|
||||
sta Enemy_Y_Speed,y ;for both platforms and leave
|
||||
; sta Enemy_Y_Speed,y ;for both platforms and leave
|
||||
phx
|
||||
tyx
|
||||
sta Enemy_Y_Speed,x
|
||||
plx
|
||||
|
||||
sta Enemy_Y_MoveForce,y
|
||||
rts
|
||||
|
||||
|
@ -11696,7 +12037,13 @@ ECLoop stx $01 ;save enemy object
|
|||
ldy $01 ;use second enemy offset for Y
|
||||
bcc NoEnemyCollision ;if carry clear, no collision, branch ahead of this
|
||||
lda Enemy_State,x
|
||||
ora Enemy_State,y ;check both enemy states for d7 set
|
||||
|
||||
; ora Enemy_State,y ;check both enemy states for d7 set
|
||||
phx
|
||||
tyx
|
||||
ora Enemy_State,x
|
||||
plx
|
||||
|
||||
and #%10000000
|
||||
bne YesEC ;branch if at least one of them is set
|
||||
lda Enemy_CollisionBits,y ;load first enemy's collision-related bits
|
||||
|
@ -11725,7 +12072,12 @@ ExitECRoutine
|
|||
rts ;leave
|
||||
|
||||
ProcEnemyCollisions
|
||||
lda Enemy_State,y ;check both enemy states for d5 set
|
||||
; lda Enemy_State,y ;check both enemy states for d5 set
|
||||
stx GTE_TMP
|
||||
tyx
|
||||
lda Enemy_State,x
|
||||
ldx GTE_TMP
|
||||
|
||||
ora Enemy_State,x
|
||||
and #%00100000 ;if d5 is set in either state, or both, branch
|
||||
bne ExitProcessEColl ;to leave and do nothing else at this point
|
||||
|
@ -11735,7 +12087,12 @@ ProcEnemyCollisions
|
|||
lda Enemy_ID,x ;check second enemy identifier for hammer bro
|
||||
cmp #HammerBro ;if hammer bro found in alt state, branch to leave
|
||||
beq ExitProcessEColl
|
||||
lda Enemy_State,y ;check first enemy state for d7 set
|
||||
|
||||
; lda Enemy_State,y ;check first enemy state for d7 set
|
||||
tyx
|
||||
lda Enemy_State,x
|
||||
ldx GTE_TMP
|
||||
|
||||
asl
|
||||
bcc ShellCollisions ;branch if d7 is clear
|
||||
lda #$06
|
||||
|
@ -11760,10 +12117,20 @@ ExitProcessEColl
|
|||
rts ;leave!!!
|
||||
|
||||
ProcSecondEnemyColl
|
||||
lda Enemy_State,y ;if first enemy state < $06, branch elsewhere
|
||||
stx GTE_TMP
|
||||
|
||||
; lda Enemy_State,y ;if first enemy state < $06, branch elsewhere
|
||||
tyx
|
||||
lda Enemy_State,x
|
||||
ldx GTE_TMP
|
||||
|
||||
cmp #$06
|
||||
bcc MoveEOfs
|
||||
lda Enemy_ID,y ;check first enemy identifier for hammer bro
|
||||
; lda Enemy_ID,y ;check first enemy identifier for hammer bro
|
||||
tyx
|
||||
lda Enemy_ID,x
|
||||
ldx GTE_TMP
|
||||
|
||||
cmp #HammerBro ;if hammer bro found in alt state, branch to leave
|
||||
beq ExitProcessEColl
|
||||
jsr ShellOrBlockDefeat ;otherwise, kill first enemy
|
||||
|
@ -16450,7 +16817,7 @@ BrickShatterEnvData
|
|||
|
||||
;-------------------------------------------------------------------------------------
|
||||
;INTERRUPT VECTORS
|
||||
|
||||
; ds 34
|
||||
dw NonMaskableInterrupt
|
||||
dw Start
|
||||
dw $fff0 ;unused
|
||||
|
|
|
@ -182,6 +182,7 @@ tileStore equ $0003
|
|||
vblCallback equ $0004
|
||||
extSpriteRenderer equ $0005
|
||||
rawDrawTile equ $0006
|
||||
extBG0TileUpdate equ $0007
|
||||
|
||||
; CopyPicToBG1 flags
|
||||
COPY_PIC_NORMAL equ $0000 ; Copy into BG1 buffer in "normal mode"
|
||||
|
|
|
@ -195,6 +195,7 @@ tileStore equ $0003
|
|||
vblCallback equ $0004 ; User routine to be called by VBL interrupt. Set to $000000 to disconnect
|
||||
extSpriteRenderer equ $0005
|
||||
rawDrawTile equ $0006
|
||||
extBG0TileUpdate equ $0007
|
||||
|
||||
; CopyPicToBG1 flags
|
||||
COPY_PIC_NORMAL equ $0000 ; Copy into BG1 buffer in "normal mode" treating the buffer as a 164x208 pixmap with stride of 256
|
||||
|
@ -310,6 +311,7 @@ StartXMod164Tbl EXT
|
|||
LastOffsetTbl EXT
|
||||
BG1StartXMod164Tbl EXT
|
||||
ExtSpriteRenderer EXT
|
||||
ExtUpdateBG0Tiles EXT
|
||||
|
||||
; Tool error codes
|
||||
NO_TIMERS_AVAILABLE equ 10
|
||||
|
|
16
src/Render.s
16
src/Render.s
|
@ -153,10 +153,24 @@ _DoOverlay
|
|||
:disp jsl $000000
|
||||
rts
|
||||
|
||||
; Special NES renderer that externalizes the sprite rendreing in order to exceed the internal limit of 16 sprites
|
||||
; Special NES renderer that externalizes the sprite rendering in order to exceed the internal limit of 16 sprites
|
||||
_RenderNES
|
||||
jsr _ApplyBG0YPos
|
||||
jsr _ApplyBG0XPosPre
|
||||
|
||||
; Callback to update the tilestore with any new tiles
|
||||
|
||||
lda ExtUpdateBG0Tiles
|
||||
ora ExtUpdateBG0Tiles+2
|
||||
beq :no_tile
|
||||
|
||||
lda ExtUpdateBG0Tiles
|
||||
stal :patch0+1
|
||||
lda ExtUpdateBG0Tiles+1
|
||||
stal :patch0+2
|
||||
:patch0 jsl $000000
|
||||
:no_tile
|
||||
|
||||
jsr _ApplyTiles ; This function actually draws the new tiles into the code field
|
||||
; jsr _ApplyBG0XPos ; Patch the code field instructions with exit BRA opcode
|
||||
|
||||
|
|
26
src/Tool.s
26
src/Tool.s
|
@ -597,7 +597,9 @@ _TSSetBG1Origin
|
|||
_TSGetTileAt
|
||||
:y equ FirstParam
|
||||
:x equ FirstParam+2
|
||||
:output equ FirstParam+4
|
||||
:output_id equ FirstParam+4
|
||||
:output_x equ FirstParam+6
|
||||
:output_y equ FirstParam+8
|
||||
|
||||
_TSEntry
|
||||
|
||||
|
@ -609,16 +611,23 @@ _TSGetTileAt
|
|||
jsr _GetTileAt
|
||||
bcc :ok
|
||||
lda #0
|
||||
sta :output_x,s
|
||||
sta :output_y,s
|
||||
bra :out
|
||||
|
||||
:ok
|
||||
txa
|
||||
sta :output_x,s
|
||||
tya
|
||||
sta :output_y,s
|
||||
|
||||
; Load the tile at that tile store location
|
||||
|
||||
:ok
|
||||
jsr _GetTileStoreOffset0 ; Get the address of the X,Y tile position
|
||||
tax
|
||||
lda TileStore+TS_TILE_ID,x
|
||||
:out
|
||||
sta :output,s
|
||||
sta :output_id,s
|
||||
|
||||
_TSExit #0;#4
|
||||
|
||||
|
@ -990,7 +999,16 @@ _TSSetAddress
|
|||
sta ExtSpriteRenderer+2
|
||||
bra :out
|
||||
|
||||
:next_4
|
||||
:next_4 cmp #extBG0TileUpdate
|
||||
bne :next_5
|
||||
|
||||
lda :ptr,s
|
||||
sta ExtUpdateBG0Tiles
|
||||
lda :ptr+2,s
|
||||
sta ExtUpdateBG0Tiles+2
|
||||
bra :out
|
||||
:next_5
|
||||
|
||||
:out
|
||||
_TSExit #0;#6
|
||||
|
||||
|
|
|
@ -562,6 +562,8 @@ BG1YCache ENT
|
|||
|
||||
ExtSpriteRenderer ENT
|
||||
dw 0,0
|
||||
ExtUpdateBG0Tiles ENT
|
||||
dw 0,0
|
||||
|
||||
; Scaling tables for the BG1 rotation tables.
|
||||
ScalingTables ENT
|
||||
|
|
Loading…
Reference in New Issue