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

📄 ppu.asm

📁 NES game Emulator in Linux.c and asm codes.
💻 ASM
📖 第 1 页 / 共 4 页
字号:
.no_change:
 mov bl,[C_LABEL(VMAIN)]
 test bl,bl
 jns .no_increment
 mov edx,[SCINC]
 add edx,[VRAMAddress]  ; Always words (since <<1)!
 and edx,0x7FFF
 mov [VRAMAddress],edx
.no_increment:
 pop ebx
 ret
%endmacro

ALIGNC
; VMDATAL, normal increment
SNES_W2118_NORM:
 push ebx

 JUMP_NOT_VBLANK .no_change

 mov ebx,C_LABEL(VRAM)
 mov edx,[VRAMAddress]
 cmp [ebx+edx*2],al
 je .no_change
 push edx
 UpdateDisplay  ;*
 pop edx
%ifdef Profile_VRAM_Writes
 inc dword [C_LABEL(VMWriteL_Norm)]
%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, normal increment
SNES_W2119_NORM:
 push ebx

 JUMP_NOT_VBLANK .no_change

 mov ebx,C_LABEL(VRAM)+1
 mov edx,[VRAMAddress]
 cmp [ebx+edx*2],al
 je .no_change
 push edx
 UpdateDisplay  ;*
 pop edx
%ifdef Profile_VRAM_Writes
 inc [C_LABEL(VMWriteH_Norm)]
%endif
 mov [ebx+edx*2],al
 VRAM_Cache_Check
.no_change:
 mov bl,[C_LABEL(VMAIN)]
 test bl,bl
 jns .no_increment
 mov edx,[SCINC]
 add edx,[VRAMAddress]  ; Always words (since <<1)!
 and edx,0x7FFF
 mov [VRAMAddress],edx
.no_increment:
 pop ebx
 ret

GEN_SNES_W2118_2119_FULL 5,32
GEN_SNES_W2118_2119_FULL 6,64
GEN_SNES_W2118_2119_FULL 7,128

; SNES_W211A: ; M7SEL in mode7.asm
; SNES_W211B: ; M7A in mode7.asm
; SNES_W211C: ; M7B in mode7.asm
; SNES_W211D: ; M7C in mode7.asm
; SNES_W211E: ; M7D in mode7.asm
; SNES_W211F: ; M7X in mode7.asm
; SNES_W2120: ; M7Y in mode7.asm

ALIGNC
SNES_W2121: ; CGADD
 push ebx
 xor ebx,ebx
 mov [CGAddress],al
 mov [CGHigh],bl
 mov [CGReadHigh],bl
 pop ebx
 ret

ALIGNC
SNES_W2122: ; CGDATA
 ; Palette should be set even if just lo byte set!
 ; We now set the palette in CGRAM

;UpdateDisplay  ;*16-bit rendering only
;push edx
 push ebx
 push eax
 xor ebx,ebx
 mov bl,[CGHigh]
 mov edx,[CGAddress]
 test ebx,ebx
 jnz .hi_byte

 cmp al,[C_LABEL(Real_SNES_Palette)+ebx+edx*2]
 jz .no_change
 mov byte [C_LABEL(PaletteChanged)],1
 mov [C_LABEL(Real_SNES_Palette)+ebx+edx*2],al
.no_change:
 mov bl,1
 pop eax
 mov [CGHigh],bl
 pop ebx
;pop edx
 ret

.hi_byte:
 and al,0x7F
 cmp al,[C_LABEL(Real_SNES_Palette)+ebx+edx*2]
 jz .no_change_hi
 mov byte [C_LABEL(PaletteChanged)],1
 mov [C_LABEL(Real_SNES_Palette)+ebx+edx*2],al

.no_change_hi:
 inc edx
 mov bl,0
 pop eax
 mov [CGHigh],bl
 pop ebx
 mov [CGAddress],dl ; Chop address for wrap
;pop edx
 ret

ALIGNC
SNES_W2123: ; W12SEL
 cmp al,[C_LABEL(W12SEL)]
 je .no_change
 UpdateDisplay  ;*windowing only
 or byte [Redo_Windowing],Redo_Win_BG(1) | Redo_Win_BG(2)
 mov [C_LABEL(W12SEL)],al
 mov [WSELBG1],al
 shr al,4
 mov [WSELBG2],al
 mov al,[C_LABEL(W12SEL)]

.no_change:
 ret

ALIGNC
SNES_W2124: ; W34SEL
 cmp al,[C_LABEL(W34SEL)]
 je .no_change
 UpdateDisplay  ;*windowing only
 or byte [Redo_Windowing],Redo_Win_BG(3) | Redo_Win_BG(4)
 mov [C_LABEL(W34SEL)],al
 mov [WSELBG3],al
 shr al,4
 mov [WSELBG4],al
 mov al,[C_LABEL(W34SEL)]

