📄 ppu.asm
字号:
mov [C_LABEL(BG12NBA)],al
mov [C_LABEL(BG34NBA)],al
mov [NBABG1],al
mov [NBABG2],al
mov [NBABG3],al
mov [NBABG4],al
mov [C_LABEL(WH0)],al
mov [C_LABEL(WH2)],al
inc eax
mov [C_LABEL(WH1)],al
mov [C_LABEL(WH3)],al
dec eax
mov [C_LABEL(WBGLOG)],al
mov [C_LABEL(WOBJLOG)],al
mov [C_LABEL(W12SEL)],al
mov [C_LABEL(W34SEL)],al
mov [C_LABEL(WOBJSEL)],al
mov [WLOGBG1],al
mov [WLOGBG2],al
mov [WLOGBG3],al
mov [WLOGBG4],al
mov [WSELBG1],al
mov [WSELBG2],al
mov [WSELBG3],al
mov [WSELBG4],al
mov [C_LABEL(TM)],al
mov [C_LABEL(TS)],al
mov [C_LABEL(TMW)],al
mov [C_LABEL(TSW)],al
mov [C_LABEL(SETINI)],al
mov byte [C_LABEL(EXTBG_Mask)],~2
mov [C_LABEL(COLDATA)],eax
mov [C_LABEL(CGWSEL)],al
mov [C_LABEL(CGADSUB)],al
mov [C_LABEL(BrightnessLevel)],al
mov byte [C_LABEL(INIDISP)],0x80
mov [C_LABEL(BG1HOFS)],eax
mov [C_LABEL(BG1VOFS)],eax
mov [C_LABEL(BG2HOFS)],eax
mov [C_LABEL(BG2VOFS)],eax
mov [C_LABEL(BG3HOFS)],eax
mov [C_LABEL(BG3VOFS)],eax
mov [C_LABEL(BG4HOFS)],eax
mov [C_LABEL(BG4VOFS)],eax
mov [SetAddressBG1],eax
mov [SetAddressBG2],eax
mov [SetAddressBG3],eax
mov [SetAddressBG4],eax
mov dword [M0_Color_BG1],0x03030303
mov dword [M0_Color_BG2],0x23232323
mov dword [M0_Color_BG3],0x43434343
mov dword [M0_Color_BG4],0x63636363
mov byte [BG_Flag_BG1],(1 << 0)
mov byte [BG_Flag_BG2],(1 << 1)
mov byte [BG_Flag_BG3],(1 << 2)
mov byte [BG_Flag_BG4],(1 << 3)
mov byte [OC_Flag_BG1],0x20
mov byte [OC_Flag_BG2],0x40
mov dword [NBATableBG1],BGNBA_Table_2
mov dword [NBATableBG2],BGNBA_Table_2
mov dword [NBATableBG3],BGNBA_Table_2
mov dword [NBATableBG4],BGNBA_Table_2
mov dword [LineRenderBG1],C_LABEL(Render_8x8_C2)
mov dword [LineRenderBG2],C_LABEL(Render_8x8_C2)
mov dword [LineRenderBG3],C_LABEL(Render_8x8_C2)
mov dword [LineRenderBG4],C_LABEL(Render_8x8_C2)
mov byte [TileHeightBG1],1
mov byte [TileHeightBG2],1
mov byte [TileHeightBG3],1
mov byte [TileHeightBG4],1
mov byte [TileWidthBG1],1
mov byte [TileWidthBG2],1
mov byte [TileWidthBG3],1
mov byte [TileWidthBG4],1
mov byte [DepthBG1],1
mov byte [DepthBG2],1
mov byte [DepthBG3],1
mov byte [DepthBG4],1
mov eax,C_LABEL(VRAM)
mov [TLMapAddressBG1],eax ;MapAddressBG1
mov [TLMapAddressBG2],eax ;MapAddressBG2
mov [TLMapAddressBG3],eax ;MapAddressBG3
mov [TLMapAddressBG4],eax ;MapAddressBG4
mov [TRMapAddressBG1],eax
mov [TRMapAddressBG2],eax
mov [TRMapAddressBG3],eax
mov [TRMapAddressBG4],eax
mov [BLMapAddressBG1],eax
mov [BLMapAddressBG2],eax
mov [BLMapAddressBG3],eax
mov [BLMapAddressBG4],eax
mov [BRMapAddressBG1],eax
mov [BRMapAddressBG2],eax
mov [BRMapAddressBG3],eax
mov [BRMapAddressBG4],eax
mov dword [OffsetChangeMap_VOffset],0
mov dword [OffsetChangeVMap_VOffset],0
mov [C_LABEL(VMAIN)],al
mov dword [VMDATAREAD_update],VMDATAREAD_update_NORM
Set_21_Write 0x18,SNES_W2118_NORM
Set_21_Write 0x19,SNES_W2119_NORM
mov [VMDATAREAD_buffer],eax
mov eax,[Screen_Mode]
mov [Render_Mode],eax
popa
ret
; Read from 21xx handlers
; SNES_R2134: ; MPYL in mode7.asm
; SNES_R2135: ; MPYM in mode7.asm
; SNES_R2136: ; MPYH in mode7.asm
; SNES_R2137: ; SLHV in timing.inc
; SNES_R2138: ; OAMDATAREAD in sprites.asm
ALIGNC
SNES_R2139: ; VMDATALREAD
mov al,[C_LABEL(VMAIN)]
test al,al
mov al,[VMDATAREAD_buffer]
jns VMDATAREAD_do_update
ret
ALIGNC
SNES_R213A: ; VMDATAHREAD
mov al,[C_LABEL(VMAIN)]
test al,al
mov al,[VMDATAREAD_buffer+1]
js VMDATAREAD_do_update
ret
ALIGNC
VMDATAREAD_do_update:
jmp [VMDATAREAD_update]
ALIGNC
VMDATAREAD_update_NORM: ; normal increment
push ebx
mov edx,[VRAMAddress]
mov bx,[C_LABEL(VRAM)+edx*2]
add edx,[SCINC]
mov [VMDATAREAD_buffer],bx
and edx,0x7FFF
pop ebx
mov [VRAMAddress],edx
ret
;bitshift (%1), bitmask (1 << (%1)) - 1, topmask 0x7FFF & ~((1 << ((%1) + 3)) - 1)
%macro GEN_SNES_R2139_213A_FULL 2
VMDATAREAD_update_FULL_%2: ; full graphic increment
mov edx,[VRAMAddress]
push eax
push edi
mov edi,edx
mov eax,edx
shr edi,(%1) ;Bitshift
and eax,byte (1 << (%1)) - 1 ;Bitmask
and edi,byte 7
shl eax,3
and edx,0x7FFF & ~((1 << ((%1) + 3)) - 1) ;Topmask
or edx,edi
or edx,eax
pop edi
mov ax,[C_LABEL(VRAM)+edx*2]
mov edx,[SCINC]
mov [VMDATAREAD_buffer],ax
add edx,[VRAMAddress] ; Always words (since <<1)!
pop eax
and edx,0x7FFF
mov [VRAMAddress],edx
ret
%endmacro
GEN_SNES_R2139_213A_FULL 5,32
GEN_SNES_R2139_213A_FULL 6,64
GEN_SNES_R2139_213A_FULL 7,128
ALIGNC
SNES_R213B: ; CGDATAREAD
push ebx
xor ebx,ebx
;push edx
mov bl,[CGReadHigh]
mov edx,[CGAddress]
mov al,[C_LABEL(Real_SNES_Palette)+ebx+edx*2]
xor bl,1
jnz .no_increment
inc edx
mov [CGAddress],dl ; Chop address for wrap
.no_increment:
mov [CGReadHigh],bl
;pop edx
pop ebx
ret
; SNES_R213C: ; OPHCT in timing.inc
; SNES_R213D: ; OPVCT in timing.inc
ALIGNC
SNES_R213E: ; STAT77
mov al,1 ; This is not supported yet!
ret
ALIGNC
SNES_R213F: ; STAT78
mov al,0
mov [OPHCT],al
mov [OPVCT],al
mov al,[STAT78]
or al,[C_LABEL(SNES_COUNTRY)] ; 0x10 means PAL, not NTSC
ret
; SNES_R2140_SKIP: ; APUI00 in APUskip.asm
; SNES_R2141_SKIP: ; APUI01 in APUskip.asm
; SNES_R2142_SKIP: ; APUI02 in APUskip.asm
; SNES_R2143_SKIP: ; APUI03 in APUskip.asm
; SNES_R2140_SPC: ; APUI00 in spc700.asm
; SNES_R2141_SPC: ; APUI01 in spc700.asm
; SNES_R2142_SPC: ; APUI02 in spc700.asm
; SNES_R2143_SPC: ; APUI03 in spc700.asm
ALIGNC
SNES_R2180: ; WMDATA
mov edx,[WMADDL]
add R_65c816_Cycles,_5A22_SLOW_CYCLE - _5A22_FAST_CYCLE
mov al,[C_LABEL(WRAM)+edx]
inc edx
and edx,0x01FFFF
mov [WMADDL],edx
ret
; Read from 40xx handlers
; SNES_R4016: ; JOYC1 in timing.inc
; SNES_R4017: ; JOYC2 in timing.inc
; Read from 42xx handlers
; SNES_R4200: ; NMITIMEN in timing.inc
; SNES_R4202: ; WRMPYA in timing.inc
; SNES_R4203: ; WRMPYB in timing.inc
; SNES_R4210: ; RDNMI in timing.inc
; SNES_R4211: ; TIMEUP in timing.inc
; SNES_R4212: ; HVBJOY in timing.inc
; SNES_R4213: ; RDIO in timing.inc
; SNES_R4214: ; RDDIVL in timing.inc
; SNES_R4215: ; RDDIVH in timing.inc
; SNES_R4216: ; RDMPYL in timing.inc
; SNES_R4217: ; RDMPYH in timing.inc
; SNES_R4218: ; JOY1L in timing.inc
; SNES_R4219: ; JOY1H in timing.inc
; SNES_R421A: ; JOY2L in timing.inc
; SNES_R421B: ; JOY2H in timing.inc
; SNES_R421C: ; JOY3L in timing.inc
; SNES_R421D: ; JOY3H in timing.inc
; SNES_R421E: ; JOY4L in timing.inc
; SNES_R421F: ; JOY4H in timing.inc
; Read from 43xx handlers
; SNES_R43xx: ; in DMA.asm
; --------
; Write to 21xx handlers
ALIGNC
SNES_W2100: ; INIDISP
cmp [C_LABEL(INIDISP)],al
je .no_change
UpdateDisplay
mov [C_LABEL(INIDISP)],al
and al,0x0F
cmp [C_LABEL(BrightnessLevel)],al
ja .no_brightness_change
mov [C_LABEL(BrightnessLevel)],al ; Sets the brightness level for SetPalette
mov byte [C_LABEL(PaletteChanged)],1
.no_brightness_change:
mov al,[C_LABEL(INIDISP)]
.no_change:
ret
; SNES_W2101: ; OBSEL in sprites.asm
; SNES_W2102: ; OAMADDL in sprites.asm
; SNES_W2103: ; OAMADDH in sprites.asm
; SNES_W2104: ; OAMDATA in sprites.asm
ALIGNC
EXPORT_C Toggle_Offset_Change
xor byte [C_LABEL(Offset_Change_Disable)],0xFF
ret
ALIGNC
SNES_W2105: ; BGMODE
%if 0
cmp al,0x02
jne .okay
mov al,0x06
.okay:
%endif
; Note: Render_Mode is declared in screen.asm
cmp [C_LABEL(BGMODE)],al
je .no_change
UpdateDisplay ;*
mov [C_LABEL(BGMODE)],al
; int mode = BGMODE & 7;
push ebx
mov edx,eax
push ecx
mov ebx,eax
push edi
and ebx,byte 7
push esi
mov [C_LABEL(Base_BGMODE)],bl
and edx,byte 7
mov ebx,0x03030303
mov ecx,0x23232323
mov edi,0x43434343
mov esi,0x63636363
jz .mode_0_palettes
mov ecx,ebx
mov edi,ebx
mov esi,ebx
.mode_0_palettes:
mov [M0_Color_BG1],ebx
mov [M0_Color_BG2],ecx
mov [M0_Color_BG3],edi
mov [M0_Color_BG4],esi
pop esi
pop edi
; BGMODE_Allowed_Layer_Mask = BGMODE_Allowed_Layer_Mask_Table[mode];
; BGMODE_Tile_Layer_Mask = BGMODE_Tile_Layer_Mask_Table[mode];
; Render_Mode = Screen_Mode[mode];
xor ebx,ebx
mov cl,[BGMODE_Tile_Layer_Mask_Table+edx]
mov bl,[BGMODE_Allowed_Layer_Mask_Table+edx]
mov [BGMODE_Tile_Layer_Mask],cl
and cl,0x0F
jnz .not_mode7
and bl,[C_LABEL(EXTBG_Mask)]
.not_mode7:
mov [BGMODE_Allowed_Layer_Mask],bl
mov bl,[BGMODE_Allowed_Offset_Change_Table+edx]
mov ecx,[Screen_Mode+edx*4]
lea edx,[BGMODE_Depth_Table+edx]
mov [BGMODE_Allowed_Offset_Change],bl
mov [Redo_Offset_Change],bl
mov [Render_Mode],ecx
; DepthBG1 = BGMODE_Depth_Table[0][mode];
; if (DepthBG1 & 3)
; {
; int tilesize;
; NBATableBG1 = Depth_NBA_Table[DepthBG1 & 3];
; SetAddressBG1 = NBATableBG1[NBABG1];
; tilesize = BGMODE & 0x10 ? 2 : 1;
; TileHeightBG1 = TileWidthBG1 = tilesize;
;
; DepthBG2 = BGMODE_Depth_Table[1][mode];
; if (DepthBG2 & 3)
; {
; NBATableBG2 = Depth_NBA_Table[DepthBG2 & 3];
; SetAddressBG2 = NBATableBG2[NBABG2];
; tilesize = BGMODE & 0x20 ? 2 : 1;
; TileHeightBG2 = TileWidthBG2 = tilesize;
;
; DepthBG3 = BGMODE_Depth_Table[2][mode];
; DepthBG4 = BGMODE_Depth_Table[3][mode];
;
; tilesize = BGMODE & 0x40 ? 2 : 1;
; TileHeightBG3 = TileWidthBG3 = tilesize;
;
; tilesize = BGMODE & 0x80 ? 2 : 1;
; TileHeightBG4 = TileWidthBG4 = tilesize;
; }
mov cl,[edx]
mov bl,[NBABG1]
mov [DepthBG1],cl
and ecx,byte 3
jz .no_more_tile_layers
mov ecx,[Depth_NBA_Table+ecx*4]
mov [NBATableBG1],ecx
mov ecx,[ecx+ebx*4]
mov [SetAddressBG1],ecx
test al,0x10 ; get (tile height / 8) for BG1
mov bl,2
jnz .large_tiles_bg1_1
mov bl,1
.large_tiles_bg1_1:
mov [TileHeightBG1],bl
mov [TileWidthBG1],bl
mov cl,[edx+8]
mov bl,[NBABG2]
mov [DepthBG2],cl
and ecx,byte 3
jz .no_more_tile_layers
mov ecx,[Depth_NBA_Table+ecx*4]
mov [NBATableBG2],ecx
mov ecx,[ecx+ebx*4]
mov [SetAddressBG2],ecx
test al,0x20 ; get (tile height / 8) for BG2
mov bl,2
jnz .large_tiles_bg2_1
mov bl,1
.large_tiles_bg2_1:
mov [TileHeightBG2],bl
mov [TileWidthBG2],bl
mov bl,[edx+16]
mov cl,[edx+24]
mov [DepthBG3],bl
mov [DepthBG4],cl
test al,0x40 ; get (tile height / 8) for BG3
mov bl,2
jnz .large_tiles_bg3_1
mov bl,1
.large_tiles_bg3_1:
mov [TileHeightBG3],bl
mov [TileWidthBG3],bl
test al,al ; get (tile height / 8) for BG4
mov bl,2
js .large_tiles_bg4_1
mov bl,1
.large_tiles_bg4_1:
mov [TileHeightBG4],bl
mov [TileWidthBG4],bl
.no_more_tile_layers:
mov byte [Redo_Layering],-1
mov al,[C_LABEL(BGMODE)]
mov edx,eax
and edx,byte 7
xor ebx,ebx
cmp edx,byte 5
jae .wide_mode
mov bl,[DepthBG1]
test al,0x10
mov edx,[LineRenderLarge+ebx*4]
jnz .large_tiles_bg1_2
mov edx,[LineRenderSmall+ebx*4]
.large_tiles_bg1_2:
mov [LineRenderBG1],edx
mov bl,[DepthBG2]
test al,0x20
mov edx,[LineRenderLarge+ebx*4]
jnz .large_tiles_bg2_2
mov edx,[LineRenderSmall+ebx*4]
.large_tiles_bg2_2:
mov [LineRenderBG2],edx
mov bl,[DepthBG3]
test al,0x40
mov edx,[LineRenderLarge+ebx*4]
jnz .large_tiles_bg3_2
mov edx,[LineRenderSmall+ebx*4]
.large_tiles_bg3_2:
mov [LineRenderBG3],edx
mov bl,[DepthBG4]
test al,al
mov edx,[LineRenderLarge+ebx*4]
js .large_tiles_bg4_2
mov edx,[LineRenderSmall+ebx*4]
.large_tiles_bg4_2:
mov [LineRenderBG4],edx
pop ecx
pop ebx
.no_change:
ret
ALIGNC
; Mode 5/6: uses half-wide tile counts for half-512
.wide_mode:
mov bl,1
; 16-wide tiles with 8-wide addressing on background layers always
mov [TileWidthBG1],bl
mov [TileWidthBG2],bl
mov [TileWidthBG3],bl
mov [TileWidthBG4],bl
mov bl,[DepthBG1]
test al,0x10
mov edx,[LineRenderEvenLarge+ebx*4]
jnz .large_tiles_wide_bg1
mov edx,[LineRenderEvenSmall+ebx*4]
.large_tiles_wide_bg1:
mov [LineRenderBG1],edx
mov bl,[DepthBG2]
test al,0x20
mov edx,[LineRenderEvenLarge+ebx*4]
jnz .large_tiles_wide_bg2
mov edx,[LineRenderEvenSmall+ebx*4]
.large_tiles_wide_bg2:
mov [LineRenderBG2],edx
mov bl,[DepthBG3]
test al,0x40
mov edx,[LineRenderEvenLarge+ebx*4]
jnz .large_tiles_wide_bg3
mov edx,[LineRenderEvenSmall+ebx*4]
.large_tiles_wide_bg3:
mov [LineRenderBG3],edx
mov bl,[DepthBG4]
test al,al
mov edx,[LineRenderEvenLarge+ebx*4]
js .large_tiles_wide_bg4
mov edx,[LineRenderEvenSmall+ebx*4]
.large_tiles_wide_bg4:
mov [LineRenderBG4],edx
pop ecx
pop ebx
ret
ALIGNC
SNES_W2106: ; MOSAIC
cmp [MOSAIC],al
je .no_change
%ifdef FORCE_MOSAIC
push eax ;***
%endif
UpdateDisplay ;*
%ifdef FORCE_MOSAIC
mov al,0x0F + (FORCE_MOSAIC << 4) ;***
%endif
mov [MOSAIC],al
mov edx,eax
and al,0x01
mov [MosaicBG1],al
mov eax,edx
and al,0x02
mov [MosaicBG2],al
mov eax,edx
and al,0x04
mov [MosaicBG3],al
mov eax,edx
and al,0x08
mov [MosaicBG4],al
mov eax,edx
shr edx,4
and edx,byte 15
inc edx
mov [Mosaic_Size],edx
dec edx
shl edx,8
mov [Mosaic_Size_Select],edx
%ifdef FORCE_MOSAIC
pop eax ;***
%endif
.no_change:
ret
ALIGNC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -