554 lines
9.8 KiB
NASM
554 lines
9.8 KiB
NASM
;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.
|
|
|
|
|
|
|
|
%include "macros.mac"
|
|
|
|
EXTSYM flagnz,flago,flagc,SfxSCMR,curnmi,execloop,initaddrl,nmiv,snesmap2
|
|
EXTSYM snesmmap,stackand,stackor,xe,xirqb,xpb,xpc,xs,irqon,irqv,irqv8
|
|
EXTSYM execloopdeb,nmiv8,membank0w8
|
|
|
|
; NMI Hardware 00FFFA,B 00FFEA,B 3 -> 000108
|
|
; RES Hardware 00FFFC.D 00FFFC,D 1
|
|
; BRK Software 00FFFE,F 00FFE6,7 N/A
|
|
; IRQ Hardware 00FFFE,F 00FFEE,F 4 -> 00010C
|
|
|
|
|
|
%macro makedl 0
|
|
and dl,00111100b
|
|
test dword[flagnz],18000h
|
|
jz %%noneg
|
|
or dl,80h
|
|
%%noneg
|
|
test dword[flagnz],0FFFFh
|
|
jnz %%nozero
|
|
or dl,02h
|
|
%%nozero
|
|
test dword[flagc],0FFh
|
|
jz %%nocarry
|
|
or dl,01h
|
|
%%nocarry
|
|
test dword[flago],0FFh
|
|
jz %%nov
|
|
or dl,40h
|
|
%%nov
|
|
%endmacro
|
|
|
|
SECTION .text
|
|
|
|
;*******************************************************
|
|
; SwitchToNMI/VIRQ Calls NMI/VIRQ
|
|
;*******************************************************
|
|
NEWSYM switchtonmi
|
|
mov byte[curnmi],1
|
|
sub dh,100
|
|
test byte[xe],1
|
|
jne near NMIemulmode
|
|
mov ebx,esi
|
|
sub ebx,[initaddrl]
|
|
mov [xpc],bx
|
|
|
|
xor ebx,ebx
|
|
|
|
mov cx,[xs]
|
|
mov al,[xpb]
|
|
call membank0w8
|
|
dec cx
|
|
and cx,word[stackand]
|
|
or cx,word[stackor]
|
|
|
|
mov al,[xpc+1]
|
|
call membank0w8
|
|
dec cx
|
|
and cx,word[stackand]
|
|
or cx,word[stackor]
|
|
|
|
mov al,[xpc]
|
|
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 [xs],cx
|
|
|
|
xor bh,bh
|
|
mov bl,[xirqb]
|
|
mov [xpb],bl
|
|
xor eax,eax
|
|
mov ax,[nmiv]
|
|
test byte[SfxSCMR],10h
|
|
jz .nosfxnmi
|
|
; mov ax,0108h
|
|
.nosfxnmi
|
|
mov [xpc],ax
|
|
and dl,11110011b
|
|
or dl,00000100b
|
|
test ax,8000h
|
|
jz .loweraddr
|
|
mov esi,[snesmmap+ebx*4]
|
|
mov [initaddrl],esi
|
|
add esi,eax
|
|
jmp execloop
|
|
.loweraddr
|
|
mov esi,[snesmap2+ebx*4]
|
|
mov [initaddrl],esi
|
|
add esi,eax
|
|
jmp execloop
|
|
|
|
NEWSYM NMIemulmode
|
|
mov ebx,esi
|
|
sub ebx,[initaddrl]
|
|
mov [xpc],bx
|
|
|
|
mov cx,[xs]
|
|
mov al,[xpc+1]
|
|
call membank0w8
|
|
dec cx
|
|
and cx,word[stackand]
|
|
or cx,word[stackor]
|
|
|
|
mov al,[xpc]
|
|
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 [xs],cx
|
|
|
|
xor bh,bh
|
|
mov [xpb],bh
|
|
mov bl,[xpb]
|
|
xor eax,eax
|
|
mov ax,[nmiv8]
|
|
mov [xpc],ax
|
|
and dl,11110011b
|
|
or dl,00000100b
|
|
test ax,8000h
|
|
jz .loweraddr
|
|
mov esi,[snesmmap+ebx*4]
|
|
mov [initaddrl],esi
|
|
add esi,eax
|
|
jmp execloop
|
|
.loweraddr
|
|
mov esi,[snesmap2+ebx*4]
|
|
mov [initaddrl],esi
|
|
add esi,eax
|
|
jmp execloop
|
|
|
|
NEWSYM switchtovirq
|
|
mov byte[irqon],80h
|
|
sub dh,3
|
|
test byte[xe],1
|
|
jne near IRQemulmode
|
|
|
|
mov ebx,esi
|
|
sub ebx,[initaddrl]
|
|
mov [xpc],bx
|
|
|
|
mov cx,[xs]
|
|
mov al,[xpb]
|
|
call membank0w8
|
|
dec cx
|
|
and cx,word[stackand]
|
|
or cx,word[stackor]
|
|
|
|
mov al,[xpc+1]
|
|
call membank0w8
|
|
dec cx
|
|
and cx,word[stackand]
|
|
or cx,word[stackor]
|
|
|
|
mov al,[xpc]
|
|
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 [xs],cx
|
|
|
|
xor bh,bh
|
|
mov bl,[xirqb]
|
|
mov [xpb],bl
|
|
xor eax,eax
|
|
mov ax,[irqv]
|
|
test byte[SfxSCMR],10h
|
|
jz .nosfxnmi
|
|
mov ax,010Ch
|
|
.nosfxnmi
|
|
mov [xpc],ax
|
|
and dl,11110011b
|
|
or dl,00000100b
|
|
test ax,8000h
|
|
jz .loweraddr
|
|
mov esi,[snesmmap+ebx*4]
|
|
mov [initaddrl],esi
|
|
add esi,eax
|
|
jmp execloop
|
|
.loweraddr
|
|
mov esi,[snesmap2+ebx*4]
|
|
mov [initaddrl],esi
|
|
add esi,eax
|
|
jmp execloop
|
|
|
|
NEWSYM switchtovirqret
|
|
mov byte[irqon],80h
|
|
test byte[xe],1
|
|
jne near IRQemulmode
|
|
|
|
mov ebx,esi
|
|
sub ebx,[initaddrl]
|
|
mov [xpc],bx
|
|
|
|
mov cx,[xs]
|
|
mov al,[xpb]
|
|
call membank0w8
|
|
dec cx
|
|
and cx,word[stackand]
|
|
or cx,word[stackor]
|
|
|
|
mov al,[xpc+1]
|
|
call membank0w8
|
|
dec cx
|
|
and cx,word[stackand]
|
|
or cx,word[stackor]
|
|
|
|
mov al,[xpc]
|
|
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 [xs],cx
|
|
|
|
xor bh,bh
|
|
mov bl,[xirqb]
|
|
mov [xpb],bl
|
|
xor eax,eax
|
|
mov ax,[irqv]
|
|
test byte[SfxSCMR],10h
|
|
jz .nosfxnmi
|
|
mov ax,010Ch
|
|
.nosfxnmi
|
|
mov [xpc],ax
|
|
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 IRQemulmode
|
|
mov ebx,esi
|
|
sub ebx,[initaddrl]
|
|
mov [xpc],bx
|
|
|
|
mov cx,[xs]
|
|
mov al,[xpc+1]
|
|
call membank0w8
|
|
dec cx
|
|
and cx,word[stackand]
|
|
or cx,word[stackor]
|
|
|
|
mov al,[xpc]
|
|
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 [xs],cx
|
|
|
|
xor bh,bh
|
|
mov [xpb],bh
|
|
mov bl,[xpb]
|
|
xor eax,eax
|
|
mov ax,[irqv8]
|
|
mov [xpc],ax
|
|
and dl,11110011b
|
|
or dl,00000100b
|
|
test ax,8000h
|
|
jz .loweraddr
|
|
mov esi,[snesmmap+ebx*4]
|
|
mov [initaddrl],esi
|
|
add esi,eax
|
|
jmp execloop
|
|
.loweraddr
|
|
mov esi,[snesmap2+ebx*4]
|
|
mov [initaddrl],esi
|
|
add esi,eax
|
|
jmp execloop
|
|
|
|
|
|
NEWSYM switchtovirqdeb
|
|
mov byte[irqon],80h
|
|
test byte[xe],1
|
|
jne near IRQemulmodedeb
|
|
|
|
mov ebx,esi
|
|
sub ebx,[initaddrl]
|
|
mov [xpc],bx
|
|
|
|
mov cx,[xs]
|
|
mov al,[xpb]
|
|
call membank0w8
|
|
dec cx
|
|
and cx,word[stackand]
|
|
or cx,word[stackor]
|
|
|
|
mov al,[xpc+1]
|
|
call membank0w8
|
|
dec cx
|
|
and cx,word[stackand]
|
|
or cx,word[stackor]
|
|
|
|
mov al,[xpc]
|
|
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 [xs],cx
|
|
|
|
xor bh,bh
|
|
mov bl,[xirqb]
|
|
mov [xpb],bl
|
|
xor eax,eax
|
|
mov ax,[irqv]
|
|
test byte[SfxSCMR],10h
|
|
jz .nosfxnmi
|
|
mov ax,010Ch
|
|
.nosfxnmi
|
|
mov [xpc],ax
|
|
and dl,11110011b
|
|
or dl,00000100b
|
|
test ax,8000h
|
|
jz .loweraddr
|
|
mov esi,[snesmmap+ebx*4]
|
|
mov [initaddrl],esi
|
|
add esi,eax
|
|
jmp execloopdeb
|
|
.loweraddr
|
|
mov esi,[snesmap2+ebx*4]
|
|
mov [initaddrl],esi
|
|
add esi,eax
|
|
jmp execloopdeb
|
|
|
|
NEWSYM IRQemulmodedeb
|
|
mov ebx,esi
|
|
sub ebx,[initaddrl]
|
|
mov [xpc],bx
|
|
|
|
mov cx,[xs]
|
|
mov al,[xpc+1]
|
|
call membank0w8
|
|
dec cx
|
|
and cx,word[stackand]
|
|
or cx,word[stackor]
|
|
|
|
mov al,[xpc]
|
|
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 [xs],cx
|
|
|
|
xor bh,bh
|
|
mov [xpb],bh
|
|
mov bl,[xpb]
|
|
xor eax,eax
|
|
mov ax,[irqv8]
|
|
mov [xpc],ax
|
|
and dl,11110011b
|
|
or dl,00000100b
|
|
test ax,8000h
|
|
jz .loweraddr
|
|
mov esi,[snesmmap+ebx*4]
|
|
mov [initaddrl],esi
|
|
add esi,eax
|
|
jmp execloopdeb
|
|
.loweraddr
|
|
mov esi,[snesmap2+ebx*4]
|
|
mov [initaddrl],esi
|
|
add esi,eax
|
|
jmp execloopdeb
|
|
|
|
NEWSYM switchtonmideb
|
|
mov byte[curnmi],1
|
|
test byte[xe],1
|
|
jne near NMIemulmodedeb
|
|
mov ebx,esi
|
|
sub ebx,[initaddrl]
|
|
mov [xpc],bx
|
|
|
|
mov cx,[xs]
|
|
mov al,[xpb]
|
|
call membank0w8
|
|
dec cx
|
|
and cx,word[stackand]
|
|
or cx,word[stackor]
|
|
|
|
mov al,[xpc+1]
|
|
call membank0w8
|
|
dec cx
|
|
and cx,word[stackand]
|
|
or cx,word[stackor]
|
|
|
|
mov al,[xpc]
|
|
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 [xs],cx
|
|
|
|
xor bh,bh
|
|
mov bl,[xirqb]
|
|
mov [xpb],bl
|
|
xor eax,eax
|
|
mov ax,[nmiv]
|
|
test byte[SfxSCMR],10h
|
|
jz .nosfxnmi
|
|
mov ax,0108h
|
|
.nosfxnmi
|
|
mov [xpc],ax
|
|
and dl,11110011b
|
|
or dl,00000100b
|
|
test ax,8000h
|
|
jz .loweraddr
|
|
mov esi,[snesmmap+ebx*4]
|
|
mov [initaddrl],esi
|
|
add esi,eax
|
|
jmp execloopdeb
|
|
.loweraddr
|
|
mov esi,[snesmap2+ebx*4]
|
|
mov [initaddrl],esi
|
|
add esi,eax
|
|
jmp execloopdeb
|
|
|
|
NEWSYM NMIemulmodedeb
|
|
mov ebx,esi
|
|
sub ebx,[initaddrl]
|
|
mov [xpc],bx
|
|
|
|
mov cx,[xs]
|
|
mov al,[xpc+1]
|
|
call membank0w8
|
|
dec cx
|
|
and cx,word[stackand]
|
|
or cx,word[stackor]
|
|
|
|
mov al,[xpc]
|
|
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 [xs],cx
|
|
|
|
xor bh,bh
|
|
mov [xpb],bh
|
|
mov bl,[xpb]
|
|
xor eax,eax
|
|
mov ax,[nmiv8]
|
|
mov [xpc],ax
|
|
and dl,11110011b
|
|
or dl,00000100b
|
|
test ax,8000h
|
|
jz .loweraddr
|
|
mov esi,[snesmmap+ebx*4]
|
|
mov [initaddrl],esi
|
|
add esi,eax
|
|
jmp execloopdeb
|
|
.loweraddr
|
|
mov esi,[snesmap2+ebx*4]
|
|
mov [initaddrl],esi
|
|
add esi,eax
|
|
jmp execloopdeb
|