Swizzle support

This commit is contained in:
Lucas Scharenbroich 2023-06-02 00:37:14 -05:00
parent 0715efa684
commit 459bc645be
7 changed files with 928 additions and 313 deletions

View File

@ -36,6 +36,7 @@ OldROMScrollEdge equ 20
CurrScrollEdge equ 22
CurrNTQueueEnd equ 40
BGToggle equ 44
LastEnable equ 46
Tmp0 equ 240
Tmp1 equ 242
@ -43,6 +44,7 @@ Tmp2 equ 244
Tmp3 equ 246
Tmp4 equ 248
Tmp5 equ 250
Tmp6 equ 252
FTblPtr equ 224
FTblTmp equ 228
@ -63,8 +65,12 @@ FTblTmp equ 228
lda #1
sta BGToggle
lda #$0008
sta LastEnable
; 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
tdc
sta DPSave
clc
@ -74,6 +80,8 @@ FTblTmp equ 228
adc #$1FF ; Stack starts at the top of the page
sta ROMStk
; brl :debug
lda #ENGINE_MODE_USER_TOOL ; Engine in Fast Mode as a User Tool
jsr GTEStartUp ; Load and install the GTE User Tool
@ -95,6 +103,12 @@ FTblTmp equ 228
pea #UpdateFromPPU
_GTESetAddress
; Install a custom tile blitter to merge PPU attributes with the extracted tile data
pea userTileCallback
pea #^NESTileBlitter
pea #NESTileBlitter
_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
@ -114,13 +128,17 @@ FTblTmp equ 228
; pea #144
_GTESetScreenMode
ldx #AreaPalette
lda #TmpPalette
jsr NESColorToIIgs
pea $0000
pea #^Greyscale
pea #Greyscale
pea #^TmpPalette
pea #TmpPalette
_GTESetPalette
; Convert the CHR ROM from the cart into GTE tiles
:debug
ldx #0
ldy #0
:tloop
@ -128,14 +146,14 @@ FTblTmp equ 228
phy
lda #TileBuff
jsr ConvertROMTile
jsr ConvertROMTile2
lda 1,s
pha
pha ; start
inc
pha
pea #^TileBuff
pha ; finish
pea #^TileBuff ; pointer
pea #TileBuff
_GTELoadTileSet
@ -220,7 +238,7 @@ EvtLoop
stz singleStepMode
:not_g
cmp #'r' ; Refresh
cmp #'r' ; Refresh
bne :not_1
jsr CopyStatus
@ -258,11 +276,37 @@ Greyscale dw $0000,$5555,$AAAA,$FFFF
dw $0000,$5555,$AAAA,$FFFF
dw $0000,$5555,$AAAA,$FFFF
TmpPalette ds 32
lastKey dw 0
singleStepMode dw 0
nmiCount dw 0
DPSave dw 0
; Convert NES palette entries to IIgs
; X = NES palette (16 color indices)
; A = 32 byte array to write results
NESColorToIIgs
sta Tmp0
stz Tmp1
:loop lda: 0,x
asl
tay
lda nesPalette,y
ldy Tmp1
sta (Tmp0),y
inx
inx
iny
iny
sty Tmp1
cpy #32
bcc :loop
rts
; Helper to perform the essential functions of rendering a frame
RenderFrame
@ -309,8 +353,12 @@ RenderFrame
lda ppumask
and #$0008 ; Isolate background enable/disable bit
cmp LastEnable
beq :bghop
sta LastEnable
pha
_GTEEnableBackground
:bghop
pea $FFFF ; NES mode
_GTERender
@ -402,8 +450,6 @@ PPUAddrToTileStore
; 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
lda CurrNTQueueEnd
sta nt_queue_front
rts
@ -433,10 +479,24 @@ DrainNTQueue
lda nt_queue,x ; get the PPU address that was stored
sta :PPUAddr ; save for later if we draw this tile
lda :PPUAddr
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
jsr PPUAddrToTileStore ; convert the PPU address to relative tile store coordinates
bcc :set_tile ; if it's onscreen, draw it
:skip
pla ; Pop the saved x-register into the accumulator
inc
inc
and #NT_QUEUE_MOD
cmp CurrNTQueueEnd
bne :loop
:out
sta nt_queue_front
rts
:set_tile
; 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)
@ -455,27 +515,93 @@ DrainNTQueue
ldx :PPUAddr
lda PPU_MEM,x
and #$00FF
ora #$0100
ora #$0100+TILE_USER_BIT
pha
jsr GetPaletteSelect
ora 1,s ; Merge bits 9 and 10 into the Tile ID that's on the stack
sta 1,s
_GTESetTile
inc :Count
brl :skip
:skip
pla ; Pop the saved x-register into the accumulator
inc
inc
and #NT_QUEUE_MOD
cmp CurrNTQueueEnd
bne :loop
:out
sta nt_queue_front
; Do the calculation to get the palette select bits from the attribute byte that corresponds to the
; PPU address in the x-registers
GetPaletteSelect
; lda :Count
; ldx #8*160
; ldy #$FFFF
; jsr DrawWord
; Get the palette select bits. We need to calculate both the address of the attribute value and
; which bits to isolate from the byte and then merge into the TileId. The most straighforward way
; is to identify the quadrant right away and have alternate code paths
txa
and #$2C00
ora #$03C0
sta Tmp6 ; Base attribute table address
; Not calculate the byte within the attribute table
txa
and #$001F ; 32 byte rows, divide by 4
lsr
lsr
ora Tmp6
sta Tmp6
txa
and #$0380 ; Isolate the top 3 bits
lsr
lsr
lsr
lsr
ora Tmp6
tay
lda PPU_MEM,y ; This is the attribute byte
and #$00FF
pha ; Which we save for a minute
; Now figure out the quadrant that this address is in for the attribute byte value
txa
bit #%01000010
beq :top_left
bit #%01000000
beq :top_right
bit #%00000010
beq :bot_left
:bot_right
pla
and #$00C0
asl
asl
asl
bra :set_palette
:bot_left
pla
and #$0030
xba
lsr
lsr
lsr
bra :set_palette
:top_right
pla
and #$000C
xba
lsr
bra :set_palette
:top_left
pla
and #$0003
xba
asl
:set_palette
rts
; Copy the necessary columns into the TileStore when setting a new scroll position
@ -645,8 +771,11 @@ CopyStatus
ldx Tmp2 ; Nametable address
lda PPU_MEM+$2000,x
and #$00FF
ora #$0100
ora #$0100+TILE_USER_BIT
pha
jsr GetPaletteSelect
ora 1,s ; Merge bits 9 and 10 into the Tile ID that's on the stack
sta 1,s
; Advance to the next tile (no wrapping needed)
@ -721,8 +850,11 @@ CopyNametable
ldx Tmp2 ; Nametable address
lda PPU_MEM+$2000,x
and #$00FF
ora #$0100
ora #$0100+TILE_USER_BIT ; USe top 256 tiles and set as a user-defined tile
pha
jsr GetPaletteSelect
ora 1,s ; Merge bits 9 and 10 into the Tile ID that's on the stack
sta 1,s
; Advance to the next tile (handle nametable wrapping)
@ -802,132 +934,132 @@ native_joy ENT
;
; This keeps the tile in 2-bit mode in a format that makes it easy to look up pixel data
; based on a dynamic palette selection
;
; Tiles are stored in a pre-shifted, 16-bit format (2 bits per pixel): 0000000w wxxyyzz0
; When rendered, the 2-bit palette selection is passed in bits 9 and 10 and ORed with
; the palette data to create a single word of 00000ppw wxxyyzz0. This value is used
; to index directly into a 2048-byte swizzel table that will load the appropriate
; pixel data for the word. There are 2 swizzle tables, one for tiles and one for sprites
; that take care of mapping the 25 possible on-screen colors to a 16-color palette.
ConvertROMTile2
:DPtr equ Tmp1
:MPtr equ Tmp2
jsr ROMTileToLookup
; Now we have 32 bytes (4 x 8) with each byte being a 4-bit value that holds two pairs of bits
; from the PPU pattern table. We use these 4-bit values as lookup indices into tables
; that decode the values differently depending on the use case.
sta :DPtr
clc
adc #32 ; Move to the mask
sta :MPtr
lda #0 ; Zero out high byte
sep #$30 ; 8-bit mode
ldy #0
:loop
lda (:DPtr),y ; Load the index for the initial high nibble
tax
lda MLUT4,x ; Look up the mask value for this byte. This table decodes the 4 bits into an 8-bit mask
sta (:MPtr),y
lda DLUT2,x ; Look up the two, 2-bit pixel values for this quad of bits. This remains a 4-bit value
asl
asl
asl
asl
sta Tmp3
iny
lda (:DPtr),y
tax
lda DLUT2,x ; Look up the two, 2-bit pixel values for next quad of bits
ora Tmp3 ; Move it int othe top nibble since it will decode to the top-byte on the SHR screen
dey
sta (:DPtr),y ; Put in low byte
iny
lda #0
sta (:DPtr),y ; Zero high byte
lda MLUT4,x
sta (:MPtr),y
iny
cpy #32
bcc :loop
; Reverse and shift the data
rep #$30
ldy #8
ldx :DPtr
:rloop
lda: 0,x ; Load the word: xx00
jsr reverse2 ; Reverse the bottom byte in chunks of 2 bits
asl ; Shift by 1 for indexing
sta: 66,x
asl: 0,x ; Shift the original word, too
lda: 2,x
jsr reverse2
asl
sta: 64,x
asl: 2,x
inx
inx
inx
inx
dey
bne :rloop
rts
; X = address in the rom file
; A = address to write
ConvertROMTile
DPtr equ Tmp1
MPtr equ Tmp2
:DPtr equ Tmp1
:MPtr equ Tmp2
sta DPtr
jsr ROMTileToLookup
sta :DPtr
clc
adc #32 ; Move to the mask
sta MPtr
lda #0 ; Clear A and B
sta :MPtr
sep #$20 ; 8-bit mode
sep #$30 ; 8-bit mode
ldy #0
:loop
lda CHR_ROM,x ; Load the high bits
rol
rol
rol
rol
and #$06
sta Tmp0
lda CHR_ROM+8,x
and #$C0
lsr
lsr
lsr
ora Tmp0 ; Combine the two and create a lookup value
phx
lda (:DPtr),y ; Load the index for this tile byte
tax
lda DLUT,x ; Look up the two, 4-bit pixel values for this quad of bits
sta (DPtr),y
lda MLUT,x
sta (MPtr),y
lda DLUT4,x ; Look up the two, 4-bit pixel values for this quad of bits
sta (:DPtr),y
lda MLUT4,x ; Look up the mask value for this byte
sta (:MPtr),y
iny
plx
; Repeat for bits 4 & 5
ldal CHR_ROM,x ; Load the high bits
and #$30
lsr
lsr
lsr
sta Tmp0
ldal CHR_ROM+8,x
and #$30
lsr
ora Tmp0 ; Combine the two and create a lookup value
phx
tax
lda DLUT,x
sta (DPtr),y
lda MLUT,x
sta (MPtr),y
iny
plx
; Repeat for bits 2 & 3
ldal CHR_ROM,x ; Load the high bits
and #$0C
lsr
sta Tmp0
ldal CHR_ROM+8,x
and #$0C
asl
ora Tmp0 ; Combine the two and create a lookup value
phx
tax
lda DLUT,x
sta (DPtr),y
lda MLUT,x
sta (MPtr),y
iny
plx
; Repeat for bits 0 & 1
ldal CHR_ROM,x ; Load the high bits
and #$03
asl
sta Tmp0
ldal CHR_ROM+8,x
and #$03
asl
asl
asl
ora Tmp0 ; Combine the two and create a lookup value
phx
tax
lda DLUT,x
sta (DPtr),y
lda MLUT,x
sta (MPtr),y
iny
plx
inx
cpy #32
bcs :done
brl :loop
:done
rep #$20
bcc :loop
; Flip the tile before returning
; Switch back to 16-bit mode and flip the tile data before returning
rep #$20
ldy #16
ldx DPtr
ldx :DPtr
:rloop
lda: 0,x
jsr reverse
jsr reverse4
sta: 66,x
lda: 2,x
jsr reverse
jsr reverse4
sta: 64,x
inx
inx
@ -937,7 +1069,176 @@ MPtr equ Tmp2
bne :rloop
rts
reverse
; Build a table of index values for the ROM tile data. The different routines
; can mix and match the lookup table information as they see fit
;
; X = address in the rom file
; A = address to write
;
; For each byte of pattern table memory, we create two bytes in the DPtr with
; a lookup value for the pixels corresponding to bits in that location
;
; Example:
; Tile 0: $03,$0F,$1F,$1F,$1C,$24,$26,$66, $00,$00,$00,$00,$1F,$3F,$3F,$7F
;
; 0,1 2,3 4,5 6,7
;
; $03 | 00000011 | 00000000 | $00 -> 0000 0000 0000 0011 -> 00 00 05 00
; $0F | 00001111 | 00000000 | $00 -> 0000 0000 0011 0011 -> 00 00 55 00
; $1F | 00011111 | 00000000 | $00 -> 0000 0001 0011 0011 -> 01 00 55 00
; $1F | 00011111 | 00000000 | $00 -> 0000 0001 0011 0011 -> 01 00 55 00
; $1C | 00011100 | 00011111 | $1F -> 0000 0101 1111 1100 -> 03 00 FA 00
; $24 | 00100100 | 00111111 | $3F -> 0000 1110 1101 1100 -> 0E 00 BA 00
; $26 | 00100110 | 00111111 | $3F -> 0000 1110 1101 1110 -> 0E 00 BE 00
; $66 | 01100110 | 01111111 | $7F -> 0101 1110 1101 1110 -> 3E 00 BE 00
;
;
; e.g. Plane 0 = 0101 0001 (LSB)
; Plane 1 = 1001 0001 (MSB)
;
; For speed, use a table and convert one pair at a time
;
; Pair 1 = 1001 -> 1001
; Pair 2 = 0101 -> 0011
; Pair 3 = 0000 -> 0000
; Pair 4 = 0101 -> 0011
;
; Lookup[0] = 10 01 00 11
; Lookup[1] = 00 00 00 11
;
; Tile Data = 63 00 03 00
; Pixel Data = 12 03 00 03
mx %00
ROMTileToLookup
:DPtr equ Tmp1
pha
phx
sta :DPtr
lda #0 ; Clear A and B
sep #$20 ; 8-bit mode
ldy #0
:loop
; Top two bits from each byte defines the two left-most pixels
lda CHR_ROM,x ; Load the low bits
and #$C0
lsr
lsr
sta Tmp0
lda CHR_ROM+8,x ; Load the high bits
and #$C0
ora Tmp0
lsr
lsr
lsr
lsr
sta (:DPtr),y ; First byte
iny
; Repeat for bits 4 & 5
lda CHR_ROM,x
and #$30
lsr
lsr
sta Tmp0
lda CHR_ROM+8,x
and #$30
ora Tmp0
lsr
lsr
sta (:DPtr),y
iny
; Repeat for bits 2 & 3
lda CHR_ROM,x
and #$0C
lsr
lsr
sta Tmp0
lda CHR_ROM+8,x
and #$0C
ora Tmp0 ; Combine the two and create a lookup value
sta (:DPtr),y
iny
; Repeat for bits 0 & 1
lda CHR_ROM,x ; Load the high bits
and #$03
sta Tmp0
lda CHR_ROM+8,x
and #$03
asl
asl
ora Tmp0 ; Combine the two and create a lookup value
sta (:DPtr),y
iny
inx
cpy #32
bcc :loop
rep #$20
plx
pla
rts
; Reverse the 2-bit fields in a byte
mx %00
reverse2
php
sta Tmp0
stz Tmp1
sep #$20
and #$C0
lsr
lsr
lsr
lsr
lsr
lsr
tsb Tmp1
lda Tmp0
and #$30
lsr
lsr
tsb Tmp1
lda Tmp0
and #$0C
asl
asl
tsb Tmp1
lda Tmp0
and #$03
asl
asl
asl
asl
asl
asl
ora Tmp1
plp
rts
; Reverse the nibbles in a word
mx %00
reverse4
xba
sta Tmp0
and #$0F0F
@ -955,11 +1256,17 @@ reverse
ora Tmp1
rts
; Look up the 2-bit indexes for the data words
DLUT2 db $00,$01,$04,$05 ; CHR_ROM[0] = xy, CHR_ROM[8] = 00 -> 0x0y
db $02,$03,$06,$07 ; CHR_ROM[0] = xy, CHR_ROM[8] = 01 -> 0x1y
db $08,$09,$0C,$0D ; CHR_ROM[0] = xy, CHR_ROM[8] = 10 ->
db $0A,$0B,$0E,$0F ; CHR_ROM[0] = xy, CHR_ROM[8] = 11
DLUT dw $00,$01,$10,$11 ; CHR_ROM[0] = xx, CHR_ROM[8] = 00
dw $02,$03,$12,$13 ; CHR_ROM[0] = xx, CHR_ROM[8] = 01
dw $20,$21,$30,$31 ; CHR_ROM[0] = xx, CHR_ROM[8] = 10
dw $22,$23,$32,$33 ; CHR_ROM[0] = xx, CHR_ROM[8] = 11
; Look up the 4-bit indexes for the data words
DLUT4 db $00,$01,$10,$11 ; CHR_ROM[0] = xx, CHR_ROM[8] = 00
db $02,$03,$12,$13 ; CHR_ROM[0] = xx, CHR_ROM[8] = 01
db $20,$21,$30,$31 ; CHR_ROM[0] = xx, CHR_ROM[8] = 10
db $22,$23,$32,$33 ; CHR_ROM[0] = xx, CHR_ROM[8] = 11
;MLUT dw $FF,$F0,$0F,$00
; dw $F0,$F0,$00,$00
@ -967,10 +1274,10 @@ DLUT dw $00,$01,$10,$11 ; CHR_ROM[0] = xx, CHR_ROM[8] = 00
; dw $00,$00,$00,$00
; Inverted mask for using eor/and/eor rendering
MLUT dw $00,$0F,$F0,$FF
dw $0F,$0F,$FF,$FF
dw $F0,$FF,$F0,$FF
dw $FF,$FF,$FF,$FF
MLUT4 db $00,$0F,$F0,$FF
db $0F,$0F,$FF,$FF
db $F0,$FF,$F0,$FF
db $FF,$FF,$FF,$FF
; Extracted tiles
TileBuff ds 128
@ -1132,7 +1439,13 @@ nmiTask
ldal singleStepMode
bne :no_nmi
; lda #1
; jsr setborder
jsr triggerNMI
; lda #0
; jsr setborder
:no_nmi
pld
@ -1199,7 +1512,13 @@ readInput
ds \,$00 ; pad to the next page boundary
PPU_MEM
CHR_ROM put chr2.s ; 8K of CHR-ROM at PPU memory $0000 - $2000
PPU_NT ds $2000 ; Nametable memory from $2000 - $3000, $3F00 - $3F14 is palette RAM
PPU_OAM ds 256 ; 256 bytes of separate OAM RAM
CHR_ROM put chr2.s ; 8K of CHR-ROM at PPU memory $0000 - $2000
PPU_NT ds $2000 ; Nametable memory from $2000 - $3000, $3F00 - $3F14 is palette RAM
PPU_OAM ds 256 ; 256 bytes of separate OAM RAM
; Palettes of NES color indexes
;AreaPalette dw $0F, $00, $29, $1A, $09, $36, $1C, $30, $21, $16, $27, $18, $17, $3C, $1D, $37
AreaPalette dw $22, $00, $29, $1A, $0F, $36, $17, $30, $21, $16, $27, $18, $1A, $00, $00, $37
; Palette remapping
put pal_w11.s

19
demos/smb/mkswizzetbl.sh Normal file
View File

@ -0,0 +1,19 @@
# World 1-1, Underground
#node swizzle.js W11_T0 2 3 4
#node swizzle.js W11_T1 13 6 0
#node swizzle.js W11_T2 7 8 6
#node swizzle.js W11_T3 1 12 6
#node swizzle.js W11_S0 15 10 11
#node swizzle.js W11_S1 6 5 12
#node swizzle.js W11_S2 9 7 10
#node swizzle.js W11_S3 14 13 6
# World 1-1, Aboveground
node swizzle.js W11_T0 2 3 4
node swizzle.js W11_T1 5 6 4
node swizzle.js W11_T2 7 8 4
node swizzle.js W11_T3 1 6 4
node swizzle.js W11_S0 15 10 11
node swizzle.js W11_S1 12 7 10
node swizzle.js W11_S2 9 7 10
node swizzle.js W11_S3 4 5 6

View File

@ -13,10 +13,12 @@
"scripts": {
"test": "npm run build && npm run build:image && npm run gsport",
"gsport": "%npm_package_config_gsport%",
"build:rom": "%npm_package_config_merlin32% -V %npm_package_config_macros% RomOnly.s",
"build:sys16": "%npm_package_config_merlin32% -V %npm_package_config_macros% App.s",
"build": "npm run build:tool && npm run build:sys16",
"build:tool": "%npm_package_config_merlin32% -V %npm_package_config_macros% ../../src/Master.s",
"build:image": "build-image.bat %npm_package_config_cadius%",
"build:swizzle": "",
"debug": "\"%npm_package_config_crossrunner%\" SuperMarioGS -Source SuperMarioGS_S02__Output.txt -Source SuperMarioGS_S03__Output.txt -Debug -CompatibilityLayer"
},

136
demos/smb/pal_w11.s Normal file
View File

@ -0,0 +1,136 @@
W11_T0
dw $0000,$0200,$0300,$0400,$2000,$2200,$2300,$2400,$3000,$3200,$3300,$3400,$4000,$4200,$4300,$4400
dw $0002,$0202,$0302,$0402,$2002,$2202,$2302,$2402,$3002,$3202,$3302,$3402,$4002,$4202,$4302,$4402
dw $0003,$0203,$0303,$0403,$2003,$2203,$2303,$2403,$3003,$3203,$3303,$3403,$4003,$4203,$4303,$4403
dw $0004,$0204,$0304,$0404,$2004,$2204,$2304,$2404,$3004,$3204,$3304,$3404,$4004,$4204,$4304,$4404
dw $0020,$0220,$0320,$0420,$2020,$2220,$2320,$2420,$3020,$3220,$3320,$3420,$4020,$4220,$4320,$4420
dw $0022,$0222,$0322,$0422,$2022,$2222,$2322,$2422,$3022,$3222,$3322,$3422,$4022,$4222,$4322,$4422
dw $0023,$0223,$0323,$0423,$2023,$2223,$2323,$2423,$3023,$3223,$3323,$3423,$4023,$4223,$4323,$4423
dw $0024,$0224,$0324,$0424,$2024,$2224,$2324,$2424,$3024,$3224,$3324,$3424,$4024,$4224,$4324,$4424
dw $0030,$0230,$0330,$0430,$2030,$2230,$2330,$2430,$3030,$3230,$3330,$3430,$4030,$4230,$4330,$4430
dw $0032,$0232,$0332,$0432,$2032,$2232,$2332,$2432,$3032,$3232,$3332,$3432,$4032,$4232,$4332,$4432
dw $0033,$0233,$0333,$0433,$2033,$2233,$2333,$2433,$3033,$3233,$3333,$3433,$4033,$4233,$4333,$4433
dw $0034,$0234,$0334,$0434,$2034,$2234,$2334,$2434,$3034,$3234,$3334,$3434,$4034,$4234,$4334,$4434
dw $0040,$0240,$0340,$0440,$2040,$2240,$2340,$2440,$3040,$3240,$3340,$3440,$4040,$4240,$4340,$4440
dw $0042,$0242,$0342,$0442,$2042,$2242,$2342,$2442,$3042,$3242,$3342,$3442,$4042,$4242,$4342,$4442
dw $0043,$0243,$0343,$0443,$2043,$2243,$2343,$2443,$3043,$3243,$3343,$3443,$4043,$4243,$4343,$4443
dw $0044,$0244,$0344,$0444,$2044,$2244,$2344,$2444,$3044,$3244,$3344,$3444,$4044,$4244,$4344,$4444
W11_T1
dw $0000,$0500,$0600,$0400,$5000,$5500,$5600,$5400,$6000,$6500,$6600,$6400,$4000,$4500,$4600,$4400
dw $0005,$0505,$0605,$0405,$5005,$5505,$5605,$5405,$6005,$6505,$6605,$6405,$4005,$4505,$4605,$4405
dw $0006,$0506,$0606,$0406,$5006,$5506,$5606,$5406,$6006,$6506,$6606,$6406,$4006,$4506,$4606,$4406
dw $0004,$0504,$0604,$0404,$5004,$5504,$5604,$5404,$6004,$6504,$6604,$6404,$4004,$4504,$4604,$4404
dw $0050,$0550,$0650,$0450,$5050,$5550,$5650,$5450,$6050,$6550,$6650,$6450,$4050,$4550,$4650,$4450
dw $0055,$0555,$0655,$0455,$5055,$5555,$5655,$5455,$6055,$6555,$6655,$6455,$4055,$4555,$4655,$4455
dw $0056,$0556,$0656,$0456,$5056,$5556,$5656,$5456,$6056,$6556,$6656,$6456,$4056,$4556,$4656,$4456
dw $0054,$0554,$0654,$0454,$5054,$5554,$5654,$5454,$6054,$6554,$6654,$6454,$4054,$4554,$4654,$4454
dw $0060,$0560,$0660,$0460,$5060,$5560,$5660,$5460,$6060,$6560,$6660,$6460,$4060,$4560,$4660,$4460
dw $0065,$0565,$0665,$0465,$5065,$5565,$5665,$5465,$6065,$6565,$6665,$6465,$4065,$4565,$4665,$4465
dw $0066,$0566,$0666,$0466,$5066,$5566,$5666,$5466,$6066,$6566,$6666,$6466,$4066,$4566,$4666,$4466
dw $0064,$0564,$0664,$0464,$5064,$5564,$5664,$5464,$6064,$6564,$6664,$6464,$4064,$4564,$4664,$4464
dw $0040,$0540,$0640,$0440,$5040,$5540,$5640,$5440,$6040,$6540,$6640,$6440,$4040,$4540,$4640,$4440
dw $0045,$0545,$0645,$0445,$5045,$5545,$5645,$5445,$6045,$6545,$6645,$6445,$4045,$4545,$4645,$4445
dw $0046,$0546,$0646,$0446,$5046,$5546,$5646,$5446,$6046,$6546,$6646,$6446,$4046,$4546,$4646,$4446
dw $0044,$0544,$0644,$0444,$5044,$5544,$5644,$5444,$6044,$6544,$6644,$6444,$4044,$4544,$4644,$4444
W11_T2
dw $0000,$0700,$0800,$0400,$7000,$7700,$7800,$7400,$8000,$8700,$8800,$8400,$4000,$4700,$4800,$4400
dw $0007,$0707,$0807,$0407,$7007,$7707,$7807,$7407,$8007,$8707,$8807,$8407,$4007,$4707,$4807,$4407
dw $0008,$0708,$0808,$0408,$7008,$7708,$7808,$7408,$8008,$8708,$8808,$8408,$4008,$4708,$4808,$4408
dw $0004,$0704,$0804,$0404,$7004,$7704,$7804,$7404,$8004,$8704,$8804,$8404,$4004,$4704,$4804,$4404
dw $0070,$0770,$0870,$0470,$7070,$7770,$7870,$7470,$8070,$8770,$8870,$8470,$4070,$4770,$4870,$4470
dw $0077,$0777,$0877,$0477,$7077,$7777,$7877,$7477,$8077,$8777,$8877,$8477,$4077,$4777,$4877,$4477
dw $0078,$0778,$0878,$0478,$7078,$7778,$7878,$7478,$8078,$8778,$8878,$8478,$4078,$4778,$4878,$4478
dw $0074,$0774,$0874,$0474,$7074,$7774,$7874,$7474,$8074,$8774,$8874,$8474,$4074,$4774,$4874,$4474
dw $0080,$0780,$0880,$0480,$7080,$7780,$7880,$7480,$8080,$8780,$8880,$8480,$4080,$4780,$4880,$4480
dw $0087,$0787,$0887,$0487,$7087,$7787,$7887,$7487,$8087,$8787,$8887,$8487,$4087,$4787,$4887,$4487
dw $0088,$0788,$0888,$0488,$7088,$7788,$7888,$7488,$8088,$8788,$8888,$8488,$4088,$4788,$4888,$4488
dw $0084,$0784,$0884,$0484,$7084,$7784,$7884,$7484,$8084,$8784,$8884,$8484,$4084,$4784,$4884,$4484
dw $0040,$0740,$0840,$0440,$7040,$7740,$7840,$7440,$8040,$8740,$8840,$8440,$4040,$4740,$4840,$4440
dw $0047,$0747,$0847,$0447,$7047,$7747,$7847,$7447,$8047,$8747,$8847,$8447,$4047,$4747,$4847,$4447
dw $0048,$0748,$0848,$0448,$7048,$7748,$7848,$7448,$8048,$8748,$8848,$8448,$4048,$4748,$4848,$4448
dw $0044,$0744,$0844,$0444,$7044,$7744,$7844,$7444,$8044,$8744,$8844,$8444,$4044,$4744,$4844,$4444
W11_T3
dw $0000,$0100,$0600,$0400,$1000,$1100,$1600,$1400,$6000,$6100,$6600,$6400,$4000,$4100,$4600,$4400
dw $0001,$0101,$0601,$0401,$1001,$1101,$1601,$1401,$6001,$6101,$6601,$6401,$4001,$4101,$4601,$4401
dw $0006,$0106,$0606,$0406,$1006,$1106,$1606,$1406,$6006,$6106,$6606,$6406,$4006,$4106,$4606,$4406
dw $0004,$0104,$0604,$0404,$1004,$1104,$1604,$1404,$6004,$6104,$6604,$6404,$4004,$4104,$4604,$4404
dw $0010,$0110,$0610,$0410,$1010,$1110,$1610,$1410,$6010,$6110,$6610,$6410,$4010,$4110,$4610,$4410
dw $0011,$0111,$0611,$0411,$1011,$1111,$1611,$1411,$6011,$6111,$6611,$6411,$4011,$4111,$4611,$4411
dw $0016,$0116,$0616,$0416,$1016,$1116,$1616,$1416,$6016,$6116,$6616,$6416,$4016,$4116,$4616,$4416
dw $0014,$0114,$0614,$0414,$1014,$1114,$1614,$1414,$6014,$6114,$6614,$6414,$4014,$4114,$4614,$4414
dw $0060,$0160,$0660,$0460,$1060,$1160,$1660,$1460,$6060,$6160,$6660,$6460,$4060,$4160,$4660,$4460
dw $0061,$0161,$0661,$0461,$1061,$1161,$1661,$1461,$6061,$6161,$6661,$6461,$4061,$4161,$4661,$4461
dw $0066,$0166,$0666,$0466,$1066,$1166,$1666,$1466,$6066,$6166,$6666,$6466,$4066,$4166,$4666,$4466
dw $0064,$0164,$0664,$0464,$1064,$1164,$1664,$1464,$6064,$6164,$6664,$6464,$4064,$4164,$4664,$4464
dw $0040,$0140,$0640,$0440,$1040,$1140,$1640,$1440,$6040,$6140,$6640,$6440,$4040,$4140,$4640,$4440
dw $0041,$0141,$0641,$0441,$1041,$1141,$1641,$1441,$6041,$6141,$6641,$6441,$4041,$4141,$4641,$4441
dw $0046,$0146,$0646,$0446,$1046,$1146,$1646,$1446,$6046,$6146,$6646,$6446,$4046,$4146,$4646,$4446
dw $0044,$0144,$0644,$0444,$1044,$1144,$1644,$1444,$6044,$6144,$6644,$6444,$4044,$4144,$4644,$4444
W11_S0
dw $0000,$0f00,$0a00,$0b00,$f000,$ff00,$fa00,$fb00,$a000,$af00,$aa00,$ab00,$b000,$bf00,$ba00,$bb00
dw $000f,$0f0f,$0a0f,$0b0f,$f00f,$ff0f,$fa0f,$fb0f,$a00f,$af0f,$aa0f,$ab0f,$b00f,$bf0f,$ba0f,$bb0f
dw $000a,$0f0a,$0a0a,$0b0a,$f00a,$ff0a,$fa0a,$fb0a,$a00a,$af0a,$aa0a,$ab0a,$b00a,$bf0a,$ba0a,$bb0a
dw $000b,$0f0b,$0a0b,$0b0b,$f00b,$ff0b,$fa0b,$fb0b,$a00b,$af0b,$aa0b,$ab0b,$b00b,$bf0b,$ba0b,$bb0b
dw $00f0,$0ff0,$0af0,$0bf0,$f0f0,$fff0,$faf0,$fbf0,$a0f0,$aff0,$aaf0,$abf0,$b0f0,$bff0,$baf0,$bbf0
dw $00ff,$0fff,$0aff,$0bff,$f0ff,$ffff,$faff,$fbff,$a0ff,$afff,$aaff,$abff,$b0ff,$bfff,$baff,$bbff
dw $00fa,$0ffa,$0afa,$0bfa,$f0fa,$fffa,$fafa,$fbfa,$a0fa,$affa,$aafa,$abfa,$b0fa,$bffa,$bafa,$bbfa
dw $00fb,$0ffb,$0afb,$0bfb,$f0fb,$fffb,$fafb,$fbfb,$a0fb,$affb,$aafb,$abfb,$b0fb,$bffb,$bafb,$bbfb
dw $00a0,$0fa0,$0aa0,$0ba0,$f0a0,$ffa0,$faa0,$fba0,$a0a0,$afa0,$aaa0,$aba0,$b0a0,$bfa0,$baa0,$bba0
dw $00af,$0faf,$0aaf,$0baf,$f0af,$ffaf,$faaf,$fbaf,$a0af,$afaf,$aaaf,$abaf,$b0af,$bfaf,$baaf,$bbaf
dw $00aa,$0faa,$0aaa,$0baa,$f0aa,$ffaa,$faaa,$fbaa,$a0aa,$afaa,$aaaa,$abaa,$b0aa,$bfaa,$baaa,$bbaa
dw $00ab,$0fab,$0aab,$0bab,$f0ab,$ffab,$faab,$fbab,$a0ab,$afab,$aaab,$abab,$b0ab,$bfab,$baab,$bbab
dw $00b0,$0fb0,$0ab0,$0bb0,$f0b0,$ffb0,$fab0,$fbb0,$a0b0,$afb0,$aab0,$abb0,$b0b0,$bfb0,$bab0,$bbb0
dw $00bf,$0fbf,$0abf,$0bbf,$f0bf,$ffbf,$fabf,$fbbf,$a0bf,$afbf,$aabf,$abbf,$b0bf,$bfbf,$babf,$bbbf
dw $00ba,$0fba,$0aba,$0bba,$f0ba,$ffba,$faba,$fbba,$a0ba,$afba,$aaba,$abba,$b0ba,$bfba,$baba,$bbba
dw $00bb,$0fbb,$0abb,$0bbb,$f0bb,$ffbb,$fabb,$fbbb,$a0bb,$afbb,$aabb,$abbb,$b0bb,$bfbb,$babb,$bbbb
W11_S1
dw $0000,$0c00,$0700,$0a00,$c000,$cc00,$c700,$ca00,$7000,$7c00,$7700,$7a00,$a000,$ac00,$a700,$aa00
dw $000c,$0c0c,$070c,$0a0c,$c00c,$cc0c,$c70c,$ca0c,$700c,$7c0c,$770c,$7a0c,$a00c,$ac0c,$a70c,$aa0c
dw $0007,$0c07,$0707,$0a07,$c007,$cc07,$c707,$ca07,$7007,$7c07,$7707,$7a07,$a007,$ac07,$a707,$aa07
dw $000a,$0c0a,$070a,$0a0a,$c00a,$cc0a,$c70a,$ca0a,$700a,$7c0a,$770a,$7a0a,$a00a,$ac0a,$a70a,$aa0a
dw $00c0,$0cc0,$07c0,$0ac0,$c0c0,$ccc0,$c7c0,$cac0,$70c0,$7cc0,$77c0,$7ac0,$a0c0,$acc0,$a7c0,$aac0
dw $00cc,$0ccc,$07cc,$0acc,$c0cc,$cccc,$c7cc,$cacc,$70cc,$7ccc,$77cc,$7acc,$a0cc,$accc,$a7cc,$aacc
dw $00c7,$0cc7,$07c7,$0ac7,$c0c7,$ccc7,$c7c7,$cac7,$70c7,$7cc7,$77c7,$7ac7,$a0c7,$acc7,$a7c7,$aac7
dw $00ca,$0cca,$07ca,$0aca,$c0ca,$ccca,$c7ca,$caca,$70ca,$7cca,$77ca,$7aca,$a0ca,$acca,$a7ca,$aaca
dw $0070,$0c70,$0770,$0a70,$c070,$cc70,$c770,$ca70,$7070,$7c70,$7770,$7a70,$a070,$ac70,$a770,$aa70
dw $007c,$0c7c,$077c,$0a7c,$c07c,$cc7c,$c77c,$ca7c,$707c,$7c7c,$777c,$7a7c,$a07c,$ac7c,$a77c,$aa7c
dw $0077,$0c77,$0777,$0a77,$c077,$cc77,$c777,$ca77,$7077,$7c77,$7777,$7a77,$a077,$ac77,$a777,$aa77
dw $007a,$0c7a,$077a,$0a7a,$c07a,$cc7a,$c77a,$ca7a,$707a,$7c7a,$777a,$7a7a,$a07a,$ac7a,$a77a,$aa7a
dw $00a0,$0ca0,$07a0,$0aa0,$c0a0,$cca0,$c7a0,$caa0,$70a0,$7ca0,$77a0,$7aa0,$a0a0,$aca0,$a7a0,$aaa0
dw $00ac,$0cac,$07ac,$0aac,$c0ac,$ccac,$c7ac,$caac,$70ac,$7cac,$77ac,$7aac,$a0ac,$acac,$a7ac,$aaac
dw $00a7,$0ca7,$07a7,$0aa7,$c0a7,$cca7,$c7a7,$caa7,$70a7,$7ca7,$77a7,$7aa7,$a0a7,$aca7,$a7a7,$aaa7
dw $00aa,$0caa,$07aa,$0aaa,$c0aa,$ccaa,$c7aa,$caaa,$70aa,$7caa,$77aa,$7aaa,$a0aa,$acaa,$a7aa,$aaaa
W11_S2
dw $0000,$0900,$0700,$0a00,$9000,$9900,$9700,$9a00,$7000,$7900,$7700,$7a00,$a000,$a900,$a700,$aa00
dw $0009,$0909,$0709,$0a09,$9009,$9909,$9709,$9a09,$7009,$7909,$7709,$7a09,$a009,$a909,$a709,$aa09
dw $0007,$0907,$0707,$0a07,$9007,$9907,$9707,$9a07,$7007,$7907,$7707,$7a07,$a007,$a907,$a707,$aa07
dw $000a,$090a,$070a,$0a0a,$900a,$990a,$970a,$9a0a,$700a,$790a,$770a,$7a0a,$a00a,$a90a,$a70a,$aa0a
dw $0090,$0990,$0790,$0a90,$9090,$9990,$9790,$9a90,$7090,$7990,$7790,$7a90,$a090,$a990,$a790,$aa90
dw $0099,$0999,$0799,$0a99,$9099,$9999,$9799,$9a99,$7099,$7999,$7799,$7a99,$a099,$a999,$a799,$aa99
dw $0097,$0997,$0797,$0a97,$9097,$9997,$9797,$9a97,$7097,$7997,$7797,$7a97,$a097,$a997,$a797,$aa97
dw $009a,$099a,$079a,$0a9a,$909a,$999a,$979a,$9a9a,$709a,$799a,$779a,$7a9a,$a09a,$a99a,$a79a,$aa9a
dw $0070,$0970,$0770,$0a70,$9070,$9970,$9770,$9a70,$7070,$7970,$7770,$7a70,$a070,$a970,$a770,$aa70
dw $0079,$0979,$0779,$0a79,$9079,$9979,$9779,$9a79,$7079,$7979,$7779,$7a79,$a079,$a979,$a779,$aa79
dw $0077,$0977,$0777,$0a77,$9077,$9977,$9777,$9a77,$7077,$7977,$7777,$7a77,$a077,$a977,$a777,$aa77
dw $007a,$097a,$077a,$0a7a,$907a,$997a,$977a,$9a7a,$707a,$797a,$777a,$7a7a,$a07a,$a97a,$a77a,$aa7a
dw $00a0,$09a0,$07a0,$0aa0,$90a0,$99a0,$97a0,$9aa0,$70a0,$79a0,$77a0,$7aa0,$a0a0,$a9a0,$a7a0,$aaa0
dw $00a9,$09a9,$07a9,$0aa9,$90a9,$99a9,$97a9,$9aa9,$70a9,$79a9,$77a9,$7aa9,$a0a9,$a9a9,$a7a9,$aaa9
dw $00a7,$09a7,$07a7,$0aa7,$90a7,$99a7,$97a7,$9aa7,$70a7,$79a7,$77a7,$7aa7,$a0a7,$a9a7,$a7a7,$aaa7
dw $00aa,$09aa,$07aa,$0aaa,$90aa,$99aa,$97aa,$9aaa,$70aa,$79aa,$77aa,$7aaa,$a0aa,$a9aa,$a7aa,$aaaa
W11_S3
dw $0000,$0400,$0500,$0600,$4000,$4400,$4500,$4600,$5000,$5400,$5500,$5600,$6000,$6400,$6500,$6600
dw $0004,$0404,$0504,$0604,$4004,$4404,$4504,$4604,$5004,$5404,$5504,$5604,$6004,$6404,$6504,$6604
dw $0005,$0405,$0505,$0605,$4005,$4405,$4505,$4605,$5005,$5405,$5505,$5605,$6005,$6405,$6505,$6605
dw $0006,$0406,$0506,$0606,$4006,$4406,$4506,$4606,$5006,$5406,$5506,$5606,$6006,$6406,$6506,$6606
dw $0040,$0440,$0540,$0640,$4040,$4440,$4540,$4640,$5040,$5440,$5540,$5640,$6040,$6440,$6540,$6640
dw $0044,$0444,$0544,$0644,$4044,$4444,$4544,$4644,$5044,$5444,$5544,$5644,$6044,$6444,$6544,$6644
dw $0045,$0445,$0545,$0645,$4045,$4445,$4545,$4645,$5045,$5445,$5545,$5645,$6045,$6445,$6545,$6645
dw $0046,$0446,$0546,$0646,$4046,$4446,$4546,$4646,$5046,$5446,$5546,$5646,$6046,$6446,$6546,$6646
dw $0050,$0450,$0550,$0650,$4050,$4450,$4550,$4650,$5050,$5450,$5550,$5650,$6050,$6450,$6550,$6650
dw $0054,$0454,$0554,$0654,$4054,$4454,$4554,$4654,$5054,$5454,$5554,$5654,$6054,$6454,$6554,$6654
dw $0055,$0455,$0555,$0655,$4055,$4455,$4555,$4655,$5055,$5455,$5555,$5655,$6055,$6455,$6555,$6655
dw $0056,$0456,$0556,$0656,$4056,$4456,$4556,$4656,$5056,$5456,$5556,$5656,$6056,$6456,$6556,$6656
dw $0060,$0460,$0560,$0660,$4060,$4460,$4560,$4660,$5060,$5460,$5560,$5660,$6060,$6460,$6560,$6660
dw $0064,$0464,$0564,$0664,$4064,$4464,$4564,$4664,$5064,$5464,$5564,$5664,$6064,$6464,$6564,$6664
dw $0065,$0465,$0565,$0665,$4065,$4465,$4565,$4665,$5065,$5465,$5565,$5665,$6065,$6465,$6565,$6665
dw $0066,$0466,$0566,$0666,$4066,$4466,$4566,$4666,$5066,$5466,$5566,$5666,$6066,$6466,$6566,$6666

View File

@ -67,3 +67,55 @@ nesPalette
dw $0EEE
dw $0111
dw $0111
; Swizzle tables based on AreaType
;
; IIgs palette index 0 is always the background color: 'BBB'
; IIgs palette index 0 is always the color cycling color 'RRR'
;
; The rest are remapped.
;
; Underground:
;
; T0: $0F $29 $1A $09
; T1: --- $3C $1C $0F
; T2: --- $30 $21 $1C
; T3: --- RRR $17 $1C
; S0: --- $16 $27 $18 --> $37 $27 $16
; S1: --- $1C $36 $17
; S2: --- $16 $30 $27
; S3: --- $1D $3C $1C --> $0F RR $29 $1A $09 $36 $1C $30 $21 $16 $27 $18 $17 $3C $1D $37 : 0 free colors
; --> $00 $01 $02 $03 $04 $05 $06 $07 $08 $09 $0A $0B $0C $0D $0E $0F
;
; Mapped palettes
;
; T0: 0 2 3 4
; T1: 0 D 6 0
; T2: 0 7 8 6
; T3: 0 1 C 6
; S0: 0 F A B
; S1: 0 6 5 C
; S2: 0 9 7 A
; S3: 0 E D 6
;
; Above Ground
;
; T0: $22 $29 $1A $0F
; T1: --- $36 $17 $0F
; T2: --- $30 $21 $0F
; T3: --- RRR $17 $0F
; S0: --- $16 $27 $18 --> $37 $27 $16
; S1: --- $1A $30 $17
; S2: --- $16 $30 $27
; S3: --- $0F $36 $17 --> $22 RR $29 $1A $0F $36 $17 $30 $21 $16 $27 $18 $1A --- --- $16 : 2 free colors
; --> $00 $01 $02 $03 $04 $05 $06 $07 $08 $09 $0A $0B $0C $0D $0E $0F
; Mapped palettes
;
; T0: 0 2 3 4
; T1: 0 5 6 4
; T2: 0 7 8 4
; T3: 0 1 6 4
; S0: 0 F A B
; S1: 0 C 7 A
; S2: 0 9 7 A
; S3: 0 4 5 6

View File

@ -259,42 +259,15 @@ PPUDATA_WRITE ENT
plb
pha
phx
phy
rep #$10
ldx ppuaddr
* cpx #$3F00 ; Just log nametable access, not palette info
* bcs :nolog
* phy
* pha
* ldy ppu_write_log_len
* cpy #50
* bcs :log_full
* rep #$20
* txa
* sta ppu_write_log,y
* lda 1,s
* and #$00FF
* sta ppu_write_log+50,y
* iny
* iny
* sty ppu_write_log_len
* sep #$20
* :log_full
* pla
* ply
* :nolog
; cmp #$47
; bne :nobrk
; cpx #$2308
; bne :nobrk
; brk $FD
;:nobrk
cmp PPU_MEM,x
beq :nochange
ldy PPU_MEM,x ; Save in case we need to compare later
sta PPU_MEM,x
rep #$30
@ -307,13 +280,50 @@ PPUDATA_WRITE ENT
; 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
;
; There is one special case. We want the nt_queue to only be a queue of tiles to possibly redraw. If the PPU
; data that is updated is in the attribute table area, then we do some extra work to decide which of the 16
; tiles *actually* need to be redrawn
cpx #$3000
bcs :nocache
cpx #$2000 ; Change to $2080 to ignore score field updates
bcc :nocache
phy
txa
and #$03C0
cmp #$03C0
beq :attrtbl
jsr :enqueue ; Add the address in the X register to the queue
:nocache
cpx #$3F00
bcc :done
brl :extra
; bcs :extra
; bra :done
:nochange
rep #$30
txa
clc
adc ppuincr
and #$3FFF
sta ppuaddr
:done
sep #$30
ply
plx
pla
plb
plp
rtl
mx %00
:enqueue
lda nt_queue_end
tay
inc
@ -327,37 +337,98 @@ PPUDATA_WRITE ENT
sta nt_queue,y
:full
lda #1
jsr setborder
ply
; lda #1
; jsr setborder
rts
:nocache
cpx #$3F00
bcs :extra
bra :done
:attrtbl
txa ; Calculate the base address in the nametable from the attribute address
and #$2C00
pha
txa
and #$0007
asl
asl
ora 1,s
sta 1,s
txa
and #$0038
asl
asl
asl
asl
ora 1,s
sta 1,s
:nochange
rep #$30
tya
eor PPU_MEM,x ; Identify bit that have changed
and #$00FF
bit #$00C0
beq :skip_bot_right
pha
lda 3,s
clc
adc #64+2 ; offset 2 rows an 2 columns
tax
jsr :enqueue_blk
pla
:skip_bot_right
bit #$0030
beq :skip_bot_left
pha
lda 3,s
clc
adc #64 ; offset 2 rows
tax
jsr :enqueue_blk
pla
:skip_bot_left
bit #$000C
beq :skip_top_right
pha
lda 3,s
tax
inx
inx
tax
jsr :enqueue_blk
pla
:skip_top_right
bit #$0003
beq :skip_top_left
lda 1,s
tax
jsr :enqueue_blk
:skip_top_left
pla ; pop the base address off
brl :done
; Pass in PPU address in X register
:enqueue_blk
jsr :enqueue
inx
jsr :enqueue
txa
clc
adc ppuincr
and #$3FFF
sta ppuaddr
:done
sep #$30
plx
pla
plb
plp
rtl
adc #32
tax
jsr :enqueue
dex
jmp :enqueue
setborder
php
sep #$20
eorl $E0C034
and #$F0
and #$0F
eorl $E0C034
stal $E0C034
plp
@ -365,45 +436,13 @@ setborder
; 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
; Based on the palette data that SMB uses, we remap the NES palette entries
; based on the AreaType, so most of the PPU writes are ignored. However,
; we do update some specific palette entries
;
; NES Description IIgs Palette
; ----------------------------------------
; BG0 Background color 0
; BG0,1 Light Green 1
; BG0,2 Dark Green 2
; BG0,3 Black 3
; BG1,1 Peach 4
; BG1,2 Brown 5
; BG1,3 Black 3
; BG2,1 White 6
; BG2,2 Light Blue 7
; BG2,3 Black 3
; BG3,1 Cycle 8 ; Coins / Blocks
; BG3,2 Brown 5
; BG3,3 Black 3
; SP0 0
; SP0,1 Red 9
; SP0,2 Orange 10
; SP0,3 Olive 11
; SP1,1 Dark Green 2
; SP1,2 White 6
; SP1,3 Orange 10
; SP2,1 Red 9
; SP2,2 White 6
; SP2,3 Orange 10
; SP3,1 Black 3
; SP3,2 Peach 4
; SP3,3 Brown 5
;
; There are 4 color to spare in case we need to add more entries. This mapping table is important because
; we have to have a custom tile rendering function and custom sprite rendering function that will dynamically
; map the 2-bit tile data into the proper palette range. This will likely be implemented with an 8-bit
; swizzle table. Possible optimization later on is to pre-swizzle certain tiles assuming that the palette
; assignments never change.
;
; BG Palette 2 can probably be ignored because it's just for the top of the screen and we can use a separate
; SCB palette for that line
; BG0,0 maps to IIgs Palette index 0 (Background color)
; BG3,1 maps to IIgs Palette index 1 (Color cycle for blocks)
; SP0,1 maps to IIgs Palette index 15 (Player primary color; changes with fire flower)
mx %00
:extra
txa
@ -427,92 +466,29 @@ ppu_3F00
ldx #0
brl extra_out
; Background Palette 0
ppu_3F01
lda PPU_MEM+$3F01
ldx #2
brl extra_out
ppu_3F02
lda PPU_MEM+$3F02
ldx #4
brl extra_out
ppu_3F03
lda PPU_MEM+$3F03
ldx #6
brl extra_out
; Shadow for background color
ppu_3F10
lda PPU_MEM+$3F10
ldx #0
brl extra_out
; Sprite Palette 0
; Tile palette 3, color 1
ppu_3F0D
lda PPU_MEM+$3F0D
ldx #2
brl extra_out
; Sprite Palette 0, color 1
ppu_3F11
lda PPU_MEM+$3F11
ldx #8
brl extra_out
ppu_3F12
lda PPU_MEM+$3F12
ldx #10
brl extra_out
ppu_3F13
lda PPU_MEM+$3F13
ldx #12
brl extra_out
; Sprite Palette 1
ppu_3F15
lda PPU_MEM+$3F15
ldx #14
brl extra_out
ppu_3F16
lda PPU_MEM+$3F16
ldx #16
brl extra_out
ppu_3F17
lda PPU_MEM+$3F17
ldx #18
brl extra_out
; Sprite Palette 2
ppu_3F19
lda PPU_MEM+$3F19
ldx #20
brl extra_out
ppu_3F1A
lda PPU_MEM+$3F1A
ldx #22
brl extra_out
ppu_3F1B
lda PPU_MEM+$3F1B
ldx #24
brl extra_out
; Sprite Palette 3
ppu_3F1D
lda PPU_MEM+$3F1D
ldx #26
brl extra_out
ppu_3F1E
lda PPU_MEM+$3F1E
ldx #28
brl extra_out
ppu_3F1F
lda PPU_MEM+$3F1F
ldx #30
brl extra_out
ppu_3F01
ppu_3F02
ppu_3F03
ppu_3F04
ppu_3F05
ppu_3F06
@ -524,29 +500,42 @@ ppu_3F0A
ppu_3F0B
ppu_3F0C
ppu_3F0D
ppu_3F0E
ppu_3F0F
ppu_3F12
ppu_3F13
ppu_3F14
ppu_3F15
ppu_3F16
ppu_3F17
ppu_3F18
ppu_3F19
ppu_3F1A
ppu_3F1B
ppu_3F1C
ppu_3F1D
ppu_3F1E
ppu_3F1F
brl no_pal
; Exit code to set a IIgs palette entry from the PPU memory
;
; A = NES palette value
; X = IIgs Palette index
extra_out
phy
and #$00FF
asl
tay
lda nesPalette,y
ply
stal $E19E00,x
no_pal
sep #$30
ply
plx
pla
plb
@ -1072,6 +1061,8 @@ oam_loop
tax
:noflip
; sta swizzle ; store a pointer to the swizzle table to use
pla
asl
and #$0146 ; Set the vflip bit, priority, and palette select bits
@ -1091,3 +1082,45 @@ drawTilePatch
rep #$30
rts
; Custom tile blitter
;
; D = GTE blitter direct page space
; X = offset to the tile record
;
mx %00
; Temporary tile space on the direct page
tmp_tile_data equ 80
;USER_TILE_RECORD equ 178
USER_TILE_ID equ 178 ; copy of the tile id in the tile store
;USER_TILE_CODE_PTR equ 180 ; pointer to the code bank in which to patch
USER_TILE_ADDR equ 184 ; address in the tile data bank (set on entry)
USER_FREE_SPACE equ 186 ; a few bytes of scratch space
LDA_IND_LONG_IDX equ $B7
; Assume that when the tile is updated, it includes a full 10-bit value with the
; palette bits included with the lookup bits
NESTileBlitter
lda USER_TILE_ID
and #$0600 ; Select the tile palette from the tile id
clc
adc #W11_T0
sta USER_FREE_SPACE
lda #^W11_T0
sta USER_FREE_SPACE+2
ldx USER_TILE_ADDR ; Get the address of the tile (base only)
]line equ 0
lup 8
ldy: {]line*4},x
db LDA_IND_LONG_IDX,USER_FREE_SPACE
sta tmp_tile_data+{]line*4}
ldy: {]line*4}+2,x
db LDA_IND_LONG_IDX,USER_FREE_SPACE
sta tmp_tile_data+{]line*4}+2
]line equ ]line+1
--^
lda #1 ; Request tmp_tile_data be copies to tile store
rtl

54
demos/smb/swizzle.js Normal file
View File

@ -0,0 +1,54 @@
// Generate seizzle tables
//
// Maps an 8-bit value of wwxxyyzz to a lookup table that takes each 2-bit
// value to a 16-bit pixel index. Zero always maps to zero. The input
// is three 4-bit values that define the targets for 1, 2, and 3.
// Run as: node swizzle.js label val1 val2 val3
if (process.argv.length !== 6) {
console.log(process.argv);
process.exit(1);
}
const output = process.stdout;
const values = [
0,
Number(process.argv[3]),
Number(process.argv[4]),
Number(process.argv[5]),
];
output.write(process.argv[2] + '\n');
for (let w = 0; w < 4; w++) {
for (let x = 0; x < 4; x++) {
output.write(' dw ');
const row = [];
for (let y = 0; y < 4; y++) {
for (let z = 0; z < 4; z++) {
// Because the NES PPU bits define the pixel order from high bit to low bit, but the
// 65816 is little endian, we need to swap the byte order in the mapping
/*
const target =
(values[w] * 4096) +
(values[x] * 256) +
(values[y] * 16) +
values[z];
*/
const target =
(values[w] * 16) +
(values[x] * 1) +
(values[y] * 4096) +
(values[z] * 256);
row.push(target);
}
}
// Output the values
output.write(row.map(s => '$' + s.toString(16).padStart(4, '0')).join(','));
// Line break
output.write('\n');
}
}