📄 screena.asm
字号:
; Instruction U first, then V
;The following instructions are pairable in either pipe:
; MOV register, memory, or immediate into register or memory
; PUSH register or immediate
; POP register
; LEA, NOP
; INC, DEC, ADD, SUB, CMP, AND, OR, XOR,
; and some forms of TEST (see section 17.3)
; test immediate value only pairable if testing AL or EAX
; test reg,mem or mem,reg is pairable
;The following instructions are pairable in the U-pipe only:
;ADC, SBB
;SHR, SAR, SHL, SAL with immediate count
;ROR, ROL, RCR, RCL with an immediate count of 1
.model flat, C
.486P
.data
;_DATA SEGMENT DWORD PUBLIC USE32 'DATA'
align 4
bginfo struct
cdepth dd ?
scrollx dd ?
scrolly dd ?
width64 dd ?
height64 dd ?
tile16x16 dd ?
width8x8 dd ?
width8x8and dd ?
height8x8 dd ?
height8x8and dd ?
tilemap dd ? ; Pointer to byte
tcharbase dd ?
tcharshift dd ?
lastbgrow dd ?
bgnum dd ?
cgoffs dd ?
bginfo ends
align 1
cachetilemap struct
tile dd ? ; pointer to a subarray of the ctile array
palor db ?
empty db ?
solid db ?
prio db ?
cachetilemap ends
extrn _ctmap:dword near ; Array 4*128*128*2 * 8 (sizeof)
extrn _sprmap:dword near ; Array 128*8*8 * 8
align 4
extrn _ctile:byte near ; Array 4 * 4096 * 64
extrn _cstatus:byte near ; Array 4096
extrn _csolid:byte near ; Array 2*4096
extrn _cempty:byte near ; Array 2*4096
extrn _spr8x8size:byte near ; Array 128
extrn _curbg:near ; bginfo structure... how do I declare it as such?
flagand dd 0
oldscrstart dd 0
PRELINESIZE equ 272
public _blitbglineasm
_blitbglineasm proc near C
push ebp
; Register Usage
; Arguments:
; cache tile map pointer: esi
; screen pointer: edi
; offset y: bl (0 to 7)
; column in tile map: eax
; must copy flags: ecx
; Returns: new value for must copy flags, in cx
; During routine:
; cl: draw countdown
; ch: column in tile map
; esi/edi: tile map pointer, screen pointer
; high word of ecx: must copy flags
; ebp: temporary 32-bit data
; ebx: offset y in bytes (offsy << 3)
; edx: temporary data
; eax: temporary data
; Destroys all registers except ESP/EBP
shl ecx, 16 ; High word now contains mustcopy flags
and ebx, 7 ; offsy % 8
mov cl, bl ; cl = offsy temporarily
mov ch, 1 ; find flagand (1 << offsy)
shl ebx, 3 ; offset in bytes from cached tile top
shl ch, cl
mov byte [flagand], ch ; store flagand
mov cl, 33 ; Tile counter
mov ch, al ; ch = column
test eax, 0FFFFFF80h
jz loopstart
or ch, 80h ; sign-collapse
loopstart:
test ch, 80h ; u column >= 128? Then go back to start of tile map row
jz @F ; v
and ch, 7Fh ; u
sub esi, 400h ; v 80h*sizeof cachetilemap
@@:
mov eax, [esi+4] ; u eax=flags etc. in tile map entry--empty flags contained in ah
xor edx, edx ; use for clearing memory
test ah, byte [flagand] ; test reg,memory is pairable
jz notempty
mov dword [edi], edx ;
mov dword [edi+4], edx ;
mov dword [edi+PRELINESIZE], edx ;
mov dword [edi+PRELINESIZE+4], edx ;
jmp skipdatacopy ;
notempty:
test eax, 01000000h ; u Test priority bit, write to other scanline if priority=1
; test immediate value only pairable if testing AL or EAX
jz @F ; v
add edi, PRELINESIZE ; u
@@: mov ah, al ; ? al contains pal_or, so copy this byte into a dword
nop
mov edx, eax ; ?
shl eax, 16 ; ?
and edx, 0FFFFh ; ?
nop
or eax, edx ; ? eax = dwpal_or
; Okay, now there's two registers free: ebp and edx. Copy two dwords at
; once and mix instructions to optimize register pairing
mov edx, [esi] ; get pointer to pointer to data
mov ebp, [esi]
mov edx, [edx+ebx] ; ctilemap->tile->dwpixel[offsy] load pixel value
mov ebp, [ebp+ebx+4] ; ctilemap->tile->dwpixel[offsy+1]
or edx, eax
or ebp, eax
mov dword [edi], edx
mov eax, dword [esi+4]
mov dword [edi+4], ebp
; Damn I'm good. Okay, now test the priority bit again...
shr eax, 25 ; in carry flag
jnc @F
sub edi, PRELINESIZE ; restore virtual screen pointer to previous value
xor eax, eax ; use eax to clear memory
add ecx, 01000000h ; increment highest byte of ecx (mustcopy[1]++)
mov dword [edi], eax
mov dword [edi+4], eax ; clear 8 bytes in unused priority
jmp skipelse
@@:
xor eax, eax ; use eax to clear memory
add ecx, 00010000h ; increment low byte of high word of ecx (mustcopy[0]++)
mov dword [edi+PRELINESIZE], eax
mov dword [edi+PRELINESIZE+4], eax ; clear 8 bytes in unused priority
skipelse:
skipdatacopy:
inc ch ; increment column #
add edi, 8
add esi, 8 ; sizeof (cachetilemapentry)
dec cl
jnz loopstart
shr ecx, 16 ; return mustcopy flags in cx
pop ebp
ret
_blitbglineasm endp
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -