📄 sa1regs.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.; 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,SDD1BankA,NumofBanks,BWUsed2EXTSYM Get_Time,Get_TimeDate,irqv2,irqv,nmiv2,nmiv,snesmmap,snesmap2EXTSYM curypos,CurrentExecSA1,memaccessbankr8sdd1,memtabler8,AddrNoIncr%ifndef NO_DEBUGGEREXTSYM debuggeron,debstop4%endif%include "cpu/regs.mac"%include "cpu/regsw.mac"SECTION .dataNEWSYM RTCData, db 0Fh,0,0,0,0,0,0,0,0,0,0,0,0,0,0Fh,0NEWSYM RTCPtr, dd 0NEWSYM RTCPtr2, dd 0NEWSYM RTCRest, dd 0SECTION .textRTC2800: push ebx cmp dword[RTCRest],100; je .go; inc dword[RTCRest]; jmp .notfirst.go cmp dword[RTCPtr],0 jne near .notfirst%ifndef NO_DEBUGGER cmp byte[debuggeron],1 je near .notfirst%endif ; 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 retRTC2801w:; 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,[RTCPtr2] cmp ebx,0 je .next cmp ebx,13 ja .nomore mov [RTCData+ebx],al.next inc dword[RTCPtr2].nomore pop ebx retNEWSYM RTCinit mov dword[RTCPtr],0 retNEWSYM RTCReset setreg 2800h*4,RTC2800 retNEWSYM RTCReset2 setregw 2801h*4,RTC2801w ret; SA-1 Start; ----------SECTION .data; IRQ StuffNEWSYM SA1Mode, dd 0 ; 0 = SNES CPU, 1 = SA1 CPUNEWSYM SA1Control, dd 0 ; don't execute if b5 or 6 are setNEWSYM SA1BankPtr, dd 0NEWSYM SA1ResetV, dd 0NEWSYM SA1NMIV, dd 0NEWSYM SA1IRQV, dd 0NEWSYM SA1RV, dd 0NEWSYM CurBWPtr, dd 0NEWSYM SA1TempVar, dd 0NEWSYM SA1IRQEn, dd 0NEWSYM SA1Message, dd 0NEWSYM SA1IRQExec, dd 0NEWSYM SA1IRQEnable, dd 0NEWSYM SA1DoIRQ, dd 0; Arithmetic StuffNEWSYM SA1ARC, dd 0NEWSYM SA1AR1, dd 0NEWSYM SA1AR2, dd 0NEWSYM SA1ARR1, dd 0NEWSYM SA1ARR2,dd 0NEWSYM SA1Stat, dd 0NEWSYM SNSNMIV, dd 0NEWSYM SNSIRQV, dd 0NEWSYM SA1DMACount, dd 0NEWSYM SA1DMAInfo, dd 0NEWSYM SA1DMAChar, dd 0NEWSYM SA1DMASource, dd 0NEWSYM SA1DMADest, dd 0NEWSYM SA1IRQTemp, dd 0NEWSYM SA1BankSw, dd 1NEWSYM SA1BankVal, db 0,1,2,3NEWSYM BWShift, dd 0NEWSYM BWAndAddr, dd 0NEWSYM BWAnd, dd 0NEWSYM BWRAnd, dd 0SA1Reserved times 456 db 0; SA1 Swap StuffNEWSYM SA1xa, dd 0NEWSYM SA1xx, dd 0NEWSYM SA1xy, dd 0NEWSYM SA1xd, dd 0NEWSYM SA1xdb, dd 0NEWSYM SA1xpb, dd 0NEWSYM SA1xs, dd 0NEWSYM SA1RegP, dd 0NEWSYM SA1RegE, dd 0NEWSYM SA1RegPCS,dd 0NEWSYM SA1BWPtr,dd 0NEWSYM SA1Ptr, dd 0 ; Current PC, SA-1NEWSYM SA1Overflow, dd 0NEWSYM VarLenAddr, dd 0NEWSYM VarLenAddrB, dd 0NEWSYM VarLenBarrel, dd 0NEWSYM SA1TimerVal, dd 0NEWSYM SA1TimerSet, dd 0NEWSYM SA1TimerCount, dd 0NEWSYM SA1IRQData, dd 0; SNES Swap StuffNEWSYM SNSRegP, dd 0NEWSYM SNSRegE, dd 0NEWSYM SNSRegPCS,dd 0NEWSYM SNSBWPtr,dd 0NEWSYM SNSPtr, dd 0 ; Current PC, SNESNEWSYM IRAM, times 2049 db 0 ;2 kbytes of iramnum2writesa1reg equ $-SA1ModeNEWSYM PHnum2writesa1reg, dd num2writesa1regNEWSYM SA1RAMArea, dd 0NEWSYM SA1Temp, dd 0NEWSYM Sdd1Mode, dd 0NEWSYM Sdd1Bank, dd 0NEWSYM Sdd1Addr, dd 0NEWSYM Sdd1NewAddr, dd 0SECTION .text%macro SA1QuickF 2NEWSYM %1 mov [%2],al ret%endmacroNEWSYM SA1Reset mov byte[SA1IRQData+1],0 mov byte[SA1Mode],0 mov byte[SA1Status],0 mov byte[SA1Control],20h mov dword[SA1DoIRQ],0 mov ax,[irqv2] mov [irqv],ax mov ax,[nmiv2] mov [nmiv],ax mov eax,[romdata] sub eax,8000h mov [SA1RegPCS],eax mov eax,[romdata] add eax,4096*1024 mov [SA1RAMArea],eax mov eax,[romdata] add eax,4096*1024-6000h mov [CurBWPtr],eax mov [SA1BWPtr],eax mov [SNSBWPtr],eax mov dword[SA1xa],0 mov dword[SA1xx],0 mov dword[SA1xy],0 mov dword[SA1xd],0 mov dword[SA1xdb],0 mov dword[SA1xpb],0 mov dword[SA1xs],1FFh mov dword[SA1RegP],0 mov dword[SA1RegE],0 mov dword[SA1IRQExec],0 mov dword[SA1IRQEnable],0 mov dword[SA1Message],0 mov word[SA1Overflow],0 ret%macro BankSwitch 4 push ecx push edx push eax mov [SA1BankVal+%1],al mov ebx,snesmmap+%2*4 test al,80h jz .noupper cmp byte[NumofBanks],64 jne .BSBigBank and eax,1.BSBigBank and eax,07h shl eax,20 push eax jmp .yesupper.noupper cmp byte[NumofBanks],64 jne .BSBigBank2 and eax,1.BSBigBank2 and eax,07h shl eax,20 push eax mov eax,%4.yesupper mov ecx,20h add eax,[romdata] sub eax,8000h.mmaploop mov [ebx],eax add eax,8000h add ebx,4 dec ecx jnz .mmaploop pop eax add eax,[romdata] mov ecx,10h mov ebx,snesmap2+%3*4 mov edx,snesmmap+%3*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%endmacroNEWSYM sa12220w BankSwitch 0,0,0C0h,0NEWSYM sa12221w BankSwitch 1,20h,0D0h,100000hNEWSYM sa12222w BankSwitch 2,80h,0E0h,200000hNEWSYM sa12223w BankSwitch 3,0A0h,0F0h,300000h%macro BankSwitchSDD1 2 push ecx push edx push eax mov [SDD1BankA+%1],al 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%endmacrosdd14804: mov al,[SDD1BankA] retsdd14805: mov al,[SDD1BankA+1] retsdd14806: mov al,[SDD1BankA+2] retsdd14807: mov al,[SDD1BankA+3] retNEWSYM sdd14804w BankSwitchSDD1 0,0C0hNEWSYM sdd14805w BankSwitchSDD1 1,0D0hNEWSYM sdd14806w BankSwitchSDD1 2,0E0hNEWSYM sdd14807w BankSwitchSDD1 3,0F0hNEWSYM sa12200w mov bl,al and bl,0Fh mov [SA1Message],bl test al,80h jz .noirq or byte[SA1DoIRQ],1.noirq test al,10h jz .nonmi or byte[SA1DoIRQ],2.nonmi test byte[SA1Control],20h jz .noreset test al,20h jnz .noreset mov [SA1Control],al mov ebx,[romdata] mov [SA1BankPtr],ebx xor ebx,ebx mov bx,[SA1ResetV] add ebx,[romdata] sub ebx,8000h mov [SA1Ptr],ebx mov byte[SA1xpb],0 mov word[SA1xs],1FFh mov ebx,[romdata] sub ebx,8000h mov [SA1RegPCS],ebx xor ebx,ebx ret.noreset mov [SA1Control],al retNEWSYM sa12201w ; IRQ Enable mov [SA1IRQEnable],al retNEWSYM sa12202w ; IRQ Clear test al,80h jz .noirqclear and byte[SA1IRQExec],0FEh and byte[SA1DoIRQ],0FBh.noirqclear test al,20h jz .nocdmairqclear and byte[SA1IRQExec],0FDh and byte[SA1DoIRQ],0F7h.nocdmairqclear retSA1QuickF sa12203w, SA1ResetVSA1QuickF sa12204w, SA1ResetV+1SA1QuickF sa12205w, SA1NMIVSA1QuickF sa12206w, SA1NMIV+1SA1QuickF sa12207w, SA1IRQVSA1QuickF sa12208w, SA1IRQV+1NEWSYM sa12209w ; IRQ Stuff mov [SA1IRQData+1],al test al,80h jz .noirq ; execute IRQ on the SNES or byte[SA1DoIRQ],4.noirq mov bl,al and bl,0Fh mov [SA1Message+1],bl mov bx,[irqv2] test al,40h jz .noirqchange mov bx,[SNSIRQV].noirqchange mov [irqv],bx mov bx,[nmiv2] test al,10h jz .nonmichange mov bx,[SNSNMIV].nonmichange mov [nmiv],bx retSA1QuickF sa1220Aw, SA1IRQEnNEWSYM sa1220Bw ; SA-1 IRQ Clear test al,80h jz .noirqclear mov byte[SA1IRQExec+1],0 and byte[SA1DoIRQ],0FEh.noirqclear test al,20h jz .nocdmairqclear.nocdmairqclear test al,10h jz .nonmiclear mov byte[SA1IRQExec+2],0 and byte[SA1DoIRQ],0FDh.nonmiclear retSA1QuickF sa1220Cw, SNSNMIVSA1QuickF sa1220Dw, SNSNMIV+1SA1QuickF sa1220Ew, SNSIRQVSA1QuickF sa1220Fw, SNSIRQV+1NEWSYM sa12224w ; BWRAM mov bl,al and ebx,1Fh shl ebx,13 add ebx,[romdata] add ebx,1024*4096-6000h mov [SNSBWPtr],ebx cmp byte[SA1Status],0 jne .nosnes mov [CurBWPtr],ebx.nosnes retNEWSYM sa12225w ; BWRAM mov [BWUsed2],al test al,80h jnz .upper mov bl,al and ebx,1Fh shl ebx,13 add ebx,[romdata] add ebx,1024*4096-6000h mov [SA1BWPtr],ebx cmp byte[SA1Status],0 je .nosa1b mov [CurBWPtr],ebx.nosa1b mov byte[BWShift],0 mov byte[BWAndAddr],0 mov byte[BWAnd],0FFh mov byte[BWRAnd],0h ret.upper mov bl,al and ebx,7Fh test byte[SA1Overflow+1],80h jz .16col shl ebx,11 mov byte[BWShift],2 mov byte[BWAndAddr],03h mov byte[BWAnd],03h mov byte[BWRAnd],0FCh jmp .4col.16col mov byte[BWShift],1 mov byte[BWAndAddr],01h mov byte[BWAnd],0Fh mov byte[BWRAnd],0F0h and ebx,3Fh shl ebx,12.4col add ebx,[romdata] add ebx,1024*4096 mov [SA1BWPtr],ebx cmp byte[SA1Status],0 je .nosa1 mov [CurBWPtr],ebx.nosa1; mov byte[debstop3],1 retNEWSYM sa12250w mov [SA1ARC],al mov byte[SA1ARC+1],1 test al,2 jz .notcumul mov word[SA1ARR1],0 mov word[SA1ARR1+2],0 mov word[SA1ARR1+4],0.notcumul retNEWSYM sa12251w mov [SA1AR1],al mov byte[SA1ARC+1],1 retNEWSYM sa12252w mov [SA1AR1+1],al mov byte[SA1ARC+1],1 retNEWSYM sa12253w mov [SA1AR2],al mov byte[SA1ARC+1],1 retNEWSYM sa12254w mov [SA1AR2+1],al mov byte[SA1ARC+1],1 test byte[SA1ARC],2 jnz .cumul call UpdateArithStuff ret ; set overflow bit if exceeds 40bits.cumul pushad xor edx,edx mov ax,[SA1AR1] mov bx,[SA1AR2] imul bx shl edx,16 mov dx,ax mov byte[SA1Overflow],0 add [SA1ARR1],edx adc byte[SA1ARR2],0 jnc .notoverflow mov byte[SA1Overflow],80h.notoverflow popad retUpdateArithStuff: cmp byte[SA1ARC+1],1 jne .noarith pushad mov byte[SA1ARC+1],0 test byte[SA1ARC],3 jz .multiply test byte[SA1ARC],2 jnz near .cumulativesum test byte[SA1ARC],1 jnz .division.multiply xor edx,edx mov ax,[SA1AR1] mov bx,[SA1AR2] imul bx mov [SA1ARR1],ax mov [SA1ARR1+2],dx popad.noarith ret.division movsx eax,word[SA1AR1] xor edx,edx test eax,80000000h jz .notneg mov edx,0FFFFFFFFh.notneg xor ebx,ebx mov bx,[SA1AR2] or ebx,ebx jz .invalid idiv ebx mov [SA1ARR1],ax mov [SA1ARR1+2],dx; mov word[SA1AR1],0; mov word[SA1AR2],0 popad ret.invalid mov word[SA1ARR1],0 mov word[SA1ARR1+2],0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -