📄 memory.asm
字号:
mov esi,[C4Ram]
mov dword[C4count],8
mov cl,[esi+626h]
mov byte[C4sprites],cl
mov ecx,[C4sprites]
shl ecx,2
mov dword[C4ObjDisp],ecx
mov ecx,128
; cmp byte[esi+65],50h
; jne .noincdisp
mov dword[C4count],32
sub ecx,[C4sprites]
.noincdisp
add esi,[C4ObjDisp]
; Clear OAM to-be ram
.next
mov byte[esi+1],0E0h
add esi,4
dec ecx
jnz .next
call C4ConvOAM
pop edx
pop ebx
pop edi
pop esi
pop ecx
ret
NEWSYM SprValAdd, db 0
C4Data dd 0
C4sprites dd 0
OBClog dd 0
NumSprites db 0
OBCOldRegArray db 0
NEWSYM InitOBC
pushad
mov esi,[romdata]
add esi,4096*1024
mov [C4RamR],esi
mov [C4RamW],esi
mov [C4Ram],esi
add dword[C4RamW],8192*4
add dword[C4Ram],8192*8
mov ecx,8192
.c4loop
mov dword[esi],OBCReadReg
mov dword[esi+8192*4],OBCWriteReg
mov dword[esi+8192*8],0
add esi,4
dec ecx
jnz .c4loop
mov esi,[romdata]
add esi,4096*1024
mov dword[esi+3A1Eh*4],OBCClear
mov dword[esi+3FF0h*4],OBCRegs
mov dword[esi+3FF1h*4],OBCRegs
mov dword[esi+3FF2h*4],OBCRegs
mov dword[esi+3FF3h*4],OBCRegs
mov dword[esi+3FF4h*4],OBCRegs
mov dword[esi+3FF5h*4],OBCRegs
mov dword[esi+3FF6h*4],OBCRegs
mov dword[esi+3FF7h*4],OBCRegs
popad
ret
OBCSprites:
pushad
mov byte[NumSprites],0
mov esi,[C4Ram]
mov edi,esi
add edi,1800h
add byte[OBCRegArray],2
and byte[OBCRegArray],0FEh
cmp byte[OBCRegArray],0FEh
je .ohno
cmp byte[OBCRegArray],0
je .ohno
jmp .okay
.ohno
mov al,[OBCOldRegArray]
mov [OBCRegArray],al
jmp .loop
.okay
mov al,[OBCRegArray]
mov [OBCOldRegArray],al
.loop
cmp byte[OBCRegArray],0
je .nomore
sub byte[OBCRegArray],2
xor ebx,ebx
mov bl,[esi+6]
shl ebx,2
; Get X,Y,OAM, and Attr
mov al,[esi+3] ;0,3
mov [edi+ebx],al
mov al,[esi+9]
mov [edi+ebx+1],al
mov al,[esi+10] ;2,10
mov [edi+ebx+2],al
mov al,[esi+0Bh]
mov byte[edi+ebx+3],al
xor ebx,ebx
mov bl,[esi+6]
shr ebx,2
add ebx,512
mov cl,[esi+6]
and cl,03h
add cl,cl
xor al,al
mov ah,0FCh
mov al,byte[esi+4] ;1,4
and al,03h
shl al,cl
rol ah,cl
and byte[edi+ebx],ah
or byte[edi+ebx],al
inc byte[NumSprites]
add esi,16
jmp .loop
.nomore
mov esi,[C4Ram]
mov edi,esi
add edi,1800h
; mov dword[edi+200h],0AAAAAAAAh
popad
ret
OBCClear:
call OBCSprites
mov byte[clearmem],1
mov dword[OBClog],0
ret
; Affected values: 0,1,2,3,4,6,7,9,A,B
; 0,1 - Another X value (unused?)
; 2 - OAM value
; 3/4 - X value (bits 0-8)
; 5 - N/A (not written to)
; 6 - OAM #
; 7 - Always 0?
; 9 - Y value (bits 0-7)
; A - OAM value
; B - OAM Status
; X,Y,OAM,Attr / xhighbit / OAM highbit / Sprite size
;bit 0 = OAM b8, bit 1-3 = palette number bit 4,5 = playfield priority
;bit 6 = horizontal flip bit 7 = horizonal flip
; Extra: bit 0 = X bit 8, bit 1 = Larger sprite size
OBCRegArray times 8 db 0
OBCIncArray db 2,1,1,1,2,2,2,2
clearmem db 0
OBCRegs:
pushad
sub ecx,1FF0h
cmp byte[clearmem],0
je near .noclearmem
cmp ecx,6
je .okay
popad
ret
.okay
mov dword[OBCRegArray],0
mov dword[OBCRegArray+4],0
mov byte[OBCRegArray],0FEh
mov byte[clearmem],0
.noclearmem
mov ebx,[C4Ram]
add ebx,1000h
add ebx,[OBClog]
inc dword[OBClog]
mov [ebx],cl
cmp cl,6
jne .notsix
add byte[OBCRegArray],2
mov bl,[OBCRegArray]
mov bh,bl
mov [OBCRegArray+1],bl
mov [OBCRegArray+2],bx
mov [OBCRegArray+4],bx
mov [OBCRegArray+6],bx
.notsix
xor ebx,ebx
mov bl,[OBCRegArray+ecx]
cmp byte[OBCIncArray+ecx],1
jne .noinc
or byte[OBCRegArray+ecx],1
.noinc
shl ebx,3
add ecx,ebx
add ecx,[C4Ram]
mov byte[ecx],al
; cmp dl,1
; jne .second
mov byte[ecx+8],0FFh
; jmp .first
;.second
; mov byte[ecx+16],0FFh
;.first
popad
ret
OBCReadReg:
add ecx,[C4Ram]
mov al,[ecx]
sub ecx,[C4Ram]
ret
OBCWriteReg
add ecx,[C4Ram]
mov [ecx],al
sub ecx,[C4Ram]
ret
NEWSYM InitC4
pushad
mov esi,[romdata]
add esi,4096*1024
mov [C4Data],esi
add dword[C4Data],128*1024
mov [C4RamR],esi
mov [C4RamW],esi
mov [C4Ram],esi
add dword[C4RamW],8192*4
add dword[C4Ram],8192*8
mov ecx,8192
.c4loop
mov dword[esi],C4ReadReg
mov dword[esi+8192*4],C4WriteReg
mov dword[esi+8192*8],0
add esi,4
dec ecx
jnz .c4loop
mov esi,[C4RamW]
mov dword[esi+1F4Fh*4],C4RegFunction
mov esi,[C4Data]
mov ecx,16*4096
.c4loopb
mov dword[esi],0
add esi,4
loop .c4loopb
popad
ret
C4ClearSpr:
mov esi,ebx
mov edi,eax
; xor ecx,ecx
; mov cx,[eax+1F44h]
; sub cx,6000h
; add eax,ecx
shl ch,3
.scloop2
mov cl,byte[C4SprPos]
shl cl,2
.scloop
mov byte[edi],0
mov byte[edi+2000h],0
inc edi
dec cl
jnz .scloop
dec ch
jnz .scloop2
ret
C4SprBitPlane:
mov edi,eax
shl ebx,2
.scloop3
mov ch,[C4SprPos]
push esi
.scloop4
push esi
mov cl,8
.loop
mov dh,8
mov dl,80h
mov eax,[esi]
.nextd
test al,1
jz .not0
or byte[edi],dl
.not0
test al,2
jz .not1
or byte[edi+1],dl
.not1
test al,4
jz .not2
or byte[edi+16],dl
.not2
test al,8
jz .not3
or byte[edi+17],dl
.not3
shr eax,4
shr dl,1
dec dh
jnz .nextd
add esi,ebx
add edi,2
dec cl
jnz .loop
add edi,16
pop esi
add esi,4
dec ch
jnz .scloop4
pop esi
shl ebx,3
add esi,ebx
add edi,dword[C4SprPtrInc]
shr ebx,3
dec byte[C4SprPos+1]
jnz .scloop3
.end
ret
C4XXScale dw 0
C4XYScale dw 0
C4YXScale dw 0
C4YYScale dw 0
C4CXPos dw 0
C4CYPos dw 0
C4CXMPos dd 0
C4CYMPos dd 0
C4PCXMPos dd 0
C4PCYMPos dd 0
DoScaleRotate:
pushad
mov esi,eax
; Calculate X scaler
mov ax,[esi+1F80h]
and eax,01FFh
mov ax,[CosTable+eax*2]
mov bx,[esi+1F8Fh]
test bx,8000h
jz .notover
mov bx,7FFFh
.notover
imul bx
add ax,ax
adc dx,dx
mov [C4XXScale],dx
mov ax,[esi+1F80h]
and eax,01FFh
mov ax,[SinTable+eax*2]
imul bx
add ax,ax
adc dx,dx
mov [C4XYScale],dx
; Calculate Y scaler
mov ax,[esi+1F80h]
and eax,01FFh
mov ax,[CosTable+eax*2]
mov bx,[esi+1F92h]
test bx,8000h
jz .notoverb
mov bx,7FFFh
.notoverb
imul bx
add ax,ax
add dx,dx
mov [C4YYScale],dx
mov ax,[esi+1F80h]
and eax,01FFh
mov ax,[SinTable+eax*2]
imul bx
add ax,ax
adc dx,dx
neg dx
mov [C4YXScale],dx
cmp word[esi+1F80h],0
jne .effect
cmp word[esi+1F92h],1000h
jne .effect
mov word[C4YYScale],1000h
mov word[C4YXScale],0
.effect
; Calculate Pixel Resolution
mov cl,byte[C4SprPos]
shl cl,3
mov byte[C4SprPos+2],cl
mov cl,byte[C4SprPos+1]
shl cl,3
mov byte[C4SprPos+3],cl
; Calculate Positions
; (1-scale)*(pos/2)
xor eax,eax
mov al,[C4SprPos+2]
shl eax,11
mov [C4PCXMPos],eax
xor eax,eax
mov al,[C4SprPos+3]
shl eax,11
mov [C4PCYMPos],eax
mov bx,[C4XXScale]
xor eax,eax
mov al,[C4SprPos+2]
shr ax,1
imul bx
shl edx,16
mov dx,ax
sub [C4PCXMPos],edx
mov bx,[C4YXScale]
xor eax,eax
mov al,[C4SprPos+3]
shr ax,1
imul bx
shl edx,16
mov dx,ax
sub [C4PCXMPos],edx
mov bx,[C4XYScale]
xor eax,eax
mov al,[C4SprPos+2]
shr ax,1
imul bx
shl edx,16
mov dx,ax
sub [C4PCYMPos],edx
mov bx,[C4YYScale]
xor eax,eax
mov al,[C4SprPos+3]
shr ax,1
imul bx
shl edx,16
mov dx,ax
sub [C4PCYMPos],edx
; Start loop
mov word[C4CYPos],0
xor edi,edi
.loop
mov ecx,[C4PCXMPos]
mov [C4CXMPos],ecx
mov ecx,[C4PCYMPos]
mov [C4CYMPos],ecx
mov al,[C4SprPos+2]
mov byte[C4CXPos],al
.loop2
xor eax,eax
mov al,[C4SprPos+2]
mov ebx,[C4CXMPos]
sar ebx,12
cmp ebx,eax
jae near .blank
xor eax,eax
mov al,[C4SprPos+3]
mov ebx,[C4CYMPos]
sar ebx,12
cmp ebx,eax
jae near .blank
; Get pixel value
mov ebx,[C4CYMPos]
xor eax,eax
shr ebx,12
mov al,[C4SprPos+2]
mul ebx
mov ebx,[C4CXMPos]
shr ebx,12
add eax,ebx
mov ebx,[C4SprPtr]
test al,1
jnz .upperb
shr eax,1
add ebx,eax
mov al,[ebx]
jmp .lowerb
.upperb
shr eax,1
add ebx,eax
mov al,[ebx]
shr al,4
.lowerb
mov ebx,edi
shr ebx,1
add ebx,esi
test edi,1
jnz .upperb2
and al,0Fh
and byte[ebx+2000h],0F0h
or byte[ebx+2000h],al
jmp .done
.upperb2
shl al,4
and byte[ebx+2000h],0Fh
or byte[ebx+2000h],al
jmp .done
.blank
mov eax,edi
shr eax,1
add eax,esi
test edi,1
jnz .upper
and byte[eax+2000h],0F0h
jmp .done
.upper
and byte[eax+2000h],0Fh
.done
movsx eax,word[C4XXScale]
add [C4CXMPos],eax
movsx eax,word[C4XYScale]
add [C4CYMPos],eax
inc edi
dec byte[C4CXPos]
jne near .loop2
movsx eax,word[C4YXScale]
add [C4PCXMPos],eax
movsx eax,word[C4YYScale]
add [C4PCYMPos],eax
inc word[C4CYPos]
mov al,[C4SprPos+3]
cmp byte[C4CYPos],al
jne near .loop
.noimage
popad
ret
DoScaleRotate2:
pushad
xor ebx,ebx
mov bx,[eax+1F8Fh]
cmp bx,1000h
ja .scaled
mov bx,1000h
.scaled
mov [C4SprScale],ebx
xor ebx,ebx
mov bx,[eax+1F92h]
cmp bx,1000h
ja .scaledb
mov bx,1000h
.scaledb
mov [C4SprScaleY],ebx
mov cl,[C4SprPos]
shl cl,3
mov ch,cl
xor ebx,ebx
.leftovercheck
dec ch
add ebx,[C4SprScale]
.leftovercheckb
cmp ebx,1000h
jb .leftovercheck
sub ebx,1000h
dec cl
jz .donecheck
jmp .leftovercheckb
.donecheck
shr ch,1
mov cl,ch
and ecx,0FFh
mov esi,ecx
mov cl,[C4SprPos+1]
shl cl,3
mov ch,cl
xor ebx,ebx
.leftovercheckc
dec ch
add ebx,[C4SprScaleY]
.leftovercheckd
cmp ebx,1000h
jb .leftovercheckc
sub ebx,1000h
dec cl
jz .donecheckc
jmp .leftovercheckd
.donecheckc
shr ch,1
mov cl,ch
and ecx,0FFh
push eax
xor eax,eax
mov al,[C4SprPos]
shl al,3
mul ecx
add esi,eax
pop eax
mov dword[C4SprScalerY],0
xor edi,edi
mov cl,[C4SprPos+1]
shl cl,3
mov [C4SprPos+3],cl
.next
push esi
push edi
xor ecx,ecx
mov cl,[C4SprPos]
shl cl,3
mov ch,cl
mov dword[C4SprScaler],0
xor edx,edx
.loop
mov edx,edi
shr edx,1
add edx,[C4SprPtr]
mov bl,[edx]
test esi,1
jz .notupper
shr bl,4
.notupper
and bl,0Fh
mov edx,esi
shr edx,1
test esi,1
jz .notupperb
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -