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

📄 bg16o.asm

📁 NES game Emulator in Linux.c and asm codes.
💻 ASM
📖 第 1 页 / 共 2 页
字号:
 mov [RO16x16_BaseDestPtr],edi ; Point screen to next line
 jnz .next_line
%endif

 mov edx,[RO16x16_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 RO16x16_Local_Bytes
 ret

;%define RO16x16_Inner 4

;%1 = label, %2 = priority - 0 = none, 1 = low, 2 = high
%macro Plot_Lines_Offset_16x16_C4 2
%if %2 > 0
%%return:
 ret

ALIGNC
%1_check:
 pop ebx
 pop esi
 pop ecx

%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]
 push ecx
 mov dh,[1+esi]     ; Horizontal offset change map
 push eax

 mov ebp,[RO16x16_FirstTile+RO16x16_Inner+8]
 mov eax,[OffsetChangeVMap_VOffset]
 test dh,ch         ; H-offset enabled?
 jz .have_h_offset
 mov dl,[esi]
 mov ebp,edx
 shr ebp,3
.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,[RO16x16_Current_Line+RO16x16_Inner+8]
 add eax,edx

.calc_v_offset:
 and ah,2
 mov esi,[RO16x16_TMapAddress+RO16x16_Inner+8]
 jz .line_in_screen_map_top
 mov esi,[RO16x16_BMapAddress+RO16x16_Inner+8]
.line_in_screen_map_top:

 ; al contains real Y offset for next tile
 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
 jmp .have_v_offset

.LeftEdge:
 push ecx
 push esi

 mov ebp,[RO16x16_FirstTile+RO16x16_Inner+8]

.No_VChange:
 mov eax,[LineAddress]
 mov esi,[RO16x16_MapAddress_Current+RO16x16_Inner+8]
 mov edx,[LineAddressY]

.have_v_offset:
 add ebp,ebx
 inc ebx            ; Update X offset
 mov [RO16x16_LineAddressOffset+RO16x16_Inner+8],eax
 push ebx
 mov ebx,ebp
 and ebp,byte 63    ; X offset wrap
 and ebx,byte 64
 mov [RO16x16_LineAddressOffsetY+RO16x16_Inner+12],edx
 mov ebx,[RO16x16_RMapDifference+RO16x16_Inner+12]
 jz  .tile_in_screen_map_left
 add esi,ebx
.tile_in_screen_map_left:
 mov ebx,ebp
 and ebp,byte ~1

 mov al,[esi+ebp+1] ; Combine X and Y offsets into tile map
 Check_Tile_Priority %2, %1_check

 mov si,[esi+ebp]   ; Get tile #
 mov ebp,[RO16x16_LineAddressOffsetY+RO16x16_Inner+12]
 test al,al         ; Check Y flip
 js .flip_y
 mov ebp,[RO16x16_LineAddressOffset+RO16x16_Inner+12]

.flip_y:
 shl esi,3
 mov edx,eax
 add esi,ebp
 and edx,byte 7*4   ; Get palette
 and ebx,byte 1
 add al,al      ; Get X flip (now in MSB)
 mov ebp,[palette_4bpl+edx]
 mov edx,[TilesetAddress]
 js .xflip

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

 Plot_8_Paletted_Lines_noflip 0,C_LABEL(TileCache4)+esi*8,0

 pop ebx
 pop esi
 pop ecx

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

 ret

ALIGNC
.xflip:
 shl ebx,3
 add esi,byte 8
 sub esi,ebx
 and esi,0x3FF * 8 + 7  ; Clip to tileset
 add esi,edx
 and esi,0xFFFF * 2 / 8 ; Clip to VRAM

 Plot_8_Paletted_Lines_Xflip 0,C_LABEL(TileCache4)+esi*8,0

 pop ebx
 pop esi
 pop ecx

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

 ret
%endmacro

;%1 = label, %2 = priority - 0 = none, 1 = low, 2 = high
%macro Plot_Lines_Offset_16x16_C2 2
%if %2 > 0
%%return:
 ret

ALIGNC
%1_check:
 pop ebx
 pop esi
 pop ecx

%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:
 mov eax,esi
 push ecx
 add eax,byte 2
 mov dh,[1+esi]     ; Offset change map
 push eax

 mov ebp,[RO16x16_FirstTile+RO16x16_Inner+8]
 mov eax,[RO16x16_Current_Line+RO16x16_Inner+8]
 test dh,ch         ; Offset enabled?
 jz .No_VChange

 test dh,dh         ; vertical offset?
 jnz .calc_v_offset

 mov dl,[esi]
 mov ebp,edx
 shr ebp,3
 jmp .No_VChange

.calc_v_offset:
 mov dl,[esi]
 add eax,edx

 and ah,2
 mov esi,[RO16x16_TMapAddress+RO16x16_Inner+8]
 jz  .line_in_screen_map_top
 mov esi,[RO16x16_BMapAddress+RO16x16_Inner+8]
.line_in_screen_map_top:

 ; al contains real Y offset for next tile
 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
 jmp .have_v_offset

.LeftEdge:
 push ecx
 push esi

 mov ebp,[RO16x16_FirstTile+RO16x16_Inner+8]

.No_VChange:
 mov eax,[LineAddress]
 mov esi,[RO16x16_MapAddress_Current+RO16x16_Inner+8]
 mov edx,[LineAddressY]

.have_v_offset:
 add ebp,ebx
 inc ebx            ; Update X offset
 mov [RO16x16_LineAddressOffset+RO16x16_Inner+8],eax
 push ebx
 mov ebx,ebp
 and ebp,byte 63    ; X offset wrap
 and ebx,byte 64
 mov [RO16x16_LineAddressOffsetY+RO16x16_Inner+12],edx
 mov ebx,[RO16x16_RMapDifference+RO16x16_Inner+12]
 jz  .tile_in_screen_map_left
 add esi,ebx
.tile_in_screen_map_left:
 mov ebx,ebp
 and ebp,byte ~1

 mov al,[esi+ebp+1] ; Combine X and Y offsets into tile map
 Check_Tile_Priority %2, %1_check

 mov si,[esi+ebp]   ; Get tile #
 mov ebp,[RO16x16_LineAddressOffsetY+RO16x16_Inner+12]
 test al,al         ; Check Y flip
 js .flip_y
 mov ebp,[RO16x16_LineAddressOffset+RO16x16_Inner+12]

.flip_y:
 shl esi,3
 mov edx,eax
 add esi,ebp
 and edx,byte 7*4   ; Get palette
 and ebx,byte 1
 add al,al      ; Get X flip (now in MSB)
 mov ebp,[palette_2bpl+edx]
 mov edx,[TilesetAddress]
 js .xflip

 lea esi,[esi+ebx*8]
 and esi,0x3FF * 8 + 7  ; Clip to tileset
 add esi,edx
 and esi,0xFFFF * 4 / 8 ; Clip to VRAM

 Plot_8_Paletted_Lines_noflip 0,C_LABEL(TileCache2)+esi*8,0

 pop ebx
 pop esi
 pop ecx

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

 ret

ALIGNC
.xflip:
 shl ebx,3
 add esi,byte 8
 sub esi,ebx
 and esi,0x3FF * 8 + 7  ; Clip to tileset
 add esi,edx
 and esi,0xFFFF * 4 / 8 ; Clip to VRAM

 Plot_8_Paletted_Lines_Xflip 0,C_LABEL(TileCache2)+esi*8,0

 pop ebx
 pop esi
 pop ecx

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

 ret
%endmacro

;%1 = label, %2 = priority - 0 = none, 1 = low, 2 = high
%macro Plot_Lines_Offset_16x16_C8 2
%if %2 > 0
%%return:
 ret

ALIGNC
%1_check:
 pop ebx
 pop esi
 pop ecx

%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:
 mov eax,esi
 push ecx
 add eax,byte 2
 mov dh,[1+esi]     ; Offset change map
 push eax

 mov ebp,[RO16x16_FirstTile+RO16x16_Inner+8]
 mov eax,[RO16x16_Current_Line+RO16x16_Inner+8]
 test dh,ch         ; Offset enabled?
 jz .No_VChange

 test dh,dh         ; vertical offset?
 jnz .calc_v_offset

 mov dl,[esi]
 mov ebp,edx
 shr ebp,3
 jmp .No_VChange

.calc_v_offset:
 mov dl,[esi]
 add eax,edx

 and ah,2
 mov esi,[RO16x16_TMapAddress+RO16x16_Inner+8]
 jz  .line_in_screen_map_top
 mov esi,[RO16x16_BMapAddress+RO16x16_Inner+8]
.line_in_screen_map_top:

 ; al contains real Y offset for next tile
 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
 jmp .have_v_offset

.LeftEdge:
 push ecx
 push esi

 mov ebp,[RO16x16_FirstTile+RO16x16_Inner+8]

.No_VChange:
 mov eax,[LineAddress]
 mov esi,[RO16x16_MapAddress_Current+RO16x16_Inner+8]
 mov edx,[LineAddressY]

.have_v_offset:
 add ebp,ebx
 inc ebx            ; Update X offset
 mov [RO16x16_LineAddressOffset+RO16x16_Inner+8],eax
 push ebx
 mov ebx,ebp
 and ebp,byte 63    ; X offset wrap
 and ebx,byte 64
 mov [RO16x16_LineAddressOffsetY+RO16x16_Inner+12],edx
 mov ebx,[RO16x16_RMapDifference+RO16x16_Inner+12]
 jz  .tile_in_screen_map_left
 add esi,ebx
.tile_in_screen_map_left:
 mov ebx,ebp
 and ebp,byte ~1

 mov al,[esi+ebp+1] ; Combine X and Y offsets into tile map
 Check_Tile_Priority %2, %1_check

 mov si,[esi+ebp]   ; Get tile #
 mov ebp,[RO16x16_LineAddressOffsetY+RO16x16_Inner+12]
 test al,al         ; Check Y flip
 js .flip_y
 mov ebp,[RO16x16_LineAddressOffset+RO16x16_Inner+12]

.flip_y:
 shl esi,3
 add esi,ebp
 and ebx,byte 1
 add al,al      ; Get X flip (now in MSB)
 mov edx,[TilesetAddress]
 js .xflip

 lea esi,[esi+ebx*8]
 and esi,0x3FF * 8 + 7  ; Clip to tileset
 add esi,edx
 and esi,0xFFFF / 8 ; Clip to VRAM

 Plot_8_Lines_noflip 0,C_LABEL(TileCache8)+esi*8,0

 pop ebx
 pop esi
 pop ecx

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

 ret

ALIGNC
.xflip:
 shl ebx,3
 add esi,byte 8
 sub esi,ebx
 and esi,0x3FF * 8 + 7  ; Clip to tileset
 add esi,edx
 and esi,0xFFFF / 8 ; Clip to VRAM

 Plot_8_Lines_Xflip 0,C_LABEL(TileCache8)+esi*8,0

 pop ebx
 pop esi
 pop ecx

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

 ret
%endmacro

;%1 = depth
%macro Generate_Line_Plotters_Offset_16x16 1
%ifndef NO_NP_RENDER
 Plot_Lines_Offset_16x16_C%1 Plot_Lines_NP_Offset_16x16_C%1,0
%endif
 Plot_Lines_Offset_16x16_C%1 Plot_Lines_V_Offset_16x16_C%1,3
%endmacro

Generate_Line_Plotters_Offset_16x16 4
Generate_Line_Plotters_Offset_16x16 2
Generate_Line_Plotters_Offset_16x16 8

section .data
%macro Generate_Line_Plotter_Table_Offset_16x16 2
EXPORT_C Plot_Lines_%1_Offset_16x16_Table_C%2
dd C_LABEL(Plot_Lines_%1_Offset_16x16_C%2).LeftEdge
dd C_LABEL(Plot_Lines_%1_Offset_16x16_C%2)
%endmacro

%ifndef NO_NP_RENDER
Generate_Line_Plotter_Table_Offset_16x16 NP,4
Generate_Line_Plotter_Table_Offset_16x16 NP,2
Generate_Line_Plotter_Table_Offset_16x16 NP,8
%endif

Generate_Line_Plotter_Table_Offset_16x16 V,4
Generate_Line_Plotter_Table_Offset_16x16 V,2
Generate_Line_Plotter_Table_Offset_16x16 V,8

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

⌨️ 快捷键说明

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