📄 bg8om.asm
字号:
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 + -