.no_change:
 ret

ALIGNC
SNES_W2125: ; WOBJSEL
 cmp al,[C_LABEL(WOBJSEL)]
 je .no_change
 UpdateDisplay  ;*windowing only
 or byte [Redo_Windowing],Redo_Win_OBJ | Redo_Win_Color
 mov [C_LABEL(WOBJSEL)],al

.no_change:
 ret

ALIGNC
SNES_W2126: ; WH0
 cmp al,[C_LABEL(WH0)]
 je .no_change
 UpdateDisplay  ;*windowing only
 or byte [Redo_Windowing],Redo_Win(1) | \
  Redo_Win_BG(1) | Redo_Win_BG(2) | Redo_Win_BG(3) | Redo_Win_BG(4) | \
  Redo_Win_OBJ | Redo_Win_Color
 mov [C_LABEL(WH0)],al

.no_change:
 ret

ALIGNC
SNES_W2127: ; WH1
 inc eax
 cmp al,[C_LABEL(WH1)]
 je .no_change
 UpdateDisplay  ;*windowing only
 or byte [Redo_Windowing],Redo_Win(1) | \
  Redo_Win_BG(1) | Redo_Win_BG(2) | Redo_Win_BG(3) | Redo_Win_BG(4) | \
  Redo_Win_OBJ | Redo_Win_Color
 mov [C_LABEL(WH1)],al

.no_change:
 dec eax
 ret

ALIGNC
SNES_W2128: ; WH2
 cmp al,[C_LABEL(WH2)]
 je .no_change
 UpdateDisplay  ;*windowing only
 or byte [Redo_Windowing],Redo_Win(2) | \
  Redo_Win_BG(1) | Redo_Win_BG(2) | Redo_Win_BG(3) | Redo_Win_BG(4) | \
  Redo_Win_OBJ | Redo_Win_Color
 mov [C_LABEL(WH2)],al

.no_change:
 ret

ALIGNC
SNES_W2129: ; WH3
 inc eax
 cmp al,[C_LABEL(WH3)]
 je .no_change
 UpdateDisplay  ;*windowing only
 or byte [Redo_Windowing],Redo_Win(2) | \
  Redo_Win_BG(1) | Redo_Win_BG(2) | Redo_Win_BG(3) | Redo_Win_BG(4) | \
  Redo_Win_OBJ | Redo_Win_Color
 mov [C_LABEL(WH3)],al

.no_change:
 dec eax
 ret

ALIGNC
SNES_W212A: ; WBGLOG
 cmp al,[C_LABEL(WBGLOG)]
 je .no_change
 UpdateDisplay  ;*windowing only
 or byte [Redo_Windowing], \
  Redo_Win_BG(1) | Redo_Win_BG(2) | Redo_Win_BG(3) | Redo_Win_BG(4)
 push ebx
 mov ebx,eax
 mov [C_LABEL(WBGLOG)],al
 shr bl,2
 mov [WLOGBG1],al
 shr al,4
 mov [WLOGBG2],bl
 shr bl,4
 mov [WLOGBG3],al
 mov [WLOGBG4],bl
 pop ebx
 mov al,[C_LABEL(WBGLOG)]

.no_change:
 ret

ALIGNC
SNES_W212B: ; WOBJLOG
 cmp al,[C_LABEL(WOBJLOG)]
 je .no_change
;UpdateDisplay  ;*windowing only
;or byte [Redo_Windowing],Redo_Win_OBJ | Redo_Win_Color
 mov [C_LABEL(WOBJLOG)],al

.no_change:
 ret

ALIGNC
EXPORT_C Update_Layering
 pusha

 mov byte [Redo_Layering],0

 or byte [Redo_Windowing], \
  Redo_Win_BG(1) | Redo_Win_BG(2) | Redo_Win_BG(3) | Redo_Win_BG(4) | \
  Redo_Win_OBJ

 mov al,[C_LABEL(TM)]
 mov bl,[C_LABEL(TS)]
 mov cl,[BGMODE_Allowed_Layer_Mask]
 mov dl,[C_LABEL(Layer_Disable_Mask)]
 and al,cl
 and bl,cl
 and al,dl
 and bl,dl
 mov [TM_Allowed],al
 mov [TS_Allowed],bl
 or al,bl
 mov [Layers_In_Use],al

 cmp byte [C_LABEL(Layering_Mode)],1
 je .Update_Layering_1
 ja .Update_Layering_2
