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

📄 bg16oe.asm

📁 NES game Emulator in Linux.c and asm codes.
💻 ASM
📖 第 1 页 / 共 2 页
字号:
 jmp C_LABEL(Render_16x%2_Even_C%1)
%endif  ; NO_OFFSET_CHANGE

%ifdef OFFSET_CHANGE_ELIMINATION
 ;mode 6: 4-plane tiles, split offset table
 mov cl,[OffsetChangeDetect3]
 test cl,[OC_Flag+edx]
 jz C_LABEL(Render_16x%2_Even_C%1)
%endif

 cmp byte [Mosaic+edx],0
 jnz C_LABEL(Render_Offset_16x%2M_Even_C%1)

%ifndef NO_NP_RENDER
 mov ecx,C_LABEL(Plot_Lines_NP_Offset_16x%2_Even_Table_C%1)
 test al,al
 jnz .have_plotter
%endif

 mov ecx,C_LABEL(Plot_Lines_V_Offset_16x%2_Even_Table_C%1)
.have_plotter:

 push ecx
 push esi
 push edx ;BG_Table
 push ebx ;Current_Line
 push edi ;BaseDestPtr
 push ebp ;Lines
 sub esp,byte RO16E_Local_Bytes-24

 ; ch contains bit for determining planes to affect
 mov ch,[OC_Flag+edx]
 mov eax,[SetAddress+edx]
 mov [RO16E_OC_Flag],ch
 mov [TilesetAddress],eax

.next_line:
 mov edx,[RO16E_BG_Table]

 mov eax,[RO16E_Current_Line]
 call Sort_Screen_Height

 mov eax,[RO16E_Current_Line]
 SORT_TILES_%2_TALL [RO16E_MapAddress_Current]

 ; Corrupts eax,ecx,ebp
 mov eax,[TLMapAddress+edx]
 mov ecx,[RO16E_Current_Line]
 mov edi,[BLMapAddress+edx]
 mov ebp,[VScroll+edx]
 mov [RO16E_TMapAddress],eax
 add ecx,ebp
 mov [RO16E_BMapAddress],edi
 mov ebp,[RO16E_MapAddress_Current]

 and ch,(%2) / 8
;global Tile_Height
;Tile_Height equ $-1    ; 1 = 8x8, 16x8, 2 = 16x16
 jz .current_line_in_screen_map_top
 mov eax,edi
.current_line_in_screen_map_top:
 add eax,ebp

 mov ebp,[HScroll+edx]
 mov [RO16E_MapAddress_Current],eax
 shr ebp,3
 mov eax,[TRMapAddress+edx]
 add ebp,ebp
 mov ecx,[TLMapAddress+edx]
 mov [RO16E_FirstTile],ebp  ;FirstTile = (HScroll / 8) * 2

 sub eax,ecx
 mov [RO16E_RMapDifference],eax

 mov eax,[C_LABEL(SNES_Screen8)]
 mov edi,[RO16E_BaseDestPtr]
 add edi,eax

 mov esi,[RO16E_Clipped]
 mov al,[Win_Count+edx+esi]

 test al,al
 jz .done

 mov ebx,[OffsetChangeMap_VOffset]
 mov [RO16E_Runs_Left],eax
 lea edx,[Win_Bands+edx+esi]

 mov [RO16E_Output],edi
 mov [RO16E_RunListPtr],edx
 mov [RO16ER_VMapOffset],ebx    ;vertical screen map address
 xor ebx,ebx
 mov bl,[edx]

 xor ecx,ecx
 mov cl,[edx+1]
 mov edx,[RO16E_BG_Table]
 sub cl,bl
 setz ch

 mov [RO16ER_Next_Pixel],ebx
 mov [RO16ER_Pixel_Count],ecx

 dec al
 je .last_run

