📄 sa1regs.asm
字号:
shr eax,4
xor ebx,ebx
mov bl,al
mov al,[SPCTimerVal+ebx]
mov bl,al
and bl,0Fh
mov [SPC7110RTC+4],bl ; hours
shr eax,4
mov bl,al
and bl,0Fh
mov [SPC7110RTC+5],bl
.24hrs
call Get_TimeDate
mov bl,al
and bl,0Fh
mov [SPC7110RTC+6],bl ; day
shr eax,4
mov bl,al
and bl,0Fh
mov [SPC7110RTC+7],bl
shr eax,4
mov bl,al
and bl,0Fh
xor bh,bh
cmp bl,9
jbe .less
sub bl,10
mov bh,1
.less
mov [SPC7110RTC+8],bl ; month
mov [SPC7110RTC+9],bh ; month
shr eax,8
mov bl,al
and bl,0Fh
mov [SPC7110RTC+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 [SPC7110RTC+11],bl
shr eax,8
and al,0Fh
mov [SPC7110RTC+12],al ; day of week
.done
pop eax
pop ebx
.dontupdate
; test byte[SPC7110RTC+0Fh],1
; jz .realtime
; cmp ebx,0Dh
; jae .realtime
; mov al,[SPC7110RTCB+ebx]
; jmp .next
;.realtime
mov al,[SPC7110RTC+ebx]
;.next
pop ebx
inc byte[SPC7110RTCStat+1]
and byte[SPC7110RTCStat+1],0Fh
ret
.commandbyte
inc byte[SPC7110RTCStat+1]
mov al,byte[SPC7110RTCStat+2]
ret
SPCTimerVal
db 12h,01h,02h,03h,04h,05h,06h,07h,08h,09h,0,0,0,0,0,0
db 10h,11h,32h,21h,22h,23h,24h,25h,26h,27h,0,0,0,0,0,0
db 28h,29h
SPC4842:
mov al,80h
ret
;$4820 16 BIT MULTIPLICAND: ($00FF) low byte, defval:00
; 32 BIT DIVI: ($000000FF) low byte of low word, defval:00
;$4821 16 BIT MULTIPLICAND: ($FF00) high byte, defval:00
; 32 BIT DIVI: ($0000FF00) high byte of low word, defval:00
;$4822 32 BIT DIVI: ($00FF0000) low byte of high word, defval:00
;$4823 32 BIT DIVI: ($FF000000) high byte of high word, defval:00
;$4824 16 BIT MULTIPLIER: ($00FF) low byte, defval:00
;$4825 16 BIT MULTIPLIER: ($FF00) high byte, defval:00
;$4826 16 BIT DIVISOR: ($00FF), defval:00
;$4827 16 BIT DIVISOR: ($FF00), defval:00
;$4828 32 BIT PRODUCT: ($000000FF) low byte of low word, defval:00
; 32 BIT QUOTIENT:($000000FF) low byte of low word, defval:00
;$4829 32 BIT PRODUCT: ($0000FF00) high byte of low word, defval:00
; 32 BIT QUOTIENT:($0000FF00) high byte of low word, defval:00
;$482A 32 BIT PRODUCT: ($00FF0000) low byte of high word, defval:00
; 32 BIT QUOTIENT:($00FF0000) low byte of high word, defval:00
;$482B 32 BIT PRODUCT: ($FF000000) high byte of high word, defval:00
; 32 BIT QUOTIENT:($FF000000) high byte of high word, defval:00
;$482C 16 BIT REMAINDER: ($00FF) low byte, defval:00
;$482D 16 BIT REMAINDER: ($FF00) high byte, defval:00
;$482E MUL/DIV RESET, write = reset $4820 to $482D, defval:00
;$482F MUL/DIV FINISHED STATUS: bit 7: on = processing, off = finished,
; high bit is set after a write to multiplier or divisor regs $4825/$4827, defval:00
; SA-1 Start
; ----------
ALIGN32
; IRQ Stuff
NEWSYM SA1Mode, dd 0 ; 0 = SNES CPU, 1 = SA1 CPU
NEWSYM SA1Control, dd 0 ; don't execute if b5 or 6 are set
NEWSYM SA1BankPtr, dd 0
NEWSYM SA1ResetV, dd 0
NEWSYM SA1NMIV, dd 0
NEWSYM SA1IRQV, dd 0
NEWSYM SA1RV, dd 0
NEWSYM CurBWPtr, dd 0
NEWSYM SA1TempVar, dd 0
NEWSYM SA1IRQEn, dd 0
NEWSYM SA1Message, dd 0
NEWSYM SA1IRQExec, dd 0
NEWSYM SA1IRQEnable, dd 0
NEWSYM SA1DoIRQ, dd 0
; Arithmetic Stuff
NEWSYM SA1ARC, dd 0
NEWSYM SA1AR1, dd 0
NEWSYM SA1AR2, dd 0
NEWSYM SA1ARR1, dd 0
NEWSYM SA1ARR2,dd 0
NEWSYM SA1Stat, dd 0
NEWSYM SNSNMIV, dd 0
NEWSYM SNSIRQV, dd 0
NEWSYM SA1DMACount, dd 0
NEWSYM SA1DMAInfo, dd 0
NEWSYM SA1DMAChar, dd 0
NEWSYM SA1DMASource, dd 0
NEWSYM SA1DMADest, dd 0
NEWSYM SA1IRQTemp, dd 0
NEWSYM SA1BankSw, dd 1
NEWSYM SA1BankVal, db 0,1,2,3
NEWSYM BWShift, dd 0
NEWSYM BWAndAddr, dd 0
NEWSYM BWAnd, dd 0
NEWSYM BWRAnd, dd 0
SA1Reserved times 456 db 0
; SA1 Swap Stuff
NEWSYM SA1xa, dd 0
NEWSYM SA1xx, dd 0
NEWSYM SA1xy, dd 0
NEWSYM SA1xd, dd 0
NEWSYM SA1xdb, dd 0
NEWSYM SA1xpb, dd 0
NEWSYM SA1xs, dd 0
NEWSYM SA1RegP, dd 0
NEWSYM SA1RegE, dd 0
NEWSYM SA1RegPCS,dd 0
NEWSYM SA1BWPtr,dd 0
NEWSYM SA1Ptr, dd 0 ; Current PC, SA-1
NEWSYM SA1Overflow, dd 0
NEWSYM VarLenAddr, dd 0
NEWSYM VarLenAddrB, dd 0
NEWSYM VarLenBarrel, dd 0
NEWSYM SA1TimerVal, dd 0
NEWSYM SA1TimerSet, dd 0
NEWSYM SA1TimerCount, dd 0
NEWSYM SA1IRQData, dd 0
; SNES Swap Stuff
NEWSYM SNSRegP, dd 0
NEWSYM SNSRegE, dd 0
NEWSYM SNSRegPCS,dd 0
NEWSYM SNSBWPtr,dd 0
NEWSYM SNSPtr, dd 0 ; Current PC, SNES
NEWSYM IRAM, times 2049 db 0 ;2 kbytes of iram
num2writesa1reg equ $-SA1Mode
NEWSYM PHnum2writesa1reg, dd num2writesa1reg
NEWSYM SA1RAMArea, dd 0
NEWSYM SA1Temp, dd 0
NEWSYM Sdd1Mode, dd 0
NEWSYM Sdd1Bank, dd 0
NEWSYM Sdd1Addr, dd 0
NEWSYM Sdd1NewAddr, dd 0
%macro SA1QuickF 2
NEWSYM %1
mov [%2],al
ret
%endmacro
NEWSYM RestoreSA1
mov eax,[romdata]
add [SA1RegPCS],eax
add [CurBWPtr],eax
add [SA1BWPtr],eax
add [SNSBWPtr],eax
cmp byte[SA1Stat],1
jne .notsa1stat
mov dword[SA1RegPCS],IRAM
.notsa1stat
cmp byte[SA1Stat],2
jne .notsa1stat2
mov dword[SA1RegPCS],IRAM-3000h
.notsa1stat2
mov eax,[SA1RegPCS]
add [SA1Ptr],eax
mov eax,[romdata]
add eax,4096*1024
mov [SA1RAMArea],eax
pushad
call UpdateBanks
popad
ret
NEWSYM SaveSA1
mov byte[SA1Stat],0
mov eax,[SA1RegPCS]
sub [SA1Ptr],eax
cmp dword[SA1RegPCS],IRAM
jne .notiram
mov byte[SA1Stat],1
.notiram
cmp dword[SA1RegPCS],IRAM-3000h
jne .notiram2
mov byte[SA1Stat],2
.notiram2
mov eax,[romdata]
sub [SA1RegPCS],eax
sub [CurBWPtr],eax
sub [SA1BWPtr],eax
sub [SNSBWPtr],eax
ret
NEWSYM 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 dword[CurBWPtr],eax
mov dword[SA1BWPtr],eax
mov dword[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
NEWSYM UpdateBanks
cmp byte[SA1BankSw],1
jne .noswap
mov al,[SA1BankVal]
call sa12220w
mov al,[SA1BankVal+1]
call sa12221w
mov al,[SA1BankVal+2]
call sa12222w
mov al,[SA1BankVal+3]
call sa12223w
.noswap
ret
NEWSYM UpdateBanksSDD1
pushad
cmp dword[SDD1BankA],0
je .nobank
mov al,[SDD1BankA]
call sdd14804w
mov al,[SDD1BankA+1]
call sdd14805w
mov al,[SDD1BankA+2]
call sdd14806w
mov al,[SDD1BankA+3]
call sdd14807w
.nobank
popad
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
loop .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
loop .mmaploop2
pop eax
pop edx
pop ecx
ret
%endmacro
NEWSYM sa12220w
BankSwitch 0,0,0C0h,0
NEWSYM sa12221w
BankSwitch 1,20h,0D0h,100000h
NEWSYM sa12222w
BankSwitch 2,80h,0E0h,200000h
NEWSYM 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
loop .mmaploop2
pop eax
pop edx
pop ecx
ret
%endmacro
sdd14804:
mov al,[SDD1BankA]
ret
sdd14805:
mov al,[SDD1BankA+1]
ret
sdd14806:
mov al,[SDD1BankA+2]
ret
sdd14807:
mov al,[SDD1BankA+3]
ret
NEWSYM sdd14804w
BankSwitchSDD1 0,0C0h
NEWSYM sdd14805w
BankSwitchSDD1 1,0D0h
NEWSYM sdd14806w
BankSwitchSDD1 2,0E0h
NEWSYM sdd14807w
BankSwitchSDD1 3,0F0h
NEWSYM sa12200w
mov bl,al
and bl,0Fh
mov byte[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
ret
NEWSYM sa12201w ; IRQ Enable
mov byte[SA1IRQEnable],al
ret
NEWSYM 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
ret
SA1QuickF sa12203w, SA1ResetV
SA1QuickF sa12204w, SA1ResetV+1
SA1QuickF sa12205w, SA1NMIV
SA1QuickF sa12206w, SA1NMIV+1
SA1QuickF sa12207w, SA1IRQV
SA1QuickF sa12208w, SA1IRQV+1
NEWSYM 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 byte[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
ret
SA1QuickF sa1220Aw, SA1IRQEn
NEWSYM 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
ret
SA1QuickF sa1220Cw, SNSNMIV
SA1QuickF sa1220Dw, SNSNMIV+1
SA1QuickF sa1220Ew, SNSIRQV
SA1QuickF sa1220Fw, SNSIRQV+1
NEWSYM sa12224w ; BWRAM
mov bl,al
and ebx,1Fh
shl ebx,13
add ebx,[romdata]
add ebx,1024*4096-6000h
mov dword[SNSBWPtr],ebx
cmp byte[SA1Status],0
jne .nosnes
mov dword[CurBWPtr],ebx
.nosnes
ret
NEWSYM sa12225w ; BWRAM
EXTSYM BWUsed2
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 dword[SA1BWPtr],ebx
cmp byte[SA1Status],0
je .nosa1b
mov dword[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 dword[SA1BWPtr],ebx
cmp byte[SA1Status],0
je .nosa1
mov dword[CurBWPtr],ebx
.nosa1
; mov byte[debstop3],1
ret
NEWSYM sa12250w
mov byte[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
ret
NEWSYM sa12251w
mov byte[SA1AR1],al
mov byte[SA1ARC+1],1
ret
NEWSYM sa12252w
mov byte[SA1AR1+1],al
mov byte[SA1ARC+1],1
ret
NEWSYM sa12253w
mov byte[SA1AR2],al
mov byte[SA1ARC+1],1
ret
NEWSYM sa12254w
mov byte[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
ret
UpdateArithStuff:
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
popad
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -