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

📄 bg8om.asm

📁 NES game Emulator in Linux.c and asm codes.
💻 ASM
📖 第 1 页 / 共 2 页
字号:
 dec eax
 jnz %%flip_none_next_pixel

 mov eax,[Mosaic_Size]
 test ecx,ecx
 jz %%flip_none_return

 cmp ebp,byte 8
 jb %%flip_none_same_tile

 pop ebx
 pop esi
 jmp %%next_tile

%%flip_none_empty_run:
 add edi,eax
 add ebp,eax
 sub ecx,eax
 jz %%flip_none_return

 cmp ebp,byte 8
 jb %%flip_none_same_tile

 pop ebx
 pop esi
 jmp %%next_tile

%%flip_none_return:
 pop ebx
 pop esi
 ret

ALIGNC
%%xflip:
 lea esi,[C_LABEL(TileCache4)+esi*8+8]
 xor ebp,byte -1
%%flip_x_same_tile:
 cmp ecx,eax
 ja %%flip_x_partial
 mov eax,ecx
%%flip_x_partial:
 mov bl,[esi+ebp]
%if %2 == 1 || %2 == 3
 mov [Tile_Priority_Used],al
%endif
 and bl,dl
 jz %%flip_x_empty_run

;eax = count, esi = source base, ebp = offset, edi = dest, ecx = # left
;edx = palette, bl = pixel
 sub ebp,eax
 sub ecx,eax

%%flip_x_next_pixel:
%assign PLM8x8_Dest_Offset 0
%rep %3
 mov [edi+PLM8x8_Dest_Offset],bl
%assign PLM8x8_Dest_Offset (PLM8x8_Dest_Offset + GfxBufferLinePitch)
%endrep
%undef PLM8x8_Dest_Offset
 inc edi
 dec eax
 jnz %%flip_x_next_pixel

 mov eax,[Mosaic_Size]
 test ecx,ecx
 jz %%flip_x_return

 cmp ebp,byte ~8
 ja %%flip_x_same_tile

 pop ebx
 pop esi
 xor ebp,byte -1
 jmp %%next_tile

%%flip_x_empty_run:
 add edi,eax
 sub ebp,eax
 sub ecx,eax
 jz %%flip_x_return

 cmp ebp,byte ~8
 ja %%flip_x_same_tile

 pop ebx
 pop esi
 xor ebp,byte -1
 jmp %%next_tile

%%flip_x_return:
 pop ebx
 pop esi
 ret
%endmacro

;%1 = label, %2 = priority - 0 = none, 1 = low, 2 = high, %3 = lines
%macro Plot_Lines_Offset_8x8M_C2 3
ALIGNC
%if %2 > 0
%%wrong_priority_last:
%if %2 == 1 || %2 == 3
 mov [Tile_Priority_Unused],cl
%endif
 add edi,ecx
 add ebp,ecx
%%return:
 ret

ALIGNC
%1_check:
 pop ebp
 pop ebx
 pop esi

 mov eax,[Mosaic_Size]
%%wrong_priority_same_tile:
 cmp ecx,eax
 jbe %%wrong_priority_last
%if %2 == 1 || %2 == 3
 mov [Tile_Priority_Unused],al
%endif
 add edi,eax
 add ebp,eax
 sub ecx,eax

 cmp ebp,byte 8
 jb %%wrong_priority_same_tile
%endif

%%next_tile:
 mov eax,ebp
 and ebp,byte 7
 shr eax,3
 add eax,eax
 add ebx,eax        ; Update screen pointer
 lea esi,[esi+eax-2]

EXPORT_C %1     ; Define label, entry point
 lea eax,[esi+2]
 mov dh,[1+esi]     ; Offset change map
 push eax
 push ebx
 push ebp

 mov ebp,[RO8x8M_FirstTile+RO8x8M_Inner+12]
 mov eax,[RO8x8M_Current_Line_Mosaic+RO8x8M_Inner+12]
 test dh,[RO8x8M_OC_Flag+RO8x8M_Inner+12]   ; Offset enabled?
 jz .No_VChange

 test dh,dh         ; vertical offset?
 jnz .calc_v_offset

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

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

 and ah,1
 mov esi,[RO8x8M_TMapAddress+RO8x8M_Inner+12]
 jz .line_in_screen_map_top
 mov esi,[RO8x8M_BMapAddress+RO8x8M_Inner+12]
.line_in_screen_map_top:

 ; al contains real Y offset for next tile
 push ecx
 mov ecx,0xF8
 mov edx,7
 and ecx,eax
 and eax,byte 7
 sub edx,eax
 lea esi,[esi+ecx*8]    ; Get screen offset
 pop ecx
 jmp .have_v_offset

.LeftEdge:
 push esi
 push ebx
 push ebp

 mov ebp,[RO8x8M_FirstTile+RO8x8M_Inner+12]

.No_VChange:
 mov eax,[LineAddress]
 mov esi,[RO8x8M_MapAddress_Current+RO8x8M_Inner+12]
 mov edx,[LineAddressY]

.have_v_offset:
 add ebp,ebx
 mov [RO8x8M_LineAddressOffset+RO8x8M_Inner+12],eax
 mov ebx,ebp
 and ebp,byte 31*2  ; X offset wrap
 mov [RO8x8M_LineAddressOffsetY+RO8x8M_Inner+12],edx
 add esi,ebp        ; Combine X and Y offsets into tile map
 and ebx,byte 32*2
 mov ebx,[RO8x8M_RMapDifference+RO8x8M_Inner+12]
 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,[RO8x8M_LineAddressOffsetY+RO8x8M_Inner+12]
 test al,al         ; Check Y flip
 mov si,[esi]       ; Get tile #
 js .flip_y
 mov ebp,[RO8x8M_LineAddressOffset+RO8x8M_Inner+12]

.flip_y:
 shl esi,3
 mov edx,eax
 add esi,ebp
 mov ebp,[TilesetAddress]
 and esi,0x3FF * 8 + 7  ; Clip to tileset
 and edx,byte 7*4   ; Get palette
 add esi,ebp

 pop ebp
 and esi,0xFFFF * 4 / 8 ; Clip to VRAM
 mov edx,[palette_2bpl+edx]

 add al,al      ; Get X flip (now in MSB)
 mov eax,[Mosaic_Size]
 js %%xflip

 lea esi,[C_LABEL(TileCache2)+esi*8]
%%flip_none_same_tile:
 cmp ecx,eax
 ja %%flip_none_partial
 mov eax,ecx
%%flip_none_partial:
 mov bl,[esi+ebp]
%if %2 == 1 || %2 == 3
 mov [Tile_Priority_Used],al
%endif
 and bl,dl
 jz %%flip_none_empty_run

;eax = count, esi = source base, ebp = offset, edi = dest, ecx = # left
;edx = palette, bl = pixel
 add ebp,eax
 sub ecx,eax

%%flip_none_next_pixel:
%assign PLM8x8_Dest_Offset 0
%rep %3
 mov [edi+PLM8x8_Dest_Offset],bl
%assign PLM8x8_Dest_Offset (PLM8x8_Dest_Offset + GfxBufferLinePitch)
%endrep
%undef PLM8x8_Dest_Offset
 inc edi
 dec eax
 jnz %%flip_none_next_pixel

 mov eax,[Mosaic_Size]
 test ecx,ecx
 jz %%flip_none_return

 cmp ebp,byte 8
 jb %%flip_none_same_tile

 pop ebx
 pop esi
 jmp %%next_tile

%%flip_none_empty_run:
 add edi,eax
 add ebp,eax
 sub ecx,eax
 jz %%flip_none_return

 cmp ebp,byte 8
 jb %%flip_none_same_tile

 pop ebx
 pop esi
 jmp %%next_tile

%%flip_none_return:
 pop ebx
 pop esi
 ret

ALIGNC
%%xflip:
 lea esi,[C_LABEL(TileCache2)+esi*8+8]
 xor ebp,byte -1
%%flip_x_same_tile:
 cmp ecx,eax
 ja %%flip_x_partial
 mov eax,ecx
%%flip_x_partial:
 mov bl,[esi+ebp]
%if %2 == 1 || %2 == 3
 mov [Tile_Priority_Used],al
%endif
 and bl,dl
 jz %%flip_x_empty_run

;eax = count, esi = source base, ebp = offset, edi = dest, ecx = # left
;edx = palette, bl = pixel
 sub ebp,eax
 sub ecx,eax

%%flip_x_next_pixel:
%assign PLM8x8_Dest_Offset 0
%rep %3
 mov [edi+PLM8x8_Dest_Offset],bl
%assign PLM8x8_Dest_Offset (PLM8x8_Dest_Offset + GfxBufferLinePitch)
%endrep
%undef PLM8x8_Dest_Offset
 inc edi
 dec eax
 jnz %%flip_x_next_pixel

 mov eax,[Mosaic_Size]
 test ecx,ecx
 jz %%flip_x_return

 cmp ebp,byte ~8
 ja %%flip_x_same_tile

 pop ebx
 pop esi
 xor ebp,byte -1
 jmp %%next_tile

%%flip_x_empty_run:
 add edi,eax
 sub ebp,eax
 sub ecx,eax
 jz %%flip_x_return

 cmp ebp,byte ~8
 ja %%flip_x_same_tile

 pop ebx
 pop esi
 xor ebp,byte -1
 jmp %%next_tile

%%flip_x_return:
 pop ebx
 pop esi
 ret
%endmacro

;%1 = label, %2 = priority - 0 = none, 1 = low, 2 = high, %3 = lines
%macro Plot_Lines_Offset_8x8M_C8 3
ALIGNC
%if %2 > 0
%%wrong_priority_last:
%if %2 == 1 || %2 == 3
 mov [Tile_Priority_Unused],cl
%endif
 add edi,ecx
 add ebp,ecx
%%return:
 ret

ALIGNC
%1_check:
 pop ebp
 pop ebx
 pop esi

 mov eax,[Mosaic_Size]
%%wrong_priority_same_tile:
 cmp ecx,eax
 jbe %%wrong_priority_last
%if %2 == 1 || %2 == 3
 mov [Tile_Priority_Unused],al
%endif
 add edi,eax
 add ebp,eax
 sub ecx,eax

 cmp ebp,byte 8
 jb %%wrong_priority_same_tile
%endif

%%next_tile:
 mov eax,ebp
 and ebp,byte 7
 shr eax,3
 add eax,eax
 add ebx,eax        ; Update screen pointer
 lea esi,[esi+eax-2]

EXPORT_C %1     ; Define label, entry point
 lea eax,[esi+2]
 mov dh,[1+esi]     ; Offset change map
 push eax
 push ebx
 push ebp

 mov ebp,[RO8x8M_FirstTile+RO8x8M_Inner+12]
 mov eax,[RO8x8M_Current_Line_Mosaic+RO8x8M_Inner+12]
 test dh,[RO8x8M_OC_Flag+RO8x8M_Inner+12]   ; Offset enabled?
 jz .No_VChange

 test dh,dh         ; vertical offset?
 jnz .calc_v_offset

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

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

 and ah,1
 mov esi,[RO8x8M_TMapAddress+RO8x8M_Inner+12]
 jz .line_in_screen_map_top
 mov esi,[RO8x8M_BMapAddress+RO8x8M_Inner+12]
.line_in_screen_map_top:

 ; al contains real Y offset for next tile
 push ecx
 mov ecx,0xF8
 mov edx,7
 and ecx,eax
 and eax,byte 7
 sub edx,eax
 lea esi,[esi+ecx*8]    ; Get screen offset
 pop ecx
 jmp .have_v_offset

.LeftEdge:
 push esi
 push ebx
 push ebp

 mov ebp,[RO8x8M_FirstTile+RO8x8M_Inner+12]

.No_VChange:
 mov eax,[LineAddress]
 mov esi,[RO8x8M_MapAddress_Current+RO8x8M_Inner+12]
 mov edx,[LineAddressY]

.have_v_offset:
 add ebp,ebx
 mov [RO8x8M_LineAddressOffset+RO8x8M_Inner+12],eax
 mov ebx,ebp
 and ebp,byte 31*2  ; X offset wrap
 mov [RO8x8M_LineAddressOffsetY+RO8x8M_Inner+12],edx
 add esi,ebp        ; Combine X and Y offsets into tile map
 and ebx,byte 32*2
 mov ebx,[RO8x8M_RMapDifference+RO8x8M_Inner+12]
 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,[RO8x8M_LineAddressOffsetY+RO8x8M_Inner+12]
 test al,al         ; Check Y flip
 mov si,[esi]       ; Get tile #
 js .flip_y
 mov ebp,[RO8x8M_LineAddressOffset+RO8x8M_Inner+12]

.flip_y:
 shl esi,3
 add esi,ebp
 mov ebp,[TilesetAddress]
 and esi,0x3FF * 8 + 7  ; Clip to tileset
 add esi,ebp

 pop ebp
 and esi,0xFFFF / 8 ; Clip to VRAM

 add al,al      ; Get X flip (now in MSB)
 mov eax,[Mosaic_Size]
 js %%xflip

 lea esi,[C_LABEL(TileCache8)+esi*8]
%%flip_none_same_tile:
 cmp ecx,eax
 ja %%flip_none_partial
 mov eax,ecx
%%flip_none_partial:
 mov dl,[esi+ebp]
%if %2 == 1 || %2 == 3
 mov [Tile_Priority_Used],al
%endif
 test dl,dl
 jz %%flip_none_empty_run

;eax = count, esi = source base, ebp = offset, edi = dest, ecx = # left
;ebx = screen map, dl = pixel
 add ebp,eax
 sub ecx,eax

%%flip_none_next_pixel:
%assign PLM8x8_Dest_Offset 0
%rep %3
 mov [edi+PLM8x8_Dest_Offset],dl