.Update_Layering_0:
 mov dword [Render_Select],C_LABEL(Render_Layering_Option_0)
 mov dword [Window_Offset_First],BG_Win_Sub
 mov dword [Window_Offset_Second],BG_Win_Main

 ; layering option 0: main-on-sub
 mov al,[TM_Allowed]
 mov bl,[C_LABEL(TMW)]
 mov [SCR_TM],al
 mov [SCR_TMW],bl
 xor al,0xFF
 mov bl,[C_LABEL(TSW)]
 and al,[TS_Allowed]
 mov [SCR_TSW],bl
 mov [SCR_TS],al
 popa
 ret
ALIGNC
.Update_Layering_1:
 mov dword [Render_Select],C_LABEL(Render_Layering_Option_1)
 mov dword [Window_Offset_First],BG_Win_Main
 mov dword [Window_Offset_Second],BG_Win_Sub

 ; layering option 1: sub-on-main
 mov al,[TS_Allowed]
 mov bl,[C_LABEL(TSW)]
 mov [SCR_TS],al
 mov [SCR_TSW],bl
 xor al,0xFF
 mov bl,[C_LABEL(TMW)]
 and al,[TM_Allowed]
 mov [SCR_TMW],bl
 mov [SCR_TM],al
 popa
 ret
ALIGNC
.Update_Layering_2:
 mov dword [Render_Select],C_LABEL(Render_Layering_Option_2)
 mov dword [Window_Offset_First],BG_Win_Main
 mov dword [Window_Offset_Second],BG_Win_Sub

 ; layering option 2: main-with-sub
 mov al,[TM_Allowed]
 mov bl,[C_LABEL(TMW)]
 mov dl,[TS_Allowed]
 mov cl,[C_LABEL(TSW)]
 and bl,al
 and cl,dl
 or al,dl
 or bl,cl
 mov byte [SCR_TS],0
 mov [SCR_TM],al
 mov [SCR_TMW],bl
 popa
 ret

ALIGNC
SNES_W212C: ; TM
 cmp al,[C_LABEL(TM)]
 je .no_change
 UpdateDisplay  ;*
 mov [C_LABEL(TM)],al
 mov byte [Redo_Layering],-1
 or byte [Redo_Windowing], \
  Redo_Win_BG(1) | Redo_Win_BG(2) | Redo_Win_BG(3) | Redo_Win_BG(4) | \
  Redo_Win_OBJ
 mov al,[C_LABEL(TM)]

.no_change:
 ret

ALIGNC
SNES_W212D: ; TS
 cmp al,[C_LABEL(TS)]
 je .no_change
 UpdateDisplay  ;*
 mov [C_LABEL(TS)],al
 mov byte [Redo_Layering],-1
 or byte [Redo_Windowing], \
  Redo_Win_BG(1) | Redo_Win_BG(2) | Redo_Win_BG(3) | Redo_Win_BG(4) | \
  Redo_Win_OBJ
 mov al,[C_LABEL(TS)]

.no_change:
 ret

ALIGNC
SNES_W212E: ; TMW
 cmp al,[C_LABEL(TMW)]
 je .no_change
 UpdateDisplay  ;*windowing only
 mov [C_LABEL(TMW)],al
 mov byte [Redo_Layering],-1
 or byte [Redo_Windowing], \
  Redo_Win_BG(1) | Redo_Win_BG(2) | Redo_Win_BG(3) | Redo_Win_BG(4) | \
  Redo_Win_OBJ
 mov al,[C_LABEL(TMW)]

.no_change:
 ret

ALIGNC
SNES_W212F: ; TSW
 cmp al,[C_LABEL(TSW)]
 je .no_change
 UpdateDisplay  ;*windowing only
 mov [C_LABEL(TSW)],al
 mov byte [Redo_Layering],-1
 or byte [Redo_Windowing], \
  Redo_Win_BG(1) | Redo_Win_BG(2) | Redo_Win_BG(3) | Redo_Win_BG(4) | \
  Redo_Win_OBJ
 mov al,[C_LABEL(TSW)]

.no_change:
 ret

ALIGNC
SNES_W2130: ; CGWSEL
 cmp al,[C_LABEL(CGWSEL)]
 je .no_change
;UpdateDisplay  ;*windowing only
 or byte [Redo_Windowing],Redo_Win_Color
 mov [C_LABEL(CGWSEL)],al

.no_change:
 ret

ALIGNC
SNES_W2131: ; CGADSUB
 cmp al,[C_LABEL(CGADSUB)]
 je .no_change
;UpdateDisplay  ;*16-bit rendering only
 push eax
 mov [C_LABEL(CGADSUB)],al

 test al,0xA0   ; Hack for back area color addition
 mov ah,0
 jz .no_add_hack
 js .no_add_hack
 mov ah,-1
.no_add_hack:
 mov [C_LABEL(fixedpalettecheck)],ah
 pop eax
.no_change:
 ret

ALIGNC
SNES_W2132: ; COLDATA
;UpdateDisplay  ;*16-bit rendering only
 push ebx
 mov edx,[C_LABEL(COLDATA)]

 test al,0xC0
 jns .no_blue

 mov bl,al
 and ebx,0x1F
 shl ebx,10

 and edx,0x3FF
 or edx,ebx

 test al,0x40
.no_blue:
 jz .no_green

 mov bl,al
 and ebx,0x1F
 shl ebx,5

 and edx,0x7C1F
 or edx,ebx

.no_green:
 test al,0x20
 jz .no_red

 mov bl,al
 and ebx,0x1F

 and edx,0x7FE0
 or edx,ebx

.no_red:
 mov [C_LABEL(COLDATA)],edx
 pop ebx

 ret

ALIGNC
SNES_W2133: ; SETINI
 cmp al,[C_LABEL(SETINI)]
 je .no_change
 UpdateDisplay  ;*interlaced etc. not yet supported
 xor edx,edx
 test al,4
 mov [C_LABEL(SETINI)],al
 mov dl,239
 jnz .tall_screen
 mov dl,224
.tall_screen:
 ; if SETINI:6 (EXTBG enable) is clear, ignore BG2 enable (EXTBG)
 ; we pregenerate a mask for this here
 shr al,7
 mov [C_LABEL(LastRenderLine)],edx

 sbb dl,dl
 mov al,[BGMODE_Tile_Layer_Mask]
 or dl,~2
 and al,0x0F
 mov [C_LABEL(EXTBG_Mask)],dl
 jnz .not_mode7
 mov al,[BGMODE_Allowed_Layer_Mask_Table+7]
 and dl,al
 mov [BGMODE_Allowed_Layer_Mask],dl
.not_mode7:

 mov al,[C_LABEL(SETINI)]
.no_change:
 ret

; SNES_W2140_SKIP: ; APUI00 in APUskip.asm
; SNES_W2141_SKIP: ; APUI01 in APUskip.asm
; SNES_W2142_SKIP: ; APUI02 in APUskip.asm
; SNES_W2143_SKIP: ; APUI03 in APUskip.asm

; SNES_W2140_SPC:  ; APUI00 in spc700.asm
; SNES_W2141_SPC:  ; APUI01 in spc700.asm
; SNES_W2142_SPC:  ; APUI02 in spc700.asm
; SNES_W2143_SPC:  ; APUI03 in spc700.asm

ALIGNC
SNES_W2180: ; WMDATA
 mov edx,[WMADDL]
 add R_65c816_Cycles,_5A22_SLOW_CYCLE - _5A22_FAST_CYCLE
 mov [C_LABEL(WRAM)+edx],al
 inc edx
 and edx,0x01FFFF
 mov [WMADDL],edx
 ret

ALIGNC
SNES_W2181: ; WMADDL
 mov [WMADDL],al
 ret

ALIGNC
SNES_W2182: ; WMADDM
 mov [WMADDM],al
 ret

ALIGNC
SNES_W2183: ; WMADDH
 push eax
 and al,1
 mov [WMADDH],al
 pop eax
 ret

; Write to 40xx handlers
; SNES_W4016: ; JOYC1 in timing.inc
; SNES_W4017: ; JOYC2 in timing.inc

; Write to 42xx handlers
; SNES_W4200: ; NMITIMEN in timing.inc
; SNES_W4201: ; WRIO in timing.inc
; SNES_W4202: ; WRMPYA in timing.inc
; SNES_W4203: ; WRMPYB in timing.inc
; SNES_W4204: ; WRDIVL in timing.inc
; SNES_W4205: ; WRDIVH in timing.inc
; SNES_W4206: ; WRDIVB in timing.inc
; SNES_W4207: ; HTIMEL in timing.inc
; SNES_W4208: ; HTIMEH in timing.inc
; SNES_W4209: ; VTIMEL in timing.inc
; SNES_W420A: ; VTIMEH in timing.inc
; SNES_W420B: ; MDMAEN in DMA.asm
; SNES_W420C: ; HDMAEN in DMA.asm
; SNES_W420D: ; MEMSEL in timing.inc
; SNES_W4210: ; RDNMI in timing.inc
; SNES_W4211: ; TIMEUP in timing.inc

; Write to 43xx handlers
; SNES_W43xx: ; in DMA.asm

section .text
ALIGNC
section .data
ALIGND
section .bss
ALIGNB

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -