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

📄 ppu.asm

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