📄 7110proc.asm
字号:
;Copyright (C) 1997-2007 ZSNES Team ( zsKnight, _Demo_, pagefault, Nach );;http://www.zsnes.com;http://sourceforge.net/projects/zsnes;https://zsnes.bountysource.com;;This program is free software; you can redistribute it and/or;modify it under the terms of the GNU General Public License;version 2 as published by the Free Software Foundation.;;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 memaccessbankr8,memaccessbankr16,memaccessbankw8,memaccessbankw16EXTSYM regaccessbankr8,regaccessbankr16,regaccessbankw8,regaccessbankw16EXTSYM sramaccessbankr8b,sramaccessbankr16b,sramaccessbankw8b,sramaccessbankw16bEXTSYM SPC7110PackPtr,SPC7110IndexPtr,SPC7110IndexSize,SPC7_Data_LoadEXTSYM SPC7110Entries,SPC7110filep,Get_Time,Get_TimeDate,snesmmap,snesmap2EXTSYM curromsize,regptw,regptr,romdata%include "cpu/regs.mac"%include "cpu/regsw.mac"%ifndef NO_DEBUGGEREXTSYM debuggeron%endif; SPC7110 emulation. Information fully reverse engineered; by Dark Force and John Weidman, ZSNES code by zsKnightSECTION .dataNEWSYM SPCMultA, dd 0NEWSYM SPCMultB, dd 0NEWSYM SPCDivEnd, dd 0NEWSYM SPCMulRes, dd 0NEWSYM SPCDivRes, dd 0NEWSYM SPC7110BankA, dd 020100hNEWSYM SPC7110RTCStat, dd 0NEWSYM SPC7110RTC, db 00,00,00,00,00,00,01,00,01,00,00,00,00,00,0Fh,00NEWSYM SPC7110RTCB, db 00,00,00,00,00,00,01,00,01,00,00,00,00,01,0Fh,06NEWSYM SPCROMPtr, dd 0NEWSYM SPCROMtoI, dd SPCROMPtrNEWSYM SPCROMAdj, dd 0NEWSYM SPCROMInc, dd 0NEWSYM SPCROMCom, dd 0NEWSYM SPCCompPtr, dd 0NEWSYM SPCDecmPtr, dd 0NEWSYM SPCCompCounter, dd 0NEWSYM SPCCompCommand, dd 0NEWSYM SPCCheckFix, dd 0NEWSYM SPCSignedVal, dd 0num2writespc7110reg equ $-SPCMultANEWSYM PHnum2writespc7110reg, dd num2writespc7110regNEWSYM SPC7110TempPosition, dd 0NEWSYM SPC7110TempLength, dd 0NEWSYM SPCPrevCompPtr, dd 0SECTION .bssNEWSYM SPCDecompFin, resd 1SECTION .textNEWSYM 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 retNEWSYM 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 retNEWSYM 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 dec ecx jnz .mmaploop2 pop eax pop edx pop ecx ret%endmacro%ifndef NO_DEBUGGERNEWSYM 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%endifSPC4800:; 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,[SPC7110PackPtr] 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,[SPC7110PackPtr] 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 retSPC4801: mov al,[SPCCompPtr] retSPC4802: mov al,[SPCCompPtr+1] retSPC4803: mov al,[SPCCompPtr+2] retSPC4804: mov al,[SPCCompPtr+3] retSPC4805: mov al,[SPCDecmPtr] retSPC4806: mov al,[SPCDecmPtr+1] retSPC4807: xor al,al retSPC4808: xor al,al retSPC4809: mov al,[SPCCompCounter] retSPC480A: mov al,[SPCCompCounter+1] retSPC480B: mov al,[SPCCompCommand] mov dword[SPCDecmPtr],0 retSPC480C: ; decompression finished status mov al,[SPCDecompFin] mov byte[SPCDecompFin],0 retSECTION .bssNEWSYM CurPtrVal, resd 1NEWSYM CurPtrLen, resd 1NEWSYM CurValUsed, resb 1NEWSYM PrevDecompPtr, resw 1NEWSYM CurDecompPtr, resw 1NEWSYM CurDecompSize, resw 1NEWSYM DecompArray, resb 65536NEWSYM DecompAPtr, resd 1lastentry resd 1SECTION .textSPC4801w: mov [SPCCompPtr],al retSPC4802w: mov [SPCCompPtr+1],al retSPC4803w: mov [SPCCompPtr+2],al retSPC4804w: mov [SPCCompPtr+3],al retSPC4805w: mov [SPCDecmPtr],al retSPC4806w: mov [SPCDecmPtr+1],al; cmp dword[SPCCompPtr],0124AD48h; jne .nodata; mov byte[debstop3],1;.nodata push ebx mov ebx,[SPCCompPtr] and ebx,0ffffffh push ecx movzx ecx,byte[SPCCompPtr+3] shl ecx,2 add ebx,ecx pop ecx add ebx,100000h add ebx,[romdata] cmp byte[ebx],3 jne .try2 shl word[SPCDecmPtr],3.try2 cmp byte[ebx],2 jne .try1 shl word[SPCDecmPtr],2.try1 cmp byte[ebx],1 jne .skip shl word[SPCDecmPtr],1.skip pop ebx 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 mov byte[CurValUsed],1 mov eax,[SPCCompPtr] and eax,0FFFFFFh mov [CurPtrVal],eax popad mov word[CurDecompSize],0 push eax mov al,[SPCCompPtr+3] mov [CurPtrLen+2],al mov ax,[SPCDecmPtr] mov [CurPtrLen],ax mov eax,[SPCCompPtr] mov [CurPtrVal],eax mov ax,[SPCDecmPtr] mov [PrevDecompPtr],ax mov [CurDecompPtr],ax mov word[CurDecompSize],0 pop eax mov byte[SPCDecompFin],0h ; Start Decompression pushad mov eax,[SPCCompPtr] cmp [SPCPrevCompPtr],eax je near .previousequal mov [SPCPrevCompPtr],eax mov ecx,[SPC7110Entries] mov ebx,[SPCCompPtr] and ebx,0FFFFFFh mov eax,[SPC7110IndexPtr] or ecx,ecx jz .noentries.loopc mov edx,[eax] cmp dl,[SPCCompPtr+3] jne .notfound shr edx,8 cmp ebx,edx je .found.notfound add eax,12 dec ecx jnz .loopc jmp .noentries.found xor word[CurPtrLen],0FFFFh mov ecx,[eax+8] mov ebx,[eax+4] xor edx,edx mov dx,[SPCDecmPtr] add edx,[SPC7110PackPtr] push eax.loopb mov al,[ebx] mov [edx],al inc ebx inc edx dec ecx jnz .loopb pop eax mov ebx,[eax+4] mov edx,[lastentry]; mov [edx+4],ebx mov ebx,[eax]; mov [edx],ebx jmp .foundentry.noentries mov ecx,[SPC7110IndexSize] ; Address/index, pointer, length, SPC7110nfname mov edx,[SPC7110IndexPtr].sploop mov eax,[SPCCompPtr] shl eax,8 mov al,[SPCCompPtr+3] cmp [edx],eax je .foundsp add edx,12 sub ecx,12 jc .overflow jnz .sploop.overflow jmp .notfoundentry.foundsp mov eax,[edx+4] mov [SPC7110TempPosition],eax mov eax,[edx+8] mov [SPC7110TempLength],eax mov edx,[SPC7110filep] mov eax,[SPCCompPtr] and eax,0FFFFFFh mov ecx,6.sploop2 mov ebx,eax shr ebx,20 and ebx,0Fh cmp bl,9 jbe .below9 add bl,55-48.below9 add bl,48 mov [edx],bl inc edx shl eax,4 dec ecx jnz .sploop2 pushad call SPC7_Data_Load popad.notfoundentry.foundentry.previousequal popad.fin.blah ; Finished; mov word[SPCCompCounter],0FFFFh mov byte[SPCDecompFin],80h retSPC4807w: retSPC4808w: retSPC4809w: mov [SPCCompCounter],al retSPC480Aw: mov [SPCCompCounter+1],al retSPC480Bw: mov [SPCCompCommand],al ret; 01,;$4810 DATA ROM CONTINUOUS READ PORT: returns a byte from data rom at data; rom pointer location, defval:00;$4811 DATA ROM POINTER: ($0000FF) r/w low offset, defval:00;$4812 DATA ROM POINTER: ($00FF00) r/w high offset, defval:00;$4813 DATA ROM POINTER: ($FF0000) r/w bank offset, defval:00; bank offset is zero based from start of data rom: banks $00-$3f; data rom -> $10-$4f full rom;$4814 DATA ROM POINTER ADJUST: ($00FF) low byte, defval:00;$4815 DATA ROM POINTER ADJUST: ($FF00) high byte, defval:00;$4816 DATA ROM POINTER INCREMENT: ($00FF) low byte, defval:00;$4817 DATA ROM POINTER INCREMENT: ($FF00) high byte, defval:00;$4818 DATA ROM COMMAND MODE: bit field control of data rom pointer (see; data rom command mode byte), defval:00; write: set command mode,; read: performs action instead of returning value, unknown purpose,; command mode is loaded to $4818 but only set after writing to both; $4814 and $4815 in any order;$481A DATA ROM READ AFTER ADJUST PORT: returns a byte from data rom at; data rom pointer location + adjust value ($4814/5), defval:00SPC4810: cmp dword[SPCCheckFix],0 jne .okay xor al,al ret.okay push ebx mov ebx,[SPCROMPtr] add ebx,[romdata] add ebx,100000h test byte[SPCROMCom],2 jz .no2 add ebx,[SPCROMAdj] inc word[SPCROMAdj] mov al,[ebx] pop ebx ret.no2 mov al,[ebx] cmp byte[SPCROMCom+1],0 jne .noincr1 mov ebx,[SPCROMtoI] inc dword[ebx].noincr1 cmp byte[SPCROMCom+1],1 ; add 4816 after 4810 read jne .noincr1b mov ebx,[SPCROMtoI] push ecx mov ecx,[SPCROMInc] add dword[ebx],ecx pop ecx.noincr1b pop ebx retSPC4811: mov al,[SPCROMPtr] retSPC4812: mov al,[SPCROMPtr+1] retSPC4813: mov al,[SPCROMPtr+2]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -