1003 lines
26 KiB
NASM
1003 lines
26 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 UpdateDevices,Makemode7Table,MusicRelVol,MusicVol,makesprprtable
|
|
EXTSYM romloadskip,start65816,showinfogui,inittable,zexit
|
|
EXTSYM SA1inittable,MessageOn,Msgptr,MsgCount,sndrot,SnowTimer
|
|
EXTSYM inittablec,newgfx16b,DisplayInfo,ssautosw,GUIDelayB,pl12s34
|
|
EXTSYM Output_Text,Turbo30hz,CombinDataLocl,current_zst
|
|
EXTSYM BackupSystemVars,SnowData,SnowVelDist,Setper2exec,ShowMMXSupport
|
|
EXTSYM JoyRead,pressed,mousebuttons,mousexdir,mouseydir,mousexpos,mouseypos
|
|
EXTSYM pl1selk,pl1startk,pl1upk,pl1downk,pl1leftk,pl1rightk,pl1Xk
|
|
EXTSYM pl1Ak,pl1Lk,pl1Yk,pl1Bk,pl1Rk,pl1Xtk,pl1Ytk,pl1Atk,pl1Btk,pl1Ltk,pl1Rtk
|
|
EXTSYM pl1ULk,pl1URk,pl1DLk,pl1DRk,pl2contrl,pl2selk,pl2startk,pl2upk,pl2downk
|
|
EXTSYM pl2leftk,pl2rightk,pl2Xk,pl2Ak,pl2Lk,pl2Yk,pl2Bk,pl2Rk,pl2Xtk,pl2Ytk
|
|
EXTSYM pl2Atk,pl2Btk,pl2Ltk,pl2Rtk,pl2ULk,pl2URk,pl2DLk,pl2DRk,pl3contrl,pl3selk
|
|
EXTSYM pl3startk,pl3upk,pl3downk,pl3leftk,pl3rightk,pl3Xk,pl3Ak,pl3Lk,pl3Yk
|
|
EXTSYM pl3Bk,pl3Rk,pl3Xtk,pl3Ytk,pl3Atk,pl3Btk,pl3Ltk,pl3Rtk,pl3ULk,pl3URk
|
|
EXTSYM pl3DLk,pl3DRk,pl4contrl,pl4selk,pl4startk,pl4upk,pl4downk,pl4leftk
|
|
EXTSYM pl4rightk,pl4Xk,pl4Ak,pl4Lk,pl4Yk,pl4Bk,pl4Rk,pl4Xtk,pl4Ytk,pl4Atk,pl4Btk
|
|
EXTSYM pl4Ltk,pl4Rtk,pl4ULk,pl4URk,pl4DLk,pl4DRk,pl5contrl,pl5selk,pl5startk
|
|
EXTSYM pl5upk,pl5downk,pl5leftk,pl5rightk,pl5Xk,pl5Ak,pl5Lk,pl5Yk,pl5Bk,pl5Rk
|
|
EXTSYM pl5Xtk,pl5Ytk,pl5Atk,pl5Btk,pl5Ltk,pl5Rtk,pl5ULk,pl5URk,pl5DLk,pl5DRk
|
|
EXTSYM CombinDataGlob,NumCombo,GUIComboGameSpec,mousexloc,mouseyloc,extlatch
|
|
EXTSYM AllowMMX,MMXextSupport,romdata,procexecloop,wramdata,LoadSecondState
|
|
EXTSYM romispal,initregr,initregw,loadfileGUI,loadstate2,CMovieExt,AutoState
|
|
EXTSYM MoviePlay,MovieDumpRaw,AllowUDLR,device1,device2,processmouse1,SaveSecondState
|
|
EXTSYM processmouse2,cpalval,init65816,clearmem,SetupROM,ZCartName,initsnes,SSPause
|
|
|
|
%ifdef __MSDOS__
|
|
EXTSYM init18_2hz
|
|
%endif
|
|
|
|
%ifndef NO_DEBUGGER
|
|
EXTSYM startdebugger
|
|
%ifndef __MSDOS__
|
|
%ifdef __WIN32__
|
|
EXTSYM initwinvideo
|
|
%endif
|
|
EXTSYM Start60HZ
|
|
%endif
|
|
%endif
|
|
|
|
; Initiation
|
|
|
|
SECTION .data
|
|
NEWSYM regsbackup, times 3019 db 0
|
|
NEWSYM forceromtype, db 0
|
|
; FIX STATMAT
|
|
NEWSYM autoloadstate, db 0 ; auto load state slot number
|
|
NEWSYM autoloadmovie, db 0
|
|
NEWSYM ZMVRawDump, db 0
|
|
|
|
SECTION .text
|
|
|
|
NEWSYM init
|
|
; prevents a crash if cpalval gets accessed before initializing
|
|
mov eax,cpalval
|
|
mov ecx,256
|
|
.looppal
|
|
mov dword[eax],cpalval
|
|
add eax,4
|
|
dec ecx
|
|
jnz .looppal
|
|
|
|
; Initialize snow stuff
|
|
mov ecx,400
|
|
xor edx,edx
|
|
.snowloop
|
|
shl word[SnowData+edx*2],8
|
|
and byte[SnowVelDist+edx],0F7h
|
|
cmp dword[SnowTimer],0
|
|
jne .skip
|
|
or byte[SnowVelDist+edx],08h
|
|
.skip
|
|
inc edx
|
|
dec ecx
|
|
jnz .snowloop
|
|
|
|
pushad
|
|
call BackupSystemVars
|
|
popad
|
|
|
|
mov al,[romtype]
|
|
mov [forceromtype],al
|
|
mov byte[romtype],0
|
|
mov ax,ds
|
|
mov es,ax
|
|
mov eax,regsbackup
|
|
mov ebx,sndrot
|
|
mov ecx,3019
|
|
.rbackupl
|
|
mov dl,[ebx]
|
|
mov [eax],dl
|
|
inc ebx
|
|
inc eax
|
|
dec ecx
|
|
jnz .rbackupl
|
|
pushad
|
|
call clearmem
|
|
popad
|
|
call inittable
|
|
call inittablec
|
|
call SA1inittable
|
|
; SPC Init
|
|
pushad
|
|
call procexecloop
|
|
popad
|
|
; SNES Init
|
|
pushad
|
|
call Setper2exec
|
|
popad
|
|
call Makemode7Table
|
|
call makesprprtable
|
|
mov eax,[ZCartName]
|
|
cmp byte[eax],0
|
|
jne .found
|
|
cmp byte[romloadskip],1
|
|
je .noloadfile
|
|
.found
|
|
mov byte[romloadskip],0
|
|
pushad
|
|
call loadfileGUI
|
|
call SetupROM
|
|
popad
|
|
cmp byte[DisplayInfo],0
|
|
je .noloadfile
|
|
pushad
|
|
call showinfogui
|
|
popad
|
|
.noloadfile
|
|
call UpdateDevices
|
|
pushad
|
|
call init65816
|
|
popad
|
|
call initregr
|
|
call initregw
|
|
pushad
|
|
call initsnes
|
|
popad
|
|
|
|
; Initialize volume
|
|
xor edx,edx
|
|
movzx eax,byte[MusicRelVol]
|
|
shl eax,7
|
|
mov ebx,0A3D70A3Dh
|
|
mul ebx
|
|
shr edx,6
|
|
cmp dl,127
|
|
jb .noof
|
|
mov dl,127
|
|
.noof
|
|
mov [MusicVol],dl
|
|
|
|
cmp byte[AutoState],1
|
|
jne .noloadzss
|
|
pushad
|
|
call LoadSecondState
|
|
popad
|
|
.noloadzss
|
|
|
|
; FIX STATMAT
|
|
; Here's the auto-load ZST file stuff
|
|
cmp byte[autoloadstate],1
|
|
jl .noautoloadstate
|
|
movzx eax,byte[autoloadstate]
|
|
dec eax
|
|
mov [current_zst],eax
|
|
|
|
; Load the specified state file
|
|
pushad
|
|
call loadstate2
|
|
popad
|
|
.noautoloadstate
|
|
|
|
cmp byte[autoloadmovie],1
|
|
jb .noautloadmovie
|
|
cmp byte[autoloadmovie],10
|
|
ja .noautloadmovie
|
|
mov al,[autoloadmovie]
|
|
add al,'0'-1
|
|
cmp al,'0'
|
|
jne .notzero1
|
|
mov al,'v'
|
|
.notzero1
|
|
mov [CMovieExt],al
|
|
|
|
pushad
|
|
cmp byte[ZMVRawDump],0
|
|
je .norawdump
|
|
call MovieDumpRaw
|
|
jmp .aftermovieplay
|
|
.norawdump
|
|
call MoviePlay
|
|
.aftermovieplay
|
|
popad
|
|
.noautloadmovie
|
|
|
|
cmp byte[yesoutofmemory],1
|
|
jne .noout
|
|
call outofmemfix
|
|
.noout
|
|
%ifndef NO_DEBUGGER
|
|
cmp byte[debugger],0
|
|
je near start65816
|
|
cmp byte[romloadskip],1
|
|
je near start65816
|
|
%ifndef __MSDOS__
|
|
;; Prevent nasty hang in debugger. Likely not a good way...
|
|
;; If we don't do this, then on the SDL and win32 ports, update_ticks_pc2
|
|
;; won't be set and CheckTimers will hang.
|
|
|
|
;; Most likely it isn't desirable to be checking timers under the
|
|
;; debugger anyway, but this is a much simpler fix.
|
|
|
|
pushad
|
|
%ifdef __WIN32__
|
|
;; need to get "freq" set first
|
|
call initwinvideo
|
|
%endif
|
|
call Start60HZ
|
|
popad
|
|
%endif
|
|
jmp startdebugger
|
|
%else
|
|
jmp start65816
|
|
%endif
|
|
|
|
; global variables
|
|
|
|
SECTION .data
|
|
|
|
NEWSYM romtype, db 0 ; ROM type in bytes
|
|
NEWSYM resetv, dw 0 ; reset vector
|
|
NEWSYM abortv, dw 0 ; abort vector
|
|
NEWSYM nmiv2, dw 0 ; nmi vector
|
|
NEWSYM nmiv, dw 0 ; nmi vector
|
|
NEWSYM irqv, dw 0 ; irq vector
|
|
NEWSYM irqv2, dw 0 ; irq vector
|
|
NEWSYM brkv, dw 0 ; brk vector
|
|
NEWSYM copv, dw 0 ; cop vector
|
|
NEWSYM abortv8, dw 0 ; abort vector emulation mode
|
|
NEWSYM nmiv8, dw 0 ; nmi vector emulation mode
|
|
NEWSYM irqv8, dw 0 ; irq vector emulation mode
|
|
NEWSYM brkv8, dw 0 ; brk vector emulation mode
|
|
NEWSYM copv8, dw 0 ; cop vector emulation mode
|
|
NEWSYM cycpb268, db 109 ; 110
|
|
NEWSYM cycpb358, db 149 ; 155
|
|
NEWSYM cycpbl2, db 109 ; percentage left of CPU/SPC to run (3.58 = 175)
|
|
NEWSYM cycpblt2, db 149 ; percentage of CPU/SPC to run
|
|
NEWSYM writeon, db 0 ; Write enable/disable on snes rom memory
|
|
NEWSYM totlines, dw 263 ; total # of lines
|
|
|
|
;This is saved in states
|
|
NEWSYM curcyc, db 0 ; cycles left in scanline
|
|
NEWSYM cacheud, db 1 ; update cache every ? frames
|
|
NEWSYM ccud, db 0 ; current cache increment
|
|
NEWSYM spcon, db 0 ; SPC Enable (1=enabled)
|
|
|
|
; 65816 registers
|
|
NEWSYM xat, dw 0
|
|
NEWSYM xdbt, db 0
|
|
NEWSYM xpbt, db 0
|
|
NEWSYM xst, dw 0
|
|
NEWSYM xdt, dw 0
|
|
NEWSYM xxt, dw 0
|
|
NEWSYM xyt, dw 0
|
|
NEWSYM xpc, dw 0
|
|
NEWSYM debugger, db 0 ; Start with debugger (1=yes,0=no)
|
|
NEWSYM curnmi, db 0 ; if in NMI(1) or not(0)
|
|
|
|
ALIGN32
|
|
NEWSYM cycpbl, dd 110 ; percentage left of CPU/SPC to run (3.58 = 175)
|
|
NEWSYM cycpblt, dd 110 ; percentage of CPU/SPC to run
|
|
|
|
NEWSYM cpuoverptr, dd 0 ; pointer to cpuover
|
|
|
|
ALIGN32
|
|
NEWSYM xa, dd 0
|
|
NEWSYM xdb, dd 0
|
|
NEWSYM xpb, dd 0
|
|
NEWSYM xs, dd 0
|
|
NEWSYM xd, dd 0
|
|
NEWSYM xx, dd 0
|
|
NEWSYM xy, dd 0
|
|
NEWSYM flagnz, dd 0
|
|
NEWSYM flago, dd 0
|
|
NEWSYM flagc, dd 0
|
|
NEWSYM bankkp, dd 0
|
|
NEWSYM Sflagnz, dd 0
|
|
NEWSYM Sflago, dd 0
|
|
NEWSYM Sflagc, dd 0
|
|
|
|
;*******************************************************
|
|
; Read Input Device Reads from Keyboard, etc.
|
|
;*******************************************************
|
|
|
|
SECTION .bss
|
|
NEWSYM WhichSW, resb 1
|
|
NEWSYM WhichGR, resb 1
|
|
NEWSYM autofr, resb 1
|
|
TurboCB resb 1
|
|
|
|
NEWSYM JoyAOrig, resd 1
|
|
NEWSYM JoyBOrig, resd 1
|
|
NEWSYM JoyCOrig, resd 1
|
|
NEWSYM JoyDOrig, resd 1
|
|
NEWSYM JoyEOrig, resd 1
|
|
NEWSYM JoyANow, resd 1
|
|
NEWSYM JoyBNow, resd 1
|
|
NEWSYM JoyCNow, resd 1
|
|
NEWSYM JoyDNow, resd 1
|
|
NEWSYM JoyENow, resd 1
|
|
NEWSYM LethEnData, resd 1
|
|
NEWSYM ComboCounter, resb 1
|
|
SECTION .text
|
|
|
|
%macro PlayerDeviceHelp 3
|
|
mov eax,[%1]
|
|
cmp byte[pressed+eax],1
|
|
jne %%no
|
|
or dword[%2],%3
|
|
%%no
|
|
%endmacro
|
|
|
|
%macro ProcSNESMouse 1
|
|
test byte[mousebuttons],02h
|
|
jz %%n
|
|
or dword[%1],00000000100000000000000000000000b
|
|
mov al,1
|
|
%%n
|
|
test byte[mousebuttons],01h
|
|
jz %%n2
|
|
or dword[%1],00000000010000000000000000000000b
|
|
%%n2
|
|
or dword[%1],00000000000000010000000000000000b
|
|
mov al,[mouseypos]
|
|
and al,7Fh
|
|
or byte[%1+1],al
|
|
mov al,[mousexpos]
|
|
and al,7Fh
|
|
or byte[%1],al
|
|
test byte[mouseydir],01h
|
|
jz %%n3
|
|
or dword[%1],00000000000000001000000000000000b
|
|
%%n3
|
|
test byte[mousexdir],01h
|
|
jz %%n4
|
|
or dword[%1],00000000000000000000000010000000b
|
|
%%n4
|
|
%endmacro
|
|
|
|
%macro ProcessKeyComb 2
|
|
cmp dword[NumCombo],0
|
|
je near %%nocomb
|
|
mov eax,CombinDataGlob
|
|
cmp byte[GUIComboGameSpec],0
|
|
je %%local
|
|
mov eax,CombinDataLocl
|
|
%%local
|
|
push ecx
|
|
push ebx
|
|
xor ebx,ebx
|
|
cmp byte[ComboProg+%1],0
|
|
jne near %%progressing
|
|
test dword[%2],01000000h
|
|
jz %%noright
|
|
mov dword[CombDirSwap],0
|
|
%%noright
|
|
test dword[%2],02000000h
|
|
jz %%noleft
|
|
mov dword[CombDirSwap],1
|
|
%%noleft
|
|
mov ecx,[NumCombo]
|
|
%%loop
|
|
mov bx,[eax+62]
|
|
cmp byte[pressed+ebx],1
|
|
jne %%nopress
|
|
cmp byte[eax+64],%1
|
|
je %%startprogress
|
|
%%nopress
|
|
add eax,66
|
|
dec ecx
|
|
jnz %%loop
|
|
jmp %%endcomb
|
|
%%startprogress
|
|
mov byte[pressed+ebx],2
|
|
inc byte[ComboCounter]
|
|
mov byte[ComboProg+%1],1
|
|
mov byte[ComboPtr+%1],0
|
|
mov dword[PressComb+%1*4],0
|
|
mov dword[HoldComb+%1*4],0
|
|
mov dword[CombCont+%1*4],CombContDatN
|
|
cmp dword[CombDirSwap],0
|
|
je %%NoSwapLeftRight
|
|
cmp byte[eax+65],0
|
|
je %%NoSwapLeftRight
|
|
mov dword[CombCont+%1*4],CombContDatR
|
|
%%NoSwapLeftRight
|
|
add eax,20
|
|
mov [StartComb+%1*4],eax
|
|
%%progressing
|
|
mov ecx,%1
|
|
mov eax,[StartComb+%1*4]
|
|
call ProcessCombo
|
|
mov [StartComb+%1*4],eax
|
|
or ebx,ebx
|
|
jz %%proccomb
|
|
mov byte[ComboProg+%1],0
|
|
%%proccomb
|
|
mov dword[%2],0
|
|
mov eax,[HoldComb+%1*4]
|
|
or dword[%2],eax
|
|
mov eax,[PressComb+%1*4]
|
|
or dword[%2],eax
|
|
%%endcomb
|
|
pop ebx
|
|
pop ecx
|
|
%%nocomb
|
|
%endmacro
|
|
|
|
ProcessCombo:
|
|
mov dword[KeyLPress],0
|
|
cmp dword[CombDelay+ecx*4],0
|
|
jne .delay
|
|
.nextsession
|
|
xor ebx,ebx
|
|
cmp byte[eax],0
|
|
je .finish
|
|
mov bl,[eax]
|
|
cmp bl,37
|
|
jb .keypress
|
|
cmp bl,48
|
|
ja .finish
|
|
sub ebx,37
|
|
shl ebx,2
|
|
add ebx,CombTDelN
|
|
cmp byte[romispal],0
|
|
je .ntsc
|
|
sub ebx,CombTDelN
|
|
add ebx,CombTDelP
|
|
.ntsc
|
|
mov ebx,[ebx]
|
|
mov [CombDelay+ecx*4],ebx
|
|
inc eax
|
|
inc byte[ComboPtr+ecx]
|
|
cmp byte[ComboPtr+ecx],42
|
|
je .finish
|
|
.delay
|
|
dec dword[CombDelay+ecx*4]
|
|
xor ebx,ebx
|
|
ret
|
|
.finish
|
|
mov ebx,1
|
|
ret
|
|
.keypress
|
|
cmp dword[KeyLPress],0
|
|
jne .alreadyproc
|
|
mov dword[PressComb+ecx*4],0
|
|
mov dword[KeyLPress],1
|
|
.alreadyproc
|
|
dec ebx
|
|
cmp ebx,12
|
|
jae .pressonly
|
|
shl ebx,2
|
|
add ebx,[CombCont+ecx*4]
|
|
mov ebx,[ebx]
|
|
or [PressComb+ecx*4],ebx
|
|
jmp .finkeyproc
|
|
.pressonly
|
|
sub ebx,12
|
|
cmp ebx,12
|
|
jae .releaseonly
|
|
shl ebx,2
|
|
add ebx,[CombCont+ecx*4]
|
|
mov ebx,[ebx]
|
|
or [HoldComb+ecx*4],ebx
|
|
jmp .finkeyproc
|
|
.releaseonly
|
|
sub ebx,12 ; <- bugfix from Maxim
|
|
shl ebx,2
|
|
add ebx,[CombCont+ecx*4]
|
|
mov ebx,[ebx]
|
|
xor ebx,0FFFFFFFFh
|
|
and [HoldComb+ecx*4],ebx
|
|
and [PressComb+ecx*4],ebx ; <- buxfix from Maxim
|
|
.finkeyproc
|
|
inc eax
|
|
inc byte[ComboPtr+ecx]
|
|
cmp byte[ComboPtr+ecx],42
|
|
je near .finish
|
|
jmp .nextsession
|
|
|
|
SECTION .data
|
|
TurboSw db 0
|
|
ComboProg times 5 db 0
|
|
ComboPtr times 5 db 0
|
|
KeyLPress dd 0
|
|
CombDirSwap dd 0
|
|
CombDelay times 5 dd 0
|
|
StartComb times 5 dd 0
|
|
HoldComb times 5 dd 0
|
|
PressComb times 5 dd 0
|
|
CombCont times 5 dd 0
|
|
CombTDelN dd 1,2,3,4,5,9,30,60,120,180,240,300
|
|
CombTDelP dd 1,2,3,4,5,9,25,50,100,150,200,250
|
|
CombContDatN dd 08000000h,04000000h,02000000h,01000000h,00800000h,80000000h
|
|
dd 00400000h,40000000h,00200000h,00100000h,10000000h,20000000h
|
|
CombContDatR dd 08000000h,04000000h,01000000h,02000000h,00800000h,80000000h
|
|
dd 00400000h,40000000h,00200000h,00100000h,10000000h,20000000h
|
|
|
|
SECTION .text
|
|
|
|
%macro PlayerDeviceFix 1
|
|
cmp byte[AllowUDLR],1
|
|
je %%noleftright
|
|
mov eax,[%1]
|
|
and eax,0C000000h
|
|
cmp eax,0C000000h
|
|
jne %%noupdown
|
|
and dword[%1],0F3FFFFFFh
|
|
%%noupdown
|
|
mov eax,[%1]
|
|
and eax,03000000h
|
|
cmp eax,03000000h
|
|
jne %%noleftright
|
|
and dword[%1],0FCFFFFFFh
|
|
%%noleftright
|
|
%endmacro
|
|
|
|
NEWSYM ReadInputDevice
|
|
mov byte[WhichSW],1
|
|
mov byte[WhichGR],0
|
|
inc byte[TurboSw]
|
|
mov byte[TurboCB],01h
|
|
cmp byte[Turbo30hz],0
|
|
je .noturbo30
|
|
mov byte[TurboCB],02h
|
|
.noturbo30
|
|
; Read External Devices (Joystick, PPort, etc.)
|
|
call JoyRead
|
|
; Process Data
|
|
mov dword[JoyAOrig],0
|
|
mov dword[JoyBOrig],0
|
|
|
|
; Get Player1 input device
|
|
cmp byte[device1],1
|
|
jne .nomouse1
|
|
call processmouse1
|
|
ProcSNESMouse JoyAOrig
|
|
jmp .noinput1
|
|
.nomouse1
|
|
PlayerDeviceHelp pl1Bk ,JoyAOrig,80000000h
|
|
PlayerDeviceHelp pl1Yk ,JoyAOrig,40000000h
|
|
PlayerDeviceHelp pl1selk ,JoyAOrig,20000000h
|
|
PlayerDeviceHelp pl1startk,JoyAOrig,10000000h
|
|
PlayerDeviceHelp pl1upk ,JoyAOrig,08000000h
|
|
PlayerDeviceHelp pl1downk ,JoyAOrig,04000000h
|
|
PlayerDeviceHelp pl1leftk ,JoyAOrig,02000000h
|
|
PlayerDeviceHelp pl1rightk,JoyAOrig,01000000h
|
|
PlayerDeviceHelp pl1Ak ,JoyAOrig,00800000h
|
|
PlayerDeviceHelp pl1Xk ,JoyAOrig,00400000h
|
|
PlayerDeviceHelp pl1Lk ,JoyAOrig,00200000h
|
|
PlayerDeviceHelp pl1Rk ,JoyAOrig,00100000h
|
|
PlayerDeviceHelp pl1ULk ,JoyAOrig,0A000000h
|
|
PlayerDeviceHelp pl1URk ,JoyAOrig,09000000h
|
|
PlayerDeviceHelp pl1DLk ,JoyAOrig,06000000h
|
|
PlayerDeviceHelp pl1DRk ,JoyAOrig,05000000h
|
|
PlayerDeviceFix JoyAOrig
|
|
mov al,[TurboCB]
|
|
test byte[TurboSw],al
|
|
jnz near .noswitch
|
|
PlayerDeviceHelp pl1Xtk ,JoyAOrig,00400000h
|
|
PlayerDeviceHelp pl1Ytk ,JoyAOrig,40000000h
|
|
PlayerDeviceHelp pl1Atk ,JoyAOrig,00800000h
|
|
PlayerDeviceHelp pl1Btk ,JoyAOrig,80000000h
|
|
PlayerDeviceHelp pl1Ltk ,JoyAOrig,00200000h
|
|
PlayerDeviceHelp pl1Rtk ,JoyAOrig,00100000h
|
|
.noswitch
|
|
mov byte[ComboCounter],0
|
|
ProcessKeyComb 0,JoyAOrig
|
|
or dword[JoyAOrig],00008000h ; Joystick Enable
|
|
cmp byte[GUIDelayB],0
|
|
je .noinput1
|
|
cmp byte[GUIDelayB],1
|
|
jne .inputbd
|
|
test dword[JoyAOrig],80000000h
|
|
jnz .inputbdcb
|
|
dec byte[GUIDelayB]
|
|
jmp .noinput1
|
|
.inputbd
|
|
dec byte[GUIDelayB]
|
|
.inputbdcb
|
|
and dword[JoyAOrig],7FFFFFFFh
|
|
.noinput1
|
|
cmp byte[device2],1
|
|
jne .nomouse2
|
|
call processmouse2
|
|
ProcSNESMouse JoyBOrig
|
|
jmp .noinput2
|
|
.nomouse2
|
|
cmp byte[device2],2
|
|
jne .nosuperscope
|
|
call processmouse2
|
|
mov byte[JoyBOrig+2],0FFh
|
|
mov al,[ssautosw]
|
|
test byte[mousebuttons],01h
|
|
jz .nobutton1
|
|
or al,80h
|
|
.nobutton1
|
|
push eax
|
|
mov eax,[SSPause]
|
|
cmp byte[pressed+eax],0
|
|
pop eax
|
|
jz .nobutton3
|
|
or al,10h
|
|
.nobutton3
|
|
test byte[mousebuttons],02h
|
|
jz .nobutton4
|
|
or al,40h
|
|
.nobutton4
|
|
mov [JoyBOrig+3],al
|
|
jmp .noinput2
|
|
.nosuperscope
|
|
cmp byte[device2],3
|
|
jne .nolethalen
|
|
call processmouse2
|
|
mov eax,[romdata]
|
|
cmp dword[eax+1000h],0AD20C203h
|
|
jne .not
|
|
mov eax,[wramdata]
|
|
cmp byte[eax],26
|
|
je .not
|
|
mov bl,[mousexloc]
|
|
mov [eax+40Ah],bl
|
|
mov bl,[mouseyloc]
|
|
mov [eax+40Eh],bl
|
|
.not
|
|
; mov word[JoyBOrig+2],000Eh
|
|
; and dword[LethEnData],0000000FFh
|
|
; or dword[LethEnData],055010000h
|
|
; inc byte[LethEnData]
|
|
test byte[LethEnData],1
|
|
jz .n1
|
|
; mov byte[LethEnData+2],8
|
|
mov byte[extlatch],0
|
|
.n1
|
|
test byte[mousebuttons],01h
|
|
jz .nobutton1b
|
|
; or dword[LethEnData+2],10h
|
|
or byte[JoyAOrig+3],80h
|
|
.nobutton1b
|
|
push eax
|
|
mov eax,[SSPause]
|
|
cmp byte[pressed+eax],0
|
|
pop eax
|
|
jz .nobutton3b
|
|
; or byte[LethEnData+2],40h
|
|
.nobutton3b
|
|
test byte[mousebuttons],02h
|
|
jz .nobutton4b
|
|
; or byte[LethEnData+2],40h
|
|
or byte[JoyAOrig+2],80h
|
|
.nobutton4b
|
|
jmp .noinput2
|
|
.nolethalen
|
|
cmp byte[pl2contrl],0
|
|
je near .noinput2
|
|
; Get Player2 input device
|
|
PlayerDeviceHelp pl2Bk ,JoyBOrig,80000000h
|
|
PlayerDeviceHelp pl2Yk ,JoyBOrig,40000000h
|
|
PlayerDeviceHelp pl2selk ,JoyBOrig,20000000h
|
|
PlayerDeviceHelp pl2startk,JoyBOrig,10000000h
|
|
PlayerDeviceHelp pl2upk ,JoyBOrig,08000000h
|
|
PlayerDeviceHelp pl2downk ,JoyBOrig,04000000h
|
|
PlayerDeviceHelp pl2leftk ,JoyBOrig,02000000h
|
|
PlayerDeviceHelp pl2rightk,JoyBOrig,01000000h
|
|
PlayerDeviceHelp pl2Ak ,JoyBOrig,00800000h
|
|
PlayerDeviceHelp pl2Xk ,JoyBOrig,00400000h
|
|
PlayerDeviceHelp pl2Lk ,JoyBOrig,00200000h
|
|
PlayerDeviceHelp pl2Rk ,JoyBOrig,00100000h
|
|
PlayerDeviceHelp pl2ULk ,JoyBOrig,0A000000h
|
|
PlayerDeviceHelp pl2URk ,JoyBOrig,09000000h
|
|
PlayerDeviceHelp pl2DLk ,JoyBOrig,06000000h
|
|
PlayerDeviceHelp pl2DRk ,JoyBOrig,05000000h
|
|
PlayerDeviceFix JoyBOrig
|
|
mov al,[TurboCB]
|
|
test byte[TurboSw],al
|
|
jnz near .noswitch2
|
|
PlayerDeviceHelp pl2Xtk ,JoyBOrig,00400000h
|
|
PlayerDeviceHelp pl2Ytk ,JoyBOrig,40000000h
|
|
PlayerDeviceHelp pl2Atk ,JoyBOrig,00800000h
|
|
PlayerDeviceHelp pl2Btk ,JoyBOrig,80000000h
|
|
PlayerDeviceHelp pl2Ltk ,JoyBOrig,00200000h
|
|
PlayerDeviceHelp pl2Rtk ,JoyBOrig,00100000h
|
|
.noswitch2
|
|
ProcessKeyComb 1,JoyBOrig
|
|
or dword[JoyBOrig],00008000h ; Joystick Enable
|
|
.noinput2
|
|
mov dword[JoyCOrig],0
|
|
cmp byte[pl3contrl],0
|
|
je near .noinput3
|
|
; Get Player3 input device
|
|
PlayerDeviceHelp pl3Bk ,JoyCOrig,80000000h
|
|
PlayerDeviceHelp pl3Yk ,JoyCOrig,40000000h
|
|
PlayerDeviceHelp pl3selk ,JoyCOrig,20000000h
|
|
PlayerDeviceHelp pl3startk,JoyCOrig,10000000h
|
|
PlayerDeviceHelp pl3upk ,JoyCOrig,08000000h
|
|
PlayerDeviceHelp pl3downk ,JoyCOrig,04000000h
|
|
PlayerDeviceHelp pl3leftk ,JoyCOrig,02000000h
|
|
PlayerDeviceHelp pl3rightk,JoyCOrig,01000000h
|
|
PlayerDeviceHelp pl3Ak ,JoyCOrig,00800000h
|
|
PlayerDeviceHelp pl3Xk ,JoyCOrig,00400000h
|
|
PlayerDeviceHelp pl3Lk ,JoyCOrig,00200000h
|
|
PlayerDeviceHelp pl3Rk ,JoyCOrig,00100000h
|
|
PlayerDeviceHelp pl3ULk ,JoyCOrig,0A000000h
|
|
PlayerDeviceHelp pl3URk ,JoyCOrig,09000000h
|
|
PlayerDeviceHelp pl3DLk ,JoyCOrig,06000000h
|
|
PlayerDeviceHelp pl3DRk ,JoyCOrig,05000000h
|
|
PlayerDeviceFix JoyCOrig
|
|
mov al,[TurboCB]
|
|
test byte[TurboSw],al
|
|
jnz near .noswitch3
|
|
PlayerDeviceHelp pl3Xtk ,JoyCOrig,00400000h
|
|
PlayerDeviceHelp pl3Ytk ,JoyCOrig,40000000h
|
|
PlayerDeviceHelp pl3Atk ,JoyCOrig,00800000h
|
|
PlayerDeviceHelp pl3Btk ,JoyCOrig,80000000h
|
|
PlayerDeviceHelp pl3Ltk ,JoyCOrig,00200000h
|
|
PlayerDeviceHelp pl3Rtk ,JoyCOrig,00100000h
|
|
.noswitch3
|
|
ProcessKeyComb 2,JoyCOrig
|
|
or dword[JoyCOrig],00008000h ; Joystick Enable
|
|
.noinput3
|
|
mov dword[JoyDOrig],0
|
|
cmp byte[pl4contrl],0
|
|
je near .noinput4
|
|
; Get Player4 input device
|
|
PlayerDeviceHelp pl4Bk ,JoyDOrig,80000000h
|
|
PlayerDeviceHelp pl4Yk ,JoyDOrig,40000000h
|
|
PlayerDeviceHelp pl4selk ,JoyDOrig,20000000h
|
|
PlayerDeviceHelp pl4startk,JoyDOrig,10000000h
|
|
PlayerDeviceHelp pl4upk ,JoyDOrig,08000000h
|
|
PlayerDeviceHelp pl4downk ,JoyDOrig,04000000h
|
|
PlayerDeviceHelp pl4leftk ,JoyDOrig,02000000h
|
|
PlayerDeviceHelp pl4rightk,JoyDOrig,01000000h
|
|
PlayerDeviceHelp pl4Ak ,JoyDOrig,00800000h
|
|
PlayerDeviceHelp pl4Xk ,JoyDOrig,00400000h
|
|
PlayerDeviceHelp pl4Lk ,JoyDOrig,00200000h
|
|
PlayerDeviceHelp pl4Rk ,JoyDOrig,00100000h
|
|
PlayerDeviceHelp pl4ULk ,JoyDOrig,0A000000h
|
|
PlayerDeviceHelp pl4URk ,JoyDOrig,09000000h
|
|
PlayerDeviceHelp pl4DLk ,JoyDOrig,06000000h
|
|
PlayerDeviceHelp pl4DRk ,JoyDOrig,05000000h
|
|
PlayerDeviceFix JoyDOrig
|
|
mov al,[TurboCB]
|
|
test byte[TurboSw],al
|
|
jnz near .noswitch4
|
|
PlayerDeviceHelp pl4Xtk ,JoyDOrig,00400000h
|
|
PlayerDeviceHelp pl4Ytk ,JoyDOrig,40000000h
|
|
PlayerDeviceHelp pl4Atk ,JoyDOrig,00800000h
|
|
PlayerDeviceHelp pl4Btk ,JoyDOrig,80000000h
|
|
PlayerDeviceHelp pl4Ltk ,JoyDOrig,00200000h
|
|
PlayerDeviceHelp pl4Rtk ,JoyDOrig,00100000h
|
|
.noswitch4
|
|
ProcessKeyComb 3,JoyDOrig
|
|
or dword[JoyDOrig],00008000h ; Joystick Enable
|
|
.noinput4
|
|
mov dword[JoyEOrig],0
|
|
cmp byte[pl5contrl],0
|
|
je near .noinput5
|
|
; Get Player4 input device
|
|
PlayerDeviceHelp pl5Bk ,JoyEOrig,80000000h
|
|
PlayerDeviceHelp pl5Yk ,JoyEOrig,40000000h
|
|
PlayerDeviceHelp pl5selk ,JoyEOrig,20000000h
|
|
PlayerDeviceHelp pl5startk,JoyEOrig,10000000h
|
|
PlayerDeviceHelp pl5upk ,JoyEOrig,08000000h
|
|
PlayerDeviceHelp pl5downk ,JoyEOrig,04000000h
|
|
PlayerDeviceHelp pl5leftk ,JoyEOrig,02000000h
|
|
PlayerDeviceHelp pl5rightk,JoyEOrig,01000000h
|
|
PlayerDeviceHelp pl5Ak ,JoyEOrig,00800000h
|
|
PlayerDeviceHelp pl5Xk ,JoyEOrig,00400000h
|
|
PlayerDeviceHelp pl5Lk ,JoyEOrig,00200000h
|
|
PlayerDeviceHelp pl5Rk ,JoyEOrig,00100000h
|
|
PlayerDeviceHelp pl5ULk ,JoyEOrig,0A000000h
|
|
PlayerDeviceHelp pl5URk ,JoyEOrig,09000000h
|
|
PlayerDeviceHelp pl5DLk ,JoyEOrig,06000000h
|
|
PlayerDeviceHelp pl5DRk ,JoyEOrig,05000000h
|
|
PlayerDeviceFix JoyEOrig
|
|
mov al,[TurboCB]
|
|
test byte[TurboSw],al
|
|
jnz near .noswitch5
|
|
PlayerDeviceHelp pl5Xtk ,JoyEOrig,00400000h
|
|
PlayerDeviceHelp pl5Ytk ,JoyEOrig,40000000h
|
|
PlayerDeviceHelp pl5Atk ,JoyEOrig,00800000h
|
|
PlayerDeviceHelp pl5Btk ,JoyEOrig,80000000h
|
|
PlayerDeviceHelp pl5Ltk ,JoyEOrig,00200000h
|
|
PlayerDeviceHelp pl5Rtk ,JoyEOrig,00100000h
|
|
.noswitch5
|
|
ProcessKeyComb 4,JoyEOrig
|
|
or dword[JoyEOrig],00008000h ; Joystick Enable
|
|
.noinput5
|
|
cmp byte[pl12s34],1
|
|
jne .nop24
|
|
cmp byte[device1],0
|
|
jne .nop13
|
|
mov eax,[JoyCOrig]
|
|
or [JoyAOrig],eax
|
|
.nop13
|
|
cmp byte[device2],0
|
|
jne .nop24
|
|
mov eax,[JoyDOrig]
|
|
or [JoyBOrig],eax
|
|
.nop24
|
|
ret
|
|
|
|
;*******************************************************
|
|
; Init 65816 Initializes the Registers
|
|
;*******************************************************
|
|
|
|
SECTION .data
|
|
|
|
NEWSYM disablespcclr, db 0
|
|
NEWSYM numspcvblleft, dd 0
|
|
NEWSYM spc700idle, dd 0
|
|
NEWSYM ENVDisable, db 0
|
|
SECTION .text
|
|
|
|
NEWSYM idledetectspc
|
|
inc dword[numspcvblleft]
|
|
cmp byte[SPCStallSetting],2
|
|
jae .fullstall
|
|
inc byte[SPCStallSetting]
|
|
mov byte[ReturnFromSPCStall],1
|
|
ret
|
|
.fullstall
|
|
mov dword[spc700idle],29
|
|
mov dword[Msgptr],.unableskip
|
|
mov eax,[MsgCount]
|
|
mov [MessageOn],eax
|
|
ret
|
|
|
|
SECTION .data
|
|
.unableskip db 'SPC700 STALL DETECTED.',0
|
|
|
|
SECTION .bss
|
|
NEWSYM ReturnFromSPCStall, resb 1
|
|
NEWSYM SPCStallSetting, resb 1
|
|
SECTION .text
|
|
|
|
;*******************************************************
|
|
; Print Hexadecimal (16-bit/8-bit)
|
|
;*******************************************************
|
|
NEWSYM printhex
|
|
mov ecx,4
|
|
xor ebx,ebx
|
|
.loopa
|
|
mov bx,ax
|
|
and bx,0F000h
|
|
shr bx,12
|
|
mov dl,[.hexdat+ebx]
|
|
push ax
|
|
mov ah,02h
|
|
call Output_Text
|
|
pop ax
|
|
shl ax,4
|
|
dec ecx
|
|
jnz .loopa
|
|
ret
|
|
|
|
SECTION .data
|
|
.hexdat db '0123456789ABCDEF'
|
|
|
|
SECTION .bss
|
|
NEWSYM IPSPatched, resb 1
|
|
NEWSYM Checksumvalue, resw 1
|
|
NEWSYM SramExists, resb 1
|
|
NEWSYM NumofBanks, resd 1
|
|
NEWSYM NumofBytes, resd 1
|
|
|
|
SECTION .text
|
|
|
|
NEWSYM DosExit ; Terminate Program
|
|
cmp byte[AutoState],1
|
|
jne .noautostate
|
|
pushad
|
|
call SaveSecondState
|
|
popad
|
|
.noautostate
|
|
%ifdef __MSDOS__
|
|
call init18_2hz
|
|
%endif
|
|
call zexit
|
|
|
|
NEWSYM MMXCheck
|
|
; Check for cpu that doesn't support CPUID
|
|
mov byte[ShowMMXSupport],0
|
|
mov byte[MMXSupport],0
|
|
mov byte[MMXextSupport],0
|
|
|
|
; Real way to check for presence of CPUID instruction -kode54
|
|
pushfd
|
|
pop eax
|
|
mov edx,eax
|
|
xor eax,1 << 21
|
|
push eax
|
|
popfd
|
|
pushfd
|
|
pop eax
|
|
xor eax,edx
|
|
jz .nommx
|
|
|
|
; MMX support
|
|
mov eax,1
|
|
CPUID
|
|
|
|
test edx,1 << 23
|
|
jz .nommx
|
|
mov byte[ShowMMXSupport],1
|
|
mov al,[AllowMMX]
|
|
mov [MMXSupport],al
|
|
jz .nommx
|
|
|
|
; Check if CPU has SSE (also support mmxext)
|
|
test edx,1 << 25
|
|
jz .tryextmmx
|
|
mov byte[MMXextSupport],1
|
|
ret
|
|
|
|
.tryextmmx
|
|
; Test extended CPU flag
|
|
mov eax,80000001h
|
|
CPUID
|
|
test edx,1 << 22
|
|
jz .nommx
|
|
mov byte[MMXextSupport],1
|
|
.nommx
|
|
ret
|
|
|
|
;*******************************************************
|
|
; Show Information
|
|
;*******************************************************
|
|
;
|
|
; Maker Code = FFB0-FFB1
|
|
; Game Code = FFB2-FFB5
|
|
; Expansion RAM Size = FFBD (0=none, 1=16kbit, 3=64kbit, 5=256kbit,etc.
|
|
; Map Mode = FFD5 2.68-20h=map20h,21h=map21h,22h=reserved,23h=SA-1,25h=map25h
|
|
; 3.58-30h=map20h,31h=map21h,35h=map25h,highspeed
|
|
; Rom Mask Version = FFDB
|
|
; FFD6 (ROM Type) : 0*=DSP,1*=SFX,2*=OBC1,3*=SA-1,E*-F*=other
|
|
; *3=ROM,*4=ROM+RAM,*5=ROM+RAM+BATTERY,*6=ROM+BATTERY
|
|
; F3=C4
|
|
|
|
|
|
SECTION .bss
|
|
NEWSYM DSP1Type, resb 1
|
|
NEWSYM Interleaved, resb 1
|
|
SECTION .text
|
|
|
|
NEWSYM outofmemfix
|
|
mov esi,[romdata]
|
|
cmp byte[romtype],2
|
|
jne .nhirom
|
|
add esi,8000h
|
|
.nhirom
|
|
mov word[resetv],8000h
|
|
mov word[xpc],8000h
|
|
mov byte[esi],58h
|
|
mov byte[esi+1],80h
|
|
mov byte[esi+2],0FEh
|
|
mov dword[Msgptr],outofmemoryerror
|
|
cmp byte[newgfx16b],1
|
|
jne .notso
|
|
mov dword[Msgptr],outofmemoryerror2
|
|
.notso
|
|
mov dword[MessageOn],0FFFFFFFFh
|
|
ret
|
|
|
|
SECTION .bss
|
|
NEWSYM yesoutofmemory, resb 1
|
|
NEWSYM MMXSupport, resb 1
|
|
SECTION .data
|
|
NEWSYM outofmemoryerror, db 'OUT OF MEMORY.',0
|
|
NEWSYM outofmemoryerror2, db 'ROM IS TOO BIG.',0
|