2647 lines
52 KiB
NASM
2647 lines
52 KiB
NASM
;Copyright (C) 1997-2005 ZSNES Team ( zsKnight, _Demo_, pagefault, Nach )
|
|
;
|
|
;http://www.zsnes.com
|
|
;http://sourceforge.net/projects/zsnes
|
|
;
|
|
;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,debuggeron
|
|
EXTSYM Get_Time,Get_TimeDate,spc7110romptr,SPC7110Entries,SPC7110IndexSize
|
|
EXTSYM SPC7110nfname,SPC7110filep,SPC7_Convert_Upper,SPC7_Convert_Lower
|
|
EXTSYM Open_File,Close_File,Read_File,File_Seek,irqv2,irqv,nmiv2,nmiv,snesmmap
|
|
EXTSYM snesmap2,curypos,CurrentExecSA1,memaccessbankr8sdd1,memtabler8,AddrNoIncr
|
|
EXTSYM NumofBanks
|
|
|
|
%include "cpu/regs.mac"
|
|
%include "cpu/regsw.mac"
|
|
|
|
|
|
SECTION .data
|
|
|
|
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
|
|
|
|
SECTION .text
|
|
|
|
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
|
|
|
|
SECTION .bss
|
|
NEWSYM SPCDecompFin, resd 1
|
|
|
|
SECTION .text
|
|
|
|
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
|
|
dec ecx
|
|
jnz .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
|
|
|
|
SECTION .bss
|
|
NEWSYM CurPtrVal, resd 1
|
|
NEWSYM CurCompCounter2, resd 1
|
|
NEWSYM CurPtrLen, resd 1
|
|
NEWSYM CurValUsed, resb 1
|
|
NEWSYM PrevDecompPtr, resw 1
|
|
NEWSYM CurDecompPtr, resw 1
|
|
NEWSYM CurDecompSize, resw 1
|
|
NEWSYM DecompArray, resb 65536
|
|
NEWSYM DecompAPtr, resd 1
|
|
lastentry resd 1
|
|
|
|
SECTION .text
|
|
|
|
|
|
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
|
|
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] ;CurCompCounter2]
|
|
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,[spc7110romptr]
|
|
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,[romdata]
|
|
add edx,510000h
|
|
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,[romdata]
|
|
add edx,580000h
|
|
.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,dword[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
|
|
|
|
mov edx,SPC7110nfname
|
|
call Open_File
|
|
jnc .nocaseerror
|
|
pushad
|
|
call SPC7_Convert_Upper
|
|
popad
|
|
call Open_File
|
|
jnc .nocaseerror
|
|
pushad
|
|
call SPC7_Convert_Lower
|
|
popad
|
|
call Open_File
|
|
jc .error
|
|
.nocaseerror
|
|
mov bx,ax
|
|
mov dx,[SPC7110TempPosition]
|
|
mov cx,[SPC7110TempPosition+2]
|
|
call File_Seek
|
|
xor edx,edx
|
|
mov dx,[SPCDecmPtr]
|
|
add edx,[romdata]
|
|
add edx,510000h
|
|
mov ecx,[SPC7110TempLength]
|
|
call Read_File
|
|
call Close_File
|
|
jmp .foundentry
|
|
.error
|
|
; mov dword[Msgptr],SPC7110nfname
|
|
; mov dword[MessageOn],60*6
|
|
.notfoundentry
|
|
.foundentry
|
|
.previousequal
|
|
popad
|
|
.fin
|
|
.blah
|
|
; Finished
|
|
; mov word[SPCCompCounter],0FFFFh
|
|
mov byte[SPCDecompFin],80h
|
|
ret
|
|
SPC4807w:
|
|
ret
|
|
SPC4808w:
|
|
ret
|
|
SPC4809w:
|
|
mov [SPCCompCounter],al
|
|
mov [CurCompCounter2],al
|
|
ret
|
|
SPC480Aw:
|
|
mov [SPCCompCounter+1],al
|
|
mov [CurCompCounter2+1],al
|
|
ret
|
|
SPC480Bw:
|
|
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:00
|
|
|
|
|
|
SPC4810:
|
|
cmp dword[SPCCheckFix],0
|
|
jne .okay
|
|
xor al,al
|
|
ret
|
|
.okay
|
|
push ebx
|
|
push ecx
|
|
mov ebx,[SPCROMPtr]
|
|
add ebx,[romdata]
|
|
add ebx,100000h
|
|
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]
|
|
mov ecx,[SPCROMInc]
|
|
add dword[ebx],ecx
|
|
.noincr1b
|
|
pop ecx
|
|
pop ebx
|
|
ret
|
|
SPC4811:
|
|
mov al,[SPCROMPtr]
|
|
ret
|
|
SPC4812:
|
|
mov al,[SPCROMPtr+1]
|
|
ret
|
|
SPC4813:
|
|
mov al,[SPCROMPtr+2]
|
|
ret
|
|
SPC4814:
|
|
mov al,[SPCROMAdj]
|
|
ret
|
|
SPC4815:
|
|
mov al,[SPCROMAdj+1]
|
|
ret
|
|
SPC4816:
|
|
mov al,[SPCROMInc]
|
|
ret
|
|
SPC4817:
|
|
mov al,[SPCROMInc+1]
|
|
ret
|
|
SPC4818:
|
|
mov al,[SPCROMCom]
|
|
ret
|
|
SPC481A:
|
|
cmp dword[SPCCheckFix],0
|
|
jne .okay
|
|
xor al,al
|
|
ret
|
|
.okay
|
|
push ebx
|
|
push ecx
|
|
xor ebx,ebx
|
|
xor ecx,ecx
|
|
mov bx,[SPCROMAdj]
|
|
add ebx,[SPCROMPtr]
|
|
add ebx,[romdata]
|
|
add ebx,100000h
|
|
mov al,[ebx]
|
|
|
|
cmp byte[SPCROMCom+1],4 ; 16bit 4814
|
|
jne .notincr
|
|
mov ecx,[SPCROMtoI]
|
|
mov ebx,[SPCROMAdj]
|
|
add [ecx],ebx
|
|
.notincr
|
|
pop ecx
|
|
pop ebx
|
|
ret
|
|
|
|
SPC4811w:
|
|
mov [SPCROMPtr],al
|
|
mov byte[SPCCheckFix],1
|
|
ret
|
|
SPC4812w:
|
|
mov [SPCROMPtr+1],al
|
|
ret
|
|
SPC4813w:
|
|
mov [SPCROMPtr+2],al
|
|
ret
|
|
SPC4814w:
|
|
mov [SPCROMAdj],al
|
|
cmp byte[SPCROMCom+1],2 ; 8 bit 4814
|
|
jne .notincr
|
|
mov ebx,[SPCROMtoI]
|
|
xor ecx,ecx
|
|
mov cl,[SPCROMAdj]
|
|
test byte[SPCROMCom],08h
|
|
jz .noneg
|
|
movsx ecx,byte[SPCROMAdj]
|
|
.noneg
|
|
add dword[ebx],ecx
|
|
.notincr
|
|
ret
|
|
SPC4815w:
|
|
mov [SPCROMAdj+1],al
|
|
mov word[SPCROMAdj+2],0
|
|
test byte[SPCROMCom],08h
|
|
jz .noneg
|
|
test byte[SPCROMAdj+1],80h
|
|
jz .noneg
|
|
mov word[SPCROMAdj+2],0FFFFh
|
|
.noneg
|
|
cmp byte[SPCROMCom+1],3 ; 16bit 4814
|
|
jne .notincr
|
|
push ebx
|
|
push ecx
|
|
mov ecx,[SPCROMtoI]
|
|
mov ebx,[SPCROMAdj]
|
|
add [ecx],ebx
|
|
pop ecx
|
|
pop ebx
|
|
.notincr
|
|
ret
|
|
SPC4816w:
|
|
mov [SPCROMInc],al
|
|
ret
|
|
SPC4817w:
|
|
mov [SPCROMInc+1],al
|
|
mov word[SPCROMInc+2],0
|
|
test byte[SPCROMCom],04h
|
|
jz .noneg
|
|
test byte[SPCROMInc+1],40h
|
|
jz .noneg
|
|
mov word[SPCROMInc+2],0FFFFh
|
|
.noneg
|
|
ret
|
|
SPC4818w:
|
|
mov [SPCROMCom],al
|
|
mov word[SPCROMAdj+2],0
|
|
test byte[SPCROMCom],08h
|
|
jz .noneg
|
|
test byte[SPCROMAdj+1],80h
|
|
jz .noneg
|
|
mov word[SPCROMAdj+2],0FFFFh
|
|
.noneg
|
|
mov word[SPCROMInc+2],0
|
|
test byte[SPCROMCom],04h
|
|
jz .noneg2
|
|
test byte[SPCROMInc+1],40h
|
|
jz .noneg2
|
|
mov word[SPCROMInc+2],0FFFFh
|
|
.noneg2
|
|
mov dword[SPCROMtoI],SPCROMPtr
|
|
test byte[SPCROMCom],10h
|
|
jz .nouseadjust
|
|
mov dword[SPCROMtoI],SPCROMAdj
|
|
.nouseadjust
|
|
test al,02h
|
|
jz .no4814
|
|
test al,40h
|
|
jz .no16b
|
|
test al,20h
|
|
jz .not481A
|
|
mov byte[SPCROMCom+1],4 ; 16bit 4814 after 481A
|
|
jmp .fin
|
|
.not481A
|
|
mov byte[SPCROMCom+1],3 ; 16bit 4814
|
|
jmp .fin
|
|
.no16b
|
|
test al,20h
|
|
jz .nooffsetadd
|
|
mov byte[SPCROMCom+1],2 ; 8 bit 4814
|
|
jmp .fin
|
|
.nooffsetadd
|
|
mov byte[SPCROMCom+1],0FFh
|
|
jmp .fin
|
|
.no4814
|
|
test al,01h
|
|
jz .incrval0
|
|
mov byte[SPCROMCom+1],1 ; add 4816 after 4810 read
|
|
jmp .fin
|
|
.incrval0
|
|
mov byte[SPCROMCom+1],0 ; add 1 after 4810 read
|
|
.fin
|
|
ret
|
|
|
|
;Data Rom Command Mode Byte:
|
|
;X6543210
|
|
;||||||||
|
|
;|||||| \__ : 00 - use 1 as the offset increment value, add immediately after reading $4810
|
|
;|||||| : 01 - use $4816 as offset increment, add immediately after reading $4810
|
|
;|||||| : 10 - use $4814 as offset increment, see below for when to add
|
|
;|||||| : 11 - unused
|
|
;||||||____ : 0 - unsigned calculation for $4816
|
|
;||||| 1 - signed calculation for $4816
|
|
;|||||_____ : 0 - unsigned calculation for $4814
|
|
;|||| 1 - signed calculation for $4814
|
|
;||||______ : 0 - offset increment gets added to $4811/2/3
|
|
;||| 1 - offset increment gets added to $4814/5
|
|
;| \_______ : 00 - disable offset addition
|
|
;| : 01 - 8 bit offset addition using $4814, immediately after writing to $4814/5
|
|
;| : 10 - 16 bit offset addition using $4814/5, immediately after writing to $4814/5
|
|
;| : 11 - 16 bit offset addition using $4814/5, only after reading $481A
|
|
;|_________ : unused
|
|
|
|
SPC4820:
|
|
mov al,[SPCMultA]
|
|
; mov byte[debstop3],1
|
|
ret
|
|
SPC4821:
|
|
mov al,[SPCMultA+1]
|
|
ret
|
|
SPC4822:
|
|
mov al,[SPCMultA+2]
|
|
ret
|
|
SPC4823:
|
|
mov al,[SPCMultA+3]
|
|
ret
|
|
SPC4824:
|
|
mov al,[SPCMultB]
|
|
ret
|
|
SPC4825:
|
|
mov al,[SPCMultB+1]
|
|
ret
|
|
SPC4826:
|
|
mov al,[SPCDivEnd]
|
|
ret
|
|
SPC4827:
|
|
mov al,[SPCDivEnd+1]
|
|
ret
|
|
|
|
SPC4820w:
|
|
mov [SPCMultA],al
|
|
ret
|
|
SPC4821w:
|
|
mov [SPCMultA+1],al
|
|
ret
|
|
SPC4822w:
|
|
mov [SPCMultA+2],al
|
|
ret
|
|
SPC4823w:
|
|
mov [SPCMultA+3],al
|
|
ret
|
|
SPC4824w:
|
|
mov [SPCMultB],al
|
|
ret
|
|
SPC4825w:
|
|
mov [SPCMultB+1],al
|
|
; Calculate SPCMultA*SPCMultB -> SPCMulRes
|
|
test byte[SPCSignedVal],1
|
|
jnz .signed
|
|
push edx
|
|
push eax
|
|
push ebx
|
|
xor eax,eax
|
|
xor ebx,ebx
|
|
mov ax,[SPCMultA]
|
|
mov bx,[SPCMultB]
|
|
mul ebx
|
|
mov [SPCMulRes],eax
|
|
pop ebx
|
|
pop eax
|
|
pop edx
|
|
ret
|
|
.signed
|
|
push edx
|
|
push eax
|
|
push ebx
|
|
movsx eax,word[SPCMultA]
|
|
movsx ebx,word[SPCMultB]
|
|
imul ebx
|
|
mov [SPCMulRes],eax
|
|
pop ebx
|
|
pop eax
|
|
pop edx
|
|
ret
|
|
SPC4826w:
|
|
mov [SPCDivEnd],al
|
|
ret
|
|
SPC4827w:
|
|
mov [SPCDivEnd+1],al
|
|
; Calculte SPCMultA/SPCDivEnd -> SPCMulRes, rem SPCDivRes
|
|
cmp word[SPCDivEnd],0
|
|
je near .nodivide
|
|
test byte[SPCSignedVal],1
|
|
jnz .signed
|
|
push edx
|
|
push eax
|
|
push ebx
|
|
xor edx,edx
|
|
xor ebx,ebx
|
|
mov eax,[SPCMultA]
|
|
mov bx,[SPCDivEnd]
|
|
div ebx
|
|
mov [SPCMulRes],eax
|
|
mov [SPCDivRes],dx
|
|
pop ebx
|
|
pop eax
|
|
pop edx
|
|
ret
|
|
.signed
|
|
push edx
|
|
push eax
|
|
push ebx
|
|
xor edx,edx
|
|
mov eax,[SPCMultA]
|
|
test eax,80000000h
|
|
jz .nd
|
|
mov edx,0FFFFFFFFh
|
|
.nd
|
|
movsx ebx,word[SPCDivEnd]
|
|
idiv ebx
|
|
mov [SPCMulRes],eax
|
|
mov [SPCDivRes],dx
|
|
pop ebx
|
|
pop eax
|
|
pop edx
|
|
ret
|
|
.nodivide
|
|
mov dword[SPCMulRes],0FFFFFFFFh
|
|
mov dword[SPCDivRes],0FFFFh
|
|
ret
|
|
SPC4828:
|
|
mov al,[SPCMulRes]
|
|
ret
|
|
SPC4829:
|
|
mov al,[SPCMulRes+1]
|
|
ret
|
|
SPC482A:
|
|
mov al,[SPCMulRes+2]
|
|
ret
|
|
SPC482B:
|
|
mov al,[SPCMulRes+3]
|
|
ret
|
|
SPC482C:
|
|
mov al,[SPCDivRes]
|
|
ret
|
|
SPC482D:
|
|
mov al,[SPCDivRes+1]
|
|
ret
|
|
SPC482E:
|
|
xor al,al
|
|
ret
|
|
SPC482Ew:
|
|
mov byte[SPCSignedVal],al
|
|
mov dword[SPCMultA],0
|
|
mov dword[SPCMultB],0
|
|
mov dword[SPCDivEnd],0
|
|
mov dword[SPCMulRes],0
|
|
mov dword[SPCDivRes],0
|
|
ret
|
|
SPC482F:
|
|
xor al,al
|
|
ret
|
|
|
|
SPC4831w:
|
|
BankSwitchSPC7110 0,0D0h
|
|
ret
|
|
SPC4832w:
|
|
BankSwitchSPC7110 1,0E0h
|
|
ret
|
|
SPC4833w:
|
|
; mov byte[debstop3],1
|
|
BankSwitchSPC7110 2,0F0h
|
|
ret
|
|
SPC4831:
|
|
mov al,[SPC7110BankA]
|
|
ret
|
|
SPC4832:
|
|
mov al,[SPC7110BankA+1]
|
|
ret
|
|
SPC4833:
|
|
mov al,[SPC7110BankA+2]
|
|
ret
|
|
|
|
SPC4834:
|
|
xor al,al
|
|
ret
|
|
|
|
;$4840 RTC CHIP ENABLE/DISABLE: bit 0: on = enable, off = disable, defval:00
|
|
;$4841 RTC INDEX/DATA PORT:
|
|
; first write after rtc enable: rtc command mode byte (see rtc command modes)
|
|
; subsequent writes: index of rtc register to read/write (00-0f)
|
|
; read: returns value of indexed rtc register
|
|
; auto-increment of register index occurs after each subsequent read/write
|
|
;$4842 RTC READY STATUS: bit 7: on = ready, off = still processing, tested before reading rtc data
|
|
; high bit cleared after successful read
|
|
|
|
SPC4840w:
|
|
test al,1
|
|
jz .notreset
|
|
mov byte[SPC7110RTCStat],al
|
|
mov byte[SPC7110RTCStat+1],0FEh
|
|
.notreset
|
|
ret
|
|
SPC4841w:
|
|
cmp byte[SPC7110RTCStat+1],0FEh
|
|
je .commandbyte
|
|
cmp byte[SPC7110RTCStat+1],0FFh
|
|
je .commandindex
|
|
push ebx
|
|
xor ebx,ebx
|
|
mov bl,[SPC7110RTCStat+1]
|
|
mov [SPC7110RTC+ebx],al
|
|
cmp ebx,0Fh
|
|
jne .notlast
|
|
test al,01h
|
|
jz .notlast
|
|
mov dword[SPC7110RTC],0
|
|
mov dword[SPC7110RTC+4],010000h
|
|
mov dword[SPC7110RTC+8],01h
|
|
mov byte[SPC7110RTC+12],0
|
|
.notlast
|
|
pop ebx
|
|
inc byte[SPC7110RTCStat+1]
|
|
and byte[SPC7110RTCStat+1],0Fh
|
|
ret
|
|
.commandbyte
|
|
inc byte[SPC7110RTCStat+1]
|
|
mov byte[SPC7110RTCStat+2],al
|
|
ret
|
|
.commandindex
|
|
push eax
|
|
and al,0Fh
|
|
mov byte[SPC7110RTCStat+1],al
|
|
pop eax
|
|
ret
|
|
SPC4842w:
|
|
ret
|
|
SPC4840:
|
|
mov al,[SPC7110RTCStat]
|
|
ret
|
|
SPC4841:
|
|
cmp byte[SPC7110RTCStat+1],0FEh
|
|
je near .commandbyte
|
|
cmp byte[SPC7110RTCStat+1],0FFh
|
|
je near .commandbyte
|
|
push ebx
|
|
xor ebx,ebx
|
|
mov bl,[SPC7110RTCStat+1]
|
|
or ebx,ebx
|
|
jnz near .dontupdate
|
|
test byte[SPC7110RTC+0Fh],03h
|
|
jnz near .dontupdate
|
|
test byte[SPC7110RTC+0Dh],01h
|
|
jnz near .dontupdate
|
|
;00 - seconds 1's digit 00
|
|
;01 - seconds 10's digit 00
|
|
;02 - minutes 1's digit 00
|
|
;03 - minutes 10's digit 00
|
|
;04 - hours 1's digit 00
|
|
;05 - hours 10's digit 00
|
|
;06 - day of month 1's digit 01
|
|
;07 - day of month 10's digit 00
|
|
;08 - month 1's digit 01
|
|
;09 - month 10's digit 00
|
|
;0a - year 1's digit 00
|
|
;0b - year 10's digit 00
|
|
;0c - day of week 00
|
|
|
|
cmp byte[debuggeron],1
|
|
je near .dontupdate
|
|
; fill time/date
|
|
push ebx
|
|
push eax
|
|
call Get_Time
|
|
mov bl,al
|
|
and bl,0Fh
|
|
mov [SPC7110RTC],bl ; seconds
|
|
shr eax,4
|
|
mov bl,al
|
|
and bl,0Fh
|
|
mov [SPC7110RTC+1],bl
|
|
shr eax,4
|
|
mov bl,al
|
|
and bl,0Fh
|
|
mov [SPC7110RTC+2],bl ; minutes
|
|
shr eax,4
|
|
mov bl,al
|
|
and bl,0Fh
|
|
mov [SPC7110RTC+3],bl
|
|
test byte[SPC7110RTC+0Fh],4
|
|
; jz .not24hrs
|
|
; jmp .not24hrs
|
|
shr eax,4
|
|
mov bl,al
|
|
and bl,0Fh
|
|
mov [SPC7110RTC+4],bl ; hours
|
|
shr eax,4
|
|
mov bl,al
|
|
and bl,0Fh
|
|
mov [SPC7110RTC+5],bl
|
|
jmp .24hrs
|
|
.not24hrs
|
|
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
|
|
|
|
SECTION .data
|
|
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
|
|
|
|
SECTION .text
|
|
|
|
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
|
|
; ----------
|
|
|
|
SECTION .data
|
|
|
|
; 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
|
|
|
|
SECTION .text
|
|
|
|
%macro SA1QuickF 2
|
|
NEWSYM %1
|
|
mov [%2],al
|
|
ret
|
|
%endmacro
|
|
|
|
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
|
|
|
|
%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
|
|
%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
|
|
dec ecx
|
|
jnz .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
|
|
ret
|
|
.cumulativesum
|
|
popad
|
|
ret
|
|
|
|
sa12300r:
|
|
mov al,[SA1Message+1]
|
|
test byte[SA1IRQExec],1
|
|
jz .notexecuted
|
|
or al,80h
|
|
.notexecuted
|
|
test byte[SA1IRQExec],2
|
|
jz .notexecutedi
|
|
or al,20h
|
|
.notexecutedi
|
|
mov bl,[SA1IRQData+1]
|
|
and bl,50h
|
|
or al,bl
|
|
ret
|
|
sa12301r:
|
|
mov al,[SA1Message]
|
|
test byte[SA1IRQExec+1],1
|
|
jz .notexecuted
|
|
or al,80h
|
|
.notexecuted
|
|
ret
|
|
sa12306r:
|
|
; call UpdateArithStuff
|
|
mov al,[SA1ARR1]
|
|
ret
|
|
sa12307r:
|
|
; call UpdateArithStuff
|
|
mov al,[SA1ARR1+1]
|
|
ret
|
|
sa12308r:
|
|
; call UpdateArithStuff
|
|
mov al,[SA1ARR1+2]
|
|
ret
|
|
sa12309r:
|
|
; call UpdateArithStuff
|
|
mov al,[SA1ARR1+3]
|
|
ret
|
|
sa1230Ar:
|
|
; call UpdateArithStuff
|
|
mov al,[SA1ARR2]
|
|
ret
|
|
sa1230Br:
|
|
mov al,[SA1Overflow]
|
|
ret
|
|
|
|
NEWSYM IRamRead
|
|
mov al,[IRAM+ecx-3000h]
|
|
ret
|
|
|
|
NEWSYM IRamWrite
|
|
mov [IRAM+ecx-3000h],al
|
|
ret
|
|
NEWSYM IRamWrite2
|
|
mov [IRAM+ecx-3000h],al
|
|
xor dh,dh
|
|
ret
|
|
|
|
NEWSYM sa1223Fw
|
|
mov [SA1Overflow+1],al
|
|
ret
|
|
|
|
; Variable Length Data
|
|
NEWSYM sa12258w
|
|
mov [VarLenBarrel+2],al
|
|
mov bl,al
|
|
and bl,0Fh
|
|
cmp bl,0
|
|
jne .not0
|
|
mov bl,16
|
|
.not0
|
|
mov [VarLenBarrel+3],bl
|
|
test al,80h
|
|
jz .notchange
|
|
mov [VarLenBarrel],bl
|
|
mov [VarLenBarrel+1],bl
|
|
.notchange
|
|
ret
|
|
NEWSYM sa12259w
|
|
mov [VarLenAddr],al
|
|
mov [VarLenAddrB],al
|
|
mov byte[VarLenBarrel],0
|
|
mov byte[VarLenBarrel+1],0
|
|
ret
|
|
NEWSYM sa1225Aw
|
|
mov [VarLenAddr+1],al
|
|
mov [VarLenAddrB+1],al
|
|
mov byte[VarLenBarrel],0
|
|
mov byte[VarLenBarrel+1],0
|
|
ret
|
|
NEWSYM sa1225Bw
|
|
mov [VarLenAddr+2],al
|
|
mov [VarLenAddrB+2],al
|
|
mov byte[VarLenBarrel],0
|
|
mov byte[VarLenBarrel+1],0
|
|
ret
|
|
|
|
; Variable Length Read
|
|
NEWSYM sa1230Cr
|
|
push ecx
|
|
xor ebx,ebx
|
|
xor ecx,ecx
|
|
mov bl,[VarLenAddr+2]
|
|
mov cx,[VarLenAddr]
|
|
test ecx,8000h
|
|
jz .loweraddr
|
|
add ecx,[snesmmap+ebx*4]
|
|
jmp .upperaddr
|
|
.loweraddr
|
|
add ecx,[snesmap2+ebx*4]
|
|
.upperaddr
|
|
mov ebx,[ecx]
|
|
mov cl,[VarLenBarrel+1]
|
|
shr ebx,cl
|
|
mov al,bl
|
|
pop ecx
|
|
test byte[VarLenBarrel+2],80h
|
|
jnz .autoinc
|
|
ret
|
|
.autoinc
|
|
mov bl,[VarLenBarrel+3]
|
|
add [VarLenBarrel],bl
|
|
mov bl,[VarLenBarrel]
|
|
cmp bl,16
|
|
jbe .notover
|
|
sub byte[VarLenBarrel],16
|
|
add dword[VarLenAddr],2
|
|
mov byte[VarLenAddr+3],0
|
|
.notover
|
|
ret
|
|
|
|
NEWSYM sa1230Dr
|
|
push ecx
|
|
xor ebx,ebx
|
|
xor ecx,ecx
|
|
mov bl,[VarLenAddrB+2]
|
|
mov cx,[VarLenAddrB]
|
|
test ecx,8000h
|
|
jz .loweraddr
|
|
add ecx,[snesmmap+ebx*4]
|
|
jmp .upperaddr
|
|
.loweraddr
|
|
add ecx,[snesmap2+ebx*4]
|
|
.upperaddr
|
|
mov ebx,[ecx]
|
|
mov cl,[VarLenBarrel+1]
|
|
shr ebx,cl
|
|
mov al,bh
|
|
pop ecx
|
|
test byte[VarLenBarrel+2],80h
|
|
jnz .autoinc
|
|
ret
|
|
.autoinc
|
|
mov bl,[VarLenBarrel+3]
|
|
add [VarLenBarrel+1],bl
|
|
mov bl,[VarLenBarrel+1]
|
|
cmp bl,16
|
|
jbe .notover
|
|
sub byte[VarLenBarrel+1],16
|
|
add dword[VarLenAddrB],2
|
|
mov byte[VarLenAddrB+3],0
|
|
.notover
|
|
ret
|
|
|
|
NEWSYM sa1230Er
|
|
mov al,10h
|
|
ret
|
|
|
|
; Approximate H loc
|
|
NEWSYM sa12302r
|
|
test byte[SA1TimerSet],80h
|
|
jnz .timeron
|
|
mov al,byte[CurrentExecSA1]
|
|
shl al,2
|
|
add al,dh
|
|
ret
|
|
.timeron
|
|
mov al,[SA1TimerCount]
|
|
ret
|
|
NEWSYM sa12303r
|
|
test byte[SA1TimerSet],80h
|
|
jnz .timeron
|
|
mov al,byte[CurrentExecSA1]
|
|
shr al,3
|
|
ret
|
|
.timeron
|
|
mov al,[SA1TimerCount+1]
|
|
and al,1
|
|
ret
|
|
NEWSYM sa12304r
|
|
test byte[SA1TimerSet],80h
|
|
jnz .timeron
|
|
mov al,[curypos]
|
|
ret
|
|
.timeron
|
|
mov bx,[SA1TimerCount+1]
|
|
shr bx,1
|
|
mov al,bl
|
|
ret
|
|
NEWSYM sa12305r
|
|
test byte[SA1TimerSet],80h
|
|
jnz .timeron
|
|
mov al,[curypos+1]
|
|
ret
|
|
.timeron
|
|
mov bx,[SA1TimerCount+2]
|
|
shr bx,1
|
|
mov al,bl
|
|
and al,1
|
|
ret
|
|
|
|
NEWSYM sa12210w ; Timer Settings
|
|
mov [SA1TimerSet],al
|
|
ret
|
|
NEWSYM sa12211w ; Timer Clear
|
|
mov dword[SA1TimerVal],0
|
|
ret
|
|
NEWSYM sa12212w
|
|
mov [SA1TimerCount],al
|
|
ret
|
|
NEWSYM sa12213w
|
|
mov [SA1TimerCount+1],al
|
|
ret
|
|
NEWSYM sa12214w
|
|
mov [SA1TimerCount+2],al
|
|
ret
|
|
NEWSYM sa12215w
|
|
mov [SA1TimerCount+3],al
|
|
ret
|
|
|
|
NEWSYM sa12230w
|
|
mov [SA1DMAInfo],al
|
|
ret
|
|
NEWSYM sa12231w
|
|
mov [SA1DMAChar],al
|
|
; if b7=1, then end of chdma process
|
|
ret
|
|
SA1QuickF sa12232w, SA1DMASource
|
|
SA1QuickF sa12233w, SA1DMASource+1
|
|
SA1QuickF sa12234w, SA1DMASource+2
|
|
SA1QuickF sa12235w, SA1DMADest
|
|
NEWSYM sa12236w
|
|
mov [SA1DMADest+1],al
|
|
test byte[SA1DMAInfo],10h
|
|
jnz near sa1chconv
|
|
test byte[SA1DMAInfo],4
|
|
jnz .noiram
|
|
jmp sa1dmairam
|
|
.noiram
|
|
ret
|
|
NEWSYM sa12237w
|
|
mov [SA1DMADest+2],al
|
|
test byte[SA1DMAInfo],10h
|
|
jnz .nobwram
|
|
test byte[SA1DMAInfo],4
|
|
jz .nobwram
|
|
jmp sa1dmabwram
|
|
.nobwram
|
|
ret
|
|
NEWSYM sa12238w
|
|
mov [SA1DMACount],al
|
|
ret
|
|
NEWSYM sa12239w
|
|
mov [SA1DMACount+1],al
|
|
ret
|
|
|
|
SECTION .bss
|
|
NEWSYM sa1dmaptr, resd 1
|
|
NEWSYM sa1dmaptrs, resd 1
|
|
|
|
SECTION .text
|
|
|
|
NEWSYM sa1dmairam
|
|
mov ebx,[SA1DMADest]
|
|
and ebx,7FFh
|
|
add ebx,IRAM
|
|
mov [sa1dmaptr],ebx
|
|
jmp executesa1dma
|
|
NEWSYM sa1dmabwram
|
|
mov ebx,[SA1DMADest]
|
|
and ebx,3FFFFh
|
|
add ebx,[SA1RAMArea]
|
|
mov [sa1dmaptr],ebx
|
|
executesa1dma:
|
|
test byte[SA1DMAInfo],1
|
|
jz .nobwram
|
|
mov ebx,[SA1DMASource]
|
|
and ebx,3FFFFh
|
|
add ebx,[SA1RAMArea]
|
|
mov [sa1dmaptrs],ebx
|
|
jmp .doneram
|
|
.nobwram
|
|
test byte[SA1DMAInfo],2
|
|
jz .noiram
|
|
mov ebx,[SA1DMASource]
|
|
and ebx,7FFh
|
|
add ebx,IRAM
|
|
mov [sa1dmaptrs],ebx
|
|
jmp .doneram
|
|
.noiram
|
|
xor ebx,ebx
|
|
mov bl,[SA1DMASource+2]
|
|
mov ebx,[snesmmap+ebx*4]
|
|
push ecx
|
|
xor ecx,ecx
|
|
mov cx,[SA1DMASource]
|
|
add ebx,ecx
|
|
mov [sa1dmaptrs],ebx
|
|
pop ecx
|
|
.doneram
|
|
push edx
|
|
push eax
|
|
push ecx
|
|
mov ecx,[SA1DMACount]
|
|
or ecx,ecx
|
|
jz .notransfer
|
|
mov ebx,[sa1dmaptrs]
|
|
mov edx,[sa1dmaptr]
|
|
.loop
|
|
mov al,[ebx]
|
|
mov [edx],al
|
|
inc ebx
|
|
inc edx
|
|
dec ecx
|
|
jnz .loop
|
|
.notransfer
|
|
pop ecx
|
|
pop eax
|
|
pop edx
|
|
ret
|
|
|
|
SECTION .bss
|
|
tempblah resb 1
|
|
|
|
SECTION .text
|
|
|
|
%macro setbit2b 2
|
|
test al,%1
|
|
jz %%nosb
|
|
or word[ebx],%2
|
|
%%nosb
|
|
%endmacro
|
|
|
|
%macro setbit2b2 2
|
|
test al,%1
|
|
jz %%nosb
|
|
or word[ebx+16],%2
|
|
%%nosb
|
|
%endmacro
|
|
|
|
; Character Conversion DMA
|
|
sa1chconv:
|
|
; or byte[SA1DoIRQ],4
|
|
or byte[SA1DoIRQ],8
|
|
; mov byte[debstop3],1
|
|
|
|
|
|
mov ebx,[SA1DMADest]
|
|
mov byte[debstop4],1
|
|
; and ebx,7FFh
|
|
and ebx,3FFFFh
|
|
add ebx,[SA1RAMArea]
|
|
mov [sa1dmaptr],ebx
|
|
mov ebx,[SA1DMASource]
|
|
and ebx,3FFFFh
|
|
add ebx,[SA1RAMArea]
|
|
mov [sa1dmaptrs],ebx
|
|
; 4 colors = 32 bytes, 16 colors = 64 bytes, 256 colors = 128 bytes
|
|
; SA1DMAChar,bit 2-4 = # of 8x8 tiles/horizontal row (0=1,1=2,2=3,..,5=32)
|
|
; SA1DMAChar,bit 0-1 = Color Mode (0=8b,1=4b,2=2b,3=?)
|
|
test byte[SA1DMAChar],1
|
|
jnz .4bit
|
|
test byte[SA1DMAChar],2
|
|
jnz near .2bit
|
|
mov ebx,[sa1dmaptr]
|
|
push ecx
|
|
pop ecx
|
|
ret
|
|
.4bit
|
|
pushad
|
|
mov edx,[sa1dmaptrs]
|
|
mov ebx,[romdata]
|
|
add ebx,4096*1024+1024*1024
|
|
mov edi,16
|
|
.loop34b
|
|
push ebx
|
|
push edx
|
|
mov ecx,32
|
|
.loop4b
|
|
mov esi,8
|
|
push ebx
|
|
push edx
|
|
.loop24b
|
|
mov word[ebx],0
|
|
mov al,[edx+3]
|
|
setbit2b 10h,0001h
|
|
setbit2b 20h,0100h
|
|
setbit2b2 40h,0001h
|
|
setbit2b2 80h,0100h
|
|
setbit2b 01h,0002h
|
|
setbit2b 02h,0200h
|
|
setbit2b2 04h,0002h
|
|
setbit2b2 08h,0200h
|
|
mov al,[edx+2]
|
|
setbit2b 10h,0004h
|
|
setbit2b 20h,0400h
|
|
setbit2b2 40h,0004h
|
|
setbit2b2 80h,0400h
|
|
setbit2b 01h,0008h
|
|
setbit2b 02h,0800h
|
|
setbit2b2 04h,0008h
|
|
setbit2b2 08h,0800h
|
|
mov al,[edx+1]
|
|
setbit2b 10h,0010h
|
|
setbit2b 20h,1000h
|
|
setbit2b2 40h,0010h
|
|
setbit2b2 80h,1000h
|
|
setbit2b 01h,0020h
|
|
setbit2b 02h,2000h
|
|
setbit2b2 04h,0020h
|
|
setbit2b2 08h,2000h
|
|
mov al,[edx]
|
|
setbit2b 10h,0040h
|
|
setbit2b 20h,4000h
|
|
setbit2b2 40h,0040h
|
|
setbit2b2 80h,4000h
|
|
setbit2b 01h,0080h
|
|
setbit2b 02h,8000h
|
|
setbit2b2 04h,0080h
|
|
setbit2b2 08h,8000h
|
|
add ebx,2
|
|
add edx,128
|
|
dec esi
|
|
jnz near .loop24b
|
|
pop edx
|
|
pop ebx
|
|
add edx,4
|
|
add ebx,32
|
|
dec ecx
|
|
jnz near .loop4b
|
|
pop edx
|
|
pop ebx
|
|
add edx,128*8
|
|
add ebx,128*8
|
|
dec edi
|
|
jnz near .loop34b
|
|
|
|
mov ecx,10*128*8
|
|
mov edx,[sa1dmaptrs]
|
|
mov ebx,[romdata]
|
|
add ebx,4096*1024+1024*1024
|
|
.next4b
|
|
mov al,[ebx]
|
|
mov [edx],al
|
|
inc ebx
|
|
inc edx
|
|
dec ecx
|
|
jnz .next4b
|
|
|
|
popad
|
|
ret
|
|
|
|
.2bit
|
|
pushad
|
|
mov edx,[sa1dmaptrs]
|
|
mov ebx,[romdata]
|
|
add ebx,4096*1024+1024*1024
|
|
mov edi,16
|
|
.loop3
|
|
push ebx
|
|
push edx
|
|
mov ecx,32
|
|
.loop
|
|
mov esi,8
|
|
push ebx
|
|
push edx
|
|
.loop2
|
|
mov word[ebx],0
|
|
mov al,[edx+1]
|
|
setbit2b 40h,0001h
|
|
setbit2b 80h,0100h
|
|
setbit2b 10h,0002h
|
|
setbit2b 20h,0200h
|
|
setbit2b 04h,0004h
|
|
setbit2b 08h,0400h
|
|
setbit2b 01h,0008h
|
|
setbit2b 02h,0800h
|
|
mov al,[edx]
|
|
setbit2b 40h,0010h
|
|
setbit2b 80h,1000h
|
|
setbit2b 10h,0020h
|
|
setbit2b 20h,2000h
|
|
setbit2b 04h,0040h
|
|
setbit2b 08h,4000h
|
|
setbit2b 01h,0080h
|
|
setbit2b 02h,8000h
|
|
add ebx,2
|
|
add edx,64
|
|
dec esi
|
|
jnz near .loop2
|
|
pop edx
|
|
pop ebx
|
|
add edx,2
|
|
add ebx,16
|
|
dec ecx
|
|
jnz near .loop
|
|
pop edx
|
|
pop ebx
|
|
add edx,64*8
|
|
add ebx,64*8
|
|
dec edi
|
|
jnz near .loop3
|
|
|
|
mov ecx,10*64*8
|
|
mov edx,[sa1dmaptrs]
|
|
mov ebx,[romdata]
|
|
add ebx,4096*1024+1024*1024
|
|
.next
|
|
mov al,[ebx]
|
|
mov [edx],al
|
|
inc ebx
|
|
inc edx
|
|
dec ecx
|
|
jnz .next
|
|
|
|
popad
|
|
ret
|
|
SECTION .bss
|
|
.numrows resd 1
|
|
|
|
SECTION .text
|
|
|
|
NEWSYM initSA1regs
|
|
setreg 2300h*4,sa12300r
|
|
setreg 2301h*4,sa12301r
|
|
setreg 2302h*4,sa12302r
|
|
setreg 2303h*4,sa12303r
|
|
setreg 2304h*4,sa12304r
|
|
setreg 2305h*4,sa12305r
|
|
setreg 2306h*4,sa12306r
|
|
setreg 2307h*4,sa12307r
|
|
setreg 2308h*4,sa12308r
|
|
setreg 2309h*4,sa12309r
|
|
setreg 230Ah*4,sa1230Ar
|
|
setreg 230Bh*4,sa1230Br
|
|
setreg 230Ch*4,sa1230Cr
|
|
setreg 230Dh*4,sa1230Dr
|
|
setreg 230Eh*4,sa1230Er
|
|
; Set IRam, memory address 3000-37FF
|
|
|
|
mov edi,3000h*4
|
|
add edi,[regptr]
|
|
mov eax,IRamRead
|
|
mov ecx,800h
|
|
.loopr
|
|
mov [edi],eax
|
|
add edi,4
|
|
dec ecx
|
|
jnz .loopr
|
|
ret
|
|
|
|
NEWSYM initSA1regsw
|
|
setregw 2200h*4,sa12200w
|
|
setregw 2201h*4,sa12201w
|
|
setregw 2202h*4,sa12202w
|
|
setregw 2203h*4,sa12203w
|
|
setregw 2204h*4,sa12204w
|
|
setregw 2205h*4,sa12205w
|
|
setregw 2206h*4,sa12206w
|
|
setregw 2207h*4,sa12207w
|
|
setregw 2208h*4,sa12208w
|
|
setregw 2209h*4,sa12209w
|
|
setregw 220Ah*4,sa1220Aw
|
|
setregw 220Bh*4,sa1220Bw
|
|
setregw 220Ch*4,sa1220Cw
|
|
setregw 220Dh*4,sa1220Dw
|
|
setregw 220Eh*4,sa1220Ew
|
|
setregw 220Fh*4,sa1220Fw
|
|
setregw 2210h*4,sa12210w
|
|
setregw 2211h*4,sa12211w
|
|
setregw 2212h*4,sa12212w
|
|
setregw 2213h*4,sa12213w
|
|
setregw 2214h*4,sa12214w
|
|
setregw 2215h*4,sa12215w
|
|
|
|
setregw 2220h*4,sa12220w
|
|
setregw 2221h*4,sa12221w
|
|
setregw 2222h*4,sa12222w
|
|
setregw 2223h*4,sa12223w
|
|
|
|
setregw 2224h*4,sa12224w
|
|
setregw 2225h*4,sa12225w
|
|
; Missing 2226-222A
|
|
; Missing 2240-224F (Bitmap register file)
|
|
|
|
setregw 2230h*4,sa12230w
|
|
setregw 2231h*4,sa12231w
|
|
setregw 2232h*4,sa12232w
|
|
setregw 2233h*4,sa12233w
|
|
setregw 2234h*4,sa12234w
|
|
setregw 2235h*4,sa12235w
|
|
setregw 2236h*4,sa12236w
|
|
setregw 2237h*4,sa12237w
|
|
setregw 2238h*4,sa12238w
|
|
setregw 2239h*4,sa12239w
|
|
setregw 223Fh*4,sa1223Fw
|
|
|
|
setregw 2250h*4,sa12250w
|
|
setregw 2251h*4,sa12251w
|
|
setregw 2252h*4,sa12252w
|
|
setregw 2253h*4,sa12253w
|
|
setregw 2254h*4,sa12254w
|
|
|
|
setregw 2259h*4,sa12259w
|
|
setregw 225Ah*4,sa1225Aw
|
|
setregw 225Bh*4,sa1225Bw
|
|
|
|
mov edi,3000h*4
|
|
add edi,[regptw]
|
|
mov eax,IRamWrite
|
|
mov ecx,800h
|
|
.loopw
|
|
mov [edi],eax
|
|
add edi,4
|
|
dec ecx
|
|
jnz .loopw
|
|
setregw 3000h*4,IRamWrite2
|
|
ret
|
|
|
|
NEWSYM SDD1Reset
|
|
setregw 4801h*4,sdd14801w
|
|
setregw 4802h*4,dbstop
|
|
setregw 4803h*4,dbstop
|
|
setregw 4804h*4,sdd14804w
|
|
setregw 4805h*4,sdd14805w
|
|
setregw 4806h*4,sdd14806w
|
|
setregw 4807h*4,sdd14807w
|
|
setregw 4808h*4,dbstop
|
|
setregw 4809h*4,dbstop
|
|
setregw 480Ah*4,dbstop
|
|
setregw 480Bh*4,dbstop
|
|
setregw 480Ch*4,dbstop
|
|
setregw 480Dh*4,dbstop
|
|
setregw 480Eh*4,dbstop
|
|
setregw 480Fh*4,dbstop
|
|
ret
|
|
|
|
NEWSYM initSDD1regs
|
|
setreg 4804h*4,sdd14804
|
|
setreg 4805h*4,sdd14805
|
|
setreg 4806h*4,sdd14806
|
|
setreg 4807h*4,sdd14807
|
|
ret
|
|
|
|
dbstop:
|
|
; mov byte[debstop3],1
|
|
ret
|
|
|
|
NEWSYM sdd14801w
|
|
cmp al,0
|
|
jne .notzero
|
|
ret
|
|
.notzero
|
|
mov byte[AddrNoIncr],0
|
|
; set banks C0h-FFh to decompressing routine
|
|
push eax
|
|
push ebx
|
|
mov eax,memtabler8+0C0h*4
|
|
mov ebx,40h
|
|
.loop
|
|
mov dword[eax],memaccessbankr8sdd1
|
|
add eax,4
|
|
dec ebx
|
|
jnz .loop
|
|
mov dword[Sdd1Mode],1
|
|
pop ebx
|
|
pop eax
|
|
ret
|