📄 sa1regs.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.
; SPC7110 emulation. Information fully reverse engineered
; by Dark Force and John Weidman, ZSNES code by zsKnight
; SA-1 emulation. Information provided by Ivar of Snes9x.
; coded by zsKnight
; SDD-1 emulation. SDD-1 MMC reverse engineered by zsKnight,
; SDD-1 decompress Dark Force and John Weidman,
; - Add MMC support
; - Add end of DMA IRQ support
; - Add Char Conversion #1
; - Add Char Conversion #2
; - Add Memory Disables (Guess this isn't needed)
; IRQs - IRQ Clear (also clear 2300), IRQ Disable, and IRQ Enable
; Mario RPG Level-up not working - it was using one of the IRQ functions
; that no other place in the game is using, which I suppose is the cause
; of the problem, but it's been so long since I worked on SA-1, that
; I forgot which part.
%include "macros.mac"
EXTSYM regptr,regptw,romdata,SA1Status,debstop4,SDD1BankA,curromsize
EXTSYM debuggeron
EXTSYM Get_Time,Get_TimeDate
EXTSYM spc7110romptr,SPC7110Entries
EXTSYM SPC7110IndexSize,SPC7110nfname
EXTSYM Open_File,Close_File,Read_File,File_Seek
; EXTSYM Msgptr,MessageOn
EXTSYM irqv2,irqv,nmiv2,nmiv
EXTSYM snesmmap,snesmap2
EXTSYM curypos,CurrentExecSA1
EXTSYM debstop3
EXTSYM memaccessbankr8sdd1,memtabler8,AddrNoIncr
EXTSYM NumofBanks
NEWSYM Sa1RegsAsmStart
%include "cpu/regs.mac"
%include "cpu/regsw.mac"
ALIGN32
NEWSYM SPCMultA, dd 0
NEWSYM SPCMultB, dd 0
NEWSYM SPCDivEnd, dd 0
NEWSYM SPCMulRes, dd 0
NEWSYM SPCDivRes, dd 0
NEWSYM SPC7110BankA, dd 020100h
NEWSYM SPC7110RTCStat, dd 0
NEWSYM SPC7110RTC, db 00,00,00,00,00,00,01,00,01,00,00,00,00,00,0Fh,00
NEWSYM SPC7110RTCB, db 00,00,00,00,00,00,01,00,01,00,00,00,00,01,0Fh,06
NEWSYM SPCROMPtr, dd 0
NEWSYM SPCROMtoI, dd SPCROMPtr
NEWSYM SPCROMAdj, dd 0
NEWSYM SPCROMInc, dd 0
NEWSYM SPCROMCom, dd 0
NEWSYM SPCCompPtr, dd 0
NEWSYM SPCDecmPtr, dd 0
NEWSYM SPCCompCounter, dd 0
NEWSYM SPCCompCommand, dd 0
NEWSYM SPCCheckFix, dd 0
NEWSYM SPCSignedVal, dd 0
num2writespc7110reg equ $-SPCMultA
NEWSYM PHnum2writespc7110reg, dd num2writespc7110reg
NEWSYM RTCData, db 0Fh,0,0,0,0,0,0,0,0,0,0,0,0,0,0Fh,0
NEWSYM RTCPtr, dd 0
NEWSYM RTCPtr2, dd 0
NEWSYM RTCRest, dd 0
NEWSYM SPC7110TempPosition, dd 0
NEWSYM SPC7110TempLength, dd 0
NEWSYM SPCPrevCompPtr, dd 0
RTC2800:
push ebx
cmp dword[RTCRest],100
; je .go
; inc dword[RTCRest]
; jmp .notfirst
.go
cmp dword[RTCPtr],0
jne near .notfirst
cmp byte[debuggeron],1
je near .notfirst
; fill time/date
push ebx
push eax
call Get_Time
mov bl,al
and bl,0Fh
mov [RTCData+1],bl ; seconds
shr eax,4
mov bl,al
and bl,0Fh
mov [RTCData+2],bl
; jmp .done
shr eax,4
cmp word[RTCData+1],0
; jne .notminch
mov bl,al
and bl,0Fh
mov [RTCData+3],bl ; minutes
shr eax,4
mov bl,al
and bl,0Fh
mov [RTCData+4],bl
.notminch
; jmp .done
shr eax,4
mov bl,al
and bl,0Fh
mov [RTCData+5],bl ; hours
shr eax,4
mov bl,al
and bl,0Fh
mov [RTCData+6],bl
call Get_TimeDate
mov bl,al
and bl,0Fh
mov [RTCData+7],bl ; day
shr eax,4
mov bl,al
and bl,0Fh
mov bl,al
and bl,0Fh
mov [RTCData+8],bl
shr eax,4
mov bl,al
and bl,0Fh
mov [RTCData+9],bl ; month
shr eax,8
mov bl,al
and bl,0Fh
mov [RTCData+10],bl ; year
shr eax,4
mov bl,al
and bl,01Fh
xor bh,bh
.notokay
cmp bl,9
jbe .okay
inc bh
sub bl,10
jmp .notokay
.okay
mov [RTCData+11],bl
add bh,9
mov [RTCData+12],bh
shr eax,8
and al,0Fh
mov [RTCData+13],al ; day of week
.done
pop eax
pop ebx
.notfirst
mov ebx,[RTCPtr]
mov al,[RTCData+ebx]
inc dword[RTCPtr]
cmp dword[RTCPtr],0Fh
jne .notclear
mov dword[RTCPtr],0
.notclear
pop ebx
ret
RTC2801w:
; mov byte[debstop3],1
mov dword[RTCRest],0
mov dword[RTCPtr],0
cmp al,0Eh
jne .notreset
mov dword[RTCPtr2],0
ret
.notreset
cmp al,0Dh
jne .notstop
mov dword[RTCPtr2],0
ret
.notstop
push ebx
mov ebx,dword[RTCPtr2]
cmp ebx,0
je .next
cmp ebx,13
ja .nomore
mov [RTCData+ebx],al
.next
inc dword[RTCPtr2]
.nomore
pop ebx
ret
NEWSYM RTCinit
mov dword[RTCPtr],0
ret
NEWSYM RTCReset
setreg 2800h*4,RTC2800
ret
NEWSYM RTCReset2
setregw 2801h*4,RTC2801w
ret
SPC4850:
mov al,[SPC7110RTC]
ret
SPC4851:
mov al,[SPC7110RTC+01h]
ret
SPC4852:
mov al,[SPC7110RTC+02h]
ret
SPC4853:
mov al,[SPC7110RTC+03h]
ret
SPC4854:
mov al,[SPC7110RTC+04h]
ret
SPC4855:
mov al,[SPC7110RTC+05h]
ret
SPC4856:
mov al,[SPC7110RTC+06h]
ret
SPC4857:
mov al,[SPC7110RTC+07h]
ret
SPC4858:
mov al,[SPC7110RTC+08h]
ret
SPC4859:
mov al,[SPC7110RTC+09h]
ret
SPC485A:
mov al,[SPC7110RTC+0Ah]
ret
SPC485B:
mov al,[SPC7110RTC+0Bh]
ret
SPC485C:
mov al,[SPC7110RTC+0Ch]
ret
SPC485D:
mov al,[SPC7110RTC+0Dh]
ret
SPC485E:
mov al,[SPC7110RTC+0Eh]
ret
SPC485F:
mov al,[SPC7110RTC+0Fh]
ret
NEWSYM SPCDecompFin, dd 0
NEWSYM SPC7110init
mov dword[SPCMultA],0
mov dword[SPCMultB],0
mov dword[SPCDivEnd],0
mov dword[SPCMulRes],0
mov dword[SPCDivRes],0
mov dword[SPC7110BankA],020100h
mov dword[SPC7110RTCStat],0
mov dword[SPC7110RTCStat],0
mov dword[SPCROMPtr],0
mov dword[SPCROMtoI],SPCROMPtr
mov dword[SPCROMAdj],0
mov dword[SPCROMInc],0
mov dword[SPCROMCom],0
mov dword[SPCDecompFin],0
mov dword[SPCCompPtr],0
mov dword[SPCDecmPtr],0
mov dword[SPCCompCounter],0
mov dword[SPCCompCommand],0
mov dword[SPCCheckFix],0
mov dword[SPCPrevCompPtr],0
ret
NEWSYM SPC7110Reset
setregw 4801h*4,SPC4801w
setregw 4802h*4,SPC4802w
setregw 4803h*4,SPC4803w
setregw 4804h*4,SPC4804w
setregw 4805h*4,SPC4805w
setregw 4806h*4,SPC4806w
setregw 4807h*4,SPC4807w
setregw 4808h*4,SPC4808w
setregw 4809h*4,SPC4809w
setregw 480Ah*4,SPC480Aw
setregw 480Bh*4,SPC480Bw
setregw 4811h*4,SPC4811w
setregw 4812h*4,SPC4812w
setregw 4813h*4,SPC4813w
setregw 4814h*4,SPC4814w
setregw 4815h*4,SPC4815w
setregw 4816h*4,SPC4816w
setregw 4817h*4,SPC4817w
setregw 4818h*4,SPC4818w
setregw 4820h*4,SPC4820w
setregw 4821h*4,SPC4821w
setregw 4822h*4,SPC4822w
setregw 4823h*4,SPC4823w
setregw 4824h*4,SPC4824w
setregw 4825h*4,SPC4825w
setregw 4826h*4,SPC4826w
setregw 4827h*4,SPC4827w
setregw 482Eh*4,SPC482Ew
setregw 4831h*4,SPC4831w
setregw 4832h*4,SPC4832w
setregw 4833h*4,SPC4833w
setregw 4840h*4,SPC4840w
setregw 4841h*4,SPC4841w
setregw 4842h*4,SPC4842w
ret
NEWSYM initSPC7110regs
setreg 4800h*4,SPC4800
setreg 4801h*4,SPC4801
setreg 4802h*4,SPC4802
setreg 4803h*4,SPC4803
setreg 4804h*4,SPC4804
setreg 4805h*4,SPC4805
setreg 4806h*4,SPC4806
setreg 4807h*4,SPC4807
setreg 4808h*4,SPC4808
setreg 4809h*4,SPC4809
setreg 480Ah*4,SPC480A
setreg 480Bh*4,SPC480B
setreg 480Ch*4,SPC480C
setreg 4810h*4,SPC4810
setreg 4811h*4,SPC4811
setreg 4812h*4,SPC4812
setreg 4813h*4,SPC4813
setreg 4814h*4,SPC4814
setreg 4815h*4,SPC4815
setreg 4816h*4,SPC4816
setreg 4817h*4,SPC4817
setreg 4818h*4,SPC4818
setreg 481Ah*4,SPC481A
setreg 4820h*4,SPC4820
setreg 4821h*4,SPC4821
setreg 4822h*4,SPC4822
setreg 4823h*4,SPC4823
setreg 4824h*4,SPC4824
setreg 4825h*4,SPC4825
setreg 4826h*4,SPC4826
setreg 4827h*4,SPC4827
setreg 4828h*4,SPC4828
setreg 4829h*4,SPC4829
setreg 482Ah*4,SPC482A
setreg 482Bh*4,SPC482B
setreg 482Ch*4,SPC482C
setreg 482Dh*4,SPC482D
setreg 482Eh*4,SPC482E
setreg 482Fh*4,SPC482F
setreg 4831h*4,SPC4831
setreg 4832h*4,SPC4832
setreg 4833h*4,SPC4833
setreg 4834h*4,SPC4834
setreg 4840h*4,SPC4840
setreg 4841h*4,SPC4841
setreg 4842h*4,SPC4842
setreg 4850h*4,SPC4850
setreg 4851h*4,SPC4851
setreg 4852h*4,SPC4852
setreg 4853h*4,SPC4853
setreg 4854h*4,SPC4854
setreg 4855h*4,SPC4855
setreg 4856h*4,SPC4856
setreg 4857h*4,SPC4857
setreg 4858h*4,SPC4858
setreg 4859h*4,SPC4859
setreg 485Ah*4,SPC485A
setreg 485Bh*4,SPC485B
setreg 485Ch*4,SPC485C
setreg 485Dh*4,SPC485D
setreg 485Eh*4,SPC485E
setreg 485Fh*4,SPC485F
ret
%macro BankSwitchSPC7110 2
push ecx
push edx
push eax
mov [SPC7110BankA+%1],al
inc al
cmp byte[curromsize],13
jne .mbit24
.mbit40
cmp al,5
jb .okaymbit
sub al,4
jmp .mbit40
.mbit24
cmp al,3
jb .okaymbit
sub al,2
jmp .mbit24
.okaymbit
and eax,07h
shl eax,20
add eax,[romdata]
mov ecx,10h
mov ebx,snesmap2+%2*4
mov edx,snesmmap+%2*4
.mmaploop2
mov [ebx],eax
mov [edx],eax
add eax,10000h
add ebx,4
add edx,4
loop .mmaploop2
pop eax
pop edx
pop ecx
ret
%endmacro
NEWSYM LastLog
pushad
cmp byte[CurValUsed],0
je near .novalue
xor ebx,ebx
mov edx,DecompArray
mov eax,[CurPtrVal]
cmp dword[DecompAPtr],0
je .noptr
.loop
mov ecx,[edx]
cmp ecx,eax
je .match
add edx,8
inc ebx
cmp ebx,[DecompAPtr]
jne .loop
.noptr
cmp dword[DecompAPtr],8192
je .novalue
mov [edx],eax
xor eax,eax
mov ax,[CurDecompSize]
mov [edx+4],ax
mov ax,[CurPtrLen]
mov [edx+6],ax
mov al,[CurPtrLen+2]
mov [edx+3],al
inc dword[DecompAPtr]
jmp .novalue
.match
add edx,4
mov bx,[CurDecompSize]
xor ebx,ebx
cmp [edx],bx
jae .novalue
mov [edx],bx
.novalue
mov [lastentry],edx
mov byte[CurValUsed],1
mov eax,[SPCCompPtr]
and eax,0FFFFFFh
mov [CurPtrVal],eax
popad
ret
SPC4800:
; mov byte[debstop3],1
; cmp word[SPCCompCounter],0FFFFh
; jne .notzero
; xor al,al
; ret
;.notzero
cmp byte[SPCCompCommand],0
je .manual
xor al,al
dec word[SPCCompCounter]
push ebx
xor ebx,ebx
; mov ebx,[SPCCompPtr]
; and ebx,0FFFFFFh
; add ebx,[romdata]
; add ebx,100000h
mov bx,[SPCDecmPtr]
add ebx,[romdata]
add ebx,510000h
mov al,[ebx]
pop ebx
; xor al,al
inc dword[SPCCompPtr]
push eax
inc word[SPCDecmPtr]
mov ax,[SPCDecmPtr]
mov [CurDecompPtr],ax
sub ax,[PrevDecompPtr]
mov [CurDecompSize],ax
pop eax
; cmp word[SPCCompCounter],0FFFFh
; jne .exit
; mov byte[SPCDecompFin],80h
;.exit
ret
.manual
xor al,al
push ebx
xor ebx,ebx
mov bx,[SPCDecmPtr]
add ebx,[romdata]
add ebx,510000h
mov al,[ebx]
pop ebx
dec word[SPCCompCounter]
inc dword[SPCCompPtr]
inc word[SPCDecmPtr]
inc word[CurDecompSize]
; cmp word[SPCCompCounter],0FFFFh
; jne .exit2
; mov byte[SPCDecompFin],80h
;.exit2
ret
SPC4801:
mov al,[SPCCompPtr]
ret
SPC4802:
mov al,[SPCCompPtr+1]
ret
SPC4803:
mov al,[SPCCompPtr+2]
ret
SPC4804:
mov al,[SPCCompPtr+3]
ret
SPC4805:
mov al,[SPCDecmPtr]
ret
SPC4806:
mov al,[SPCDecmPtr+1]
ret
SPC4807:
xor al,al
ret
SPC4808:
xor al,al
ret
SPC4809:
mov al,[SPCCompCounter]
ret
SPC480A:
mov al,[SPCCompCounter+1]
ret
SPC480B:
mov al,[SPCCompCommand]
mov dword[SPCDecmPtr],0
ret
SPC480C: ; decompression finished status
mov al,[SPCDecompFin]
mov byte[SPCDecompFin],0
ret
NEWSYM CurPtrVal, dd 0
NEWSYM CurCompCounter2, dd 0
NEWSYM CurPtrLen, dd 0
NEWSYM CurValUsed, db 0
NEWSYM PrevDecompPtr, dw 0
NEWSYM CurDecompPtr, dw 0
NEWSYM CurDecompSize, dw 0
NEWSYM DecompArray, times 65536 db 0
NEWSYM DecompAPtr, dd 0
lastentry dd 0
NEWSYM UpdateRTC
test byte[SPC7110RTC+0Dh],02h
jnz .notimer
.notimer
ret
SPC4801w:
mov [SPCCompPtr],al
ret
SPC4802w:
mov [SPCCompPtr+1],al
ret
SPC4803w:
mov [SPCCompPtr+2],al
ret
SPC4804w:
mov [SPCCompPtr+3],al
ret
SPC4805w:
mov [SPCDecmPtr],al
ret
SPC4806w:
mov [SPCDecmPtr+1],al
cmp dword[SPCCompPtr],0124AD48h
jne .nodata
; mov byte[debstop3],1
.nodata
pushad
cmp byte[CurValUsed],0
je near .novalue
xor ebx,ebx
mov edx,DecompArray
mov eax,[CurPtrVal]
; and eax,0FFFFFFh
cmp dword[DecompAPtr],0
je .noptr
.loop
mov ecx,[edx]
; and ecx,0FFFFFFh
cmp ecx,eax
je .match
add edx,8
inc ebx
cmp ebx,[DecompAPtr]
jne .loop
.noptr
cmp dword[DecompAPtr],8192
je .novalue
mov [edx],eax
xor eax,eax
mov ax,[CurDecompSize]
mov [edx+4],ax
mov ax,[CurPtrLen]
mov [edx+6],ax
mov al,[CurPtrLen+2]
mov [edx+3],al
inc dword[DecompAPtr]
jmp .novalue
.match
add edx,4
xor ebx,ebx
mov bx,[CurDecompSize]
cmp [edx],bx
jae .novalue
mov [edx],bx
.novalue
mov [lastentry],edx
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -