⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ppu.asm

📁 NES game Emulator in Linux.c and asm codes.
💻 ASM
📖 第 1 页 / 共 4 页
字号:
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 + -