📄 ppu.asm
字号:
SNES_W2107: ; BG1SC
cmp [C_LABEL(BG1SC)],al
je Update_BGSC.no_change
LOAD_BG_TABLE 1
Update_BGSC:
push edi
push edx
UpdateDisplay ;*
pop edx
mov edi,eax
push esi
and edi,byte 0x7C
mov esi,C_LABEL(VRAM)
shl edi,9
mov [BGSC+edx],al
push ebx
lea ebx,[esi+edi]
mov [MapAddress+edx],ebx
test al,3
jz .one_screen
lea edi,[edi+32*32*2]
jpe .four_screen
and edi,0xFFFF ;enforce VRAM wrap
test al,1
jz .tall_screen
.wide_screen:
add edi,esi
mov [BLMapAddress+edx],ebx
mov [TRMapAddress+edx],edi
mov [BRMapAddress+edx],edi
jmp .have_screen_addresses
.tall_screen:
add edi,esi
mov [TRMapAddress+edx],ebx
mov [BLMapAddress+edx],edi
mov [BRMapAddress+edx],edi
jmp .have_screen_addresses
.one_screen:
mov [TRMapAddress+edx],ebx
mov [BLMapAddress+edx],ebx
mov [BRMapAddress+edx],ebx
jmp .have_screen_addresses
.four_screen:
push eax
lea eax,[edi+32*32*2]
lea ebx,[edi+32*32*2*2]
add edi,esi
and eax,0xFFFF
and ebx,0xFFFF
add eax,esi
add ebx,esi
mov [TRMapAddress+edx],edi
mov [BLMapAddress+edx],eax
mov [BRMapAddress+edx],ebx
pop eax
.have_screen_addresses:
pop ebx
pop esi
pop edi
.no_change:
ret
ALIGNC
SNES_W2108: ; BG2SC
cmp [C_LABEL(BG2SC)],al
je Update_BGSC.no_change
LOAD_BG_TABLE 2
jmp Update_BGSC
ALIGNC
SNES_W2109: ; BG3SC
cmp [C_LABEL(BG3SC)],al
je Update_BGSC.no_change
mov byte [Redo_Offset_Change_VOffsets],0xFF
mov byte [Redo_Offset_Change],0xFF
LOAD_BG_TABLE 3
jmp Update_BGSC
ALIGNC
SNES_W210A: ; BG4SC
cmp [C_LABEL(BG4SC)],al
je Update_BGSC.no_change
LOAD_BG_TABLE 4
jmp Update_BGSC
ALIGNC
SNES_W210B: ; BG12NBA
cmp [C_LABEL(BG12NBA)],al
je .no_change
UpdateDisplay ;*
push ebx
mov [C_LABEL(BG12NBA)],al
mov bl,al
and ebx,byte 7
mov edx,[NBATableBG1]
mov [NBABG1],bl
mov ebx,[edx+ebx*4]
mov [SetAddressBG1],ebx
mov bl,al
shr ebx,4
and ebx,byte 7
mov edx,[NBATableBG2]
mov [NBABG2],bl
mov ebx,[edx+ebx*4]
mov [SetAddressBG2],ebx
pop ebx
.no_change:
ret
ALIGNC
SNES_W210C: ; BG34NBA
cmp [C_LABEL(BG34NBA)],al
je .no_change
UpdateDisplay ;*
push ebx
mov [C_LABEL(BG34NBA)],al
mov ebx,eax
and ebx,byte 7
shl ebx,12 ; * 8k * 4 (2bpl) / 8
mov [SetAddressBG3],ebx
mov ebx,eax
shr ebx,4
and ebx,byte 7
shl ebx,12 ; * 8k * 4 (2bpl) / 8
mov [SetAddressBG4],ebx
pop ebx
.no_change:
ret
ALIGNC
SNES_W210D: ; BG1HOFS
%ifdef TRAP_BGHOFS
pusha ;*
xor ebx,ebx
mov bl,[C_LABEL(Current_Line_Timing)]
shl ebx,16
or ebx,0x210D
mov [C_LABEL(Map_Address)],ebx ; Set up Map Address so message works!
mov [C_LABEL(Map_Byte)],al ; Set up Map Byte so message works
call C_LABEL(InvalidHWWrite) ; Unmapped hardware address!
popa ;*
%endif
push ebx
mov bl,[BGOFS_Last_Write]
mov bh,al
mov [BGOFS_Last_Write],al
cmp [C_LABEL(BG1HOFS)],bx
je .no_change
UpdateDisplay ;*scroll
mov [C_LABEL(BG1HOFS)],ebx
mov bl,0x40 ; Recalculate H
or [Redo_M7],bl
mov bl,1
.no_change:
pop ebx
ret
ALIGNC
SNES_W210E: ; BG1VOFS
%ifdef TRAP_BGVOFS
pusha ;*
xor ebx,ebx
mov bl,[C_LABEL(Current_Line_Timing)]
shl ebx,16
or ebx,0x210E
mov [C_LABEL(Map_Address)],ebx ; Set up Map Address so message works!
mov [C_LABEL(Map_Byte)],al ; Set up Map Byte so message works
call C_LABEL(InvalidHWWrite) ; Unmapped hardware address!
popa ;*
%endif
push ebx
mov bl,[BGOFS_Last_Write]
mov bh,al
mov [BGOFS_Last_Write],al
cmp [C_LABEL(BG1VOFS)],bx
je .no_change
UpdateDisplay ;*scroll
mov [C_LABEL(BG1VOFS)],ebx
mov bl,0x80 ; Recalculate V
or [Redo_M7],bl
.no_change:
pop ebx
ret
ALIGNC
SNES_W210F: ; BG2HOFS
%ifdef TRAP_BGHOFS
pusha ;*
xor ebx,ebx
mov bl,[C_LABEL(Current_Line_Timing)]
shl ebx,16
or ebx,0x210F
mov [C_LABEL(Map_Address)],ebx ; Set up Map Address so message works!
mov [C_LABEL(Map_Byte)],al ; Set up Map Byte so message works
call C_LABEL(InvalidHWWrite) ; Unmapped hardware address!
popa ;*
%endif
push ebx
mov bl,[BGOFS_Last_Write]
mov bh,al
mov [BGOFS_Last_Write],al
cmp [C_LABEL(BG2HOFS)],bx
je .no_change
UpdateDisplay ;*scroll
mov [C_LABEL(BG2HOFS)],ebx
mov bl,2
.no_change:
pop ebx
ret
ALIGNC
SNES_W2110: ; BG2VOFS
%ifdef TRAP_BGVOFS
pusha ;*
xor ebx,ebx
mov bl,[C_LABEL(Current_Line_Timing)]
shl ebx,16
or ebx,0x2110
mov [C_LABEL(Map_Address)],ebx ; Set up Map Address so message works!
mov [C_LABEL(Map_Byte)],al ; Set up Map Byte so message works
call C_LABEL(InvalidHWWrite) ; Unmapped hardware address!
popa ;*
%endif
push ebx
mov bl,[BGOFS_Last_Write]
mov bh,al
mov [BGOFS_Last_Write],al
cmp [C_LABEL(BG2VOFS)],bx
je .no_change
UpdateDisplay ;*scroll
mov [C_LABEL(BG2VOFS)],ebx
.no_change:
pop ebx
ret
ALIGNC
SNES_W2111: ; BG3HOFS
%ifdef TRAP_BGHOFS
pusha ;*
xor ebx,ebx
mov bl,[C_LABEL(Current_Line_Timing)]
shl ebx,16
or ebx,0x2111
mov [C_LABEL(Map_Address)],ebx ; Set up Map Address so message works!
mov [C_LABEL(Map_Byte)],al ; Set up Map Byte so message works
call C_LABEL(InvalidHWWrite) ; Unmapped hardware address!
popa ;*
%endif
push ebx
mov bl,[BGOFS_Last_Write]
mov bh,al
mov [BGOFS_Last_Write],al
cmp [C_LABEL(BG3HOFS)],bx
je .no_change
UpdateDisplay ;*scroll
mov [C_LABEL(BG3HOFS)],ebx
mov bl,4
mov [Redo_Offset_Change],bl
.no_change:
pop ebx
ret
ALIGNC
SNES_W2112: ; BG3VOFS
%ifdef TRAP_BGVOFS
pusha ;*
xor ebx,ebx
mov bl,[C_LABEL(Current_Line_Timing)]
shl ebx,16
or ebx,0x2112
mov [C_LABEL(Map_Address)],ebx ; Set up Map Address so message works!
mov [C_LABEL(Map_Byte)],al ; Set up Map Byte so message works
call C_LABEL(InvalidHWWrite) ; Unmapped hardware address!
popa ;*
%endif
push ebx
mov bl,[BGOFS_Last_Write]
mov bh,al
mov [BGOFS_Last_Write],al
cmp [C_LABEL(BG3VOFS)],bx
je .no_change
UpdateDisplay ;*scroll
mov [C_LABEL(BG3VOFS)],ebx
mov byte [Redo_Offset_Change_VOffsets],0xFF
mov byte [Redo_Offset_Change],0xFF
.no_change:
pop ebx
ret
ALIGNC
SNES_W2113: ; BG4HOFS
%ifdef TRAP_BGHOFS
pusha ;*
xor ebx,ebx
mov bl,[C_LABEL(Current_Line_Timing)]
shl ebx,16
or ebx,0x2113
mov [C_LABEL(Map_Address)],ebx ; Set up Map Address so message works!
mov [C_LABEL(Map_Byte)],al ; Set up Map Byte so message works
call C_LABEL(InvalidHWWrite) ; Unmapped hardware address!
popa ;*
%endif
push ebx
mov bl,[BGOFS_Last_Write]
mov bh,al
mov [BGOFS_Last_Write],al
cmp [C_LABEL(BG4HOFS)],bx
je .no_change
UpdateDisplay ;*scroll
mov [C_LABEL(BG4HOFS)],ebx
mov bl,8
.no_change:
pop ebx
ret
ALIGNC
SNES_W2114: ; BG4VOFS
%ifdef TRAP_BGVOFS
pusha ;*
xor ebx,ebx
mov bl,[C_LABEL(Current_Line_Timing)]
shl ebx,16
or ebx,0x2114
mov [C_LABEL(Map_Address)],ebx ; Set up Map Address so message works!
mov [C_LABEL(Map_Byte)],al ; Set up Map Byte so message works
call C_LABEL(InvalidHWWrite) ; Unmapped hardware address!
popa ;*
%endif
push ebx
mov bl,[BGOFS_Last_Write]
mov bh,al
mov [BGOFS_Last_Write],al
cmp [C_LABEL(BG4VOFS)],bx
je .no_change
UpdateDisplay ;*scroll
mov [C_LABEL(BG4VOFS)],ebx
.no_change:
pop ebx
ret
ALIGNC
SNES_W2115: ; VMAIN
mov [C_LABEL(VMAIN)],al ; Get our copy of this
and al,0x0C
jz .no_full
cmp al,2*4
je .full_64
ja .full_128
.full_32:
mov dword [VMDATAREAD_update],VMDATAREAD_update_FULL_32
Set_21_Write 0x18,SNES_W2118_FULL_32
Set_21_Write 0x19,SNES_W2119_FULL_32
jmp .full_done
ALIGNC
.full_64:
mov dword [VMDATAREAD_update],VMDATAREAD_update_FULL_64
Set_21_Write 0x18,SNES_W2118_FULL_64
Set_21_Write 0x19,SNES_W2119_FULL_64
jmp .full_done
ALIGNC
.full_128:
mov dword [VMDATAREAD_update],VMDATAREAD_update_FULL_128
Set_21_Write 0x18,SNES_W2118_FULL_128
Set_21_Write 0x19,SNES_W2119_FULL_128
jmp .full_done
ALIGNC
.no_full:
mov dword [VMDATAREAD_update],VMDATAREAD_update_NORM
Set_21_Write 0x18,SNES_W2118_NORM
Set_21_Write 0x19,SNES_W2119_NORM
.full_done:
mov al,[C_LABEL(VMAIN)]
and al,3
jnz .not_1
mov byte [SCINC],1
mov al,[C_LABEL(VMAIN)]
ret
ALIGNC
.not_1:
cmp al,2
jae .not_32
mov byte [SCINC],32
mov al,[C_LABEL(VMAIN)]
ret
ALIGNC
.not_32:
; A bug in SNES makes mode 2 = 128
mov byte [SCINC],128
mov al,[C_LABEL(VMAIN)]
ret
ALIGNC
SNES_W2116: ; VMADDL
mov edx,[VRAMAddress]
mov dl,al
mov [VRAMAddress],al
mov dx,[C_LABEL(VRAM)+edx*2]
mov [VMDATAREAD_buffer],dx
ret
ALIGNC
SNES_W2117: ; VMADDH
mov edx,[VRAMAddress]
mov dh,0x7F
and dh,al
mov [VRAMAddress+1],dh
mov dx,[C_LABEL(VRAM)+edx*2]
mov [VMDATAREAD_buffer],dx
ret
%macro VRAM_Cache_Check 0
; Check upper boundary
; Check within set (?)
%ifdef Set_Based_Tile_Cache
mov ebx,[Tile_Recache_Set_End]
%endif
;shr edx,3
shr edx,5
%ifdef Set_Based_Tile_Cache
sub ebx,edx
je %%end_of_set ; Simplest case - tile is end of set
%ifdef Check_Within_Tile_Set
jg %%check_within_set ; Tile may be within set?
%else
jg %%new_set
%endif
; Tile may be immediately after set?
cmp ebx,-1
%ifdef Check_Within_Tile_Set
jne %%new_set
jmp %%extend_set_one_tile
%%check_within_set:
; Tile may be within set?
cmp [Tile_Recache_Set_Begin],edx
jle %%end_of_set
%else
je %%extend_set_one_tile
%endif
%%new_set:
; New set
push edi
mov edi,[Tile_Recache_Set_End]
inc edi
js %%recache_done ; No set to recache?
sub edi,[Tile_Recache_Set_Begin]
call Recache_Tile_Set
%%recache_done:
pop edi
mov [Tile_Recache_Set_Begin],edx
%%extend_set_one_tile:
mov [Tile_Recache_Set_End],edx
%%end_of_set:
%endif
%endmacro
%macro JUMP_NOT_VBLANK 1+
cmp byte [HVBJOY], 0
js %%in_vblank
cmp byte [C_LABEL(INIDISP)], 0
jns %1
%%in_vblank:
%endmacro
;bitshift (%1), bitmask (1 << (%1)) - 1, topmask 0x7FFF & ~((1 << ((%1) + 3)) - 1)
%macro GEN_SNES_W2118_2119_FULL 2 0
ALIGNC
; VMDATAL, full graphic increment
SNES_W2118_FULL_%2:
push ebx
JUMP_NOT_VBLANK .no_change
mov edx,[VRAMAddress]
push edi
push eax
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,eax
pop eax
or edx,edi
pop edi
mov ebx,C_LABEL(VRAM)
cmp [ebx+edx*2],al
je .no_change
push edx
UpdateDisplay ;*
pop edx
%ifdef Profile_VRAM_Writes
inc dword [C_LABEL(VMWriteL_Full)]
%endif
mov [ebx+edx*2],al
VRAM_Cache_Check
.no_change:
mov bl,[C_LABEL(VMAIN)]
test bl,bl
js .no_increment
mov edx,[SCINC]
add edx,[VRAMAddress] ; Always words (since <<1)!
and edx,0x7FFF
mov [VRAMAddress],edx
.no_increment:
pop ebx
ret
ALIGNC
; VMDATAH, full graphic increment
SNES_W2119_FULL_%2:
push ebx
JUMP_NOT_VBLANK .no_change
mov edx,[VRAMAddress]
push edi
push eax
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,eax
pop eax
or edx,edi
pop edi
mov ebx,C_LABEL(VRAM)+1
cmp [ebx+edx*2],al
je .no_change
push edx
UpdateDisplay ;*
pop edx
%ifdef Profile_VRAM_Writes
inc dword [C_LABEL(VMWriteH_Full)]
%endif
mov [ebx+edx*2],al
VRAM_Cache_Check
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -