⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sa1regs.asm

📁 十七种模拟器源代码 非常有用的作课程设计不可缺少的
💻 ASM
📖 第 1 页 / 共 4 页
字号:
    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 + -