.not_last_run:
 mov [RO16E_Runs_Left],al
 call Render_Offset_16_Even_Run

 mov edx,[RO16E_RunListPtr]
 mov edi,[RO16E_Output]
 xor ebx,ebx
 xor ecx,ecx
 mov bl,[edx+2]

 mov cl,[edx+3]
 add edx,byte 2
 sub cl,bl
 mov [RO16E_RunListPtr],edx
 mov edx,[RO16E_BG_Table]

 mov [RO16ER_Next_Pixel],ebx
 mov [RO16ER_Pixel_Count],ecx

 mov al,[RO16E_Runs_Left]
 dec al
 jne .not_last_run
.last_run:
 call Render_Offset_16_Even_Run

.done:

%ifndef LAYERS_PER_LINE
 mov edi,[RO16E_BaseDestPtr]
 inc dword [RO16E_Current_Line]
 add edi,GfxBufferLinePitch
 dec dword [RO16E_Lines]
 mov [RO16E_BaseDestPtr],edi ; Point screen to next line
 jnz .next_line
%endif

 mov edx,[RO16E_BG_Table]
 mov al,[Tile_Priority_Used]
 mov [Priority_Used+edx],al
 mov ah,[Tile_Priority_Unused]
 mov [Priority_Unused+edx],ah

 add esp,byte RO16E_Local_Bytes
 ret
%endmacro

Render_Offset_16_Even 4,8
Render_Offset_16_Even 4,16

;%1 = label, %2 = priority - 0 = none, 1 = low, 2 = high, %3 = tile height
%macro Plot_Lines_Offset_16_Even_C4 3
%if %2 > 0
%%return:
 ret

ALIGNC
%1_check:
 pop ebx
 pop esi

%if %2 == 1 || %2 == 3
 mov [Tile_Priority_Unused],cl
%endif
 add edi,byte 8
 dec cl
 jz %%return
%else
ALIGNC
%endif

EXPORT_C %1     ; Define label, entry point
.next_tile:
 lea eax,[esi+2]
 mov dh,[1+esi]     ; Horizontal offset change map
 push eax

 mov ebp,[RO16E_FirstTile+RO16E_Inner+4]
 mov eax,[OffsetChangeVMap_VOffset]
 test dh,ch         ; H-offset enabled?
 jz .have_h_offset
 mov dl,[esi]
 mov ebp,edx
 shr ebp,3
 add ebp,ebp
.have_h_offset:

 mov dh,[1+esi+eax] ; Vertical offset change map
 test dh,ch         ; V-offset enabled?
 jz .No_VChange
 mov dl,[esi+eax]
 mov eax,[RO16E_Current_Line+RO16E_Inner+4]
 add eax,edx

.calc_v_offset:
 and ah,(%3) / 8
 mov esi,[RO16E_TMapAddress+RO16E_Inner+4]
 jz .line_in_screen_map_top
 mov esi,[RO16E_BMapAddress+RO16E_Inner+4]
.line_in_screen_map_top:

 ; al contains real Y offset for next tile
 push ecx
%if %3 == 8
 mov ecx,0xF8
 mov edx,7
 and ecx,eax
 and eax,byte 7
 sub edx,eax
 lea esi,[esi+ecx*8]    ; Get screen offset
%else
 shl eax,2          ; Get screen offset
 mov ecx,0x1F0*4    ; Current line + V scroll * 32words
 and ecx,eax
 and eax,byte 0x0F*4    ; Offset into table of line offsets
 mov edx,16*8+7
 mov eax,[Tile_Offset_Table_16_8+eax]
 sub edx,eax
 add esi,ecx
%endif
 pop ecx
 jmp .have_v_offset

.LeftEdge:
 push esi

 mov ebp,[RO16E_FirstTile+RO16E_Inner+4]

.No_VChange:
 mov eax,[LineAddress]
 mov esi,[RO16E_MapAddress_Current+RO16E_Inner+4]
 mov edx,[LineAddressY]

.have_v_offset:
 add ebp,ebx
 add ebx,byte 2     ; Update X offset
 mov [RO16E_LineAddressOffset+RO16E_Inner+4],eax
 push ebx
 mov ebx,ebp
 and ebp,byte 31*2  ; X offset wrap
 mov [RO16E_LineAddressOffsetY+RO16E_Inner+8],edx
 add esi,ebp        ; Combine X and Y offsets into tile map
 and ebx,byte 32*2
 mov ebx,[RO16E_RMapDifference+RO16E_Inner+8]
 jz  .tile_in_screen_map_left
 add esi,ebx
.tile_in_screen_map_left:

 mov al,[esi+1]
 Check_Tile_Priority %2, %1_check

 mov ebp,[RO16E_LineAddressOffsetY+RO16E_Inner+8]
 test al,al         ; Check Y flip
 mov si,[esi]       ; Get tile #
 js .flip_y
 mov ebp,[RO16E_LineAddressOffset+RO16E_Inner+8]

.flip_y:
 shl esi,3
 mov edx,eax
 add esi,ebp
 and edx,byte 7*4   ; Get palette

 push esi
 mov ebp,[palette_4bpl+edx]
 mov edx,[TilesetAddress]

 add al,al      ; Get X flip (now in MSB)
 js .xflip

 and esi,0x3FF * 8 + 7  ; Clip to tileset
 add esi,edx
 and esi,0xFFFF * 2 / 8 ; Clip to VRAM

 Plot_4_Even_Paletted_Lines_Clip_noflip 0,C_LABEL(TileCache4)+esi*8,0,TileClip1Left

 pop esi
 add esi,byte 8
 mov edx,[TilesetAddress]
 and esi,0x3FF * 8 + 7  ; Clip to tileset
 add esi,edx
 and esi,0xFFFF * 2 / 8 ; Clip to VRAM
 Plot_4_Even_Paletted_Lines_Clip_noflip 0,C_LABEL(TileCache4)+esi*8,4,TileClip1Right

 pop ebx
 pop esi

 add edi,byte 8
%if %2 == 1 || %2 == 3
 mov [Tile_Priority_Used],cl
%endif
 dec cl
 jnz .next_tile

 ret

ALIGNC
.xflip:
 add esi,byte 8

 and esi,0x3FF * 8 + 7  ; Clip to tileset
 add esi,edx
 and esi,0xFFFF * 2 / 8 ; Clip to VRAM

 Plot_4_Even_Paletted_Lines_Clip_Xflip 0,C_LABEL(TileCache4)+esi*8,0,TileClip1Left

 pop esi
 mov edx,[TilesetAddress]
 and esi,0x3FF * 8 + 7  ; Clip to tileset
 add esi,edx
 and esi,0xFFFF * 2 / 8 ; Clip to VRAM
 Plot_4_Even_Paletted_Lines_Clip_Xflip 0,C_LABEL(TileCache4)+esi*8,4,TileClip1Right

 pop ebx
 pop esi

 add edi,byte 8
%if %2 == 1 || %2 == 3
 mov [Tile_Priority_Used],cl
%endif
 dec cl
 jnz .next_tile

 ret
%endmacro

;%1 = depth, %2 = tile height
%macro Generate_Line_Plotters_Offset_16_Even 2
%ifndef NO_NP_RENDER
 Plot_Lines_Offset_16_Even_C%1 Plot_Lines_NP_Offset_16x%2_Even_C%1,0,%2
%endif
 Plot_Lines_Offset_16_Even_C%1 Plot_Lines_V_Offset_16x%2_Even_C%1,3,%2
%endmacro

Generate_Line_Plotters_Offset_16_Even 4,8
Generate_Line_Plotters_Offset_16_Even 4,16

section .data
%macro Generate_Line_Plotter_Table_Offset_16_Even 3
EXPORT_C Plot_Lines_%1_Offset_16x%3_Even_Table_C%2
dd C_LABEL(Plot_Lines_%1_Offset_16x%3_Even_C%2).LeftEdge
dd C_LABEL(Plot_Lines_%1_Offset_16x%3_Even_C%2)
%endmacro

%ifndef NO_NP_RENDER
Generate_Line_Plotter_Table_Offset_16_Even NP,4,8
Generate_Line_Plotter_Table_Offset_16_Even NP,4,16
%endif

Generate_Line_Plotter_Table_Offset_16_Even V,4,8
Generate_Line_Plotter_Table_Offset_16_Even V,4,16

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

⌨️ 快捷键说明

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