%assign PLM8x8_Dest_Offset (PLM8x8_Dest_Offset + GfxBufferLinePitch)
%endrep
%undef PLM8x8_Dest_Offset
 inc edi
 dec eax
 jnz %%flip_none_next_pixel

 mov eax,[Mosaic_Size]
 test ecx,ecx
 jz %%flip_none_return

 cmp ebp,byte 8
 jb %%flip_none_same_tile

 pop ebx
 pop esi
 jmp %%next_tile

ALIGNC
%%flip_none_empty_run:
 add edi,eax
 add ebp,eax
 sub ecx,eax
 jz %%flip_none_return

 cmp ebp,byte 8
 jb %%flip_none_same_tile

 pop ebx
 pop esi
 jmp %%next_tile

%%flip_none_return:
 pop ebx
 pop esi
 ret

ALIGNC
%%xflip:
 lea esi,[C_LABEL(TileCache8)+esi*8+8]
 xor ebp,byte -1
%%flip_x_same_tile:
 cmp ecx,eax
 ja %%flip_x_partial
 mov eax,ecx
%%flip_x_partial:
 mov dl,[esi+ebp]
%if %2 == 1 || %2 == 3
 mov [Tile_Priority_Used],al
%endif
 test dl,dl
 jz %%flip_x_empty_run

;eax = count, esi = source base, ebp = offset, edi = dest, ecx = # left
;ebx = screen map, dl = pixel
 sub ebp,eax
 sub ecx,eax

%%flip_x_next_pixel:
%assign PLM8x8_Dest_Offset 0
%rep %3
 mov [edi+PLM8x8_Dest_Offset],dl
%assign PLM8x8_Dest_Offset (PLM8x8_Dest_Offset + GfxBufferLinePitch)
%endrep
%undef PLM8x8_Dest_Offset
 inc edi
 dec eax
 jnz %%flip_x_next_pixel

 mov eax,[Mosaic_Size]
 test ecx,ecx
 jz %%flip_x_return

 cmp ebp,byte ~8
 ja %%flip_x_same_tile

 pop ebx
 pop esi
 xor ebp,byte -1
 jmp %%next_tile

ALIGNC
%%flip_x_empty_run:
 add edi,eax
 sub ebp,eax
 sub ecx,eax
 jz %%flip_x_return

 cmp ebp,byte ~8
 ja %%flip_x_same_tile

 pop ebx
 pop esi
 xor ebp,byte -1
 jmp %%next_tile

%%flip_x_return:
 pop ebx
 pop esi
 ret
%endmacro

;%1 = depth, %2 = count
%macro Generate_Line_Plotters_Offset_8x8M 2
%ifndef NO_NP_RENDER
 Plot_Lines_Offset_8x8M_C%1 Plot_Lines_%2_NP_Offset_8x8M_C%1,0,%2
%endif
 Plot_Lines_Offset_8x8M_C%1 Plot_Lines_%2_V_Offset_8x8M_C%1,3,%2
%endmacro

%macro Generate_Line_Plotters_Offset_8x8M_Depth 1
%assign GLPO_8x8M_Count 1
%rep RO8x8M_MAX_LINE_COUNT
Generate_Line_Plotters_Offset_8x8M %1,GLPO_8x8M_Count
%assign GLPO_8x8M_Count GLPO_8x8M_Count+1
%endrep
%undef GLPO_8x8M_Count
%endmacro

Generate_Line_Plotters_Offset_8x8M_Depth 2
Generate_Line_Plotters_Offset_8x8M_Depth 4
Generate_Line_Plotters_Offset_8x8M_Depth 8

section .data
%macro Generate_Line_Plotter_Offsets_8x8M 3
dd C_LABEL(Plot_Lines_%3_%1_Offset_8x8M_C%2).LeftEdge
dd C_LABEL(Plot_Lines_%3_%1_Offset_8x8M_C%2)
%endmacro

;%1 = type, %2 = depth
%macro Generate_Line_Plotter_Table_Offset_8x8M 2
ALIGND
EXPORT_C Plot_Lines_%1_Offset_8x8M_Table_C%2
%assign GLPTO_8x8M_Count 1
%rep RO8x8M_MAX_LINE_COUNT
Generate_Line_Plotter_Offsets_8x8M %1,%2,GLPTO_8x8M_Count
%assign GLPTO_8x8M_Count GLPTO_8x8M_Count+1
%endrep
%undef GLPTO_8x8M_Count
%endmacro

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

Generate_Line_Plotter_Table_Offset_8x8M V,2
Generate_Line_Plotter_Table_Offset_8x8M V,4
Generate_Line_Plotter_Table_Offset_8x8M V,8

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

⌨️ 快捷键说明

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