execute.asm

来自「linux下的任天堂模拟器代码。供大家参考。」· 汇编 代码 · 共 2,207 行 · 第 1/3 页

ASM
2,207
字号
;Copyright (C) 1997-2007 ZSNES Team ( zsKnight, _Demo_, pagefault, Nach );;http://www.zsnes.com;http://sourceforge.net/projects/zsnes;https://zsnes.bountysource.com;;This program is free software; you can redistribute it and/or;modify it under the terms of the GNU General Public License;version 2 as published by the Free Software Foundation.;;This program is distributed in the hope that it will be useful,;but WITHOUT ANY WARRANTY; without even the implied warranty of;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the;GNU General Public License for more details.;;You should have received a copy of the GNU General Public License;along with this program; if not, write to the Free Software;Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.%include "macros.mac"EXTSYM KeyRewind,statesaver,Voice0Status,UpdateDPageEXTSYM StartGUI,romdata,initvideo,DosExit,sfxramdata,deinitvideoEXTSYM vidbufferofsa,device2,RawDumpInProgressEXTSYM KeySaveState,KeyLoadState,KeyQuickExit,KeyQuickLoad,KeyQuickRstEXTSYM GUIDoReset,GUIReset,KeyOnStA,KeyOnStB,ProcessKeyOn,C4Enable,KeyQuickClockEXTSYM KeyQuickSaveSPC,TimerEnable,splitflags,joinflagsEXTSYM KeyQuickSnapShot,csounddisable,videotroub,ResetTripleBufEXTSYM InitPreGame,Curtableaddr,curcyc,debugdisble,dmadata,guioff,memtabler8EXTSYM SetupPreGame,memtablew8,regaccessbankr8,showmenu,snesmap2,snesmmapEXTSYM DeInitPostGame,spcPCRam,xp,xpb,xpc,tableadEXTSYM tableadc,SA1UpdateDPage,Makemode7Table,nextmenupopup,MovieProcessingEXTSYM SFXEnable,wramdata,cycpbl,cycpblt,irqon,spconEXTSYM multchange,romispal,scrndis,sprlefttot,sprleftpr,processspritesEXTSYM cachesprites,opcjmptab,CheatOn,Output_Text,Check_Key,Get_Key,EXTSYM INTEnab,JoyCRead,NMIEnab,NumCheats,CurrentExecSA1,ReadInputDeviceEXTSYM StartDrawNewGfx,VIRQLoc,cachevideo,cfield,cheatdata,curblank,curnmiEXTSYM curypos,cycpl,doirqnext,drawline,exechdma,hdmadelay,intrset,newengenEXTSYM oamaddr,oamaddrs,resolutn,showvideo,starthdma,switchtonmiEXTSYM switchtovirq,totlines,updatetimer,SA1Swap,SA1DoIRQ,JoyAOrig,JoyANowEXTSYM JoyBOrig,JoyBNow,JoyCOrig,JoyCNow,JoyDOrig,JoyDNow,JoyEOrig,JoyENowEXTSYM SA1Message,MultiTapStat,idledetectspc,SA1Control,SA1Enable,SA1IRQEnableEXTSYM SPC700read,SPC700write,numspcvblleft,spc700idle,SA1IRQExec,ForceNewGfxOffEXTSYM LethEnData,GUIQuit,IRAM,SA1Ptr,SA1BWPtr,outofmemfixEXTSYM yesoutofmemory,ProcessMovies,MovieStop,ppustatus,C4VBlankEXTSYM ReturnFromSPCStall,scanlines,MainLoop,MoviePassWaiting,MovieDumpRawEXTSYM NumberOfOpcodes,SfxCLSR,SfxSCMR,SfxPOR,sfx128lineloc,sfx160linelocEXTSYM sfx192lineloc,sfxobjlineloc,sfxclineloc,PLOTJmpa,PLOTJmpb,FxTableEXTSYM FxTableb,FxTablec,FxTabled,SfxPBR,SCBRrel,SfxSCBR,SfxCOLR,SFXCounterEXTSYM fxbit01,fxbit01pcal,fxbit23,fxbit23pcal,fxbit45,fxbit45pcal,fxbit67EXTSYM fxbit67pcal,SfxSFR,nosprincr,cpucycle,switchtovirqdeb,switchtonmidebEXTSYM MovieSeekBehind,BackupCVFrame,RestoreCVFrame,loadstateEXTSYM KeyInsrtChap,KeyNextChap,KeyPrevChap,MovieInsertChapter,MovieSeekAheadEXTSYM ResetDuringMovie,EMUPauseKey,INCRFrameKey,MovieWaiting,NoInputReadEXTSYM AllocatedRewindStates,PauseFrameMode,RestorePauseFrame,BackupPauseFrame%ifndef NO_DEBUGGEREXTSYM debuggeron,startdebugger%endif%ifdef __MSDOS__EXTSYM dssel,Game60hzcall,NextLineStart,FlipWait,LastLineStart,smallscreenon,ScreenScaleEXTSYM cvidmode,GUI16VID,ScreenShotFormat%endifSECTION .dataNEWSYM tempedx, dd 0NEWSYM tempesi, dd 0NEWSYM tempedi, dd 0NEWSYM tempebp, dd 0NEWSYM RewindTimer, dd 0NEWSYM BackState, db 1NEWSYM BackStateSize, dd 6NEWSYM DblRewTimer, dd 0SECTION .textNEWSYM 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    call UpdateDPage    mov esi,[tempesi]    mov edi,[tempedi]    mov ebp,[tempebp]    mov edx,[tempedx].notokay    retNEWSYM UpdateRewind    cmp byte[AllocatedRewindStates],0    je .norewinds    cmp dword[KeyRewind],0    je .norewinds    dec dword[DblRewTimer]    dec dword[RewindTimer]    jnz .checkrewind    mov [tempedx],edx    mov [tempesi],esi    mov [tempedi],edi    mov [tempebp],ebp    pushad    call BackupCVFrame    popad.checkrewind    call ProcessRewind    call UpdateDPage.norewinds    retSECTION .dataNEWSYM MuteVoiceF, dd 0SECTION .textVoiceEndMute:    mov byte[MuteVoiceF],0    ret%macro StartMute 1    mov al,[Voice0Status+%1]    or al,al    jz %%notmuted    or byte[MuteVoiceF],1 << %1%%notmuted%endmacroVoiceStartMute:    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    test dl,04h    jnz %%virqdo    cmp byte[doirqnext],1    je near .virq%%virqdo    test byte[INTEnab],20h    jz near %%novirq    mov ax,[VIRQLoc]    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    mov byte[doirqnext],1    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 executedSECTION .dataNEWSYM romloadskip, db 0NEWSYM SSKeyPressed, dd 0NEWSYM SPCKeyPressed, dd 0NEWSYM NoSoundReinit, dd 0NEWSYM NextNGDisplay, db 0NEWSYM TempVidInfo, dd 0NEWSYM tempdh, db 0SECTION .text; this wonderful mess starts up the CPU and initialized the emulation stateNEWSYM 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 StartGUINEWSYM 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%ifndef NO_DEBUGGER    mov byte[debuggeron],0%endif    mov byte[exiter],0    call InitPreGame    jmp reexecuteNEWSYM continueprognokeys    mov byte[romloadskip],0%ifndef NO_DEBUGGER    mov byte[debuggeron],0%endif    mov byte[exiter],0    call InitPreGame    jmp reexecuteb2; IncorrectNEWSYM reexecuteb%ifndef __MSDOS__    jmp reexecuteb2%endifNEWSYM 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 .loopareexecuteb2:    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    mov edi,[tableadc+ebx*4]    or byte[curexecstate],2    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    ;Multipass Movies    cmp byte[MoviePassWaiting],1    jne .nomoviepasswaiting    pushad    call MovieDumpRaw    popad    jmp continueprog.nomoviepasswaiting    ; 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%ifndef NO_DEBUGGER   cmp byte[debugdisble],0    jne .nodebugger    test byte[pressed+59],1    jne near startdebugger.nodebugger%endif    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 StartGUINEWSYM endprog    call deinitvideo    pushad    call MovieStop    popad    jmp DosExitNEWSYM interror    stim    call deinitvideo    mov edx,.nohand         ;use extended    mov ah,9                ;DOS- API    call Output_Text                 ;to print a string    jmp DosExitSECTION .data.nohand db 'Cannot process interrupt handler!',13,10,0; global variablesNEWSYM invalid, db 0NEWSYM invopcd, db 0NEWSYM pressed, times 256+128+64 db 0          ; keyboard pressed keys in scancodeNEWSYM exiter, db 0NEWSYM oldhand9o, dd 0NEWSYM oldhand9s, dw 0NEWSYM oldhand8o, dd 0NEWSYM oldhand8s, dw 0NEWSYM opcd,      dd 0NEWSYM pdh,       dd 0NEWSYM pcury,     dd 0NEWSYM timercount, dd 0NEWSYM initaddrl, dd 0                  ; initial address locationNEWSYM NetSent, dd 0NEWSYM nextframe, dd 0                  ; tick count for timerNEWSYM 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',0NEWSYM HIRQCycNext,   dd 0NEWSYM HIRQNextExe,   db 0SECTION .text;*******************************************************; Int 08h vector;*******************************************************; sets to either 60Hz or 50Hz depending on PAL/NTSCNEWSYM 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    retNEWSYM 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%endifSECTION .dataNEWSYM timeradj, dd 65536NEWSYM t1cc, dw 0SECTION .text;*******************************************************; Int 09h vector;*******************************************************%ifdef __MSDOS__SECTION .bssNEWSYM skipnextkey42, resb 1SECTION .textNEWSYM 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%endifSECTION .dataALIGN32NEWSYM soundcycleft, dd 0NEWSYM curexecstate, dd 0NEWSYM nmiprevaddrl, dd 0       ; observed address -5NEWSYM nmiprevaddrh, dd 0       ; observed address +5NEWSYM nmirept,      dd 0       ; NMI repeat check, if 6 then okayNEWSYM nmiprevline,  dd 224     ; previous lineNEWSYM nmistatus,    dd 0       ; 0 = none, 1 = waiting for nmi location,                        ; 2 = found, disable at next lineNEWSYM joycontren,   dd 0       ; joystick read control checkNEWSYM NextLineCache, db 0NEWSYM ZMVZClose, db 0SECTION .textDonextlinecache:    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;*******************************************************

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?