📄 memory.asm
字号:
;Copyright (C) 1997-2001 ZSNES Team ( zsknight@zsnes.com / _demo_@zsnes.com )
;
;This program is free software; you can redistribute it and/or
;modify it under the terms of the GNU General Public License
;as published by the Free Software Foundation; either
;version 2 of the License, or (at your option) any later
;version.
;
;This program is distributed in the hope that it will be useful,
;but WITHOUT ANY WARRANTY; without even the implied warranty of
;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;GNU General Public License for more details.
;
;You should have received a copy of the GNU General Public License
;along with this program; if not, write to the Free Software
;Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
%include "macros.mac"
EXTSYM romdata,sramb4save,pressed,vidbuffer,oamram
EXTSYM C4TransfWireFrame2
EXTSYM C4WFXVal,C4WFYVal,C4WFX2Val,C4WFY2Val,C4CalcWireFrame
EXTSYM C4WFDist,C4WFScale,C4TransfWireFrame,C4WFZVal
EXTSYM debstop3
EXTSYM C41FXVal,C41FYVal,C41FAngleRes,C41FDist,C4Op1F,C4Op15
EXTSYM C41FDistVal,C4Op0D
EXTSYM SFXEnable,regptra,sfxramdata,snesmmap,wramdataa,debstop,C4Ram,C4Enable
EXTSYM C4RamR,C4RamW,snesmap2,SPC7110Enable
EXTSYM DSP1Read16b
EXTSYM DSP1Write8b,regptwa,writeon
EXTSYM Bank0datr8,Bank0datw8,Bank0datr16,Bank0datw16,xd,SA1xd
EXTSYM DSP1Read8b,DSP1Type,SA1Enable
EXTSYM DSP1Write16b
EXTSYM CurDecompPtr,PrevDecompPtr,CurDecompSize
EXTSYM SPCDecmPtr,SPCCompPtr,SPCCompCounter
EXTSYM ramsize,ramsizeand,sram
EXTSYM ram7fa
EXTSYM DosExit,invalid,invopcd,previdmode,printhex8
EXTSYM SA1Status,IRAM,CurBWPtr,SA1RAMArea
EXTSYM SA1Overflow,OBCEnable
EXTSYM Sdd1Mode,Sdd1Bank,Sdd1Addr,Sdd1NewAddr,memtabler8,AddrNoIncr,SDD1BankA
EXTSYM SPC7110Entries,spc7110romptr
NEWSYM MemoryAsmStart
; C4SprScale
;*******************************************************
; Register & Memory Access Banks (0 - 3F) / (80 - BF)
;*******************************************************
; enter : BL = bank number, CX = address location
; leave : AL = value read
; ******************************************************
; C4 Emulation, reverse engineered & written by zsKnight
; ******************************************************
C4ProcessVectors:
mov esi,[C4Ram]
mov edi,esi
add edi,1F8Ch
xor edx,edx
mov dx,[esi+1F8Ah]
cmp dx,128
ja .ret
cmp dx,0
jne .nozero
.ret
ret
.nozero
cmp dx,10h
jb .less
mov dx,10h
.less
mov esi,[C4Ram]
add esi,800h
.loop
mov ecx,100h
xor ebx,ebx
xor eax,eax
movsx bx,byte[edi]
.spotloop
add ah,80h
mov byte[esi],ah
sub ah,80h
add ax,bx
inc esi
loop .spotloop
add edi,3
dec dx
jnz .loop
ret
C4ObjDisp dd 0
C4ColRot db 1
NEWSYM C4ObjSelec, db 0
NEWSYM C4SObjSelec, db 0
NEWSYM C4Pause, db 0
C4DataCopy times 64 db 0
;NEWSYM C4Data times 64*4096 db 0 ; 15 sprites, 4 bytes each
; x,y,oamptr,stat (b0=oamb8,b1=16x16)
; 4 byte header (#sobj,?,?,?)
CObjNum dw 0
C4Temp dd 0
C4Edit:
; C4 editing routines
; Register keyboard presses
; [ = prev object, ] = next object
; p = pause/unpause
cmp byte[pressed+1Ah],0
je .notpressed
mov byte[pressed+1Ah],0
inc byte[C4ObjSelec]
inc byte[C4Temp]
.notpressed
cmp byte[pressed+1Bh],0
je .notpressed2
mov byte[pressed+1Bh],0
dec byte[C4ObjSelec]
dec byte[C4Temp]
.notpressed2
cmp byte[pressed+19h],0
je .notpressed3
mov byte[pressed+19h],0
xor byte[C4Pause],1
.notpressed3
; Setup variables
mov esi,[C4Ram]
add byte[C4ColRot],16
mov al,[esi+620h]
cmp byte[C4ObjSelec],0FFh
jne .notneg
dec al
mov byte[C4ObjSelec],al
jmp .notof
.notneg
cmp byte[C4ObjSelec],al
jb .notof
xor al,al
mov [C4ObjSelec],al
.notof
; Draw the dots on-screen
xor eax,eax
mov al,[C4ObjSelec]
shl eax,4
add eax,[C4Ram]
add eax,220h
mov byte[.flipped],0
test byte[eax+6],40h
jz .notflip
mov byte[.flipped],1
.notflip
; 00/01 - x position relative to BG scroll value
; 02/03 - y position relative to BG scroll value
; 04 - palette/priority settings
; 05 - OAM pointer value
; 06 - flip settings : b6 = flipx, b7 = flipy
; 07 - looks like some sprite displacement values
; 08/09 - ???
; 0A-0F - unused
xor ebx,ebx
mov bx,[eax+8]
mov [CObjNum],bx
cmp bx,4096
jae near .skipall
shl ebx,6
add ebx,[C4Data]
; t,f,g,h = move current object
; q = copy current object structure, w = paste current object structure
cmp byte[pressed+14h],0
je .notmove
mov byte[pressed+14h],0
pushad
mov ecx,15
.next
add ebx,4
dec byte[ebx+1]
loop .next
popad
.notmove
cmp byte[pressed+21h],0
je .notmove2
mov byte[pressed+21h],0
pushad
mov ecx,15
.next2
add ebx,4
cmp byte[.flipped],0
je .noflipx
add byte[ebx],2
.noflipx
dec byte[ebx]
loop .next2
popad
.notmove2
cmp byte[pressed+22h],0
je .notmove3
mov byte[pressed+22h],0
pushad
mov ecx,15
.next3
add ebx,4
inc byte[ebx+1]
loop .next3
popad
.notmove3
cmp byte[pressed+23h],0
je .notmove4
mov byte[pressed+23h],0
pushad
mov ecx,15
.next4
add ebx,4
cmp byte[.flipped],0
je .noflipx2
sub byte[ebx],2
.noflipx2
inc byte[ebx]
loop .next4
popad
.notmove4
cmp byte[pressed+10h],0
je .notcopy
mov byte[pressed+10h],0
pushad
mov edx,C4DataCopy
mov ecx,64
.copylp
mov al,[ebx]
mov [edx],al
inc ebx
inc edx
loop .copylp
popad
.notcopy
cmp byte[pressed+11h],0
je .notpaste
mov byte[pressed+11h],0
pushad
mov edx,C4DataCopy
mov ecx,64
.pastelp
mov al,[edx]
mov [ebx],al
inc ebx
inc edx
loop .pastelp
popad
.notpaste
; - = remove sub-object, + = add sub-object
; ; = previous sub-object, ' = next sub-object
cmp byte[pressed+0Ch],0
je .notpressed4
mov byte[pressed+0Ch],0
cmp byte[ebx],0
je .notpressed4
dec byte[ebx]
.notpressed4
cmp byte[pressed+0Dh],0
je .notpressed5
mov byte[pressed+0Dh],0
cmp byte[ebx],15
je .notpressed5
inc byte[ebx]
.notpressed5
cmp byte[pressed+27h],0
je .notpressed6
mov byte[pressed+27h],0
dec byte[C4SObjSelec]
.notpressed6
cmp byte[pressed+28h],0
je .notpressed7
mov byte[pressed+28h],0
inc byte[C4SObjSelec]
.notpressed7
; get current sub-object displacement (0 if no sub-objects)
xor ecx,ecx
cmp byte[ebx],0
je near .nosubobjs
mov cl,[ebx]
cmp byte[C4ObjSelec],0FFh
jne .sobjokay2
dec cl
mov byte[C4SObjSelec],cl
jmp .sobjokay
.sobjokay2
cmp byte[C4SObjSelec],cl
jb .sobjokay
mov byte[C4SObjSelec],0
.sobjokay
xor ecx,ecx
mov cl,byte[C4SObjSelec]
shl ecx,2
add ebx,ecx
add ebx,4
; i,j,k,l = move current sub-object (17,24,25,26)
; u = toggle between 8x8 and 16x16 tiles
; o = toggle between high/low oam value
; . = decrease oam value, / = increase oam value of sub-object
cmp byte[pressed+17h],0
je .notpressed8
mov byte[pressed+17h],0
dec byte[ebx+1]
.notpressed8
cmp byte[pressed+24h],0
je .notpressed9
mov byte[pressed+24h],0
dec byte[ebx]
cmp byte[.flipped],0
je .notpressed9
add byte[ebx],2
.notpressed9
cmp byte[pressed+26h],0
je .notpressed11
mov byte[pressed+26h],0
inc byte[ebx]
cmp byte[.flipped],0
je .notpressed11
sub byte[ebx],2
.notpressed11
cmp byte[pressed+25h],0
je .notpressed10
mov byte[pressed+25h],0
inc byte[ebx+1]
.notpressed10
cmp byte[pressed+16h],0
je .notpressed12
mov byte[pressed+16h],0
xor byte[ebx+3],2
.notpressed12
cmp byte[pressed+18h],0
je .notpressed13
mov byte[pressed+18h],0
xor byte[ebx+3],1
.notpressed13
cmp byte[pressed+34h],0
je .notpressed14
mov byte[pressed+34h],0
dec byte[ebx+2]
.notpressed14
cmp byte[pressed+35h],0
je .notpressed15
mov byte[pressed+35h],0
inc byte[ebx+2]
.notpressed15
mov cl,[ebx]
mov ch,[ebx+1]
.nosubobjs
mov edx,ecx
xor ebx,ebx
xor ecx,ecx
mov bl,[eax]
sub bl,[esi+621h]
add bl,dl
mov cl,[eax+2]
sub cl,[esi+623h]
add cl,dh
mov esi,[vidbuffer]
add esi,16*2+256*2+32*2
add esi,ebx
add esi,ebx
mov ebx,ecx
shl ebx,9
shl ecx,6
add esi,ebx
add esi,ecx
mov al,[C4ColRot]
mov ah,al
xor ah,0FFh
mov [esi],ax
mov [esi+16],ax
mov [esi+288*8*2],ax
mov [esi+16+288*8*2],ax
.skipall
ret
.flipped db 0
C4AddSprite:
cmp dword[C4count],0
je near .nosprite
mov [edi],ax
mov [edi+2],bx
mov ebx,[C4usprptr]
and [ebx],dl
mov al,dl
xor al,0FFh
and dh,al
or [ebx],dh
add edi,4
rol dl,2
rol dh,2
dec dword[C4count]
cmp dl,0FCh
jne .nosprite
inc dword[C4usprptr]
.nosprite
ret
C4ConvOAM:
inc byte[C4Timer]
and byte[C4Timer],15
inc byte[C4Timer2]
and byte[C4Timer2],7
mov esi,[C4Ram]
xor ecx,ecx
mov edi,esi
mov cl,[esi+620h]
mov bx,[esi+621h]
mov [.addx],bx
mov bx,[esi+623h]
mov [.addy],bx
mov [C4usprptr],esi
add dword[C4usprptr],200h
mov eax,[C4ObjDisp]
add edi,eax
shr eax,4
add dword[C4usprptr],eax
add esi,220h
; Convert from esi to edi
mov dl,0FCh
push ecx
mov cl,byte[C4sprites]
and cl,3
add cl,cl
rol dl,cl
pop ecx
cmp cl,0
je near .none
mov dword[C4count],128
mov eax,[C4sprites]
sub dword[C4count],eax
.loop
push ecx
push esi
; 00/01 - x position relative to BG scroll value
; 02/03 - y position relative to BG scroll value
; 04 - palette/priority settings
; 05 - OAM pointer value
; 06 - flip settings : b6 = flipx, b7 = flipy
; 07 - ???
; 08/09 - Pointer to Sprite Structure
; 0A-0F - unused
;bit 1-3 = palette number bit 4,5 = playfield priority
;bit 6 = horizontal flip bit 7 = horizonal flip
mov ax,[esi]
sub ax,[.addx]
mov [C4SprX],ax
mov ax,[esi+2]
sub ax,[.addy]
mov [C4SprY],ax
mov al,[esi+5]
mov [C4SprOAM],al
mov al,[esi+4]
mov ah,al
and ah,0Eh
cmp ah,0
jmp .notstage2
jne .notstage1
cmp byte[C4Timer],0
je .flash
jmp .noflash
.notstage1
jmp .notstage2
cmp ah,4
jne .notstage2
cmp byte[C4Timer2],0
je .flash
.noflash
and al,0F1h
or al,2
jmp .notstage2
.flash
and al,0F1h
.notstage2
mov [C4SprAttr],al
mov al,[esi+6]
or [C4SprAttr],al
; mov [C4SprFlip],al
xor ecx,ecx
mov cl,[esi+9]
shl ecx,16
mov cx,[esi+7]
add cx,cx
shr ecx,1
add ecx,[romdata]
mov al,[ecx]
or al,al
jz near .singlespr
mov [C4SprCnt],al
inc ecx
.nextspr
xor ebx,ebx
movsx bx,byte[ecx+1]
test byte[C4SprAttr],40h
jz .notflipx
neg bx
sub bx,8
.notflipx
add bx,[C4SprX]
xor dh,dh
test byte[ecx],20h
jz .no16x16
or dh,10101010b
test byte[C4SprAttr],40h
jz .no16x16
sub bx,8
.no16x16
cmp bx,-16
jl near .nosprite
cmp bx,272
jg near .nosprite
mov al,bl
test bx,100h
jz .not512b
or dh,01010101b
.not512b
xor ebx,ebx
movsx bx,byte[ecx+2]
test byte[C4SprAttr],80h
jz .notflipy
neg bx
sub bx,8
.notflipy
add bx,[C4SprY]
test byte[ecx],20h
jz .no16x16b
test byte[C4SprAttr],80h
jz .no16x16b
sub bx,8
.no16x16b
cmp bx,-16
jl near .nosprite
cmp bx,224
jg near .nosprite
mov ah,bl
mov bh,[C4SprAttr]
mov bl,[ecx]
and bl,0C0h
xor bh,bl
mov bl,[C4SprOAM]
add bl,[ecx+3]
call C4AddSprite
.nosprite
add ecx,4
dec byte[C4SprCnt]
jnz near .nextspr
jmp .donemultispr
.singlespr
mov dh,10101010b
test byte[C4SprX+1],1
jz .not512
or dh,01010101b
.not512
mov al,[C4SprX]
mov ah,[C4SprY]
mov bl,[C4SprOAM]
mov bh,[C4SprAttr]
call C4AddSprite
.donemultispr
pop esi
pop ecx
;NEWSYM C4Data times 64*4096 db 0 ; 15 sprites, 4 bytes each
; x,y,oamptr,stat (b0=oamb8,b1=16x16)
; 4 byte header (#sobj,?,?,?)
add esi,16
dec cl
jnz near .loop
.none
mov esi,oamram
mov edi,[C4Ram]
mov ecx,544
.next
mov al,[edi]
mov [esi],al
inc edi
inc esi
loop .next
ret
.addx dw 0
.addy dw 0
C4count dd 0
C4usprptr dd 0
C4SprX dw 0
C4SprY dw 0
C4SprCnt db 0
C4SprAttr db 0
C4SprOAM db 0
C4SprFlip db 0
C4Timer db 0
C4Timer2 db 0
NEWSYM C4VBlank
ret
NEWSYM C4ProcessSprites
push ecx
push esi
push edi
push ebx
push edx
; call C4ProcessVectors
; call C4Edit
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -