2206 lines
44 KiB
NASM
2206 lines
44 KiB
NASM
;Copyright (C) 1997-2006 ZSNES Team ( zsKnight, _Demo_, pagefault, Nach )
|
|
;
|
|
;http://www.zsnes.com
|
|
;http://sourceforge.net/projects/zsnes
|
|
;
|
|
;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 KeyRewind,statesaver,Voice0Status,UpdateDPage
|
|
EXTSYM StartGUI,debuggeron,romdata,initvideo
|
|
EXTSYM vidbufferofsa,disable65816sh,GUISaveVars,virqnodisable
|
|
EXTSYM KeySaveState,KeyLoadState,KeyQuickExit,KeyQuickLoad,KeyQuickRst
|
|
EXTSYM GUIDoReset,GUIReset,KeyOnStA,KeyOnStB,ProcessKeyOn,C4Enable,KeyQuickClock
|
|
EXTSYM KeyQuickSaveSPC,TimerEnable,IRQHack,splitflags,joinflags
|
|
EXTSYM KeyQuickSnapShot,csounddisable,videotroub,ResetTripleBuf
|
|
EXTSYM Output_Text,Check_Key,Get_Key,Change_Dir
|
|
EXTSYM InitPreGame,Curtableaddr,curcyc,debugdisble,dmadata,guioff,memtabler8
|
|
EXTSYM SetupPreGame,memtablew8,regaccessbankr8,showmenu,snesmap2,snesmmap
|
|
EXTSYM DeInitPostGame,spcPCRam,startdebugger,xp,xpb,xpc,tablead,tableadb
|
|
EXTSYM tableadc,SA1UpdateDPage,Makemode7Table,nextmenupopup,MovieProcessing
|
|
EXTSYM DosExit,InitDir,InitDrive,createnewcfg,sfxramdata,deinitvideo
|
|
EXTSYM SFXEnable,wramdata,cycpbl,cycpblt,irqon,spcon
|
|
EXTSYM multchange,romispal,scrndis,sprlefttot,sprleftpr,processsprites
|
|
EXTSYM cachesprites,opcjmptab,CheatOn
|
|
EXTSYM INTEnab,JoyCRead,NMIEnab,NumCheats,CurrentExecSA1,ReadInputDevice
|
|
EXTSYM StartDrawNewGfx,VIRQLoc,cachevideo,cfield,cheatdata,curblank,curnmi
|
|
EXTSYM curypos,cycpl,doirqnext,drawline,exechdma,hdmadelay,intrset,newengen
|
|
EXTSYM oamaddr,oamaddrs,resolutn,showvideo,snesmouse,starthdma,switchtonmi
|
|
EXTSYM switchtovirq,totlines,updatetimer,SA1Swap,SA1DoIRQ,JoyAOrig,JoyANow
|
|
EXTSYM JoyBOrig,JoyBNow,JoyCOrig,JoyCNow,JoyDOrig,JoyDNow,JoyEOrig,JoyENow
|
|
EXTSYM SA1Message,MultiTapStat,idledetectspc,SA1Control,SA1Enable,SA1IRQEnable
|
|
EXTSYM SPC700read,SPC700write,numspcvblleft,spc700idle,SA1IRQExec,ForceNewGfxOff
|
|
EXTSYM LethEnData,GUIQuit,IRAM,SA1Ptr,SA1BWPtr,scrnon,scaddset,outofmemfix
|
|
EXTSYM yesoutofmemory,ProcessMovies,MovieStop,ppustatus,C4VBlank
|
|
EXTSYM ReturnFromSPCStall,scanlines,smallscreenon,ScreenScale,MainLoop
|
|
EXTSYM NumberOfOpcodes,SfxCLSR,SfxSCMR,SfxPOR,sfx128lineloc,sfx160lineloc
|
|
EXTSYM sfx192lineloc,sfxobjlineloc,sfxclineloc,PLOTJmpa,PLOTJmpb,FxTable
|
|
EXTSYM FxTableb,FxTablec,FxTabled,SfxPBR,SCBRrel,SfxSCBR,SfxCOLR,SFXCounter
|
|
EXTSYM fxbit01,fxbit01pcal,fxbit23,fxbit23pcal,fxbit45,fxbit45pcal,fxbit67
|
|
EXTSYM fxbit67pcal,SfxSFR,nosprincr,cpucycle,switchtovirqdeb,switchtonmideb
|
|
EXTSYM MovieSeekBehind,SaveSramData,BackupCVFrame,RestoreCVFrame,loadstate
|
|
EXTSYM KeyInsrtChap,KeyNextChap,KeyPrevChap,MovieInsertChapter,MovieSeekAhead
|
|
EXTSYM ResetDuringMovie,EMUPauseKey,INCRFrameKey,MovieWaiting,NoInputRead
|
|
EXTSYM AllocatedRewindStates,PauseFrameMode,RestorePauseFrame,BackupPauseFrame
|
|
|
|
%ifdef __MSDOS__
|
|
EXTSYM dssel,Game60hzcall,NextLineStart,FlipWait,LastLineStart
|
|
%endif
|
|
|
|
SECTION .data
|
|
NEWSYM tempedx, dd 0
|
|
NEWSYM tempesi, dd 0
|
|
NEWSYM tempedi, dd 0
|
|
NEWSYM tempebp, dd 0
|
|
NEWSYM RewindTimer, dd 0
|
|
NEWSYM BackState, db 1
|
|
NEWSYM BackStateSize, dd 6
|
|
SECTION .text
|
|
|
|
NEWSYM ProcessRewind
|
|
mov eax,[KeyRewind]
|
|
cmp byte[pressed+eax],1
|
|
jne near .notokay
|
|
mov byte[pressed+eax],2
|
|
|
|
pushad
|
|
call RestoreCVFrame
|
|
popad
|
|
|
|
cmp byte[PauseFrameMode],1
|
|
jne .notpauserewind
|
|
pushad
|
|
call BackupPauseFrame
|
|
popad
|
|
.notpauserewind
|
|
|
|
mov esi,[tempesi]
|
|
mov edi,[tempedi]
|
|
mov ebp,[tempebp]
|
|
mov edx,[tempedx]
|
|
|
|
.notokay
|
|
ret
|
|
|
|
NEWSYM UpdateRewind
|
|
cmp byte[AllocatedRewindStates],0
|
|
je .norewinds
|
|
cmp dword[KeyRewind],0
|
|
je .norewinds
|
|
|
|
dec dword[RewindTimer]
|
|
jnz .checkrewind
|
|
|
|
mov [tempedx],edx
|
|
mov [tempesi],esi
|
|
mov [tempedi],edi
|
|
mov [tempebp],ebp
|
|
|
|
pushad
|
|
call BackupCVFrame
|
|
popad
|
|
|
|
.checkrewind
|
|
call ProcessRewind
|
|
.norewinds
|
|
ret
|
|
|
|
SECTION .data
|
|
NEWSYM MuteVoiceF, dd 0
|
|
SECTION .text
|
|
|
|
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
|
|
|
|
|
|
%macro stim 0
|
|
%ifdef __MSDOS__
|
|
sti
|
|
%endif
|
|
%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
|
|
%%setagain
|
|
cmp byte[intrset],2
|
|
jbe %%nointrseta3
|
|
dec byte[intrset]
|
|
cmp byte[intrset],2
|
|
ja %%noirq
|
|
%%nointrseta3
|
|
cmp byte[intrset],1
|
|
jne %%nointrseta2
|
|
test byte[INTEnab],80h
|
|
jz %%tryhirq
|
|
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
|
|
|
|
SECTION .data
|
|
NEWSYM romloadskip, db 0
|
|
NEWSYM SSKeyPressed, dd 0
|
|
NEWSYM SPCKeyPressed, dd 0
|
|
NEWSYM NoSoundReinit, dd 0
|
|
NEWSYM NextNGDisplay, db 0
|
|
NEWSYM TempVidInfo, dd 0
|
|
NEWSYM tempdh, db 0
|
|
|
|
SECTION .text
|
|
|
|
|
|
; this wonderful mess starts up the CPU and initialized the emulation state
|
|
NEWSYM start65816
|
|
|
|
call initvideo
|
|
|
|
cmp byte[videotroub],1
|
|
jne .notrouble
|
|
ret
|
|
.notrouble
|
|
|
|
mov edi,[vidbufferofsa]
|
|
mov ecx,37518
|
|
xor eax,eax
|
|
rep stosd
|
|
cmp byte[romloadskip],1
|
|
je near StartGUI
|
|
|
|
NEWSYM continueprog
|
|
; clear keyboard presses
|
|
mov esi,pressed
|
|
mov ecx,256+128+64
|
|
mov al,0
|
|
.loopa
|
|
mov [esi],al
|
|
inc esi
|
|
dec ecx
|
|
jnz .loopa
|
|
|
|
mov byte[romloadskip],0
|
|
mov byte[debuggeron],0
|
|
mov byte[exiter],0
|
|
|
|
call InitPreGame
|
|
jmp reexecute
|
|
|
|
NEWSYM continueprognokeys
|
|
mov byte[romloadskip],0
|
|
mov byte[debuggeron],0
|
|
mov byte[exiter],0
|
|
|
|
call InitPreGame
|
|
jmp reexecuteb2
|
|
|
|
; Incorrect
|
|
|
|
NEWSYM reexecuteb
|
|
%ifndef __MSDOS__
|
|
jmp reexecuteb2
|
|
%endif
|
|
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
|
|
dec ecx
|
|
jnz .loopa
|
|
reexecuteb2:
|
|
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[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
|
|
|
|
mov ebp,[spcPCRam]
|
|
|
|
mov byte[NoSoundReinit],0
|
|
mov byte[csounddisable],0
|
|
mov byte[NextNGDisplay],0
|
|
|
|
call splitflags
|
|
|
|
call execute
|
|
|
|
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]
|
|
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
|
|
|
|
; clear all keys
|
|
call Check_Key
|
|
cmp al,0
|
|
je .nokeys
|
|
.yeskeys
|
|
call Get_Key
|
|
call Check_Key
|
|
cmp al,0
|
|
jne .yeskeys
|
|
.nokeys
|
|
|
|
cmp byte[nextmenupopup],1
|
|
je near showmenu
|
|
cmp byte[ReturnFromSPCStall],1
|
|
je near .activatereset
|
|
mov eax,[KeySaveState]
|
|
test byte[pressed+eax],1
|
|
jz .nosavestt
|
|
mov byte[pressed+1],0
|
|
mov byte[pressed+eax],2
|
|
pushad
|
|
call statesaver
|
|
popad
|
|
jmp reexecuteb
|
|
.nosavestt
|
|
mov eax,[KeyLoadState]
|
|
test byte[pressed+eax],1
|
|
jz .noloadstt0
|
|
pushad
|
|
call loadstate
|
|
popad
|
|
jmp reexecuteb
|
|
.noloadstt0
|
|
mov eax,[KeyInsrtChap]
|
|
test byte[pressed+eax],1
|
|
jz .noinsertchapter
|
|
mov byte[pressed+eax],0
|
|
pushad
|
|
call MovieInsertChapter
|
|
popad
|
|
jmp continueprognokeys
|
|
.noinsertchapter
|
|
mov eax,[KeyNextChap]
|
|
test byte[pressed+eax],1
|
|
jz .nonextchapter
|
|
mov byte[pressed+eax],0
|
|
mov byte[multchange],1
|
|
pushad
|
|
call MovieSeekAhead
|
|
popad
|
|
jmp continueprognokeys
|
|
.nonextchapter
|
|
mov eax,[KeyPrevChap]
|
|
test byte[pressed+eax],1
|
|
jz .noprevchapter
|
|
mov byte[pressed+eax],0
|
|
mov byte[multchange],1
|
|
pushad
|
|
call MovieSeekBehind
|
|
popad
|
|
jmp continueprognokeys
|
|
.noprevchapter
|
|
cmp byte[SSKeyPressed],1
|
|
je near showmenu
|
|
cmp byte[SPCKeyPressed],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]
|
|
test byte[pressed+eax],1
|
|
jz .noreset
|
|
.activatereset
|
|
pushad
|
|
mov byte[GUIReset],1
|
|
cmp byte[MovieProcessing],2 ;Recording
|
|
jne .nomovierecording
|
|
call ResetDuringMovie
|
|
jmp .movieendif
|
|
.nomovierecording
|
|
call GUIDoReset
|
|
.movieendif
|
|
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 endprog
|
|
call deinitvideo
|
|
|
|
call SaveSramData
|
|
call createnewcfg
|
|
call GUISaveVars
|
|
|
|
pushad
|
|
call MovieStop
|
|
popad
|
|
|
|
; change dir to InitDrive/InitDir
|
|
mov dl,[InitDrive]
|
|
mov ebx,InitDir
|
|
call Change_Dir
|
|
|
|
jmp DosExit
|
|
|
|
NEWSYM interror
|
|
stim
|
|
call deinitvideo
|
|
mov edx,.nohand ;use extended
|
|
mov ah,9 ;DOS- API
|
|
call Output_Text ;to print a string
|
|
jmp DosExit
|
|
|
|
SECTION .data
|
|
.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 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
|
|
|
|
|
|
SECTION .text
|
|
|
|
;*******************************************************
|
|
; 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
|
|
|
|
%ifdef __MSDOS__
|
|
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
|
|
%endif
|
|
|
|
SECTION .data
|
|
NEWSYM timeradj, dd 65536
|
|
NEWSYM t1cc, dw 0
|
|
SECTION .text
|
|
|
|
;*******************************************************
|
|
; Int 09h vector
|
|
;*******************************************************
|
|
|
|
%ifdef __MSDOS__
|
|
SECTION .bss
|
|
NEWSYM skipnextkey42, resb 1
|
|
SECTION .text
|
|
|
|
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
|
|
%endif
|
|
|
|
SECTION .data
|
|
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 ZMVZClose, db 0
|
|
|
|
SECTION .text
|
|
|
|
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
|
|
|
|
;*******************************************************
|
|
; 65816 execution
|
|
;*******************************************************
|
|
|
|
SECTION .data
|
|
|
|
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
|
|
SECTION .text
|
|
|
|
NEWSYM exitloop2
|
|
mov byte[ExecExitOkay],0
|
|
NEWSYM exitloop
|
|
ret
|
|
|
|
ALIGN16
|
|
|
|
%macro FlipCheck 0
|
|
%ifdef __MSDOS__
|
|
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
|
|
%endif
|
|
%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]
|
|
%ifdef OPENSPC
|
|
pushad
|
|
mov bl,[esi]
|
|
movzx eax,byte[cpucycle+ebx]
|
|
mov ebx,0xC3A13DE6
|
|
mul ebx
|
|
add [ospc_cycle_frac],eax
|
|
adc [SPC_Cycles],edx
|
|
call OSPC_Run
|
|
popad
|
|
%else
|
|
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
|
|
%endif
|
|
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
|
|
NEWSYM EMUPause, db 0
|
|
NEWSYM INCRFrame, db 0
|
|
SECTION .text
|
|
|
|
NEWSYM cpuover
|
|
dec esi
|
|
cmp byte[HIRQNextExe],0
|
|
je .nohirq
|
|
add 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,[SA1Message+1]
|
|
mov [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,[SA1Message+1]
|
|
mov [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
|
|
jae 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
|
|
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
|
|
xor ebx,ebx
|
|
mov bl,[esi]
|
|
inc esi
|
|
jmp execloop.startagain
|
|
|
|
.nmi
|
|
mov byte[irqon],80h
|
|
mov byte[doirqnext],0
|
|
cmp byte[yesoutofmemory],1
|
|
jne .noout
|
|
call outofmemfix
|
|
.noout
|
|
|
|
dec word[curypos]
|
|
mov [tempdh],dh
|
|
xor dh,dh
|
|
|
|
; mov al,[SFXIRQFlag]
|
|
mov byte[doirqnext],0
|
|
|
|
call exechdma
|
|
call exechdma
|
|
|
|
mov byte[NextNGDisplay],1
|
|
cmp byte[newengen],0
|
|
je .nonewgfx
|
|
cmp byte[curblank],0
|
|
jne .nonewgfx
|
|
cmp byte[ForceNewGfxOff],0
|
|
jne .nonewgfx
|
|
; cmp byte[NextNGDisplay],0
|
|
; je .nonewgfx
|
|
call StartDrawNewGfx
|
|
.nonewgfx
|
|
cmp byte[GUIQuit],1
|
|
je near endprog
|
|
mov eax,[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
|
|
mov eax,[KeyQuickClock]
|
|
or eax,eax
|
|
jz .noclockkey
|
|
test byte[pressed+eax],1
|
|
jz .noclockkey
|
|
xor byte[TimerEnable],1
|
|
mov byte[pressed+eax],2
|
|
.noclockkey
|
|
mov eax,[KeyQuickSaveSPC]
|
|
or eax,eax
|
|
jz .nosavespckey
|
|
test byte[pressed+eax],1
|
|
jz .nosavespckey
|
|
mov byte[SPCKeyPressed],1
|
|
mov byte[pressed+eax],2
|
|
jmp exitloop
|
|
.nosavespckey
|
|
mov eax,[EMUPauseKey]
|
|
or eax,eax
|
|
jz .nopausekey
|
|
test byte[pressed+eax],1
|
|
jz .nopausekey
|
|
xor byte[EMUPause],1
|
|
mov byte[pressed+eax],2
|
|
.nopausekey
|
|
mov eax,[INCRFrameKey]
|
|
or eax,eax
|
|
jz .noincrframekey
|
|
test byte[pressed+eax],1
|
|
jz .noincrframekey
|
|
xor byte[INCRFrame],1
|
|
mov byte[pressed+eax],2
|
|
.noincrframekey
|
|
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,[KeyInsrtChap]
|
|
test byte[pressed+eax],01h
|
|
jnz near exitloop
|
|
mov eax,[KeyPrevChap]
|
|
test byte[pressed+eax],01h
|
|
jnz near exitloop
|
|
mov eax,[KeyNextChap]
|
|
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
|
|
mov dh,[tempdh]
|
|
inc word[curypos]
|
|
cmp byte[NoInputRead],1
|
|
je .noinputread
|
|
call ReadInputDevice
|
|
.noinputread
|
|
|
|
;Pause and Frame increment
|
|
cmp byte[PauseFrameMode],3
|
|
jne .nopauseframemode3
|
|
pushad
|
|
call RestorePauseFrame
|
|
popad
|
|
mov esi,[tempesi]
|
|
mov edi,[tempedi]
|
|
mov ebp,[tempebp]
|
|
mov edx,[tempedx]
|
|
.nopauseframemode3
|
|
|
|
cmp byte[EMUPause],1
|
|
jne .noemupause
|
|
|
|
cmp byte[PauseFrameMode],1
|
|
jne .nopauseframemode1
|
|
mov [tempedx],edx
|
|
mov [tempesi],esi
|
|
mov [tempedi],edi
|
|
mov [tempebp],ebp
|
|
pushad
|
|
call BackupPauseFrame
|
|
popad
|
|
.nopauseframemode1
|
|
|
|
call ProcessRewind
|
|
|
|
cmp byte[PauseFrameMode],2
|
|
jne .nopauseframemode2
|
|
mov byte[PauseFrameMode],3
|
|
jmp .noprocmovie
|
|
.nopauseframemode2
|
|
|
|
cmp byte[INCRFrame],1
|
|
jne .noframeincr
|
|
xor byte[INCRFrame],1
|
|
jmp .noemupause
|
|
.noframeincr
|
|
|
|
;Update screen - DISABLED FOR NOW
|
|
pushad
|
|
;call StartDrawNewGfx
|
|
;call showvideo
|
|
;call cachevideo
|
|
popad
|
|
|
|
jmp .nonewgfx
|
|
.noemupause
|
|
|
|
;Rewind update must be done before process this frame of movie, so rewind doesn't
|
|
;back up incremented values (some vars being for the next frame)
|
|
call UpdateRewind
|
|
|
|
cmp byte[MovieProcessing],0
|
|
je .noprocmovie
|
|
pushad
|
|
call ProcessMovies
|
|
popad
|
|
cmp byte[GUIReset],1
|
|
jne .notreset
|
|
mov byte[MovieWaiting],1
|
|
mov eax,[KeyQuickRst]
|
|
mov byte[pressed+eax],01h
|
|
jmp near exitloop
|
|
.notreset
|
|
cmp byte[MovieProcessing],0
|
|
jne .noprocmovie
|
|
cmp byte[ZMVZClose],1
|
|
jne .noprocmovie
|
|
jmp DosExit
|
|
.noprocmovie
|
|
|
|
cmp byte[snesmouse],5
|
|
jne .nolethalen
|
|
mov eax,[LethEnData]
|
|
mov [JoyBNow],eax
|
|
.nolethalen
|
|
|
|
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
|
|
.dis65816
|
|
cmp byte[CheatOn],1
|
|
je near .cheater
|
|
.returncheat
|
|
mov ax,[VIRQLoc]
|
|
cmp word[curypos],ax
|
|
jne .novirqz
|
|
mov byte[doirqnext],1
|
|
.novirqz
|
|
mov ax,[oamaddrs]
|
|
mov [oamaddr],ax
|
|
mov byte[nosprincr],0
|
|
call showvideo
|
|
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
|
|
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]
|
|
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
|
|
jmp switchtonmi
|
|
.failcheck
|
|
mov byte[nmirept],0
|
|
mov dword[nmiprevaddrl],0FFFFFFFFh
|
|
mov dword[nmiprevaddrh],0
|
|
mov byte[doirqnext],0
|
|
jmp switchtonmi
|
|
.nonmi
|
|
cmp byte[intrset],1
|
|
jne .nointrset2w
|
|
mov byte[intrset],2
|
|
.nointrset2w
|
|
xor ebx,ebx
|
|
xor ecx,ecx
|
|
mov bl,[esi]
|
|
inc esi
|
|
jmp execloop.startagain
|
|
|
|
|
|
.overy
|
|
sub dh,110
|
|
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
|
|
xor byte[ppustatus],80h
|
|
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 starthdma
|
|
.noirqhack
|
|
; check for VIRQ/HIRQ/NMI
|
|
ProcessIRQStuff
|
|
xor ebx,ebx
|
|
mov bl,[esi]
|
|
inc esi
|
|
jmp execloop.startagain
|
|
|
|
.virq
|
|
test byte[curexecstate],01h
|
|
jnz .dis658162
|
|
or byte[curexecstate],01h
|
|
.dis658162
|
|
mov byte[doirqnext],0
|
|
xor ebx,ebx
|
|
mov ax,[resolutn]
|
|
cmp word[curypos],ax
|
|
jnb .nodrawline
|
|
cmp byte[hdmadelay],1
|
|
jne .virqstuff
|
|
.virqstuff
|
|
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
|
|
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 [.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
|
|
|
|
SECTION .bss
|
|
.numcheat resb 1
|
|
SECTION .text
|
|
|
|
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 [FxTable+4Ch*4],eax
|
|
mov [FxTableb+4Ch*4],eax
|
|
mov [FxTablec+4Ch*4],eax
|
|
mov [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 [FxTable+4Ch*4],eax
|
|
mov [FxTableb+4Ch*4],eax
|
|
mov [FxTablec+4Ch*4],eax
|
|
mov [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 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
|
|
mov ax,[totlines]
|
|
cmp word[curypos],ax
|
|
jae 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
|
|
mov byte[irqon],80h
|
|
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
|
|
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
|
|
sub dh,110
|
|
mov word[curypos],0
|
|
xor byte[ppustatus],80h
|
|
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
|
|
jmp switchtovirqdeb
|