2009-04-22 20:04:28 +02:00

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