Files
ZSNES/zsnes/src/cpu/execute.asm
2001-04-15 08:19:09 +00:00

4376 lines
88 KiB
NASM

;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 StringLength
EXTSYM Get_Time
EXTSYM objhipr
EXTSYM KeyRewind
EXTSYM xa,timer2upd,prevoamptr,ReadHead
EXTSYM prevedi,SA1xpc,SA1RAMArea,sa1dmaptr
EXTSYM DSP1COp,C4WFXVal,C41FXVal,Op00Multiplicand,Op10Coefficient,Op04Angle
EXTSYM Op08X,Op18X,Op28X,Op0CA,Op1CAZ,Op02FX,Op0AVS,Op06X,Op0DX,Op03F,Op14Zr
EXTSYM Op0EH,DSP1Type,Op01m
EXTSYM Voice0Status
EXTSYM UpdateDPage
EXTSYM Interror,MessageOn,MsgCount,Msgptr,StartGUI,cbitmode,debuggeron,romdata
EXTSYM frameskip,initvideo,newgfx16b,oldhandSBo,oldhandSBs,soundon,cvidmode
EXTSYM vidbuffer,vidbufferofsa,vidbufferofsb,disable65816sh,GUISaveVars,virqnodisable
EXTSYM KeySaveState,KeyLoadState,KeyQuickExit,KeyQuickLoad,KeyQuickRst,GUIDoReset
EXTSYM KeyOnStA,KeyOnStB,ProcessKeyOn,printnum,sramsavedis,DSPDisable,C4Enable
EXTSYM IRQHack,HIRQLoc,Offby1line,splitflags,joinflags,KeyQuickSnapShot
EXTSYM csounddisable,videotroub,Open_File,Close_File,Read_File,ResetTripleBuf
EXTSYM Write_File,Output_Text,Create_File,Check_Key,Get_Key,Change_Dir,InitPreGame
EXTSYM OSPort
; EXTSYM tempblah,romdata
EXTSYM Curtableaddr,DeInitSPC,InitSB,PICMaskP,SBHandler,SBInt
EXTSYM SBIrq,curcyc,debugdisble,dmadata,guioff,memtabler8,SetupPreGame
EXTSYM memtablew8,regaccessbankr8,showmenu,snesmap2,snesmmap,DeInitPostGame
EXTSYM spcPCRam,startdebugger,xp,xpb,xpc,tablead,tableadb,tableadc
; EXTSYM oamram
EXTSYM SA1UpdateDPage,Makemode7Table
EXTSYM memtabler16,memaccessbankr848mb,memaccessbankr1648mb
EXTSYM nextmenupopup
EXTSYM MovieProcessing
EXTSYM MovieFileHand, PrintStr
EXTSYM OSExit,DosExit,InitDir,InitDrive,createnewcfg,fnames,gotoroot,previdmode
EXTSYM ramsize,sfxramdata,sram,SRAMDrive,SRAMDir,welcome
; EXTSYM tempstore
EXTSYM printhex
EXTSYM ModemInitStat, DeInitModem
EXTSYM deinitipx
EXTSYM deinitvideo
EXTSYM BRRBuffer,DSPMem,PrepareSaveState,ResetState,SFXEnable,PHdspsave
EXTSYM fnamest,sndrot,spcRam,spcRamDP,tableA,unpackfunct,vram,wramdata
EXTSYM zsmesg,PHnum2writesfxreg,SfxR0,PHnum2writecpureg,PHspcsave,initrevst
EXTSYM C4Ram
EXTSYM SPC7110Enable
EXTSYM SA1Mode,PHnum2writesa1reg,SaveSA1,RestoreSA1,UpdateBanksSDD1
EXTSYM SDD1Enable
EXTSYM CapturePicture,PrevPicture,NoPictureSave
EXTSYM BRRPlace0,SfxCPB,SfxCROM,SfxLastRamAdr,SfxMemTable,Totalbyteloaded
EXTSYM SfxRAMBR,SfxRAMMem,SfxROMBR,SfxRomBuffer,Voice0Freq
EXTSYM cycpbl,cycpbl2,cycpblt,cycpblt2,irqon,nexthdma
EXTSYM repackfunct,spcnumread,spcon,versn,headerhack,initpitch
EXTSYM SPCMultA,PHnum2writespc7110reg
EXTSYM multchange,procexecloop,vidmemch2
EXTSYM romispal
EXTSYM dssel
EXTSYM scrndis,sprlefttot,sprleftpr,processsprites,cachesprites
EXTSYM NextLineStart,FlipWait,LastLineStart
EXTSYM opcjmptab
EXTSYM cpuoverptr
EXTSYM CheatOn,INTEnab,JoyAPos,JoyBPos,JoyCRead,NMIEnab,NumCheats,CurrentExecSA1
EXTSYM ReadInputDevice,StartDrawNewGfx,VIRQLoc,cachevideo,cfield
EXTSYM cheatdata,curblank,curnmi,curypos,cycpl,doirqnext,drawline
EXTSYM execatzerovirq,exechdma,hdmadelay,intrset,newengen,oamaddr
EXTSYM oamaddrs,processmouse,resolutn,showvideo,snesmouse,starthdma
EXTSYM switchtonmi,switchtovirq,totlines,updatetimer,SA1Swap,SA1DoIRQ
EXTSYM JoyAOrig,JoyANow,JoyBOrig,JoyBNow,JoyCOrig,JoyCNow,JoyDOrig,JoyDNow
EXTSYM JoyEOrig,JoyENow,chaton,chatstrL,chatRTL,chatstrR,SA1Message
EXTSYM MultiTapStat,MovieCounter,idledetectspc,SA1Control,SA1Enable,SA1IRQEnable
EXTSYM SPC700read,SPC700write,numspcvblleft,spc700idle,SA1Status,SA1IRQExec
EXTSYM ForceNewGfxOff,LethEnData,C4Pause,GUIQuit
EXTSYM IRAM,SA1Ptr,SA1BWPtr
EXTSYM scrnon,scaddset
EXTSYM outofmemfix,yesoutofmemory
EXTSYM CNetType,Latency,LatencyLeft,NetSwap
; EXTSYM vesa2selec
EXTSYM RemoteSendChar,RemoteGetChar,pl1neten,pl2neten,pl3neten,pl4neten
EXTSYM pl5neten,RemoteSendEAX,prevp1net,prevp2net,prevp3net,prevp4net
EXTSYM RemoteGetEAX,cnetplaybuf,netdelayed,cnetptrtail,cnetptrhead
EXTSYM ChatProgress,RecvProgress,chatTL,WritetochatBuffer,NetAddChar
EXTSYM PreparePacket, SendPacket, NoInputRead, RemoteDisconnect
EXTSYM SendPacketUDP
EXTSYM ChatNick
EXTSYM JoyRead,ChatType2,chatstrR2,chatstrR3,chatstrR4,chatstrR5
EXTSYM chatRTL2,chatRTL3,chatRTL4,chatRTL5
EXTSYM NetLoadState
EXTSYM ProcessMovies
EXTSYM C4VBlank
EXTSYM dsp1teststuff
EXTSYM ReturnFromSPCStall,SPCStallSetting,cycpb268,cycpb358,HIRQSkip,scanlines
EXTSYM smallscreenon,ScreenScale
EXTSYM MainLoop,NumberOfOpcodes,SfxCLSR,SfxSCMR,SfxPOR
EXTSYM sfx128lineloc,sfx160lineloc,sfx192lineloc,sfxobjlineloc,sfxclineloc
EXTSYM PLOTJmpa,PLOTJmpb,FxTable,FxTableb,FxTablec,FxTabled
EXTSYM SfxPBR,SCBRrel,SfxSCBR,SfxCOLR,hdmaearlstart,SFXCounter
EXTSYM fxbit01,fxbit01pcal,fxbit23,fxbit23pcal,fxbit45,fxbit45pcal,fxbit67,fxbit67pcal
EXTSYM SfxSFR
EXTSYM cpucycle,debstop,switchtovirqdeb,debstop3,switchtonmideb
EXTSYM ReadSPC7110log,WriteSPC7110log
NEWSYM ExecuteAsmStart
%macro BackupCVMacM 2
mov edx,%1
mov ecx,%2
%%loop
movq mm0,[edx]
movq mm1,[edx+8]
movq [ebx],mm0
movq [ebx+8],mm1
add edx,16
add ebx,16
loop %%loop
%endmacro
%macro BackupCVMac 2
mov edx,%1
mov ecx,%2
%%loop
mov eax,[edx]
mov [ebx],eax
add edx,4
add ebx,4
loop %%loop
%endmacro
%macro BackupCVMacB 2
mov edx,%1
mov ecx,%2
%%loop
mov al,[edx]
mov [ebx],al
inc edx
inc ebx
loop %%loop
%endmacro
%macro BackupCVRMacM 2
mov edx,%1
mov ecx,%2
%%loop
movq mm0,[ebx]
movq mm1,[ebx+8]
movq [edx],mm0
movq [edx+8],mm1
add edx,16
add ebx,16
loop %%loop
%endmacro
%macro BackupCVRMac 2
mov edx,%1
mov ecx,%2
%%loop
mov eax,[ebx]
mov [edx],eax
add edx,4
add ebx,4
loop %%loop
%endmacro
%macro BackupCVRMacB 2
mov edx,%1
mov ecx,%2
%%loop
mov al,[ebx]
mov [edx],al
inc edx
inc ebx
loop %%loop
%endmacro
NEWSYM CBackupPos, dd 0
NEWSYM StateBackup, dd 0
NEWSYM PBackupPos, dd 0
NEWSYM PPValue, dd 0 ; Previous PValue
NEWSYM DPValue, dd 0 ; Destination PValue
NEWSYM CurRecv, dd 0 ; Set to 1 if Recovery mode is on
; if CurRecv=1, then do not send tcp/ip data, always frame skip, do not
; draw to screen, do not key on, restore previous local key presses,
; when disabling key ons, divert dspmem write/read to a different
; array temporarly, then re-copy back in when finished
NEWSYM PPContrl, times 16 dd 0 ; Previous Controller 1 Data
NEWSYM PPContrl2, times 16 dd 0 ; Previous Controller 2 Data
NEWSYM PPContrl3, times 16 dd 0 ; Previous Controller 3 Data
NEWSYM PPContrl4, times 16 dd 0 ; Previous Controller 4 Data
NEWSYM PPContrl5, times 16 dd 0 ; Previous Controller 5 Data
NEWSYM tempedx, dd 0
NEWSYM NetSent2, dd 0
NEWSYM NetQuitter, dd 0
NEWSYM QBackupPos, dd 0
NEWSYM LatencyV, times 256 db 0
NEWSYM LatencyRecvPtr, dd 0
NEWSYM LatencySendPtr, dd 0
NEWSYM latencytimer, dd 0
NEWSYM BackState, db 1
NEWSYM BackStateSize, dd 6
NEWSYM nojoystickpoll, dd 0
NEWSYM RemoteLValue, db 0
NEWSYM LocalLValue, db 0
NEWSYM chatstrLt, times 15 db 0
NEWSYM RewindOldPos, dd 0
NEWSYM RewindPos, dd 0
NEWSYM RewindTimer, dd 0
NEWSYM ResendTimer, dd 60
NEWSYM valuea, dd 0
NEWSYM valueb, dd 0
NEWSYM valuet, dd 0
BackupArray times 2000 dd 0
NEWSYM SplitStringChat
push ebx
push eax
push ecx
mov eax,chatstrR
call StringLength
cmp ecx,42
jbe near .noneed
mov eax,42
.next2
cmp byte[chatstrR+eax],' '
je near .space
cmp eax,33
jb .dontclipearly
dec eax
jmp .next2
.space
inc eax
jmp .processclip
.dontclipearly
mov eax,42
.processclip
push eax
mov ebx,[chatRTL4]
mov [chatRTL5],ebx
mov ebx,[chatRTL3]
mov [chatRTL4],ebx
mov ebx,[chatRTL2]
mov [chatRTL3],ebx
mov ebx,[chatRTL]
mov [chatRTL2],ebx
xor ecx,ecx
.chatcpyloop
mov al,[chatstrR4+ecx]
mov [chatstrR5+ecx],al
mov al,[chatstrR3+ecx]
mov [chatstrR4+ecx],al
mov al,[chatstrR2+ecx]
mov [chatstrR3+ecx],al
mov al,[chatstrR+ecx]
mov [chatstrR2+ecx],al
inc ecx
cmp ecx,100
jnz .chatcpyloop
pop eax
push eax
xor ecx,ecx
mov byte[chatstrR],' '
inc ecx
.next
mov bl,[chatstrR2+eax]
mov [chatstrR+ecx],bl
inc eax
inc ecx
or bl,bl
jnz .next
pop eax
mov byte[chatstrR2+eax],0
.noneed
pop ecx
pop eax
pop ebx
ret
NEWSYM MoveStringChat
mov ebx,[chatRTL4]
mov [chatRTL5],ebx
mov ebx,[chatRTL3]
mov [chatRTL4],ebx
mov ebx,[chatRTL2]
mov [chatRTL3],ebx
mov ebx,[chatRTL]
mov [chatRTL2],ebx
push eax
push ecx
xor ecx,ecx
.chatcpyloop
mov al,[chatstrR4+ecx]
mov [chatstrR5+ecx],al
mov al,[chatstrR3+ecx]
mov [chatstrR4+ecx],al
mov al,[chatstrR2+ecx]
mov [chatstrR3+ecx],al
mov al,[chatstrR+ecx]
mov [chatstrR2+ecx],al
inc ecx
cmp ecx,100
jnz .chatcpyloop
pop ecx
pop eax
ret
NEWSYM GenLatencyDisplay
call Get_Time
mov [.temp],eax
mov ebx,16
xor eax,eax
xor edx,edx
mov al,[valuea]
mov al,[.temp]
div ebx
add al,48
add dl,48
mov byte[chatstrLt+2],32
cmp al,9
jbe .bel9
; sub al,10
.bel9
mov [chatstrLt+1],dl
mov [chatstrLt],al
mov ebx,16
xor eax,eax
xor edx,edx
mov al,[.temp+1]
div ebx
add al,48
add dl,48
cmp al,9
jbe .bel9b
; sub al,10
.bel9b
mov [chatstrLt+4],dl
mov [chatstrLt+3],al
ret
.temp dd 0
NEWSYM ResetExecStuff
mov dword[soundcycleft],0
mov dword[curexecstate],0
mov dword[nmiprevaddrl],0
mov dword[nmiprevaddrh],0
mov dword[nmirept],0
mov dword[nmiprevline],224
mov dword[nmistatus],0
mov byte[NextLineCache],0
mov byte[spcnumread],0
mov dword[timer2upd],0
mov dword[HIRQCycNext],0
mov byte[HIRQNextExe],0
ret
NEWSYM ProcessRewind
cmp byte[CNetType],20
jb .okay
.notokayb
ret
.okay
mov eax,dword[KeyRewind]
cmp byte[pressed+eax],1
jne .notokayb
mov byte[pressed+eax],2
mov eax,[RewindOldPos]
cmp [RewindPos],eax
je .notokay
dec dword[RewindPos]
and dword[RewindPos],0Fh
mov eax,[RewindOldPos]
cmp [RewindPos],eax
je .notokay2
dec dword[RewindPos]
and dword[RewindPos],0Fh
mov eax,[RewindPos]
mov [PBackupPos],eax
push ecx
push ebx
call RestoreCVFrame
; Clear Cache Check
mov ebx,vidmemch2
mov ecx,4096+4096+4096
.next
mov byte[ebx],1
inc ebx
dec ecx
jnz .next
pop ebx
pop ecx
inc dword[RewindPos]
and dword[RewindPos],0Fh
mov edx,[tempedx]
mov dword[RewindTimer],60*3
.notokay
ret
.notokay2
inc dword[RewindPos]
and dword[RewindPos],0Fh
ret
NEWSYM UpdateRewind
cmp byte[OSPort],3
je .yeswin32
ret
.yeswin32
push eax
cmp dword[KeyRewind],0
je .notftimer
call ProcessRewind
dec dword[RewindTimer]
jnz .notftimer
cmp byte[CNetType],20
jb .okay
.notftimer
pop eax
ret
.okay
mov eax,[RewindPos]
mov [CBackupPos],eax
mov [tempedx],edx
push ecx
push ebx
call BackupCVFrame
pop ebx
pop ecx
inc dword[RewindPos]
and dword[RewindPos],0Fh
mov eax,[RewindOldPos]
cmp [RewindPos],eax
jne .noteq
inc dword[RewindOldPos]
and dword[RewindOldPos],0Fh
.noteq
mov dword[RewindTimer],60*3
pop eax
ret
NEWSYM BackupSystemVars
pushad
mov ebx,BackupArray
BackupCVMacB zsmesg,[PHnum2writecpureg]
BackupCVMac cycpbl,2
BackupCVMacB sndrot,3019
BackupCVMacB soundcycleft,33
BackupCVMac spc700read,10
BackupCVMac timer2upd,1
BackupCVMac xa,14
BackupCVMacB spcnumread,1
BackupCVMac opcd,6
BackupCVMacB HIRQCycNext,5
BackupCVMac oamaddr,14
BackupCVMacB prevoamptr,1
BackupCVMac ReadHead,1
popad
ret
NEWSYM RestoreSystemVars
pushad
mov dword[RewindPos],0
mov dword[RewindOldPos],0
mov dword[RewindTimer],60*4
mov ebx,BackupArray
BackupCVRMacB zsmesg,[PHnum2writecpureg]
BackupCVRMac cycpbl,2
BackupCVRMacB sndrot,3019
BackupCVRMacB soundcycleft,33
BackupCVRMac spc700read,10
BackupCVRMac timer2upd,1
BackupCVRMac xa,14
BackupCVRMacB spcnumread,1
BackupCVRMac opcd,6
BackupCVRMacB HIRQCycNext,5
BackupCVRMac oamaddr,14
BackupCVRMacB prevoamptr,1
BackupCVRMac ReadHead,1
popad
ret
NEWSYM BackupCVFrame
;NEWSYM StateBackup, dd 0
;NEWSYM CBackupPos, dd 0
;NEWSYM PBackupPos, dd 0
push edx
push eax
mov ebx,[CBackupPos]
shl ebx,19
add ebx,[StateBackup]
add ebx,1024
BackupCVMacB zsmesg,[PHnum2writecpureg]
BackupCVMac cycpbl,2
BackupCVMacB sndrot,3019
BackupCVMacM [wramdata],8192
BackupCVMacM [vram],4096
cmp byte[spcon],0
je .nospcon
BackupCVMacB spcRam,[PHspcsave]
BackupCVMacM DSPMem,16
.nospcon
cmp byte[C4Enable],1
jne .noc4
BackupCVMac [C4Ram],800h
.noc4
cmp byte[SFXEnable],1
jne .nosfx
BackupCVMacM [sfxramdata],8192
.nosfx
cmp byte[SA1Enable],1
jne near .nossa1
BackupCVMacB SA1Mode,[PHnum2writesa1reg]
BackupCVMacM [SA1RAMArea],8192
BackupCVMacB SA1Status,3
BackupCVMac prevedi,1
BackupCVMac SA1xpc,1
BackupCVMac SA1RAMArea,6
BackupCVMac sa1dmaptr,2
.nossa1
cmp byte[DSP1Type],0
je near .nodsp1type
BackupCVMacB DSP1COp,70+128
BackupCVMacB C4WFXVal,7*4+7*8+128
BackupCVMacB C41FXVal,5*4+128
BackupCVMacB Op00Multiplicand,3*4+128
BackupCVMacB Op10Coefficient,4*4+128
BackupCVMacB Op04Angle,4*4+128
BackupCVMacB Op08X,5*4+128
BackupCVMacB Op18X,5*4+128
BackupCVMacB Op28X,4*4+128
BackupCVMacB Op0CA,5*4+128
BackupCVMacB Op1CAZ,15*4+128
BackupCVMacB Op02FX,11*4+3*4+28*8+128
BackupCVMacB Op0AVS,5*4+14*8+128
BackupCVMacB Op06X,6*4+10*8+4+128
BackupCVMacB Op01m,4*4+128
BackupCVMacB Op0DX,6*4+128
BackupCVMacB Op03F,6*4+128
BackupCVMacB Op14Zr,9*4+128
BackupCVMacB Op0EH,4*4+128
.nodsp1type
BackupCVMacB soundcycleft,33
BackupCVMac spc700read,10
BackupCVMac timer2upd,1
BackupCVMac xa,14
BackupCVMacB spcnumread,1
BackupCVMac opcd,6
BackupCVMacB HIRQCycNext,5
BackupCVMac oamaddr,14
BackupCVMacB prevoamptr,1
BackupCVMac ReadHead,1
mov edx,[sram]
mov ecx,[ramsize]
shr ecx,4
or ecx,ecx
jz .end
.loop
movq mm0,[edx]
movq mm1,[edx+8]
movq [ebx],mm0
movq [ebx+8],mm1
add edx,16
add ebx,16
loop .loop
.end
pop eax
pop edx
mov [ebx],esi
mov [ebx+4],edi
mov ecx,[tempedx]
mov [ebx+8],ecx
mov [ebx+12],ebp
emms
ret
NEWSYM RestoreCVFrame
push edx
push eax
mov ebx,[PBackupPos]
shl ebx,19
add ebx,[StateBackup]
add ebx,1024
BackupCVRMacB zsmesg,[PHnum2writecpureg]
BackupCVRMac cycpbl,2
BackupCVRMacB sndrot,3019
BackupCVRMacM [wramdata],8192
BackupCVRMacM [vram],4096
cmp byte[spcon],0
je .nospcon
BackupCVRMacB spcRam,[PHspcsave]
BackupCVRMacM DSPMem,16
.nospcon
cmp byte[C4Enable],1
jne .noc4
BackupCVRMac [C4Ram],800h
.noc4
cmp byte[SFXEnable],1
jne .nosfx
BackupCVRMacM [sfxramdata],8192
.nosfx
cmp byte[SA1Enable],1
jne near .nossa1
BackupCVRMacB SA1Mode,[PHnum2writesa1reg]
BackupCVRMacM [SA1RAMArea],8192
BackupCVRMacB SA1Status,3
BackupCVRMac prevedi,1
BackupCVRMac SA1xpc,1
BackupCVRMac SA1RAMArea,6
BackupCVRMac sa1dmaptr,2
.nossa1
cmp byte[DSP1Type],0
je near .nodsp1type
BackupCVRMacB DSP1COp,70+128
BackupCVRMacB C4WFXVal,7*4+7*8+128
BackupCVRMacB C41FXVal,5*4+128
BackupCVRMacB Op00Multiplicand,3*4+128
BackupCVRMacB Op10Coefficient,4*4+128
BackupCVRMacB Op04Angle,4*4+128
BackupCVRMacB Op08X,5*4+128
BackupCVRMacB Op18X,5*4+128
BackupCVRMacB Op28X,4*4+128
BackupCVRMacB Op0CA,5*4+128
BackupCVRMacB Op1CAZ,15*4+128
BackupCVRMacB Op02FX,11*4+3*4+28*8+128
BackupCVRMacB Op0AVS,5*4+14*8+128
BackupCVRMacB Op06X,6*4+10*8+4+128
BackupCVRMacB Op01m,4*4+128
BackupCVRMacB Op0DX,6*4+128
BackupCVRMacB Op03F,6*4+128
BackupCVRMacB Op14Zr,9*4+128
BackupCVRMacB Op0EH,4*4+128
.nodsp1type
BackupCVRMacB soundcycleft,33
BackupCVRMac spc700read,10
BackupCVRMac timer2upd,1
BackupCVRMac xa,14
BackupCVRMacB spcnumread,1
BackupCVRMac opcd,6
BackupCVRMacB HIRQCycNext,5
BackupCVRMac oamaddr,14
BackupCVRMacB prevoamptr,1
BackupCVRMac ReadHead,1
mov edx,[sram]
mov ecx,[ramsize]
shr ecx,4
or ecx,ecx
jz .end
.loop
movq mm0,[ebx]
movq mm1,[ebx+8]
movq [edx],mm0
movq [edx+8],mm1
add edx,16
add ebx,16
loop .loop
.end
pop eax
pop edx
mov esi,[ebx]
mov edi,[ebx+4]
mov ecx,[ebx+8]
mov [tempedx],ecx
mov ebp,[ebx+12]
call UpdateDPage
call SA1UpdateDPage
emms
ret
NEWSYM MuteVoiceF, db 0
VoiceEndMute:
mov byte[MuteVoiceF],0
ret
%macro StartMute 1
mov al,[Voice0Status+%1]
or al,al
jz %%notmuted
or byte[MuteVoiceF],1 << %1
%%notmuted
%endmacro
VoiceStartMute:
mov byte[MuteVoiceF],0
push eax
StartMute 0
StartMute 1
StartMute 2
StartMute 3
StartMute 4
StartMute 5
StartMute 6
StartMute 7
pop eax
ret
NetSaveState:
call joinflags
; de-init variables (copy to variables)
mov [spcPCRam],ebp
mov [Curtableaddr],edi
mov [xp],dl
mov [curcyc],dh
mov eax,[initaddrl]
sub esi,eax ; subtract program counter by address
mov [xpc],si
call ResetTripleBuf
mov eax,[KeySaveState]
cmp byte[CNetType],20
je .skipsoundreinit
test byte[pressed+eax],1
jnz .soundreinit
mov eax,[KeyLoadState]
test byte[pressed+eax],1
jz .skipsoundreinit
.soundreinit
mov byte[NoSoundReinit],1
mov byte[csounddisable],1
.skipsoundreinit
call statesaver
; initialize variables (Copy from variables)
call UpdateDPage
call SA1UpdateDPage
call Makemode7Table
call ReadSPC7110log
cmp byte[SFXEnable],0
je .nosfxud
call UpdateSFX
.nosfxud
xor eax,eax
xor ebx,ebx
xor ecx,ecx
xor edx,edx
mov bl,[xpb]
mov ax,[xpc]
test ax,8000h
jz .loweraddr
mov esi,[snesmmap+ebx*4]
jmp .skiplower
.loweraddr
cmp ax,4300h
jb .lower
cmp dword[memtabler8+ebx*4],regaccessbankr8
je .dma
.lower
mov esi,[snesmap2+ebx*4]
jmp .skiplower
.dma
mov esi,dmadata-4300h
.skiplower
mov [initaddrl],esi
add esi,eax ; add program counter to address
mov dl,[xp] ; set flags
mov dh,[curcyc] ; set cycles
mov bl,dl
; cmp byte[CNetType],20
; je .skipmovie
; cmp byte[CNetType],21
; je .skipmovie
; jmp .skipmovie
; cmp byte[MovieProcessing],0
; jne .movie
;.skipmovie
cmp byte[spcon],0
je .nosoundta
mov edi,[tableadc+ebx*4]
or byte[curexecstate],2
jmp .soundta
.nosoundta
mov edi,[tableadb+ebx*4]
and byte[curexecstate],0FDh
.soundta
jmp .nomovie
.movie
mov edi,[tableadc+ebx*4]
test byte[curexecstate],2
jnz .nomovie
mov edi,[tableadb+ebx*4]
.nomovie
mov ebp,[spcPCRam]
mov byte[NoSoundReinit],0
mov byte[csounddisable],0
mov byte[NextNGDisplay],0
call splitflags
ret
%macro stim 0
cmp byte[OSPort],1
ja %%nosti
sti
%%nosti
%endmacro
%macro clim 0
cmp byte[OSPort],1
ja %%nocli
cli
%%nocli
%endmacro
%macro ProcessIRQStuffB 0
; check for VIRQ/HIRQ/NMI
test dl,04h
jnz %%noirq
test byte[INTEnab],20h
jz %%novirq
mov ax,[VIRQLoc]
cmp word[curypos],ax
je near .virq
jmp %%noirq
%%novirq
test byte[INTEnab],10h
jnz near .virq
%%noirq
test byte[INTEnab],20h
jz %%novirq2b
mov ax,[VIRQLoc]
cmp word[curypos],ax
jne %%novirq2b
cmp byte[intrset],1
jne %%nointrset2b
mov byte[intrset],2
%%nointrset2b
%%novirq2b
%endmacro
%macro ProcessIRQStuffC 0
; check for VIRQ/HIRQ
cmp byte[virqnodisable],1
je %%virqdo
test dl,04h
jnz %%virqdo
cmp byte[doirqnext],1
je near .virq
%%virqdo
test byte[INTEnab],20h
jz near %%novirq
mov ax,[VIRQLoc]
add ax,[IRQHack]
cmp ax,[resolutn]
jne %%notres
dec ax
; inc ax
%%notres
cmp ax,0FFFFh
jne %%notzero
xor ax,ax
%%notzero
cmp word[curypos],ax
jne near %%noirq
%%startirq
cmp byte[intrset],1
jne %%nointrseta
mov byte[intrset],2
%%nointrseta
mov byte[irqon],80h
test dl,04h
jnz %%irqd
test byte[INTEnab],10h
jnz %%tryhirq
jmp .virq
%%novirq
test byte[INTEnab],10h
jz %%noirq
%%tryhirq
jmp .virq
jmp %%startirq
%%irqd
mov byte[doirqnext],1
%%noirq
%endmacro
%macro ProcessIRQStuff 0
; check for VIRQ/HIRQ
cmp byte[virqnodisable],1
je %%virqdo
test dl,04h
jnz %%virqdo
cmp byte[doirqnext],1
je near .virq
%%virqdo
test byte[INTEnab],20h
jz near %%novirq
mov ax,[VIRQLoc]
add ax,[IRQHack]
cmp ax,[resolutn]
jne %%notres
dec ax
; inc ax
%%notres
cmp ax,0FFFFh
jne %%notzero
xor ax,ax
%%notzero
cmp word[curypos],ax
jne near %%noirq
test byte[INTEnab],10h
jnz %%tryhirq
%%startirq
cmp byte[intrset],1
jne %%nointrseta
mov byte[intrset],2
%%nointrseta
mov byte[irqon],80h
test dl,04h
jnz %%irqd
jmp .virq
%%novirq
test byte[INTEnab],10h
jz %%noirq
cmp byte[intrset],2
jbe %%nointrseta3
dec byte[intrset]
cmp byte[intrset],2
ja %%noirq
%%nointrseta3
cmp byte[intrset],1
jne %%nointrseta2
mov byte[intrset],8
jmp %%noirq
%%nointrseta2
test dl,04h
jnz %%noirq
%%tryhirq
jmp %%startirq
%%irqd
mov byte[doirqnext],1
%%noirq
%endmacro
; .returnfromsfx
; pexecs
; *** Copy to PC whenever a non-relative jump is executed
NEWSYM romloadskip, db 0
NEWSYM abcdefg, dd 0
NEWSYM abcdefg1, dd 0
NEWSYM abcdefg2, dd 0
NEWSYM abcdefg3, dd 0
NEWSYM SSKeyPressed, dd 0
NEWSYM NoSoundReinit, dd 0
NEWSYM NextNGDisplay, db 0
NEWSYM TempVidInfo, dd 0
NEWSYM tempdh, db 0
NEWSYM start65816
call initvideo
cmp byte[videotroub],1
jne .notrouble
ret
.notrouble
; cmp byte[OSPort],2
; jae .nonewgfxcheck
jmp .nonewgfxcheck
cmp byte[cbitmode],1
jne .nonewgfxcheck
cmp byte[newengen],1
jne .nonewgfxcheck
cmp byte[cvidmode],3
jne .nocorrectmode
cmp byte[newgfx16b],1
je .nonewgfxcheck
jmp .correctmode
.nocorrectmode
mov dword[Msgptr],newgfxerror2
jmp .correctmode
mov dword[Msgptr],newgfxerror
.correctmode
mov eax,[MsgCount]
mov [MessageOn],eax
mov byte[newengen],0
.nonewgfxcheck
mov edi,[vidbufferofsa]
mov ecx,37518
xor eax,eax
rep stosd
; mov edi,[vidbufferofsb]
; mov ecx,37518
; xor eax,eax
; rep stosd
cmp byte[romloadskip],1
je near StartGUI
NEWSYM continueprog
mov byte[romloadskip],0
mov byte[debuggeron],0
mov byte[exiter],0
; clear keyboard presses
mov esi,pressed
mov ecx,256+128+64
mov al,0
.loopa
mov [esi],al
inc esi
loop .loopa
call InitPreGame
; Incorrect
NEWSYM reexecute
; clear keyboard presses
mov esi,pressed
mov ecx,256+128+64
mov al,0
.loopa
cmp byte[esi],2
jne .notclear
mov [esi],al
.notclear
inc esi
loop .loopa
jmp reexecuteb2
NEWSYM reexecuteb
cmp byte[OSPort],1
ja reexecuteb2
mov esi,pressed
mov ecx,256+128+64
mov al,0
.loopa
cmp byte[esi],2
jne .notclear
mov [esi],al
.notclear
inc esi
loop .loopa
reexecuteb2:
; temporary sprite displayer
; mov edx,.sdispname
; call Open_File
; jc .failedsd
; mov bx,ax
; mov ecx,544
; mov edx,oamram
; call Read_File
; call Close_File
;.failedsd
; jmp .skipsd
;.sdispname db 'MMX3.SPR',0
;.skipsd
cmp byte[NoSoundReinit],1
je .skippregame
call SetupPreGame
.skippregame
; initialize variables (Copy from variables)
call UpdateDPage
call SA1UpdateDPage
call Makemode7Table
cmp byte[SFXEnable],0
je .nosfxud
call UpdateSFX
.nosfxud
xor eax,eax
xor ebx,ebx
xor ecx,ecx
xor edx,edx
mov bl,[xpb]
mov ax,[xpc]
test ax,8000h
jz .loweraddr
mov esi,[snesmmap+ebx*4]
jmp .skiplower
.loweraddr
cmp ax,4300h
jb .lower
cmp dword[memtabler8+ebx*4],regaccessbankr8
je .dma
.lower
mov esi,[snesmap2+ebx*4]
jmp .skiplower
.dma
mov esi,dmadata-4300h
.skiplower
mov [initaddrl],esi
add esi,eax ; add program counter to address
mov dl,[xp] ; set flags
mov dh,[curcyc] ; set cycles
mov bl,dl
; cmp byte[CNetType],20
; je .skipmovie
; cmp byte[CNetType],21
; je .skipmovie
; jmp .skipmovie
; cmp byte[MovieProcessing],0
; jne .movie
;.skipmovie
cmp byte[spcon],0
je .nosoundta
mov edi,[tableadc+ebx*4]
or byte[curexecstate],2
jmp .soundta
.nosoundta
mov edi,[tableadb+ebx*4]
and byte[curexecstate],0FDh
.soundta
jmp .nomovie
.movie
mov edi,[tableadc+ebx*4]
test byte[curexecstate],2
jnz .nomovie
mov edi,[tableadb+ebx*4]
.nomovie
mov ebp,[spcPCRam]
mov byte[NoSoundReinit],0
mov byte[csounddisable],0
mov byte[NextNGDisplay],0
call splitflags
; cmp byte[MovieProcessing],0
; jne .movie2
call execute
jmp .nomovie2
.movie2
call cpuover.returntoloop
.nomovie2
call joinflags
; de-init variables (copy to variables)
mov [spcPCRam],ebp
mov [Curtableaddr],edi
mov [xp],dl
mov [curcyc],dh
mov eax,[initaddrl]
sub esi,eax ; subtract program counter by address
mov [xpc],si
call ResetTripleBuf
mov eax,[KeySaveState]
cmp byte[CNetType],20
je .skipsoundreinit
test byte[pressed+eax],1
jnz .soundreinit
mov eax,[KeyLoadState]
test byte[pressed+eax],1
jz .skipsoundreinit
.soundreinit
mov byte[NoSoundReinit],1
mov byte[csounddisable],1
.skipsoundreinit
cmp byte[NoSoundReinit],1
je .skippostgame
call DeInitPostGame
.skippostgame
call WriteSPC7110log
; clear all keys
call Check_Key
cmp al,0
je .nokeys
.yeskeys
call Get_Key
call Check_Key
cmp al,0
jne .yeskeys
.nokeys
; mov edi,memtabler8+40h*4
; mov ecx,30h
; mov eax,memaccessbankr848mb
; rep stosd
; mov edi,memtabler16+40h*4
; mov ecx,30h
; mov eax,memaccessbankr1648mb
; rep stosd
cmp byte[nextmenupopup],1
je near showmenu
cmp byte[ReturnFromSPCStall],1
je near .activatereset
mov eax,[KeySaveState]
cmp byte[CNetType],20
je .net
test byte[pressed+eax],1
jnz near savestate
mov eax,[KeyLoadState]
test byte[pressed+eax],1
jnz near loadstate
cmp byte[SSKeyPressed],1
je near showmenu
cmp byte[debugdisble],0
jne .nodebugger
test byte[pressed+59],1
jne near startdebugger
.nodebugger
test byte[pressed+59],1
jne near showmenu
mov eax,[KeyQuickRst]
.net
test byte[pressed+eax],1
jz .noreset
.activatereset
pushad
call GUIDoReset
popad
mov byte[ReturnFromSPCStall],0
jmp continueprog
.noreset
cmp byte[guioff],1
je near endprog
mov eax,[KeyQuickExit]
test byte[pressed+eax],1
jnz near endprog
jmp StartGUI
NEWSYM EndMessage
db ' ',13,10,0
NEWSYM endprog
call deinitvideo
cmp byte[previdmode],3
jne .noendmessage
mov byte[EndMessage+13],','
mov eax,[welcome+9]
mov [EndMessage+9],eax
mov ax,[welcome+7]
mov [EndMessage+7],ax
mov edx,EndMessage
call PrintStr
.noendmessage
; mov eax,[opcd]
; mov eax,[numinst] ;Temporary
; mov eax,[NumBRRconv]
; call printnum
; save sram
; change to sram dir
mov dl,[SRAMDrive]
mov ebx,SRAMDir
call Change_Dir
cmp byte[sramsavedis],1
je .nosram
cmp dword[ramsize],0
je .nosram
xor eax,eax
xor ebx,ebx
xor ecx,ecx
xor edx,edx
xor esi,esi
xor edi,edi
mov edx,fnames+1
call Create_File
jc .nosram
mov bx,ax
xor ecx,ecx
mov ecx,[ramsize]
mov edx,[sram]
call Write_File
call Close_File
.nosram
cmp byte[SFXSRAM],0
je .nosfxsram
mov edx,fnames+1
call Create_File
jc .nosfxsram
mov bx,ax
mov ecx,65536
mov edx,[sfxramdata]
call Write_File
call Close_File
.nosfxsram
cmp byte[SA1Enable],1
jne .nosa1
mov edx,fnames+1
call Create_File
jc .nosa1
mov bx,ax
mov ecx,65536*2
mov edx,[SA1RAMArea]
call Write_File
call Close_File
.nosa1
; change dir to InitDrive/InitDir
mov dl,[InitDrive]
mov ebx,InitDir
call Change_Dir
call createnewcfg
call GUISaveVars
cmp byte[MovieProcessing],0
je .nomovieclose
mov bx,[MovieFileHand]
mov byte[MovieProcessing],0
call Close_File
.nomovieclose
;NEWSYM tempstore, times 1024*1024 db 0
; mov esi,tempstore
; mov ecx,1024*1024
;.loop
; mov al,[esi]
; cmp al,0
; jne .faulty
; inc esi
; dec ecx
; jnz .loop
; xor eax,eax
; jmp .notfaulty
;.faulty
; mov eax,1
;.notfaulty
; mov eax,[vidbufferofsa]
; call printnum
; mov dl,32
; mov ah,02h
; call Output_Text
; mov eax,[vidbufferofsb]
; call printnum
; mov dl,32
; mov ah,02h
; call Output_Text
; mov eax,[romdata]
; call printnum
; change dir to InitDrive/InitDir
mov dl,[InitDrive]
mov ebx,InitDir
call Change_Dir
; Deinit modem if necessary
cmp byte[ModemInitStat],0
je .nodeinitmodem
call DeInitModem
.nodeinitmodem
cmp byte[OSPort],1
jae .nodeinitipx
call deinitipx
.nodeinitipx
jmp OSExit
NEWSYM interror
stim
call deinitvideo
mov edx,.nohand ;use extended
mov ah,9 ;DOS- API
call Output_Text ;to print a string
jmp DosExit
.nohand db 'Cannot process interrupt handler!',13,10,0
; global variables
NEWSYM invalid, db 0
NEWSYM invopcd, db 0
NEWSYM pressed, times 256+128+64 db 0 ; keyboard pressed keys in scancode
NEWSYM exiter, db 0
NEWSYM oldhand9o, dd 0
NEWSYM oldhand9s, dw 0
NEWSYM oldhand8o, dd 0
NEWSYM oldhand8s, dw 0
NEWSYM opcd, dd 0
NEWSYM pdh, dd 0
NEWSYM pcury, dd 0
NEWSYM timercount, dd 0
NEWSYM initaddrl, dd 0 ; initial address location
NEWSYM NetSent, dd 0
NEWSYM nextframe, dd 0 ; tick count for timer
NEWSYM curfps, db 0 ; frame/sec for current screen
NEWSYM SFXSRAM, db 0
NEWSYM newgfxerror, db 'NEED MEMORY FOR GFX ENGINE',0
NEWSYM newgfxerror2, db 'NEED 320x240 FOR NEW GFX 16B',0
;newgfxerror db 'NEW GFX IN 16BIT IS N/A',0
NEWSYM HIRQCycNext, dd 0
NEWSYM HIRQNextExe, db 0
;*******************************************************
; Save/Load States
;*******************************************************
NEWSYM sramsave
mov byte[pressed+1],0
mov byte[pressed+41],0
; save sram
cmp byte[sramsavedis],1
je .nosram
cmp word[ramsize],0
je .nosram
mov edx,fnames+1
call Create_File
jc .nosram
mov bx,ax
xor ecx,ecx
mov cx,[ramsize]
mov edx,[sram]
call Write_File
call Close_File
mov dword[Msgptr],.savesrmmsg1
mov eax,[MsgCount]
mov [MessageOn],eax
jmp reexecute
.nosram
mov dword[Msgptr],.savesrmmsg2
mov eax,[MsgCount]
mov [MessageOn],eax
jmp reexecute
.savesrmmsg1 db 'SRAM DATA SAVED.',0
.savesrmmsg2 db 'NO SRAM DATA.',0
NEWSYM statesaver
clim
sub dword[Curtableaddr],tableA
sub dword[spcPCRam],spcRam
sub dword[spcRamDP],spcRam
call PrepareSaveState
call unpackfunct
call initrevst
; jmp .skipsaves
; Save State
mov edx,fnamest+1
call Create_File
jc near .nosavestuff
; Save 65816 status, etc.
mov bx,ax
mov ecx,[PHnum2writecpureg]
mov edx,zsmesg
call Write_File
mov ecx,8
mov edx,cycpbl
call Write_File
; Save SNES PPU Register status
mov ecx,3019
mov edx,sndrot
call Write_File
; Save RAM (WRAM(128k),VRAM(64k),SRAM)
; xor ecx,ecx
; mov cx,[ramsize]
mov ecx,65536+65536
mov edx,[wramdata]
call Write_File
mov ecx,65536
mov edx,[vram]
call Write_File
cmp byte[spcon],0
je .nospcon
; Save SPC stuff
mov ecx,[PHspcsave]
mov edx,spcRam
call Write_File
; Save DSP stuff
mov ecx,[PHdspsave]
mov edx,BRRBuffer
call Write_File
; Save DSP Mem
mov ecx,256
mov edx,DSPMem
call Write_File
.nospcon
cmp byte[C4Enable],1
jne .noc4
mov ecx,2000h
mov edx,[C4Ram]
call Write_File
.noc4
cmp byte[SFXEnable],1
jne .nosfx
mov ecx,[SfxCROM]
sub [SfxRomBuffer],ecx
mov ecx,[SfxRAMMem]
sub [SfxLastRamAdr],ecx
mov ecx,65536*2
mov edx,[sfxramdata]
call Write_File
; uncomment the following
mov ecx,[PHnum2writesfxreg]
mov edx,SfxR0
call Write_File
mov ecx,[SfxCROM]
add [SfxRomBuffer],ecx
mov ecx,[SfxRAMMem]
add [SfxLastRamAdr],ecx
.nosfx
cmp byte[SPC7110Enable],1
jne .nospc7110
mov edx,[romdata]
add edx,510000h
mov ecx,65536
call Write_File
mov edx,SPCMultA
mov ecx,[PHnum2writespc7110reg]
call Write_File
.nospc7110
cmp byte[SA1Enable],1
jne .nossa1
; Convert SA-1 stuff to standard, non displacement format
call SaveSA1
mov ecx,[PHnum2writesa1reg]
mov edx,SA1Mode
call Write_File
mov ecx,65536*2
mov edx,[SA1RAMArea]
call Write_File
; Convert back SA-1 stuff
call RestoreSA1
.nossa1
cmp byte[cbitmode],0
je .nocapturepicture
cmp byte[NoPictureSave],1
je .nocapturepicture
call CapturePicture
mov ecx,64*56*2
mov edx,PrevPicture
call Write_File
.nocapturepicture
call Close_File
add dword[Curtableaddr],tableA
add dword[spcPCRam],spcRam
add dword[spcRamDP],spcRam
call ResetState
call initrevst
stim
mov dword[Msgptr],.savemsg
mov eax,[MsgCount]
mov [MessageOn],eax
ret
.nosavestuff
add dword[Curtableaddr],tableA
add dword[spcPCRam],spcRam
add dword[spcRamDP],spcRam
call ResetState
call initrevst
stim
mov dword[Msgptr],.savemsgfail
mov eax,[MsgCount]
mov [MessageOn],eax
ret
.savemsg db 'STATE SAVED.',0
.savemsgfail db 'UNABLE TO SAVE.',0
NEWSYM savestate
jmp .save
mov byte[pressed+1],0
mov byte[pressed+60],0
mov edx,.fname2+1
call Create_File
mov esi,[vidbuffer]
add esi,16*2+256*2+32*2
mov edi,[vidbuffer]
mov dl,[resolutn]
mov bx,ax
; move data to a linear address from esi to edi
.loopa
mov ecx,128
add esi,64+128*4
dec dl
jnz .loopa
push edx
push esi
mov ecx,128*4
mov edx,esi
call Write_File
pop esi
pop edx
add esi,64+128*4
call Close_File
jmp reexecuteb
.save
mov byte[pressed+1],0
mov eax,[KeySaveState]
mov byte[pressed+eax],2
call statesaver
jmp reexecuteb
.fname2 db 9,'image.dat',0
; Load State
NEWSYM stateloader
mov byte[MovieProcessing],0
mov byte[prevoamptr],0FFh
; Load 65816 status, etc.
mov bx,ax
mov ecx,[PHnum2writecpureg]
add dword[Totalbyteloaded],ecx
mov edx,zsmesg
call Read_File
cmp byte[versn],60
jne near .convert
; Load SPC timers
mov ecx,8
add dword[Totalbyteloaded],ecx
mov edx,cycpbl
call Read_File
; Load SNES PPU Register status
mov ecx,3019 ; 3019
add dword[Totalbyteloaded],ecx
mov edx,sndrot
call Read_File
; Load RAM (WRAM(128k),VRAM(64k),SRAM)
mov ecx,65536+65536
add dword[Totalbyteloaded],ecx
mov edx,[wramdata]
call Read_File
mov ecx,65536
add dword[Totalbyteloaded],ecx
mov edx,[vram]
call Read_File
cmp byte[spcon],0
je .nospcon
; Load SPC stuff
mov ecx,[PHspcsave]
add dword[Totalbyteloaded],ecx
mov edx,spcRam
call Read_File
; Load DSP stuff
mov ecx,[PHdspsave]
add dword[Totalbyteloaded],ecx
mov edx,BRRBuffer
call Read_File
; Load DSP Mem
mov ecx,256
add dword[Totalbyteloaded],ecx
mov edx,DSPMem
call Read_File
.nospcon
cmp byte[SFXEnable],1
jne near .nosfx
mov ecx,65536*2
add dword[Totalbyteloaded],ecx
mov edx,[sfxramdata]
call Read_File
mov ecx,[PHnum2writesfxreg]
add dword[Totalbyteloaded],ecx
mov edx,SfxR0
call Read_File
xor ecx,ecx
mov cl,[SfxPBR]
mov ecx,[SfxMemTable+ecx*4]
mov [SfxCPB],ecx
xor ecx,ecx
mov cl,[SfxROMBR]
mov ecx,[SfxMemTable+ecx*4]
mov [SfxCROM],ecx
xor ecx,ecx
mov cl,[SfxRAMBR]
shl ecx,16
add ecx,[sfxramdata]
mov dword [SfxRAMMem],ecx
mov ecx,[SfxCROM]
add [SfxRomBuffer],ecx
mov ecx,[SfxRAMMem]
add [SfxLastRamAdr],ecx
.nosfx
cmp byte[C4Enable],1
jne .noc4
mov ecx,2000h
add dword[Totalbyteloaded],ecx
mov edx,[C4Ram]
call Read_File
.noc4
cmp byte[SPC7110Enable],1
jne .nospc7110
mov edx,[romdata]
add edx,510000h
mov ecx,65536
call Read_File
mov edx,SPCMultA
mov ecx,[PHnum2writespc7110reg]
call Read_File
.nospc7110
cmp byte[SA1Enable],1
jne .nossa1
mov ecx,[PHnum2writesa1reg]
add dword[Totalbyteloaded],ecx
mov edx,SA1Mode
call Read_File
mov ecx,65536*2
add dword[Totalbyteloaded],ecx
mov edx,[SA1RAMArea]
call Read_File
; Convert back SA-1 stuff
push ebx
call RestoreSA1
pop ebx
call SA1UpdateDPage
.nossa1
cmp byte[SDD1Enable],1
jne .nosdd1
call UpdateBanksSDD1
.nosdd1
call Close_File
call repackfunct
mov byte[spcnumread],0
mov byte[nexthdma],0
; call headerhack
call initpitch
call initrevst
ret
.convert
; Load SNES PPU Register status
mov ecx,3019
mov edx,sndrot
call Read_File
; Load RAM (WRAM(128k),VRAM(64k),SRAM)
mov dword[cycpbl],0
mov dword[cycpblt],0
mov ah,[cycpbl2]
mov [cycpbl],ah
mov ah,[cycpblt2]
mov [cycpblt],ah
mov ecx,[ramsize]
add ecx,65536+65536+65536
mov edx,[wramdata]
call Read_File
cmp byte[spcon],0
je .nospconb
; Load SPC stuff
mov ecx,[PHspcsave]
mov edx,spcRam
call Read_File
; Load DSP stuff
mov ecx,32
mov edx,BRRBuffer
call Read_File
; Convert old to new data
; read/write 6, jump 2 for 8 times
mov edx,BRRPlace0
mov ecx,8
.loopconv
push edx
push ecx
mov ecx,4
call Read_File
pop ecx
pop edx
add edx,8
dec ecx
jnz .loopconv
;dspsave equ $-BRRBuffer
;dspconvb equ $-Voice0Freq
; Load DSP stuff
mov ecx,[PHdspsave]
sub ecx,64+32
sub ecx,8
mov edx,Voice0Freq
call Read_File
; Load DSP Mem
mov ecx,256
mov edx,DSPMem
call Read_File
.nospconb
call Close_File
call repackfunct
mov dword[cycpbl],0
mov byte[spcnumread],0
mov byte[nexthdma],0
call headerhack
call initpitch
call initrevst
ret
NEWSYM loadstate
mov byte[pressed+1],0
mov eax,[KeyLoadState]
mov byte[pressed+eax],2
mov byte[multchange],1
clim
mov edx,fnamest+1
call Open_File
jc near .nofile
call stateloader
; Clear Cache Check
mov esi,vidmemch2
mov ecx,4096+4096+4096
.next
mov byte[esi],1
inc esi
dec ecx
jnz .next
cmp byte[versn],60
jne near .convert
mov dword[Msgptr],.loadmsg
jmp .noconvert
.convert
mov dword[Msgptr],.convmsg
mov byte[versn],60
mov byte[versn-2],'6'
.noconvert
mov eax,[MsgCount]
mov [MessageOn],eax
add dword[Curtableaddr],tableA
add dword[spcPCRam],spcRam
add dword[spcRamDP],spcRam
call ResetState
call procexecloop
stim
jmp reexecuteb
.nofile
mov dword[Msgptr],.nfndmsg
mov eax,[MsgCount]
mov [MessageOn],eax
stim
jmp reexecuteb
.loadmsg db 'STATE LOADED.',0
.convmsg db 'STATE LOADED/CONVERTED',0
.nfndmsg db 'UNABLE TO LOAD.',0
NEWSYM loadstate2
mov edx,fnamest+1
NEWSYM loadstate3
call Open_File
jc near .nofile
mov dword[Totalbyteloaded],0
call stateloader
; Clear Cache Check
mov esi,vidmemch2
mov ecx,4096+4096+4096
.next
mov byte[esi],1
inc esi
dec ecx
jnz .next
add dword[Curtableaddr],tableA
add dword[spcPCRam],spcRam
add dword[spcRamDP],spcRam
call ResetState
call procexecloop
ret
.nofile
ret
;*******************************************************
; Int 08h vector
;*******************************************************
; sets to either 60Hz or 50Hz depending on PAL/NTSC
NEWSYM init60hz
cmp byte[romispal],0
jne .dopal
mov al,00110110b
out 43h,al
mov ax,19900 ; 65536/(60/((65536*24+175)/(60*60*24)))
mov dword[timercount],19900
out 40h,al
mov al,ah
out 40H,al
ret
.dopal
mov al,00110110b
out 43h,al
mov ax,23863 ; 65536/(50/((65536*24+175)/(60*60*24)))
mov dword[timercount],23863
out 40h,al
mov al,ah
out 40H,al
ret
NEWSYM init18_2hz
mov al,00110110b
out 43H,al
mov ax,0
mov dword[timercount],65536
out 40H,al
mov al,ah
out 40H,al
ret
NEWSYM Game60hzcall
inc word[t1cc]
inc byte[nextframe]
ret
NEWSYM handler8h
cli
push ds
push eax
; mov ax,0
mov ax,[cs:dssel]
NEWSYM handler8hseg
mov ds,ax
call Game60hzcall
mov eax,[timercount]
sub dword[timeradj],eax
jnc .noupd
add dword[timeradj],65536
pushf
call far [oldhand8o]
.noupd
mov al,20h
out 20h,al
pop eax
pop ds
sti
iretd
NEWSYM timeradj, dd 65536
NEWSYM t1cc, dw 0
;*******************************************************
; Int 09h vector
;*******************************************************
NEWSYM skipnextkey42, db 0
NEWSYM handler9h
cli
push ds
push eax
push ebx
mov ax,[cs:dssel]
mov ds,ax
xor ebx,ebx
in al,60H ; get keyboard scan code
cmp al,42
jne .no42
cmp byte[skipnextkey42],0
je .no42
mov byte[skipnextkey42],0
jmp .skipkeyrel
.no42
cmp al,0E0h
jne .noE0
mov byte[skipnextkey42],1
jmp .skipkeyrel
.noE0
mov byte[skipnextkey42],0
mov bl,al
xor bh,bh
test bl,80h ; check if bit 7 is on (key released)
jnz .keyrel
cmp byte[pressed+ebx],0
jne .skipa
mov byte[pressed+ebx],1 ; if not, set key to pressed
.skipa
jmp .skipkeyrel
.keyrel
and ebx,7Fh
cmp ebx,59
je .skipkeyrel
cmp ebx,[KeySaveState]
je .skipkeyrel
cmp ebx,[KeyLoadState]
je .skipkeyrel
cmp ebx,[KeyQuickExit]
je .skipkeyrel
cmp ebx,[KeyQuickLoad]
je .skipkeyrel
cmp ebx,[KeyQuickRst]
je .skipkeyrel
cmp bl,1
je .skipkeyrel
mov byte[pressed+ebx],0 ; if not, set key to pressed
.skipkeyrel
mov byte[pressed],0
in al,61h
mov ah,al
or al,80h
out 61h,al
mov al,20H ; turn off interrupt mode
out 20H,al
pop ebx ; Pop registers off
pop eax ; stack in correct
pop ds
sti
iretd
ALIGN32
NEWSYM soundcycleft, dd 0
NEWSYM curexecstate, dd 0
NEWSYM nmiprevaddrl, dd 0 ; observed address -5
NEWSYM nmiprevaddrh, dd 0 ; observed address +5
NEWSYM nmirept, dd 0 ; NMI repeat check, if 6 then okay
NEWSYM nmiprevline, dd 224 ; previous line
NEWSYM nmistatus, dd 0 ; 0 = none, 1 = waiting for nmi location,
; 2 = found, disable at next line
NEWSYM joycontren, dd 0 ; joystick read control check
NEWSYM NextLineCache, db 0
NEWSYM NetQuit, db 0
Donextlinecache:
cmp word[curypos],0
je .nocache
mov ax,[resolutn]
dec ax
cmp word[curypos],ax
jae .nocache
test byte[scrndis],10h
jnz .nocache
cmp byte[curblank],0h
jne .nocache
push ecx
push ebx
push esi
push edi
xor ecx,ecx
mov cl,[curypos]
push edx
.next
mov byte[sprlefttot+ecx],0
mov dword[sprleftpr+ecx*4],0
inc cl
jnz .next
call processsprites
call cachesprites
pop edx
pop edi
pop esi
pop ebx
pop ecx
.nocache
mov byte[NextLineCache],0
ret
%macro NetHelpExecSend 1
cmp byte[pl1neten+%1],1
jne %%nopl
mov eax,[ecx]
mov [cnetplaybuf+ebx],al
inc ebx
and ebx,1FFh
mov [cnetplaybuf+ebx],ah
inc ebx
and ebx,1FFh
ror eax,16
mov [cnetplaybuf+ebx],al
inc ebx
and ebx,1FFh
mov [cnetplaybuf+ebx],ah
inc ebx
and ebx,1FFh
ror eax,16
call RemoteSendEAX
add ecx,4
%%nopl
%endmacro
%macro NetHelpExecRecv 1
cmp byte[pl1neten+%1],2
jne %%nopl
call RemoteGetEAX
mov [ecx],eax
%%nopl
add ecx,4
%endmacro
%macro NetHelpExecRecv2 1
cmp byte[pl1neten+%1],1
jne %%nopl
mov al,[cnetplaybuf+ebx]
inc ebx
and ebx,1FFh
mov ah,[cnetplaybuf+ebx]
inc ebx
and ebx,1FFh
ror eax,16
mov al,[cnetplaybuf+ebx]
inc ebx
and ebx,1FFh
mov ah,[cnetplaybuf+ebx]
inc ebx
and ebx,1FFh
ror eax,16
mov [ecx],eax
%%nopl
add ecx,4
%endmacro
;*******************************************************
; 65816 execution
;*******************************************************
SpeedHackSafeTable
db 1,0,1,0,0,0,1,0,1,0,1,1,0,0,0,0
db 0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0
db 0,0,0,0,0,0,1,0,1,0,1,1,0,0,1,0
db 0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0
db 0,0,0,0,0,1,1,1,1,1,1,1,0,1,1,1
db 0,1,1,1,0,1,1,1,0,1,1,0,0,0,1,0
db 0,1,0,1,0,1,1,1,0,1,1,0,0,1,1,1
db 0,1,1,1,0,1,1,1,0,1,0,0,0,1,1,1
db 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,1,0,1,0,1,0,0,0,1,0
db 0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0
db 0,1,0,1,0,1,1,1,1,1,0,0,0,1,1,1
db 0,1,1,1,0,1,1,1,0,1,0,0,0,1,1,1
NEWSYM exitloop2
mov byte[ExecExitOkay],0
NEWSYM exitloop
ret
cmp byte[nextmenupopup],1
je .okay
cmp byte[ExecExitOkay],0
je .okay
mov byte[pressed+1],0
mov byte[pressed+59],0
mov eax,[KeySaveState]
mov byte[pressed+eax],0
mov eax,[KeyLoadState]
mov byte[pressed+eax],0
mov eax,[KeyQuickExit]
mov byte[pressed+eax],0
mov eax,[KeyQuickLoad]
mov byte[pressed+eax],0
mov eax,[KeyQuickRst]
mov byte[pressed+eax],0
mov byte[ExecExitOkay],5
mov eax,[KeyQuickSnapShot]
mov byte[pressed+eax],0
mov byte[SSKeyPressed],0
jmp cpuover.returntoloop
.okay
mov byte[ExecExitOkay],5
ret
ALIGN16
%macro FlipCheck 0
cmp byte[FlipWait],0
je %%noflip
push edx
push eax
mov dx,3DAh ;VGA status port
in al,dx
test al,8
jz %%skipflip
push ebx
push ecx
mov ax,4F07h
mov bh,00h
mov bl,00h
xor cx,cx
mov dx,[NextLineStart]
mov [LastLineStart],dx
int 10h
mov byte[FlipWait],0
pop ecx
pop ebx
%%skipflip
pop eax
pop edx
%%noflip
%endmacro
NEWSYM execute
NEWSYM execloop
mov bl,dl
test byte[curexecstate],2
jnz .sound
mov edi,[tableadb+ebx*4]
mov bl,[esi]
inc esi
sub dh,[cpucycle+ebx]
jc .cpuover
.startagain
call dword near [edi+ebx*4]
.cpuover
jmp cpuover
.sound
mov edi,[tableadc+ebx*4]
sub dword[cycpbl],55
jnc .skipallspc
mov eax,[cycpblt]
mov bl,[ebp]
add dword[cycpbl],eax
; 1260, 10000/12625
inc ebp
call dword near [opcjmptab+ebx*4]
xor ebx,ebx
.skipallspc
mov bl,[esi]
inc esi
sub dh,[cpucycle+ebx]
jc .cpuovers
call dword near [edi+ebx*4]
.cpuovers
jmp cpuover
SECTION .data
ALIGN32
NEWSYM ExecExitOkay, db 1
NEWSYM JoyABack, dd 0
NEWSYM JoyBBack, dd 0
NEWSYM JoyCBack, dd 0
NEWSYM JoyDBack, dd 0
NEWSYM JoyEBack, dd 0
NEWSYM NetCommand, dd 0
NEWSYM spc700read, dd 0
NEWSYM lowestspc, dd 0
NEWSYM highestspc, dd 0
NEWSYM SA1UBound, dd 0
NEWSYM SA1LBound, dd 0
NEWSYM SA1SH, dd 0
NEWSYM SA1SHb, dd 0
NEWSYM NumberOfOpcodes2, dd 0
NEWSYM ChangeOps, dd 0
NEWSYM SFXProc, dd 0
SECTION .text
%macro C4Paused 0
; cmp byte[C4Pause],0
; je %%notpaused
; inc esi
; xor dh,dh
; jmp cpuover
;%%notpaused
%endmacro
NEWSYM cpuover
dec esi
cmp byte[HIRQNextExe],0
je .nohirq
mov dh,[HIRQCycNext]
mov byte[HIRQCycNext],0
jmp .hirq
.nohirq
cmp byte[SA1Enable],0
je near .nosa1b
test byte[exiter],01h
jnz near .nosa1
mov byte[cycpl],150
test byte[SA1Control],60h
jnz near .nosa1
call SA1Swap
cmp byte[CurrentExecSA1],15
ja .nocontinueexec
xor ebx,ebx
mov bl,[esi]
inc esi
jmp execloop.startagain
.nocontinueexec
; check for sa-1 speed hacks
mov byte[SA1SHb],0
cmp word[IRAM+0A0h],80BFh
jne .noshb2
cmp word[IRAM+020h],0
jne .noshb2
mov ecx,[SA1Ptr] ; small speed hack
sub ecx,[romdata]
cmp ecx,83h
jb .skipsh
cmp ecx,97h
ja .skipsh
mov byte[SA1SHb],1
.skipsh
.noshb2
mov ecx,[SA1Ptr] ; small speed hack
cmp dword[ecx],0FCF04BA5h
je .shm
cmp dword[ecx-2],0FCF04BA5h
jne .skipshm
.shm
cmp byte[IRAM+4Bh],0
jne .skipshm
mov byte[SA1SHb],1
.skipshm
cmp dword[ecx],80602EEEh
jne .skipshc
sub ecx,[romdata]
cmp ecx,4E5h
jb .skipshc
cmp ecx,4E8h
ja .skipshc
mov byte[SA1SHb],1
mov ecx,[SA1BWPtr]
add word[ecx+602Eh],4
.skipshc
test word[IRAM+0Ah],8000h
jnz .noshb2b
test word[IRAM+0Eh],8000h
jz .noshb2b
mov ecx,[SA1Ptr] ; small speed hack
sub ecx,[romdata]
cmp ecx,0C93h
jb .skipshb
cmp ecx,0C9Bh
ja .skipshb
mov byte[SA1SHb],1
.skipshb
cmp ecx,0CB8h
jb .skipshb3
cmp ecx,0CC0h
ja .skipshb3
mov byte[SA1SHb],1
.skipshb3
.noshb2b
sub esi,[wramdata]
cmp esi,224h
jb .nosh
cmp esi,22Eh
ja .nosh
mov ecx,[wramdata]
mov dword[SA1LBound],224h
mov dword[SA1UBound],22Eh
add dword[SA1LBound],ecx
add dword[SA1UBound],ecx
mov byte[SA1SH],1
.nosh
cmp esi,1F7C6h
jb .noshb
cmp esi,1F7CCh
ja .noshb
mov ecx,[wramdata]
mov dword[SA1LBound],1F7C6h
mov dword[SA1UBound],1F7CCh
add dword[SA1LBound],ecx
add dword[SA1UBound],ecx
mov byte[SA1SH],1
.noshb
cmp esi,14h
jb .noshc
cmp esi,1Ch
ja .noshc
mov ecx,[wramdata]
cmp dword[ecx+14h],0F023002Ch
jne .noshc
mov dword[SA1LBound],14h
mov dword[SA1UBound],1Ch
add dword[SA1LBound],ecx
add dword[SA1UBound],ecx
mov byte[SA1SH],1
.noshc
add esi,[wramdata]
sub esi,[romdata]
cmp esi,0A56h
jb .noshbc
cmp esi,0A59h
ja .noshbc
mov ecx,[romdata]
mov dword[SA1LBound],0A56h
mov dword[SA1UBound],0A59h
add dword[SA1LBound],ecx
add dword[SA1UBound],ecx
mov byte[SA1SH],1
.noshbc
xor ecx,ecx
add esi,[romdata]
xor dh,dh
mov byte[cycpl],10
cmp byte[CurrentExecSA1],255
jne .notsa1255
mov byte[cycpl],160
.notsa1255
mov byte[CurrentExecSA1],0
test dl,04h
jnz .nosa1
test byte[SA1IRQEnable],80h
jz .nosa1
test byte[SA1DoIRQ],4
jz .nosa1
and byte[SA1DoIRQ],0FBh
mov al,byte[SA1Message+1]
mov byte[SA1Message+3],al
or byte[SA1IRQExec],1
; Start IRQ
add dh,10
jmp .virq
.nosa1
test byte[SA1IRQEnable],20h
jz .nosa1chirq
test byte[SA1DoIRQ],8
jz .nosa1chirq
; jmp .nosa1chirq
and byte[SA1DoIRQ],0F7h
mov al,byte[SA1Message+1]
mov byte[SA1Message+3],al
or byte[SA1IRQExec],2
; Start IRQ
add dh,10
jmp .virq
.nosa1chirq
.nosa1b
FlipCheck
cmp byte[NextLineCache],0
je .nosprcache
call Donextlinecache
.nosprcache
cmp byte[KeyOnStB],0
je .nokeyon
mov al,[KeyOnStB]
call ProcessKeyOn
.nokeyon
mov al,[KeyOnStA]
mov [KeyOnStB],al
mov byte[KeyOnStA],0
test byte[exiter],01h
jnz near exitloop2
test byte[SfxSFR],20h
jnz near StartSFX
.returnfromsfx
; inc dword[numinst] ;Temporary
inc word[curypos]
add dh,[cycpl]
mov ax,[totlines]
cmp word[curypos],ax
ja near .overy
cmp byte[spcon],0
je .nosound
call updatetimer
.nosound
mov ax,[resolutn]
inc ax
cmp [curypos],ax
je near .nmi
mov ax,[resolutn]
cmp [curypos],ax
je near .hdma
; add ax,2
; cmp [curypos],ax
; je near .hdma
.hdmacont
cmp byte[curypos],100
jne .noline100
mov ax,[scrnon]
mov [TempVidInfo],ax
mov ax,[scaddset]
mov [TempVidInfo+2],ax
.noline100
; check for VIRQ/HIRQ/NMI
ProcessIRQStuff
mov ax,[resolutn]
dec ax
cmp [curypos],ax
jb .drawline
; mov ax,[resolutn]
; cmp [curypos],ax
; jb .drawline
C4Paused
xor ebx,ebx
mov bl,[esi]
inc esi
jmp execloop.startagain
.hdma
call exechdma
jmp .hdmacont
.drawline
mov al,[nmiprevline]
cmp [curypos],al
jb near .noskip
cmp byte[nmirept],10
jb near .noskip
; if between correct address, decrease by 2, set nmistatus as 2
; if not, set nmistatus as 1, increase by 2
cmp byte[curexecstate],0
jne .nn
xor dh,dh
.nn
cmp byte[nmistatus],2
jae near .noskip
cmp esi,[nmiprevaddrl]
jb .failcheck2
cmp esi,[nmiprevaddrh]
ja .failcheck2
cmp byte[nmiprevline],20
jb .nodec
sub byte[nmiprevline],10
.nodec
xor eax,eax
mov al,[esi]
cmp byte[disable65816sh],1
je .ohno
cmp byte[SpeedHackSafeTable+eax],1
jne .okay
.ohno
mov byte[nmirept],0
mov dword[nmiprevaddrl],0FFFFFFFFh
mov dword[nmiprevaddrh],0
jmp .noskip
.okay
mov byte[nmistatus],2
and byte[curexecstate],0FEh
.nodis65816
jmp .noskip
.failcheck2
add byte[nmiprevline],1
mov byte[nmistatus],1
.noskip
cmp byte[hdmadelay],0
je .dohdma
dec byte[hdmadelay]
jmp .nodohdma
.dohdma
cmp word[curypos],1
jne .nooffby1line
test byte[INTEnab],20h
jz .nooffby1line
cmp word[VIRQLoc],0
je .nodohdma
.nooffby1line
call exechdma
.nodohdma
cmp word[curypos],1
jne .nocache
call cachevideo
.nocache
cmp byte[curblank],0
jne .nodrawlineb2
call drawline
.nodrawlineb2
cmp byte[curexecstate],2
je near pexecs
cmp byte[curexecstate],0
jne .yesexec
xor dh,dh
.yesexec
C4Paused
xor ebx,ebx
mov bl,[esi]
inc esi
jmp execloop.startagain
.nmi
mov byte[doirqnext],0
inc dword[NetSent]
cmp byte[yesoutofmemory],1
jne .noout
call outofmemfix
.noout
; pushad
; call GenLatencyDisplay
; popad
; NetCommand : bit 0 = Okay (should be 1), bit 1 = control update,
; bit 2 = print update, bit 3 = quit, bit 4 = reset
dec word[curypos]
mov [tempdh],dh
xor dh,dh
mov byte[doirqnext],0
call exechdma
call exechdma
; push es
; cmp byte[cbitmode],1
; jne .nodisptest
; mov es,[vesa2selec]
; mov word[es:10+640],1111111111111111b
;.nodisptest
; pop es
mov byte[NetCommand],0
mov byte[NextNGDisplay],1
cmp byte[newengen],0
je .nonewgfx
cmp byte[curblank],0h
jne .nonewgfx
cmp byte[ForceNewGfxOff],0
jne .nonewgfx
; cmp byte[NextNGDisplay],0
; je .nonewgfx
call StartDrawNewGfx
.nonewgfx
cmp byte[chaton],1
je near .nonet
cmp byte[CNetType],20
je near .net
cmp byte[GUIQuit],1
je near endprog
mov eax,dword[KeyQuickSnapShot]
or eax,eax
jz .nosskey
test byte[pressed+eax],1
jz .nosskey
mov byte[SSKeyPressed],1
mov byte[pressed+eax],2
jmp exitloop
.nosskey
test byte[pressed+1],01h
jnz near exitloop
test byte[pressed+59],01h
jnz near exitloop
cmp byte[nextmenupopup],1
je near exitloop
cmp byte[nextmenupopup],2
jb .skipmenupop
dec byte[nextmenupopup]
.skipmenupop
mov eax,[KeySaveState]
test byte[pressed+eax],01h
jnz near exitloop
mov eax,[KeyLoadState]
test byte[pressed+eax],01h
jnz near exitloop
mov eax,[KeyQuickRst]
test byte[pressed+eax],01h
jnz near exitloop
mov eax,[KeyQuickExit]
test byte[pressed+eax],01h
jnz near exitloop
mov eax,[KeyQuickLoad]
test byte[pressed+eax],01h
jnz near exitloop
cmp byte[ExecExitOkay],0
je .returntoloop
dec byte[ExecExitOkay]
.returntoloop
jmp .nonet
.net
test byte[pressed+1],01h
jz .nonetexit
or byte[NetCommand],08h
.nonetexit
mov eax,[KeySaveState]
test byte[pressed+eax],01h
jz .notnetsave
mov byte[pressed+eax],2
call NetSaveState
.notnetsave
mov eax,[KeyLoadState]
test byte[pressed+eax],01h
jz .notnetload
or byte[NetCommand],88h
.notnetload
.nonet
mov dh,[tempdh]
inc word[curypos]
cmp byte[CurRecv],1
je .noinputread
cmp byte[NoInputRead],1
je .noinputread
call ReadInputDevice
.noinputread
call UpdateRewind
mov byte[NetQuit],0
cmp byte[CNetType],20
jne near .nozerons
test byte[NetSwap],1
jnz near .noonens
cmp byte[CurRecv],1
je near .noreceiveb2
mov eax,[JoyAOrig]
cmp eax,[prevp1net]
je .nochange1
or byte[NetCommand],02h
mov [prevp1net],eax
.nochange1
mov eax,[JoyBOrig]
cmp eax,[prevp2net]
je .nochange2
or byte[NetCommand],02h
mov [prevp2net],eax
.nochange2
mov eax,[JoyCOrig]
cmp eax,[prevp3net]
je .nochange3
or byte[NetCommand],02h
mov [prevp3net],eax
.nochange3
mov eax,[JoyDOrig]
cmp eax,[prevp4net]
je .nochange4
or byte[NetCommand],02h
mov [prevp4net],eax
.nochange4
test byte[NetCommand],02h
jz .nochangeatall
mov dword[ResendTimer],60
jmp .yeschanged
.nochangeatall
dec dword[ResendTimer]
jnz .yeschanged
or byte[NetCommand],02h
mov dword[ResendTimer],60
.yeschanged
; Send command & store command
call PreparePacket
push ebx
push ecx
mov al,[NetCommand]
mov ebx,[cnetptrhead]
mov [cnetplaybuf+ebx],al
call RemoteSendChar
; ##################
; Send latency value
cmp byte[OSPort],3
jne .nolatencysend
cmp byte[BackState],1
jne .nolatencysend
mov ebx,[LatencySendPtr]
and ebx,0FFh
inc dword[LatencySendPtr]
mov byte[LatencyV+ebx],0
mov ebx,[PBackupPos]
mov al,[LocalLValue]
; inc al
call RemoteSendChar
.nolatencysend
mov ebx,[cnetptrhead]
mov ecx,JoyAOrig
inc ebx
and ebx,1FFh
test byte[NetCommand],02h
jz near .nosendextra
NetHelpExecSend 0
NetHelpExecSend 1
NetHelpExecSend 2
NetHelpExecSend 3
NetHelpExecSend 4
.nosendextra
mov [cnetptrhead],ebx
call SendPacketUDP
cmp byte[chaton],0
jne .nosendchats
cmp byte[chatstrL],0
je .nosendchats
cmp dword[chatTL],0
jne .nosendchats
mov byte[NetCommand],04h
.nosendchats
; send chat string
test byte[NetCommand],04h
jz near .nosendchatsend
call PreparePacket
mov al,04h
call RemoteSendChar
call MoveStringChat
push esi
mov esi,chatstrR
cmp byte[OSPort],2
jae .notwin32b
mov byte[esi],'L'
mov byte[esi+1],'>'
add esi,2
jmp .skipsendnick
.notwin32b
cmp dword[chatstrL+1],'/ME '
jne .noaction
mov al,'*'
push ebx
push eax
mov [esi],al
inc esi
call RemoteSendChar
pop eax
pop ebx
.noaction
mov ebx,ChatNick
.nextchatc2
mov al,[ebx]
cmp al,0
je .nonextchat
push ebx
push eax
mov [esi],al
inc esi
call RemoteSendChar
pop eax
pop ebx
inc ebx
cmp byte[ebx-1],0
jne .nextchatc2
.nonextchat
mov al,'>'
cmp dword[chatstrL+1],'/ME '
jne .noaction2
mov al,' '
.noaction2
push ebx
push eax
mov [esi],al
inc esi
call RemoteSendChar
pop eax
pop ebx
.skipsendnick
mov ebx,chatstrL+1
cmp byte[OSPort],2
jb .noaction3
cmp dword[chatstrL+1],'/ME '
jne .noaction3
mov ebx,chatstrL+5
.noaction3
.nextchatc
mov al,[ebx]
push ebx
push eax
mov [esi],al
inc esi
call RemoteSendChar
pop eax
pop ebx
inc ebx
cmp byte[ebx-1],0
jne .nextchatc
mov byte[esi],0
pop esi
mov ecx,45
mov ebx,chatstrL
.chatsendloop
mov al,[ebx+1]
mov [ebx],al
inc ebx
loop .chatsendloop
mov byte[chatstrL],0
mov dword[chatTL],10
mov dword[chatRTL],8*60
call SplitStringChat
call SendPacket
.nosendchatsend
pop ecx
pop ebx
jmp .noreceiveb3
.noreceiveb2
.noreceiveb3
mov dword[JoyAOrig],0
mov dword[JoyBOrig],0
mov dword[JoyCOrig],0
mov dword[JoyDOrig],0
mov dword[JoyEOrig],0
cmp byte[LatencyLeft],0
jne near .latencyleft
mov [tempedx],edx
push ecx
push ebx
cmp byte[OSPort],3
jne .nobackstate
cmp byte[BackState],1
jne .nobackstate
call BackupCVFrame
.nobackupcvframe
mov ebx,[CBackupPos]
inc ebx
and ebx,0Fh
mov [CBackupPos],ebx
.nobackstate
pop ebx
pop ecx
push ebx
push ecx
cmp dword[CurRecv],1
je .yesreceive2
xor ebx,ebx
.latencyloop
add dword[LatencyV+ebx*4],01010101h
inc ebx
cmp ebx,64
jne .latencyloop
.yesreceive2
cmp dword[CurRecv],1
jne near .notreceive
mov ebx,[PPValue]
inc ebx
and ebx,0Fh
mov [PPValue],ebx
cmp ebx,[DPValue]
jne near .notreceive
mov dword[CurRecv],0
call VoiceEndMute
cmp byte[t1cc],4
jbe .noframesskippedb
mov byte[t1cc],4
.noframesskippedb
jmp .received
.notreceive
.received
pop ecx
pop ebx
; Receive command from net and process
push ebx
push ecx
cmp byte[CurRecv],1
je near .nocrupdate3b
xor bl,bl
mov cx,[t1cc]
add cx,60*15
.notfoundchar
.onlychatchar
call RemoteGetChar
; cmp [t1cc],cx
; jne .notor
jmp .notor
.netquit2
or byte[NetQuit],80h
mov byte[RemoteDisconnect],1
jmp .skipallnet
.notor
cmp dh,0
jne .foundchar
cmp byte[OSPort],3
jne .notwin32
push ebx
cmp byte[BackState],1
jne .nobackstate2
mov ebx,[CBackupPos]
dec ebx
sub ebx,[PBackupPos]
sub ebx,[BackStateSize]
and ebx,0Fh
; inc ebx
; and ebx,0Fh
; cmp ebx,[PBackupPos]
jne near .nocrupdate3 ; *************************
.nobackstate2
pop ebx
;NEWSYM StateBackup, dd 0
;NEWSYM CBackupPos, dd 0
;NEWSYM PBackupPos, dd 0
;NEWSYM PPValue, dd 0 ; Previous PValue
;NEWSYM DPValue, dd 0 ; Destination PValue
;NEWSYM CurRecv, dd 0 ; Set to 1 if Recovery mode is on
; if CurRecv=1, then do not send tcp/ip data, always frame skip, do not
; draw to screen, do not key on, restore previous local key presses,
; when disabling key ons, divert dspmem write/read to a different
; array temporarly, then re-copy back in when finished
;NEWSYM PPContrl, times 16 dd 0 ; Previous Controller 1 Data
;NEWSYM PPContrl2, times 16 dd 0 ; Previous Controller 2 Data
;NEWSYM PPContrl3, times 16 dd 0 ; Previous Controller 3 Data
;NEWSYM PPContrl4, times 16 dd 0 ; Previous Controller 4 Data
;NEWSYM PPContrl5, times 16 dd 0 ; Previous Controller 5 Data
pushad
mov byte[nojoystickpoll],1
call JoyRead
mov byte[nojoystickpoll],0
; call ChatType2
popad
cmp word[t1cc],4*60
jb .notwin32
cmp byte[pressed+1],1
je .netquit2
.notwin32
mov bl,1
jmp .notfoundchar
.foundchar
cmp dl,04h
jne .notchatchar
jmp .recvchats
.notchatchar
cmp byte[t1cc],4
jbe .noframesskipped
mov byte[t1cc],4
.noframesskipped
inc byte[netdelayed]
cmp bl,0
jne .yesdelay
mov byte[netdelayed],0
.yesdelay
cmp byte[netdelayed],10
jne .nodelayfix
mov byte[netdelayed],0
cmp byte[t1cc],0
je .nodelayfix
dec byte[t1cc]
.nodelayfix
mov [NetCommand],dl
pushad
; Receive latency value
; #####################
cmp byte[OSPort],3
jne near .nolatencyrecv2
cmp byte[BackState],1
jne near .nolatencyrecv2
.tryagainlatency
call RemoteGetChar ; **********
cmp byte[RemoteDisconnect],1
je near .netquit
cmp dh,0
je .tryagainlatency
mov ebx,[LatencyRecvPtr]
and ebx,0FFh
inc dword[LatencyRecvPtr]
mov al,[LatencyV+ebx]
mov [RemoteLValue],dl
mov [LocalLValue],al
cmp al,dl
jbe .nolatencyrecv3
; incr t1cc -> make local speed faster if local latency > remote
inc dword[latencytimer]
cmp dword[latencytimer],5
jb .nolatencyrecv2
mov dword[latencytimer],0
cmp byte[t1cc],0
je .nolatencyrecv2
dec byte[t1cc]
jmp .nolatencyrecv2
.nolatencyrecv3
cmp al,dl
je .nolatencyrecv2
inc dword[latencytimer]
cmp dword[latencytimer],5
jb .nolatencyrecv2
mov dword[latencytimer],0
inc byte[t1cc]
.nolatencyrecv2
popad
inc dword[NetSent2]
test dl,01h
jnz near .netfailed
test dl,070h
jnz near .netfailed
cmp dword[NetQuitter],0
je .noforcequit
mov ebx,[PBackupPos]
inc ebx
and ebx,0Fh
cmp ebx,[QBackupPos]
je .forcequit
.noforcequit
test dl,08h
jz .noquit
.forcequit
test dl,80h
jz .noloadstate
mov byte[NetLoadState],1
.noloadstate
or byte[NetQuit],1
cmp byte[BackState],1
jne .noquit
push edx
mov ebx,[PBackupPos]
inc ebx
and ebx,0Fh
cmp ebx,[CBackupPos]
je .noquit2
call RestoreCVFrame
add dword[NetSent],1000
.noquit2
pop edx
.noquit
test dl,02h
jz near .nocrupdate2
cmp byte[OSPort],3
jne .notwin32d
cmp byte[BackState],1
jne .notwin32d
push edx
mov ebx,[PBackupPos]
inc ebx
and ebx,0Fh
cmp ebx,[CBackupPos]
je .noupdate
call RestoreCVFrame
mov ebx,[PBackupPos] ; *****************
inc ebx
and ebx,0Fh
mov [PPValue],ebx
mov ebx,[CBackupPos]
mov [DPValue],ebx
mov ebx,[PPValue]
mov [CBackupPos],ebx
mov dword[CurRecv],1 ; *****************
call VoiceStartMute
.noupdate
mov ebx,[PBackupPos]
inc ebx
and ebx,0Fh
mov [PBackupPos],ebx
pop edx
.notwin32d
mov ecx,JoyAOrig
NetHelpExecRecv 0
NetHelpExecRecv 1
NetHelpExecRecv 2
NetHelpExecRecv 3
NetHelpExecRecv 4
jmp .donecrupdate
.nocrupdate3
pop ebx
.nocrupdate3b
mov byte[NetCommand],0
jmp .nocrupdate
.nocrupdate2
mov ebx,[PBackupPos]
inc ebx
and ebx,0Fh
mov [PBackupPos],ebx
.nocrupdate
cmp byte[pl1neten],2
jne .nopl1recv
mov eax,[JoyABack]
mov [JoyAOrig],eax
.nopl1recv
cmp byte[pl2neten],2
jne .nopl2recv
mov eax,[JoyBBack]
mov [JoyBOrig],eax
.nopl2recv
cmp byte[pl3neten],2
jne .nopl3recv
mov eax,[JoyCBack]
mov [JoyCOrig],eax
.nopl3recv
cmp byte[pl4neten],2
jne .nopl4recv
mov eax,[JoyDBack]
mov [JoyDOrig],eax
.nopl4recv
cmp byte[pl5neten],2
jne .nopl5recv
mov eax,[JoyEBack]
mov [JoyEOrig],eax
.nopl5recv
.donecrupdate
jmp .norecvchats
.recvchats
push ebx
call MoveStringChat
mov ebx,chatstrR
push edx
.nextchatcr
push ebx
push ecx
mov cx,[t1cc]
add cx,60*10
.tryagainchatc
call RemoteGetChar ; **********
cmp byte[RemoteDisconnect],1
je .netquit
cmp [t1cc],cx
jne .noto
.netquit
or byte[NetQuit],80h
mov dh,1
.noto
cmp dh,0
je .tryagainchatc ; *********
pop ecx
pop ebx
mov [ebx],dl
inc ebx
cmp dl,0
jne .nextchatcr ; *********
pop edx
pushad
cmp byte[OSPort],2
jae .notwin32e
mov dl,'R'
call NetAddChar
mov dl,'>'
call NetAddChar
.notwin32e
mov esi,chatstrR
call WritetochatBuffer
mov dl,13
call NetAddChar
mov dl,10
call NetAddChar
popad
mov dword[chatRTL],60*8
call SplitStringChat
pop ebx
jmp .onlychatchar
.norecvchats
jmp .skipfailed
.netfailed
or byte[NetQuit],80h
.skipfailed
cmp byte[CurRecv],1
je near .noreceiveb
; Process previous command from buffer
mov ebx,[cnetptrtail]
mov ecx,JoyAOrig
mov dl,[cnetplaybuf+ebx]
inc ebx
and ebx,1FFh
test dl,08h
jz .noquit2b
push ebx
mov ebx,[PBackupPos]
cmp ebx,[CBackupPos]
je .yesquit
cmp dword[NetQuitter],1
je .quitlater
test dl,80h
jz .noloadstateb
mov byte[NetLoadState],2
.noloadstateb
mov dword[NetQuitter],1
mov ebx,[CBackupPos]
mov [QBackupPos],ebx
jmp .quitlater
.yesquit
test dl,80h
jz .noloadstateb2
mov byte[NetLoadState],2
.noloadstateb2
or byte[NetQuit],1
.quitlater
pop ebx
;NEWSYM NetQuitter, dd 0
;NEWSYM QBackupPos, dd 0
.noquit2b
test dl,02h
jz near .nocrupdate2b
NetHelpExecRecv2 0
NetHelpExecRecv2 1
NetHelpExecRecv2 2
NetHelpExecRecv2 3
NetHelpExecRecv2 4
jmp .donecrupdate2
.nocrupdate2b
cmp byte[pl1neten],1
jne .nopl1recv2
mov eax,[JoyABack]
mov [JoyAOrig],eax
.nopl1recv2
cmp byte[pl2neten],1
jne .nopl2recv2
mov eax,[JoyBBack]
mov [JoyBOrig],eax
.nopl2recv2
cmp byte[pl3neten],1
jne .nopl3recv2
mov eax,[JoyCBack]
mov [JoyCOrig],eax
.nopl3recv2
cmp byte[pl4neten],1
jne .nopl4recv2
mov eax,[JoyDBack]
mov [JoyDOrig],eax
.nopl4recv2
cmp byte[pl5neten],1
jne .nopl5recv2
mov eax,[JoyEBack]
mov [JoyEOrig],eax
.nopl5recv2
.donecrupdate2
mov [cnetptrtail],ebx
.noreceiveb
; backup keyboard presses if recv=1 (delayed by 1 frame)
; else restore
; Restore previous keys if CurRecv = 1
; ************************************
cmp byte[CurRecv],1
je near .noreceive
; backup keypresses
mov ebx,[CBackupPos]
dec ebx
and ebx,0Fh
mov ecx,[JoyAOrig]
mov [PPContrl+ebx*4],ecx
mov ecx,[JoyBOrig]
mov [PPContrl2+ebx*4],ecx
mov ecx,[JoyCOrig]
mov [PPContrl3+ebx*4],ecx
mov ecx,[JoyDOrig]
mov [PPContrl4+ebx*4],ecx
mov ecx,[JoyEBack]
mov [PPContrl4+ebx*4],ecx
jmp .yesreceive
.noreceive
mov ebx,[PPValue]
dec ebx
and ebx,0Fh
cmp byte[pl1neten],1
jne .nopl1recv3
mov ecx,[PPContrl+ebx*4]
mov [JoyAOrig],ecx
.nopl1recv3
cmp byte[pl2neten],1
jne .nopl2recv3
mov ecx,[PPContrl2+ebx*4]
mov [JoyBOrig],ecx
.nopl2recv3
cmp byte[pl3neten],1
jne .nopl3recv3
mov ecx,[PPContrl3+ebx*4]
mov [JoyCOrig],ecx
.nopl3recv3
cmp byte[pl4neten],1
jne .nopl4recv3
mov ecx,[PPContrl4+ebx*4]
mov [JoyDOrig],ecx
.nopl4recv3
cmp byte[pl5neten],1
jne .nopl5recv3
mov ecx,[PPContrl5+ebx*4]
mov [JoyEOrig],ecx
.nopl5recv3
.yesreceive
.skipallnet
pop ecx
pop ebx
mov edx,[tempedx]
xor ebx,ebx
jmp .donelatency
.latencyleft
dec byte[LatencyLeft]
.donelatency
mov eax,[JoyAOrig]
mov [JoyABack],eax
mov eax,[JoyBOrig]
mov [JoyBBack],eax
mov eax,[JoyCOrig]
mov [JoyCBack],eax
mov eax,[JoyDOrig]
mov [JoyDBack],eax
mov eax,[JoyEOrig]
mov [JoyEBack],eax
jmp .reprocjoy
.noonens
test byte[NetSwap],1
jz .nozerons
; copy previous frame values into JoyxOrig and JoyxNow
mov eax,[JoyABack]
mov [JoyAOrig],eax
mov eax,[JoyBBack]
mov [JoyBOrig],eax
mov eax,[JoyCBack]
mov [JoyCOrig],eax
mov eax,[JoyDBack]
mov [JoyDOrig],eax
mov eax,[JoyEBack]
mov [JoyEOrig],eax
.reprocjoy
mov eax,[JoyAOrig]
rol eax,16
mov [JoyANow],eax
mov eax,[JoyBOrig]
rol eax,16
mov [JoyBNow],eax
mov eax,[JoyCOrig]
rol eax,16
mov [JoyCNow],eax
mov eax,[JoyDOrig]
mov [JoyDNow],eax
mov eax,[JoyEOrig]
mov [JoyENow],eax
.nozerons
cmp byte[snesmouse],4
jne .nolethalen
mov eax,[LethEnData]
mov [JoyBNow],eax
.nolethalen
xor byte[NetSwap],1
cmp byte[NetQuit],0
je .noquitb
pushad
mov esi,[wramdata]
mov ecx,65536*2
xor eax,eax
xor ebx,ebx
.quitloop
mov al,[esi]
add bx,ax
inc esi
loop .quitloop
mov [valuea],bx
popad
add [valuea],dh
mov byte[ExecExitOkay],0
mov byte[pressed+1],01h
jmp exitloop
.noquitb
cmp byte[MovieProcessing],0
je .noprocmovie
call ProcessMovies
.noprocmovie
test byte[INTEnab],1
jz .noresetjoy
mov eax,[JoyAOrig]
rol eax,16
mov [JoyANow],eax
mov eax,[JoyBOrig]
rol eax,16
mov [JoyBNow],eax
mov eax,[JoyCOrig]
rol eax,16
mov [JoyCNow],eax
mov eax,[JoyDOrig]
mov [JoyDNow],eax
mov eax,[JoyEOrig]
mov [JoyENow],eax
mov byte[JoyCRead],0
.noresetjoy
mov byte[MultiTapStat],80h
cmp byte[C4Enable],0
je .noC4
call C4VBlank
.noC4
; mov byte[hdmastartsc],0
mov byte[joycontren],0
test byte[curexecstate],01h
jnz .dis65816
or byte[curexecstate],01h
; call changeexecloop
.dis65816
cmp byte[CheatOn],1
je near .cheater
.returncheat
mov ax,[VIRQLoc]
cmp word[curypos],ax
jne .novirqz
inc word[VIRQLoc]
.novirqz
mov ax,[oamaddrs]
mov [oamaddr],ax
call showvideo
; call dsp1teststuff
xor ebx,ebx
mov byte[NMIEnab],81h
test byte[INTEnab],80h
jz near .nonmi
; cmp byte[intrset],1
; je near .nonmi
.nmiokay
mov byte[curnmi],1
cmp byte[intrset],1
jne .nointrset
mov byte[intrset],2
.nointrset
cmp byte[nmistatus],1
jne .notnonmifound
mov byte[nmirept],0
.notnonmifound
mov byte[nmistatus],0
cmp byte[nmirept],0
jne .nocheck
mov al,[resolutn]
sub al,2
mov [nmiprevline],al
mov dword[nmiprevaddrl],0FFFFFFFFh
mov dword[nmiprevaddrh],0
mov byte[nmirept],1
mov byte[doirqnext],0
C4Paused
jmp switchtonmi
.nocheck
cmp byte[nmirept],10
je .nextcheck
cmp esi,[nmiprevaddrl]
jae .notlower
mov [nmiprevaddrl],esi
.notlower
cmp esi,[nmiprevaddrh]
jbe .notgreater
mov [nmiprevaddrh],esi
.notgreater
inc byte[nmirept]
C4Paused
jmp switchtonmi
.nextcheck
mov eax,[nmiprevaddrh]
sub eax,[nmiprevaddrl]
cmp eax,10
ja .failcheck
cmp esi,[nmiprevaddrl]
jb .failcheck
cmp esi,[nmiprevaddrh]
ja .failcheck
mov byte[doirqnext],0
C4Paused
jmp switchtonmi
.failcheck
mov byte[nmirept],0
mov dword[nmiprevaddrl],0FFFFFFFFh
mov dword[nmiprevaddrh],0
mov byte[doirqnext],0
C4Paused
jmp switchtonmi
.nonmi
cmp byte[intrset],1
jne .nointrset2w
mov byte[intrset],2
.nointrset2w
cmp byte[esi],0CBh
jne .nowai
jmp .nowai
test dl,04h
jz .nowai
or byte[INTEnab],80h
.nowai
C4Paused
xor ebx,ebx
xor ecx,ecx
mov bl,[esi]
inc esi
jmp execloop.startagain
.overy
shr dh,1
cmp byte[smallscreenon],1
je .nocfield
cmp byte[ScreenScale],1
je .nocfield
cmp byte[scanlines],0
jne .nocfield
xor byte[cfield],1
.nocfield
mov word[curypos],0
cmp dword[numspcvblleft],0
je near .novblch
cmp [lowestspc],ebp
ja .failspc
cmp [highestspc],ebp
jb .failspc
jmp .okayspc
.failspc
mov eax,ebp
sub eax,10
mov [lowestspc],eax
add eax,20
mov [highestspc],eax
mov dword[spc700idle],0
.okayspc
cmp dword[SPC700write],0
jne .notwritespc
cmp dword[spc700read],0
je .notwritespc
cmp dword[SPC700read],1500
jb .notwritespc
inc dword[spc700idle]
cmp dword[spc700idle],30
jne .noidleend
call idledetectspc
cmp byte[ReturnFromSPCStall],1
jne .noidleend
mov byte[ExecExitOkay],0
jmp exitloop
.noidleend
jmp .notidle
.notwritespc
mov dword[spc700idle],0
.notidle
dec dword[numspcvblleft]
mov dword[SPC700write],0
mov dword[SPC700read],0
mov dword[spc700read],0
.novblch
mov byte[NMIEnab],01h
; call cachevideo
call starthdma
; cmp byte[Offby1line],1
; je .noirqhack
; cmp byte[IRQHack],0
; je .noirqhack
; call exechdma
.noirqhack
; check for VIRQ/HIRQ/NMI
cmp byte[execatzerovirq],1
je near .noexecatzero
ProcessIRQStuff
.noexecatzero
C4Paused
xor ebx,ebx
mov bl,[esi]
inc esi
jmp execloop.startagain
.virq
C4Paused
test byte[INTEnab],10h
jz .skiphirq
cmp word[HIRQLoc],0
je .skiphirq
jmp .skiphirq
cmp word[HIRQLoc],339
jbe .hirqnotover
mov word[HIRQLoc],339
.hirqnotover
; first dh = HIRQLoc*DHAdd/340, second dh = DHAdd-first dh
push edx
mov ax,[HIRQLoc]
xor ecx,ecx
mov cl,[cycpl]
mul cx
mov cx,340
div cx
pop edx
mov dh,al
mov cl,[cycpl]
sub cl,al
xor cl,cl
mov [HIRQCycNext],cl
mov byte[HIRQNextExe],1
; jmp .hirq
jmp .returnfromhirq
.skiphirq
test byte[curexecstate],01h
jnz .dis658162
or byte[curexecstate],01h
; call changeexecloop
.dis658162
mov byte[doirqnext],0
xor ebx,ebx
mov ax,[resolutn]
cmp word[curypos],ax
jnb .nodrawline
cmp byte[hdmadelay],0
je .dohdma2
dec byte[hdmadelay]
jmp .nodohdma2
.dohdma2
call exechdma
.nodohdma2
cmp word[curypos],1
jne .nocache2
call cachevideo
.nocache2
cmp byte[curblank],0
jne .nodrawline
call drawline
.nodrawline
cmp byte[intrset],1
jne .nointrset2
mov byte[intrset],2
.nointrset2
; sub dh,8
jmp switchtovirq
.hirq
C4Paused
mov byte[HIRQNextExe],0
test byte[INTEnab],10h
jz .hirqnotokay
test byte[curexecstate],01h
jnz .dis658162h
or byte[curexecstate],01h
.dis658162h
mov byte[doirqnext],0
cmp byte[intrset],1
jne .nointrset2h
mov byte[intrset],2
.nointrset2h
test dl,04h
jnz .irqd
jmp switchtovirq
.irqd
mov byte[doirqnext],1
.hirqnotokay
jmp .nodrawlineh
.returnfromhirq
mov ax,[resolutn]
cmp word[curypos],ax
jnb .nodrawlineh
cmp byte[hdmadelay],0
je .dohdma2h
dec byte[hdmadelay]
jmp .nodohdma2h
.dohdma2h
call exechdma
.nodohdma2h
cmp word[curypos],1
jne .nocache2h
call cachevideo
.nocache2h
cmp byte[curblank],0
jne .nodrawlineh
call drawline
.nodrawlineh
xor ebx,ebx
mov bl,[esi]
inc esi
jmp execloop.startagain
.cheater
push eax
push ebx
push ecx
push edx
mov al,[NumCheats]
mov byte[.numcheat],al
xor edx,edx
.anothercheat
xor ebx,ebx
xor ecx,ecx
test byte[cheatdata+edx],5
jnz .nonormcheat
test byte[cheatdata+edx-28],80h
jnz .nonormcheat
test byte[cheatdata+edx],80h
jnz .cheatcodereflect
mov al,[cheatdata+edx+1]
mov cx,[cheatdata+edx+2]
mov bl,[cheatdata+edx+4]
push edx
call dword near [memtablew8+ebx*4]
pop edx
jmp .nonormcheat
.cheatcodereflect
cmp byte[.numcheat],1
je .nonormcheat
mov cx,[cheatdata+edx+2+28]
mov bl,[cheatdata+edx+4+28]
push edx
call dword near [memtabler8+ebx*4]
pop edx
mov cx,[cheatdata+edx+2]
mov bl,[cheatdata+edx+4]
push edx
call dword near [memtablew8+ebx*4]
pop edx
add edx,28
dec byte[.numcheat]
.nonormcheat
add edx,28
dec byte[.numcheat]
jnz near .anothercheat
pop edx
pop ecx
pop ebx
pop eax
jmp .returncheat
.numcheat db 0
ALIGN16
NEWSYM pexecs
mov byte[soundcycleft],30
.sloop
mov bl,[ebp]
; 1260, 10000/12625
inc ebp
call dword near [opcjmptab+ebx*4]
xor ebx,ebx
dec byte[soundcycleft]
jnz .sloop
xor dh,dh
xor ebx,ebx
mov bl,[esi]
inc esi
jmp execloop.startagain
NEWSYM pexecs2
.sloop
mov bl,[ebp]
; 1260, 10000/12625
inc ebp
call dword near [opcjmptab+ebx*4]
xor ebx,ebx
dec dword[soundcycleft]
jnz .sloop
ret
NEWSYM UpdatePORSCMR
push ebx
push eax
test byte[SfxPOR],10h
jnz .objmode
mov al,[SfxSCMR]
and al,00100100b ; 4 + 32
cmp al,4
je .lines160
cmp al,32
je .lines192
cmp al,36
je .objmode
mov eax,[sfx128lineloc]
jmp .donelines
.lines160
mov eax,[sfx160lineloc]
jmp .donelines
.lines192
mov eax,[sfx192lineloc]
jmp .donelines
.objmode
mov eax,[sfxobjlineloc]
.donelines
mov [sfxclineloc],eax
mov al,[SfxSCMR]
and eax,00000011b
mov bl,[SfxPOR]
and bl,0Fh
shl bl,2
or al,bl
mov ebx,[PLOTJmpb+eax*4]
mov eax,[PLOTJmpa+eax*4]
mov dword [FxTable+4Ch*4],eax
mov dword [FxTableb+4Ch*4],eax
mov dword [FxTablec+4Ch*4],eax
mov dword [FxTabled+4Ch*4],ebx
pop eax
pop ebx
ret
NEWSYM UpdateSCBRCOLR
push eax
push ebx
mov ebx,[SfxSCBR]
shl ebx,10
add ebx,[sfxramdata]
mov [SCBRrel],ebx
mov eax,[SfxCOLR]
mov ebx,[fxbit01+eax*4]
mov [fxbit01pcal],ebx
mov ebx,[fxbit23+eax*4]
mov [fxbit23pcal],ebx
mov ebx,[fxbit45+eax*4]
mov [fxbit45pcal],ebx
mov ebx,[fxbit67+eax*4]
mov [fxbit67pcal],ebx
pop ebx
pop eax
ret
NEWSYM UpdateCLSR
mov dword [NumberOfOpcodes2],350 ; 0FFFFFFFh;350
test byte[SfxCLSR],01h
jz .nohighsfx
mov dword [NumberOfOpcodes2],700 ;700
.nohighsfx
cmp byte[SFXCounter],1
je .noyi
mov dword [NumberOfOpcodes2],0FFFFFFFh
.noyi
ret
NEWSYM UpdateSFX
call UpdatePORSCMR
call UpdatePORSCMR
call UpdateCLSR
ret
NEWSYM StartSFX
push edx
push esi
push edi
push ebp
xor ebx,ebx
mov bl,[SfxPBR]
mov al,[SfxSCMR]
and bl,7Fh
cmp bl,70h
jae .ram
test al,10h
jz .noaccess
jmp .noram
.ram
test al,08h
jz .noaccess
.noram
mov eax,[NumberOfOpcodes2]
mov [NumberOfOpcodes],eax
call MainLoop
.noaccess
pop ebp
pop edi
pop esi
pop edx
xor ebx,ebx
xor ecx,ecx
jmp cpuover.returnfromsfx
NEWSYM StartSFXdebug
push edx
push esi
push edi
push ebx
mov bl,[SfxPBR]
mov al,[SfxSCMR]
and bl,7Fh
cmp bl,70h
jae .ram
test al,10h
jz .noaccess
jmp .noram
.ram
test al,08h
jz .noaccess
.noram
mov dword [NumberOfOpcodes],350 ; 0FFFFFFFh;350
test byte[SfxCLSR],01h
jz .nohighsfx
mov dword [NumberOfOpcodes],700 ;700
.nohighsfx
cmp byte[SFXCounter],1
jne .noyi
mov dword [NumberOfOpcodes],0FFFFFFFFh
.noyi
; call SFXDebugLoop
.noaccess
pop ebx
pop edi
pop esi
pop edx
xor ecx,ecx
jmp execsingle.returnfromsfx
NEWSYM StartSFXdebugb
push edx
push esi
push edi
push ebp
push ebx
test byte[SfxPOR],10h
jnz .objmode
mov al,[SfxSCMR]
and al,00100100b ; 4 + 32
cmp al,4
je .lines160
cmp al,32
je .lines192
cmp al,36
je .objmode
mov eax,[sfx128lineloc]
jmp .donelines
.lines160
mov eax,[sfx160lineloc]
jmp .donelines
.lines192
mov eax,[sfx192lineloc]
jmp .donelines
.objmode
mov eax,[sfxobjlineloc]
.donelines
mov [sfxclineloc],eax
mov al,[SfxSCMR]
and eax,00000011b
mov bl,[SfxPOR]
and bl,0Fh
shl bl,2
or al,bl
mov ebx,[PLOTJmpb+eax*4]
mov eax,[PLOTJmpa+eax*4]
mov dword [FxTable+4Ch*4],eax
mov dword [FxTableb+4Ch*4],eax
mov dword [FxTablec+4Ch*4],eax
mov dword [FxTabled+4Ch*4],ebx
mov ebx,[SfxSCBR]
shl ebx,10
add ebx,[sfxramdata]
mov [SCBRrel],ebx
mov eax,[SfxCOLR]
mov ebx,[fxbit01+eax*4]
mov [fxbit01pcal],ebx
mov ebx,[fxbit23+eax*4]
mov [fxbit23pcal],ebx
mov ebx,[fxbit45+eax*4]
mov [fxbit45pcal],ebx
mov ebx,[fxbit67+eax*4]
mov [fxbit67pcal],ebx
xor ebx,ebx
mov bl,[SfxPBR]
mov al,[SfxSCMR]
and bl,7Fh
cmp bl,70h
jae .ram
test al,10h
jz .noaccess
jmp .noram
.ram
test al,08h
jz .noaccess
.noram
mov dword [NumberOfOpcodes],400 ;678
test byte[SfxCLSR],01h
jz .nohighsfx
mov dword [NumberOfOpcodes],800 ;678*2
.nohighsfx
cmp byte[SFXCounter],1
jne .noyi
mov dword [NumberOfOpcodes],0FFFFFFFh
.noyi
call MainLoop
.noaccess
pop ebx
pop ebp
pop edi
pop esi
pop edx
xor ecx,ecx
jmp execsingle.returnfromsfx
NEWSYM StartSFXret
test byte[SfxSFR],20h
jz .endfx
pushad
mov bl,[SfxPBR]
mov al,[SfxSCMR]
and bl,7Fh
cmp bl,70h
jae .ram
test al,10h
jz .noaccess
jmp .noram
.ram
test al,08h
jz .noaccess
.noram
mov dword [NumberOfOpcodes],400 ;678
test byte[SfxCLSR],01h
jz .nohighsfx
mov dword [NumberOfOpcodes],800 ;678*2
.nohighsfx
mov dword [NumberOfOpcodes],0FFFFFFFFh
call MainLoop
.noaccess
popad
.endfx
ret
;*******************************************************
; Execute a Single 65816 instruction (debugging purpose)
;*******************************************************
NEWSYM execloopdeb
jmp exitloop2
NEWSYM execsingle
xor ebx,ebx
test byte[curexecstate],2
jz .nosoundb
sub dword[cycpbl],55
jnc .skipallspc
mov eax,[cycpblt]
mov bl,[ebp]
add dword[cycpbl],eax
; 1260, 10000/12625
inc ebp
call dword near [opcjmptab+ebx*4]
xor ebx,ebx
.skipallspc
.nosoundb
mov bl,dl
mov byte[exiter],01h
mov edi,[tablead+ebx*4]
mov bl,[esi]
inc esi
sub dh,[cpucycle+ebx]
jc .cpuover
mov [pdh],dh
xor dh,dh
jmp dword near [edi+ebx*4]
.cpuover
; cmp byte[SA1Enable],0
; je .nosa1
; test byte[SA1Control],60h
; jnz .nosa1
; dec esi
; call SA1Swap
; mov bl,[esi]
; inc esi
; cmp byte[SA1Status],0
; je near .nosa1
; mov [pdh],dh
; xor dh,dh
; jmp cpuover
;.nosa1
cmp byte[SA1Enable],0
je near .nosa1
mov byte[cycpl],150
test byte[SA1Control],60h
jnz near .nosa1
dec esi
call SA1Swap
mov bl,[esi]
inc esi
mov [pdh],dh
xor dh,dh
cmp byte[CurrentExecSA1],17
jb near cpuover
mov byte[CurrentExecSA1],0
mov byte[cycpl],5
jmp .nosa1
.nosa1
cmp byte[KeyOnStB],0
je .nokeyon
mov al,[KeyOnStB]
call ProcessKeyOn
.nokeyon
mov al,[KeyOnStA]
mov [KeyOnStB],al
mov byte[KeyOnStA],0
test byte[SfxSFR],20h
jnz near StartSFXdebugb
.returnfromsfx
add dh,[cycpl]
mov [pdh],dh
cmp byte[spcon],0
je .nosound
call updatetimer
push ebx
xor ebx,ebx
mov bl,dl
mov edi,[tablead+ebx*4]
pop ebx
.nosound
xor dh,dh
inc word[curypos]
mov ax,[resolutn]
inc ax
cmp word[curypos],ax
je near .nmi
cmp word[curypos],261
ja near .overy
; check for VIRQ/HIRQ/NMI
ProcessIRQStuff
; test dl,04h
; jnz .noirq
; test byte[INTEnab],20h
; jz .novirq
; mov ax,[VIRQLoc]
; cmp word[curypos],ax
; je near .virq
; jmp .noirq
;.novirq
; test byte[INTEnab],10h
; jnz near .virq
;.noirq
; test byte[INTEnab],20h
; jz .novirq2b
; mov ax,[VIRQLoc]
; cmp word[curypos],ax
; jne .novirq2b
; cmp byte[intrset],1
; jne .nointrset2b
; mov byte[intrset],2
;.nointrset2b
;.novirq2b
mov ax,[resolutn]
cmp word[curypos],ax
jb .drawline
jmp dword near [edi+ebx*4]
.drawline
cmp byte[hdmadelay],0
je .dohdma
dec byte[hdmadelay]
jmp .nodohdma
.dohdma
call exechdma
.nodohdma
cmp byte[curblank],0
jne .nodrawlineb
call drawline
.nodrawlineb
jmp dword near [edi+ebx*4]
.nmi
cmp byte[C4Enable],0
je .noC4
call C4VBlank
.noC4
; mov byte[hdmastartsc],0
mov byte[joycontren],0
mov ax,[VIRQLoc]
cmp word[curypos],ax
jne .novirqz
inc word[VIRQLoc]
.novirqz
call ReadInputDevice
test byte[INTEnab],1
jz .noresetjoy
mov eax,[JoyAOrig]
rol eax,16
mov [JoyANow],eax
mov eax,[JoyBOrig]
rol eax,16
mov [JoyBNow],eax
mov eax,[JoyCOrig]
rol eax,16
mov [JoyCNow],eax
mov eax,[JoyDOrig]
mov [JoyDNow],eax
mov byte[JoyCRead],0
.noresetjoy
cmp byte[snesmouse],4
jne .nolethalen
mov eax,[LethEnData]
mov [JoyBNow],eax
.nolethalen
mov byte[MultiTapStat],80h
mov byte[NMIEnab],81h
test byte[INTEnab],80h
jz .nonmi
mov byte[curnmi],1
dec esi
cmp byte[intrset],1
jne .nointrset
mov byte[intrset],2
.nointrset
; mov byte[debstop3],1
jmp switchtonmideb
.nonmi
cmp byte[intrset],1
jne .nointrset2w
mov byte[intrset],2
.nointrset2w
cmp byte[esi],0CBh
jne .nowai
and dl,0FBh
.nowai
jmp dword near [edi+ebx*4]
.overy
shr dh,1
mov word[curypos],0
mov byte[NMIEnab],01h
add dword[opcd],170*262
call cachevideo
call starthdma
ProcessIRQStuff
; test dl,04h
; jnz .novirq2
; test byte[INTEnab],20h
; jz .novirq2
; mov ax,[VIRQLoc]
; cmp word[curypos],ax
; je near .virq
; mov ax,[VIRQLoc]
; cmp ax,[totlines]
; jae .virq
;.novirq2
jmp dword near [edi+ebx*4]
.virq
mov ax,[resolutn]
cmp word[curypos],ax
jnb .nodrawline
cmp byte[hdmadelay],0
je .dohdma2
dec byte[hdmadelay]
jmp .nodohdma2
.dohdma2
call exechdma
.nodohdma2
cmp byte[curblank],0
jne .nodrawline
call drawline
.nodrawline
dec esi
cmp byte[intrset],1
jne .nointrset2
mov byte[intrset],2
.nointrset2
; mov byte[debstop3],1
jmp switchtovirqdeb
NEWSYM ExecuteAsmEnd