www.pudn.com > zsnes117b-src.zip > sa1proc.asm


;Copyright (C) 1997-2001 ZSNES Team ( zsknight@zsnes.com / _demo_@zsnes.com ) 
; 
;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. 
 
%include "macros.mac" 
 
EXTSYM xa,xx,xy,xd,xdb,xpb,xs,xe,initaddrl,UpdateDPage,wramdata,IRAM,cycpbl,SA1DoIRQ 
EXTSYM spcnumread,SA1IRQEn,nextopcodesa1,debugds 
EXTSYM SNSRegP,SNSRegE,SNSRegPCS,SA1Ptr,SNSPtr,nmiv,irqv,nmiv2,irqv2,snesmap2,SA1tablead 
EXTSYM SA1xpb,SA1RegP,wramdataa,SA1TimerVal,debuggeron 
EXTSYM SA1RegE,SA1RegPCS,SA1BWPtr,SNSBWPtr,CurBWPtr,SA1NMIV,SA1IRQV,debstop,tablead 
EXTSYM membank0w8,romdata,SA1LBound,SA1UBound,SA1SH,SA1SHb 
EXTSYM stackor,stackand,snesmmap,SA1xs,SA1IRQExec 
EXTSYM SA1Message,Sflagnz,Sflagc,Sflago 
 
 
 
 
 
 
; In exec loop, jump to execloop if SA1Status != 0 
; *** Disable spc700 if possible *** 
 
 
 
NEWSYM SA1Status, db 0  ; 0 = 65816, 1 = SA1A, 2 = SA1B 
 
NEWSYM CurrentExecSA1, db 0 
NEWSYM CurrentCPU, db 0 
 
ALIGN32 
NEWSYM prevedi, dd 0 
 
%macro SA1Debugb 0 
    pushad 
    sub esi,[initaddrl] 
    mov [SA1xpc],esi 
    call nextopcodesa1 
    popad 
    mov bl,[esi] 
    xor dh,dh 
    inc esi 
    call dword near [edi+ebx*4] 
    dec esi 
%endmacro 
 
%macro SA1Debug 0 
    ; debug version 
    test byte[debugds],01h 
    jz near .nodebug 
    cmp byte[debuggeron],0 
    je near .nodebug 
    SA1Debugb 
    SA1Debugb 
    SA1Debugb 
    SA1Debugb 
    SA1Debugb 
    SA1Debugb 
    SA1Debugb 
    SA1Debugb 
    jmp .debug 
.nodebug 
%endmacro 
 
 
NEWSYM SA1Swap 
    mov ecx,[SA1BWPtr] 
    mov eax,[SA1Ptr]        ; small speed hack 
    test byte[SA1DoIRQ],1 
    jnz near .sa1exec3 
    cmp byte[IRAM],0 
    jne .sa1exec2 
    cmp dword[eax],0FCF000A5h 
    je near .nosa1exec 
    cmp dword[eax-2],0FCF000A5h 
    je near .nosa1exec 
.sa1exec2 
    cmp byte[SA1SHb],1 
    je near .nosa1execb 
 
    cmp word[ecx+72A4h],0 
    jnz .sa1exec 
    cmp dword[eax],0F072A4ADh 
    je near .nosa1execb 
.sa1exec 
    cmp byte[IRAM+72h],0 
    jne .sa1exec3 
    cmp dword[eax],0F03072ADh 
    je near .nosa1execb 
.sa1exec3 
.yesdebugr 
    xor ecx,ecx 
    ; store all snes 65816 stuff 
    mov [SNSRegP],dl 
    mov eax,[initaddrl] 
    mov [prevedi],edi 
    mov [SNSRegPCS],eax 
    mov [SNSPtr],esi 
    ; restore all sa1 65816 stuff 
    mov dl,[SA1RegP] 
    mov eax,[SA1RegPCS] 
    mov [initaddrl],eax 
    mov eax,[SA1BWPtr] 
    mov [CurBWPtr],eax 
    mov esi,[SA1Ptr] 
    mov dword[snesmap2],IRAM 
    mov dword[wramdata],IRAM 
    ; Check if IRQ is executed on SA-1 
    xor eax,eax 
    mov al,dl 
    add dh,25 
    mov edi,[SA1tablead+eax*4] 
    mov byte[SA1Status],1 
    test dword[SA1DoIRQ],0FF000003h 
    jnz near .switchirq 
.returnirq 
 
;    SA1Debug 
 
    cmp byte[SA1SH],1 
    je near .speedhack 
 
     ; non debug version 
    mov bl,[esi] 
    inc esi 
    call dword near [edi+ebx*4] 
    dec esi 
.debug 
 
    ; store all sa1 65816 stuff 
    mov [SA1RegP],dl 
    mov eax,[initaddrl] 
    mov [SA1RegPCS],eax 
    mov [SA1Ptr],esi 
    ; restore all snes 65816 stuff 
    mov dl,[SNSRegP] 
    mov eax,[SNSRegPCS] 
    mov [initaddrl],eax 
    mov eax,[SNSBWPtr] 
    mov [CurBWPtr],eax 
    mov dword[wramdata],wramdataa 
    mov esi,[SNSPtr] 
    mov eax,[wramdata] 
    mov dword[snesmap2],eax 
    mov edi,[prevedi] 
    xor eax,eax 
    add dh,11 
    inc byte[CurrentExecSA1] 
    mov byte[SA1Status],0 
    add dword[SA1TimerVal],23 
    ret 
 
.speedhack 
    add dh,100 
 
    mov bl,[esi] 
    inc esi 
    call dword near [edi+ebx*4] 
    dec esi 
    ; store all sa1 65816 stuff 
    mov [SA1RegP],dl 
    mov eax,[initaddrl] 
    mov [SA1RegPCS],eax 
    mov [SA1Ptr],esi 
    ; restore all snes 65816 stuff 
    mov dl,[SNSRegP] 
    mov eax,[SNSRegPCS] 
    mov [initaddrl],eax 
    mov eax,[SNSBWPtr] 
    mov [CurBWPtr],eax 
    mov dword[wramdata],wramdataa 
    mov esi,[SNSPtr] 
    mov eax,[wramdata] 
    mov dword[snesmap2],eax 
    mov edi,[prevedi] 
    xor eax,eax 
    add byte[CurrentExecSA1],4 
    mov byte[SA1Status],0 
    add dword[SA1TimerVal],23 
;    xor dh,dh 
    mov dh,18 
    cmp esi,dword[SA1LBound] 
    jb .stoph 
    cmp esi,dword[SA1UBound] 
    ja .stoph 
    ret 
.stoph 
    mov byte[SA1SH],0 
    ret 
.nosa1execb 
    xor ecx,ecx 
    add dh,15 
    add byte[CurrentExecSA1],2 
    mov byte[SA1Status],0 
    ret 
.nosa1exec 
    xor ecx,ecx 
    add dh,22 
    add byte[CurrentExecSA1],2 
    mov byte[SA1Status],0 
    ret 
.switchirq 
    test dword[SA1DoIRQ],3 
    jz .notirq 
    test dword[SA1DoIRQ],1 
    jz .nmi 
    and byte[SA1DoIRQ],0FEh 
    call SA1switchtovirq 
    jmp .returnirq 
.nmi 
    and byte[SA1DoIRQ],0FDh 
    call SA1switchtonmi 
    jmp .returnirq 
.notirq 
    dec byte[SA1DoIRQ+3] 
    jz .hack 
    jmp .returnirq 
.hack 
    or byte[SA1DoIRQ],8 
    jmp .returnirq 
 
NEWSYM SA1xpc, dd 0 
 
%macro makedl 0 
   and dl,00111100b 
   test dword[Sflagnz],18000h 
   jz %%noneg 
   or dl,80h 
%%noneg 
   test dword[Sflagnz],0FFFFh 
   jnz %%nozero 
   or dl,02h 
%%nozero 
   test dword[Sflagc],0FFh 
   jz %%nocarry 
   or dl,01h 
%%nocarry 
   test dword[Sflago],0FFh 
   jz %%nov 
   or dl,40h 
%%nov 
%endmacro 
 
NEWSYM SA1switchtonmi 
    mov al,byte[SA1Message] 
    mov byte[SA1Message+2],al 
    mov byte[SA1IRQExec+2],1 
    mov ebx,esi 
    sub ebx,[initaddrl] 
    mov [SA1xpc],bx 
 
    xor ecx,ecx 
    mov cx,[SA1xs] 
    mov al,[SA1xpb] 
    call membank0w8 
 
    dec cx 
    and cx,word[stackand] 
    or cx,word[stackor] 
    mov al,[SA1xpc+1] 
    call membank0w8 
 
    dec cx 
    and cx,word[stackand] 
    or cx,word[stackor] 
    mov al,[SA1xpc] 
    call membank0w8 
 
    dec cx 
    and cx,word[stackand] 
    or cx,word[stackor] 
    makedl 
    mov al,dl 
    call membank0w8 
 
    dec cx 
    and cx,word[stackand] 
    or cx,word[stackor] 
    mov [SA1xs],cx 
 
    xor ebx,ebx 
    mov [SA1xpb],bl 
    xor eax,eax 
    mov ax,[SA1NMIV] 
    and dl,11110011b 
    or dl,00000100b 
    test ax,8000h 
    jz .loweraddr 
    mov esi,[snesmmap+ebx*4] 
    mov [initaddrl],esi 
    add esi,eax 
    ret 
.loweraddr 
    mov esi,[snesmap2+ebx*4] 
    mov [initaddrl],esi 
    add esi,eax 
    ret 
 
NEWSYM SA1switchtovirq 
    mov al,byte[SA1Message] 
    mov byte[SA1Message+2],al 
    mov byte[SA1IRQExec+1],1 
    mov ebx,esi 
    sub ebx,[initaddrl] 
    mov [SA1xpc],bx 
 
    xor ecx,ecx 
    mov cx,[SA1xs] 
    mov al,[SA1xpb] 
    call membank0w8 
 
    dec cx 
    and cx,word[stackand] 
    or cx,word[stackor] 
    mov al,[SA1xpc+1] 
    call membank0w8 
 
    dec cx 
    and cx,word[stackand] 
    or cx,word[stackor] 
    mov al,[SA1xpc] 
    call membank0w8 
 
    dec cx 
    and cx,word[stackand] 
    or cx,word[stackor] 
    makedl 
    mov al,dl 
    call membank0w8 
 
    dec cx 
    and cx,word[stackand] 
    or cx,word[stackor] 
    mov [SA1xs],cx 
    xor ebx,ebx 
    mov [SA1xpb],bl 
    xor eax,eax 
    mov ax,[SA1IRQV] 
    and dl,11110011b 
    or dl,00000100b 
    test ax,8000h 
    jz .loweraddr 
    mov esi,[snesmmap+ebx*4] 
    mov [initaddrl],esi 
    add esi,eax 
    ret 
.loweraddr 
    mov esi,[snesmap2+ebx*4] 
    mov [initaddrl],esi 
    add esi,eax 
    ret