From 29637130ff383c164f2c1f43f5e54fa221af7534 Mon Sep 17 00:00:00 2001 From: pagefault <> Date: Thu, 23 Mar 2006 20:45:51 +0000 Subject: [PATCH] Import of ManyMouse library --- zsnes/src/Makefile.in | 7 +- zsnes/src/init.asm | 5187 +++++++++++++------------- zsnes/src/linux_evdev.c | 337 ++ zsnes/src/manymouse.c | 92 + zsnes/src/manymouse.h | 61 + zsnes/src/uic.c | 884 ++--- zsnes/src/video/procvid.asm | 6882 ++++++++++++++++++----------------- zsnes/src/windows_wminput.c | 734 ++++ 8 files changed, 7745 insertions(+), 6439 deletions(-) create mode 100644 zsnes/src/linux_evdev.c create mode 100644 zsnes/src/manymouse.c create mode 100644 zsnes/src/manymouse.h create mode 100644 zsnes/src/windows_wminput.c diff --git a/zsnes/src/Makefile.in b/zsnes/src/Makefile.in index e02572a5..02dbaf8e 100644 --- a/zsnes/src/Makefile.in +++ b/zsnes/src/Makefile.in @@ -51,10 +51,11 @@ JMAOBJ=${JMADIR}/7zlzma.o ${JMADIR}/crc32.o ${JMADIR}/iiostrm.o\ ${JMADIR}/winout.o ${JMADIR}/zsnesjma.o MAINOBJ=cfgload.o cfg.o endmem.o init.o initc.o md.o uic.o patch.o ui.o\ - vcache.o version.o zmovie.o zstate.o debug.o zloader.o + vcache.o version.o zmovie.o zstate.o debug.o zloader.o manymouse.o\ + linux_evdev.o NETOBJ= -#${NETDIR}/ztcp.o +#${NETDIR}/ztcp.os TOOLSOBJ=${TOOLSDIR}/fileutil.o ${TOOLSDIR}/strutil.o @@ -154,6 +155,8 @@ version.o: version.c zloader.o: zloader.c gblhdr.h zmovie.o: zmovie.c asm_call.h gblhdr.h gblvars.h numconv.h ${WINDIR}/safelib.h md.o zstate.o: zstate.c asm_call.h gblhdr.h gblvars.h numconv.h +manymouse.o: manymouse.c +linux_evdev.o: linux_evdev.c ${CHIPDIR}/c4emu.o: ${CHIPDIR}/c4emu.c gblhdr.h ${CHIPDIR}/dsp1emu.o: ${CHIPDIR}/dsp1emu.c gblhdr.h diff --git a/zsnes/src/init.asm b/zsnes/src/init.asm index 0314c974..30405c29 100644 --- a/zsnes/src/init.asm +++ b/zsnes/src/init.asm @@ -1,2588 +1,2599 @@ -;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 DosExit,UpdateDevices,Makemode7Table,MusicRelVol,MusicVol,makesprprtable -EXTSYM romloadskip,start65816,startdebugger,SfxR0,showinfogui,inittable -EXTSYM SA1inittable,MessageOn,Msgptr,MsgCount,sndrot,SnowTimer,inittableb -EXTSYM inittablec,newgfx16b,cfgreinittime,Open_File,Read_File,Write_File -EXTSYM Close_File,Output_Text,Change_Dir,Create_File,SPCDisable,osm2dis -EXTSYM BackupSystemVars,SnowData,SnowVelDist,cvidmode,newengen,cfgnewgfx -EXTSYM GUI16VID,NewEngEnForce,TextFile,Setper2exec,JoyRead,pressed,pl3Ak,pl3Bk -EXTSYM pl3Lk,pl3Rk,pl3Xk,pl3Yk,pl3contrl,pl3downk,pl3leftk,pl3rightk,pl3selk -EXTSYM pl3startk,pl3upk,pl4Ak,pl4Bk,pl4Lk,pl4Rk,pl4Xk,pl4Yk,pl4contrl,pl4downk -EXTSYM pl4leftk,pl4rightk,pl4selk,pl4startk,pl4upk,mousebuttons,mousexdir,pl5Ak -EXTSYM pl5Bk,pl5Lk,pl5Rk,pl5Xk,pl5Yk,pl5contrl,pl5downk,pl5leftk,pl5rightk -EXTSYM pl5selk,pl5startk,pl5upk,mouseydir,mousexpos,mouseypos,snesmouse,sram -EXTSYM processmouse,ssautosw,GUIDelayB,pl12s34,pl1Xtk,pl1Ytk,pl1Atk,pl1Btk -EXTSYM pl2Xtk,pl2Ytk,pl2Atk,pl2Btk,pl3Xtk,pl3Ytk,pl3Atk,pl3Btk,pl4Xtk,pl4Ytk -EXTSYM pl4Atk,pl4Btk,pl1ULk,pl1URk,pl1DLk,pl1DRk,pl2ULk,pl2URk,pl2DLk,pl2DRk -EXTSYM pl3ULk,pl3URk,pl3DLk,pl3DRk,pl4ULk,pl4URk,pl4DLk,pl4DRk,pl5ULk,pl5URk -EXTSYM pl5DLk,pl5DRk,pl5Xtk,pl5Ytk,pl5Atk,pl5Btk,pl1Ltk,pl1Rtk,pl2Ltk,pl2Rtk -EXTSYM pl3Ltk,pl3Rtk,pl4Ltk,pl4Rtk,pl5Ltk,pl5Rtk,Turbo30hz,NumComboLocl -EXTSYM ComboBlHeader,ComboHeader,CombinDataLocl,CombinDataGlob,NumCombo -EXTSYM GUIComboGameSpec,mousexloc,mouseyloc,extlatch,FIRTAPVal0,FIRTAPVal1 -EXTSYM FIRTAPVal2,FIRTAPVal3,FIRTAPVal4,FIRTAPVal5,FIRTAPVal6,FIRTAPVal7,INTEnab -EXTSYM JoyAPos,JoyBPos,NMIEnab,SPCROM,VIRQLoc,coladdb,coladdg,coladdr,doirqnext -EXTSYM forceblnk,nmiprevaddrh,nmiprevaddrl,nmiprevline,nmirept,nmistatus -EXTSYM opexec268,opexec268b,opexec268cph,opexec268cphb,opexec358,opexec358b -EXTSYM opexec358cph,spcextraram,opexec358cphb,prevoamptr,reg1read,reg2read -EXTSYM reg3read,reg4read,resolutn,romdata,scrndis,spcP,SPCRAM,spcnumread -EXTSYM tableD,timeron,vidbright,SPC700read,SPC700write,spc700read -EXTSYM GUIReset,InitC4,SA1Reset,SetAddressingModesSA1,SDD1BankA,SPC7110init -EXTSYM RTCinit,InitOBC,memaccessspc7110r8,memaccessspc7110r16,memaccessspc7110w8 -EXTSYM memaccessspc7110w16,ram7f,snesmap2,snesmmap,MultiTap,memaccessbankr848mb -EXTSYM memaccessbankr1648mb,procexecloop,ram7fa,wramdata,wramdataa,fname,fnames -EXTSYM GetCurDir,SRAMChdir,cfgloadsdir,fnamest,statefileloc,InitDir,InitDrive -EXTSYM curromspace,infoloc,patchfile,romispal,initregr,initregw,memtabler16 -EXTSYM memtabler8,memtablew16,memtablew8,sfxramdata,wramreadptr -EXTSYM wramwriteptr,loadstate2,CMovieExt,MoviePlay,MovieDumpRaw,AllowUDLR - -;initc.c -EXTSYM clearmem,clearSPCRAM,PatchUsingIPS,ZOpenFileName,loadROM,SPC7110IndexSize -EXTSYM SPC7PackIndexLoad,IntlEHi,C4Enable,SPC7110Enable,RTCEnable,SA1Enable -EXTSYM SDD1Enable,OBCEnable,SFXEnable,BSEnable,clearvidsound,headerhack,SetupROM - -%ifdef __UNIXSDL__ -EXTSYM LoadDir,popdir,pushdir -%endif - -; Initiation - -SECTION .data -NEWSYM regsbackup, times 3019 db 0 -NEWSYM forceromtype, db 0 -NEWSYM loadedfromgui, db 0 -NEWSYM SnowOn, db 0 -NEWSYM bgfixer, db 0 -NEWSYM bgfixer2, db 0 -NEWSYM ReInitLength, dd 0 -NEWSYM ForceNewGfxOff, dd 0 -NEWSYM SfxAC, db 0 -blah times 450 db 0 -; FIX STATMAT -NEWSYM autoloadstate, db 0 ; auto load state slot number -NEWSYM autoloadmovie, db 0 -NEWSYM ZMVRawDump, db 0 - -NEWSYM EndMessage - db ' ',13,10,0 - -SECTION .text - -EXTSYM cpalval -NEWSYM init - ; prevents a crash if cpalval gets accessed before initializing - mov eax,cpalval - mov ecx,256 -.looppal - mov dword[eax],cpalval - add eax,4 - dec ecx - jnz .looppal - - ; Initialize snow stuff - mov ecx,400 - xor edx,edx -.snowloop - shl word[SnowData+edx*2],8 - and byte[SnowVelDist+edx],0F7h - cmp dword[SnowTimer],0 - jne .skip - or byte[SnowVelDist+edx],08h -.skip - inc edx - dec ecx - jnz .snowloop - - pushad - call BackupSystemVars - popad - - xor eax,eax - mov al,[cfgreinittime] - mov ebx,50 - mul ebx - mov [ReInitLength],eax - - xor eax,eax - mov al,[romtype] - mov [forceromtype],al - mov byte[romtype],0 - mov ax,ds - mov es,ax - mov eax,regsbackup - mov ebx,sndrot - mov ecx,3019 -.rbackupl - mov dl,[ebx] - mov [eax],dl - inc ebx - inc eax - dec ecx - jnz .rbackupl - mov byte[virqnodisable],0 - pushad - call clearmem - popad - call inittable - call inittableb - call inittablec - call SA1inittable - ; SPC Init - pushad - call procexecloop - popad - ; SNES Init - pushad - call Setper2exec - popad - call Makemode7Table - call makesprprtable - cmp byte[fname],0 - jne .found - cmp byte[romloadskip],1 - je .noloadfile -.found - mov byte[romloadskip],0 - call loadfile - pushad - call SetupROM - call showinfogui - popad -.noloadfile - call UpdateDevices - call init65816 - call initregr - call initregw - call initsnes - - ; Initialize volume - xor eax,eax - xor edx,edx - mov al,[MusicRelVol] - shl eax,7 - mov ebx,0A3D70A3Dh - mul ebx - shr edx,6 - cmp dl,127 - jb .noof - mov dl,127 -.noof - mov [MusicVol],dl - -; FIX STATMAT - ; Here's the auto-load ZST file stuff - cmp byte[autoloadstate],1 - jl .noautoloadstate - je .enddigits - mov ebx,[statefileloc] - sub byte[autoloadstate],1 - cmp byte[autoloadstate],10 - jge .2digits - mov al,[autoloadstate] - add al,48 - mov [fnamest+ebx],al - jmp .enddigits -.2digits - xor eax,eax - mov al,[autoloadstate] - mov dl,10 - div dl - add al,48 - add ah,48 - mov [fnamest+ebx-1],al - mov [fnamest+ebx],ah -.enddigits - - ; Load the specified state file - pushad - call loadstate2 - popad - - ; Just skip the extension re-setup below if we don't need to do it - cmp byte[autoloadstate],9 - jbe .noautoloadstate - - ; Put back the 'ST' on the end of the extension as we changed it - ; above (by placing two digits in the extension). This is so - ; as not to break any other code later on which depends - ; on it being present. - mov ebx,[statefileloc] -%ifdef __UNIXSDL__ - mov word[fnamest+ebx-1],'st' -%else - mov word[fnamest+ebx-1],'ST' -%endif - -.noautoloadstate - - cmp byte[autoloadmovie],1 - jb .noautloadmovie - cmp byte[autoloadmovie],10 - ja .noautloadmovie - mov al,[autoloadmovie] - add al,'0'-1 - cmp al,'0' - jne .notzero1 - mov al,'v' -.notzero1 - mov [CMovieExt],al - - pushad - cmp byte[ZMVRawDump],1 - jne .norawdump - call MovieDumpRaw - jmp .aftermovieplay -.norawdump - call MoviePlay -.aftermovieplay - popad - -.noautloadmovie - - xor eax,eax - mov al,[cvidmode] - cmp byte[GUI16VID+eax],1 - je .yes16b - mov byte[newengen],1 - mov byte[cfgnewgfx],1 -.yes16b - cmp byte[NewEngEnForce],1 - jne .noforce - mov byte[NewEngEnForce],0 - mov byte[newengen],1 - mov byte[cfgnewgfx],1 -.noforce - mov ebx,ebm - mov eax,EndMessage - mov dh,17h - mov ch,67 - mov cl,1 -.loopen - mov dl,[ebx] - rol dl,cl - xor dl,dh - mov [eax],dl - rol dh,1 - inc cl - or cl,cl - jne .notzero - inc cl -.notzero - and cl,07h - inc eax - inc ebx - dec ch - jnz .loopen - - cmp byte[yesoutofmemory],1 - jne .noout - call outofmemfix -.noout - cmp byte[debugger],0 - je near start65816 - cmp byte[romloadskip],1 - je near start65816 - jmp startdebugger - -EndMessageB - -; global variables - -SECTION .data - -; Controls -;FIXME: define pl3contrl, pl4contrl and pl5contrl here? -;Christophe 2001/03/10 -NEWSYM numjoy, db 0 ; number of joysticks (1 = 1, 2 = 2) -; 0 = Disable, 1 = Keyboard, 2 = Joystick, 3 = Gamepad -; 4 = 4-button 5 = 6-button 6 = sidewinder -NEWSYM pl1contrl, db 1 ; player 1 device -NEWSYM pl1keya, dd 0 -NEWSYM pl1keyb, dd 0 -%ifdef __MSDOS__ -NEWSYM pl1selk, dd 54 -NEWSYM pl1startk, dd 28 -NEWSYM pl1upk, dd 72 -NEWSYM pl1downk, dd 80 -NEWSYM pl1leftk, dd 75 -NEWSYM pl1rightk, dd 77 -%else -NEWSYM pl1selk, dd 54 -NEWSYM pl1startk, dd 28 -NEWSYM pl1upk, dd 200 -NEWSYM pl1downk, dd 208 -NEWSYM pl1leftk, dd 203 -NEWSYM pl1rightk, dd 205 -%endif -NEWSYM pl1Xk, dd 31 -NEWSYM pl1Ak, dd 45 -NEWSYM pl1Lk, dd 32 -NEWSYM pl1Yk, dd 30 -NEWSYM pl1Bk, dd 44 -NEWSYM pl1Rk, dd 46 -NEWSYM pl2contrl, db 0 ; player 2 device -NEWSYM pl2keya, dd 0 -NEWSYM pl2keyb, dd 0 -NEWSYM pl2selk, dd 27 -NEWSYM pl2startk, dd 26 -NEWSYM pl2upk, dd 199 -NEWSYM pl2downk, dd 207 -NEWSYM pl2leftk, dd 211 -NEWSYM pl2rightk, dd 209 -NEWSYM pl2Xk, dd 24 -NEWSYM pl2Ak, dd 25 -NEWSYM pl2Lk, dd 23 -NEWSYM pl2Yk, dd 37 -NEWSYM pl2Bk, dd 38 -NEWSYM pl2Rk, dd 36 -NEWSYM JoyStart, db 0 -NEWSYM JoySelec, db 0 -NEWSYM JoyBC, db 1 -NEWSYM JoyYC, db 3 -NEWSYM JoyAC, db 2 -NEWSYM JoyXC, db 4 -NEWSYM JoyLC, db 5 -NEWSYM JoyRC, db 6 -NEWSYM TurboSw, db 0 - -NEWSYM romtype, db 0 ; ROM type in bytes -NEWSYM resetv, dw 0 ; reset vector -NEWSYM abortv, dw 0 ; abort vector -NEWSYM nmiv2, dw 0 ; nmi vector -NEWSYM nmiv, dw 0 ; nmi vector -NEWSYM irqv, dw 0 ; irq vector -NEWSYM irqv2, dw 0 ; irq vector -NEWSYM brkv, dw 0 ; brk vector -NEWSYM copv, dw 0 ; cop vector -NEWSYM abortv8, dw 0 ; abort vector emulation mode -NEWSYM nmiv8, dw 0 ; nmi vector emulation mode -NEWSYM irqv8, dw 0 ; irq vector emulation mode -NEWSYM brkv8, dw 0 ; brk vector emulation mode -NEWSYM copv8, dw 0 ; cop vector emulation mode -NEWSYM cycpb268, db 109 ; 110 -NEWSYM cycpb358, db 149 ; 155 -NEWSYM cycpbl2, db 109 ; percentage left of CPU/SPC to run (3.58 = 175) -NEWSYM cycpblt2, db 149 ; percentage of CPU/SPC to run -NEWSYM writeon, db 0 ; Write enable/disable on snes rom memory -NEWSYM totlines, dw 263 ; total # of lines -NEWSYM soundon, db 0 ; Current sound enabled (1=enabled) - -;This is saved in states -NEWSYM curcyc, db 0 ; cycles left in scanline -NEWSYM curypos, dw 0 ; current y position -NEWSYM cacheud, db 1 ; update cache every ? frames -NEWSYM ccud, db 0 ; current cache increment -NEWSYM intrset, db 0 ; interrupt set -NEWSYM cycpl, db 0 ; cycles per scanline -NEWSYM cycphb, db 0 ; cycles per hblank -NEWSYM spcon, db 0 ; SPC Enable (1=enabled) -NEWSYM stackand,dw 01FFh; value to and stack to keep it from going to the wrong area -NEWSYM stackor, dw 0100h; value to or stack to keep it from going to the wrong area - -; 65816 registers - -NEWSYM xat, dw 0 -NEWSYM xdbt, db 0 -NEWSYM xpbt, db 0 -NEWSYM xst, dw 0 -NEWSYM xdt, dw 0 -NEWSYM xxt, dw 0 -NEWSYM xyt, dw 0 -NEWSYM xp, db 0 -NEWSYM xe, db 0 -NEWSYM xpc, dw 0 -NEWSYM xirqb, db 0 ; which bank the irqs start at -NEWSYM debugger, db 0 ; Start with debugger (1=yes,0=no) -NEWSYM Curtableaddr, dd 0 ; Current table address -NEWSYM curnmi, db 0 ; if in NMI(1) or not(0) -; pharos - equ hack *sigh* -n65816regsize equ $-curcyc - -ALIGN32 -NEWSYM cycpbl, dd 110 ; percentage left of CPU/SPC to run (3.58 = 175) -NEWSYM cycpblt, dd 110 ; percentage of CPU/SPC to run - -NEWSYM PH65816regsize, dd n65816regsize - -; SNES memory map ROM locations - -NEWSYM cpuoverptr, dd 0 ; pointer to cpuover -;snesmmap times 256 dd 0 ; addresses 8000-FFFF -;snesmap2 times 256 dd 0 ; addresses 0000-7FFF -;NEWSYM exeloopa, times 128 db 0 ; execloop should be stored here -;NEWSYM exeloopb, times 128 db 0 ; execloopns should be stored here -;NEWSYM exeloopc, times 128 db 0 ; execloops should be stored here -;NEWSYM exeloopd, times 128 db 0 ; execloopn should be stored here -;NEWSYM prevcrash, times 250 db 0 - - -ALIGN32 -NEWSYM xa, dd 0 -NEWSYM xdb, dd 0 -NEWSYM xpb, dd 0 -NEWSYM xs, dd 0 -NEWSYM xd, dd 0 -NEWSYM xx, dd 0 -NEWSYM xy, dd 0 -NEWSYM flagnz, dd 0 -NEWSYM flago, dd 0 -NEWSYM flagc, dd 0 -NEWSYM bankkp, dd 0 -NEWSYM Sflagnz, dd 0 -NEWSYM Sflago, dd 0 -NEWSYM Sflagc, dd 0 - -ebm db 166,95,66,223,17,11,103,180,156,68,108,120,138,55,203,205 - db 178,210,39,252,128,66,65,167,155,151,197,125,176,66,73,230 - db 61,210,7,137,152,110,203,241,50,89,70,29,176,42,99,167 - db 155,92,3,221,224,54,53,167,155,211,70,205,138,202,91,234 - db 178,80,229,13,10 - -SECTION .text - - -;******************************************************* -; Read Input Device Reads from Keyboard, etc. -;******************************************************* - -SECTION .bss -NEWSYM WhichSW, resb 1 -NEWSYM WhichGR, resb 1 -NEWSYM autofr, resb 1 -TurboCB resb 1 - -NEWSYM JoyAOrig, resd 1 -NEWSYM JoyBOrig, resd 1 -NEWSYM JoyCOrig, resd 1 -NEWSYM JoyDOrig, resd 1 -NEWSYM JoyEOrig, resd 1 -NEWSYM JoyANow, resd 1 -NEWSYM JoyBNow, resd 1 -NEWSYM JoyCNow, resd 1 -NEWSYM JoyDNow, resd 1 -NEWSYM JoyENow, resd 1 -NEWSYM PJoyAOrig, resd 1 -NEWSYM PJoyBOrig, resd 1 -NEWSYM PJoyCOrig, resd 1 -NEWSYM PJoyDOrig, resd 1 -NEWSYM PJoyEOrig, resd 1 -NEWSYM LethEnData, resd 1 -NEWSYM ComboCounter, resb 1 -SECTION .text - -%macro PlayerDeviceHelp 3 - mov eax,[%1] - cmp byte[pressed+eax],1 - jne %%no - or dword[%2],%3 -%%no -%endmacro - -%macro ProcSNESMouse 1 - test byte[mousebuttons],02h - jz %%n - or dword[%1],00000000100000000000000000000000b - mov al,1 -%%n - test byte[mousebuttons],01h - jz %%n2 - or dword[%1],00000000010000000000000000000000b -%%n2 - or dword[%1],00000000000000010000000000000000b - mov al,[mouseypos] - and al,7Fh - or byte[%1+1],al - mov al,[mousexpos] - and al,7Fh - or byte[%1],al - test byte[mouseydir],01h - jz %%n3 - or dword[%1],00000000000000001000000000000000b -%%n3 - test byte[mousexdir],01h - jz %%n4 - or dword[%1],00000000000000000000000010000000b -%%n4 -%endmacro - -%macro ProcessKeyComb 2 - cmp dword[NumCombo],0 - je near %%nocomb - mov eax,CombinDataGlob - cmp byte[GUIComboGameSpec],0 - je %%local - mov eax,CombinDataLocl -%%local - push ecx - push ebx - xor ebx,ebx - cmp byte[ComboProg+%1],0 - jne near %%progressing - test dword[%2],01000000h - jz %%noright - mov dword[CombDirSwap],0 -%%noright - test dword[%2],02000000h - jz %%noleft - mov dword[CombDirSwap],1 -%%noleft - mov ecx,[NumCombo] -%%loop - mov bx,[eax+62] - cmp byte[pressed+ebx],1 - jne %%nopress - cmp byte[eax+64],%1 - je %%startprogress -%%nopress - add eax,66 - dec ecx - jnz %%loop - jmp %%endcomb -%%startprogress - mov byte[pressed+ebx],2 - inc byte[ComboCounter] - mov byte[ComboProg+%1],1 - mov byte[ComboPtr+%1],0 - mov dword[PressComb+%1*4],0 - mov dword[HoldComb+%1*4],0 - mov dword[CombCont+%1*4],CombContDatN - cmp dword[CombDirSwap],0 - je %%NoSwapLeftRight - cmp byte[eax+65],0 - je %%NoSwapLeftRight - mov dword[CombCont+%1*4],CombContDatR -%%NoSwapLeftRight - add eax,20 - mov [StartComb+%1*4],eax -%%progressing - mov ecx,%1 - mov eax,[StartComb+%1*4] - call ProcessCombo - mov [StartComb+%1*4],eax - or ebx,ebx - jz %%proccomb - mov byte[ComboProg+%1],0 -%%proccomb - mov dword[%2],0 - mov eax,[HoldComb+%1*4] - or dword[%2],eax - mov eax,[PressComb+%1*4] - or dword[%2],eax -%%endcomb - pop ebx - pop ecx -%%nocomb -%endmacro - -ProcessCombo: - mov dword[KeyLPress],0 - cmp dword[CombDelay+ecx*4],0 - jne .delay -.nextsession - xor ebx,ebx - cmp byte[eax],0 - je .finish - mov bl,[eax] - cmp bl,37 - jb .keypress - cmp bl,48 - ja .finish - sub ebx,37 - shl ebx,2 - add ebx,CombTDelN - cmp byte[romispal],0 - je .ntsc - sub ebx,CombTDelN - add ebx,CombTDelP -.ntsc - mov ebx,[ebx] - mov [CombDelay+ecx*4],ebx - inc eax - inc byte[ComboPtr+ecx] - cmp byte[ComboPtr+ecx],42 - je .finish -.delay - dec dword[CombDelay+ecx*4] - xor ebx,ebx - ret -.finish - mov ebx,1 - ret -.keypress - cmp dword[KeyLPress],0 - jne .alreadyproc - mov dword[PressComb+ecx*4],0 - mov dword[KeyLPress],1 -.alreadyproc - dec ebx - cmp ebx,12 - jae .pressonly - shl ebx,2 - add ebx,[CombCont+ecx*4] - mov ebx,[ebx] - or [PressComb+ecx*4],ebx - jmp .finkeyproc -.pressonly - sub ebx,12 - cmp ebx,12 - jae .releaseonly - shl ebx,2 - add ebx,[CombCont+ecx*4] - mov ebx,[ebx] - or [HoldComb+ecx*4],ebx - jmp .finkeyproc -.releaseonly - sub ebx,12 ; <- bugfix from Maxim - shl ebx,2 - add ebx,[CombCont+ecx*4] - mov ebx,[ebx] - xor ebx,0FFFFFFFFh - and [HoldComb+ecx*4],ebx - and [PressComb+ecx*4],ebx ; <- buxfix from Maxim -.finkeyproc - inc eax - inc byte[ComboPtr+ecx] - cmp byte[ComboPtr+ecx],42 - je near .finish - jmp .nextsession - -SECTION .data -ComboProg times 5 db 0 -ComboPtr times 5 db 0 -KeyLPress dd 0 -CombDirSwap dd 0 -CombDelay times 5 dd 0 -StartComb times 5 dd 0 -HoldComb times 5 dd 0 -PressComb times 5 dd 0 -CombCont times 5 dd 0 -CombTDelN dd 1,2,3,4,5,9,30,60,120,180,240,300 -CombTDelP dd 1,2,3,4,5,9,25,50,100,150,200,250 -CombContDatN dd 08000000h,04000000h,02000000h,01000000h,00800000h,80000000h - dd 00400000h,40000000h,00200000h,00100000h,10000000h,20000000h -CombContDatR dd 08000000h,04000000h,01000000h,02000000h,00800000h,80000000h - dd 00400000h,40000000h,00200000h,00100000h,10000000h,20000000h -SECTION .text - -%macro PlayerDeviceFix 1 - cmp byte[AllowUDLR],1 - je %%noleftright - mov eax,[%1] - and eax,0C000000h - cmp eax,0C000000h - jne %%noupdown - and dword[%1],0F3FFFFFFh -%%noupdown - mov eax,[%1] - and eax,03000000h - cmp eax,03000000h - jne %%noleftright - and dword[%1],0FCFFFFFFh -%%noleftright -%endmacro - -NEWSYM ReadInputDevice - mov byte[WhichSW],1 - mov byte[WhichGR],0 - inc byte[TurboSw] - mov byte[TurboCB],01h - cmp byte[Turbo30hz],0 - je .noturbo30 - mov byte[TurboCB],02h -.noturbo30 - ; Read External Devices (Joystick, PPort, etc.) - call JoyRead - ; Process Data - mov dword[JoyAOrig],0 - ; Get Player1 input device - cmp byte[snesmouse],1 - jne .nomouse1 - call processmouse - ProcSNESMouse JoyAOrig - jmp .noinput1 -.nomouse1 - PlayerDeviceHelp pl1Bk ,JoyAOrig,80000000h - PlayerDeviceHelp pl1Yk ,JoyAOrig,40000000h - PlayerDeviceHelp pl1selk ,JoyAOrig,20000000h - PlayerDeviceHelp pl1startk,JoyAOrig,10000000h - PlayerDeviceHelp pl1upk ,JoyAOrig,08000000h - PlayerDeviceHelp pl1downk ,JoyAOrig,04000000h - PlayerDeviceHelp pl1leftk ,JoyAOrig,02000000h - PlayerDeviceHelp pl1rightk,JoyAOrig,01000000h - PlayerDeviceHelp pl1Ak ,JoyAOrig,00800000h - PlayerDeviceHelp pl1Xk ,JoyAOrig,00400000h - PlayerDeviceHelp pl1Lk ,JoyAOrig,00200000h - PlayerDeviceHelp pl1Rk ,JoyAOrig,00100000h - PlayerDeviceHelp pl1ULk ,JoyAOrig,0A000000h - PlayerDeviceHelp pl1URk ,JoyAOrig,09000000h - PlayerDeviceHelp pl1DLk ,JoyAOrig,06000000h - PlayerDeviceHelp pl1DRk ,JoyAOrig,05000000h - PlayerDeviceFix JoyAOrig - mov al,[TurboCB] - test byte[TurboSw],al - jnz near .noswitch - PlayerDeviceHelp pl1Xtk ,JoyAOrig,00400000h - PlayerDeviceHelp pl1Ytk ,JoyAOrig,40000000h - PlayerDeviceHelp pl1Atk ,JoyAOrig,00800000h - PlayerDeviceHelp pl1Btk ,JoyAOrig,80000000h - PlayerDeviceHelp pl1Ltk ,JoyAOrig,00200000h - PlayerDeviceHelp pl1Rtk ,JoyAOrig,00100000h -.noswitch - mov byte[ComboCounter],0 - ProcessKeyComb 0,JoyAOrig - or dword[JoyAOrig],00008000h ; Joystick Enable - cmp byte[GUIDelayB],0 - je .noinput1 - cmp byte[GUIDelayB],1 - jne .inputbd - test dword[JoyAOrig],80000000h - jnz .inputbdcb - dec byte[GUIDelayB] - jmp .noinput1 -.inputbd - dec byte[GUIDelayB] -.inputbdcb - and dword[JoyAOrig],7FFFFFFFh -.noinput1 - mov dword[JoyBOrig],0 - cmp byte[snesmouse],2 - jne .nomouse2 - call processmouse - ProcSNESMouse JoyBOrig - jmp .noinput2 -.nomouse2 - cmp byte[snesmouse],3 - jne .nosuperscope - call processmouse - mov byte[JoyBOrig+2],0FFh - mov al,[ssautosw] - test byte[mousebuttons],01h - jz .nobutton1 - or al,80h -.nobutton1 - cmp byte[pressed+14],0 - jz .nobutton3 - or al,10h -.nobutton3 - test byte[mousebuttons],02h - jz .nobutton4 - or al,40h -.nobutton4 - mov [JoyBOrig+3],al - jmp .noinput2 -.nosuperscope - cmp byte[snesmouse],4 - jne .nolethalen - call processmouse - mov eax,[romdata] - cmp dword[eax+1000h],0AD20C203h - jne .not - mov eax,[wramdata] - cmp byte[eax],26 - je .not - mov bl,[mousexloc] - mov [eax+40Ah],bl - mov bl,[mouseyloc] - mov [eax+40Eh],bl -.not -; mov word[JoyBOrig+2],000Eh -; and dword[LethEnData],0000000FFh -; or dword[LethEnData],055010000h -; inc byte[LethEnData] - test byte[LethEnData],1 - jz .n1 -; mov byte[LethEnData+2],8 - mov byte[extlatch],0 -.n1 - test byte[mousebuttons],01h - jz .nobutton1b -; or dword[LethEnData+2],10h - or byte[JoyAOrig+3],80h -.nobutton1b - cmp byte[pressed+14],0 - jz .nobutton3b -; or byte[LethEnData+2],40h -.nobutton3b - test byte[mousebuttons],02h - jz .nobutton4b -; or byte[LethEnData+2],40h - or byte[JoyAOrig+2],80h -.nobutton4b - jmp .noinput2 -.nolethalen - cmp byte[pl2contrl],0 - je near .noinput2 - ; Get Player2 input device - PlayerDeviceHelp pl2Bk ,JoyBOrig,80000000h - PlayerDeviceHelp pl2Yk ,JoyBOrig,40000000h - PlayerDeviceHelp pl2selk ,JoyBOrig,20000000h - PlayerDeviceHelp pl2startk,JoyBOrig,10000000h - PlayerDeviceHelp pl2upk ,JoyBOrig,08000000h - PlayerDeviceHelp pl2downk ,JoyBOrig,04000000h - PlayerDeviceHelp pl2leftk ,JoyBOrig,02000000h - PlayerDeviceHelp pl2rightk,JoyBOrig,01000000h - PlayerDeviceHelp pl2Ak ,JoyBOrig,00800000h - PlayerDeviceHelp pl2Xk ,JoyBOrig,00400000h - PlayerDeviceHelp pl2Lk ,JoyBOrig,00200000h - PlayerDeviceHelp pl2Rk ,JoyBOrig,00100000h - PlayerDeviceHelp pl2ULk ,JoyBOrig,0A000000h - PlayerDeviceHelp pl2URk ,JoyBOrig,09000000h - PlayerDeviceHelp pl2DLk ,JoyBOrig,06000000h - PlayerDeviceHelp pl2DRk ,JoyBOrig,05000000h - PlayerDeviceFix JoyBOrig - mov al,[TurboCB] - test byte[TurboSw],al - jnz near .noswitch2 - PlayerDeviceHelp pl2Xtk ,JoyBOrig,00400000h - PlayerDeviceHelp pl2Ytk ,JoyBOrig,40000000h - PlayerDeviceHelp pl2Atk ,JoyBOrig,00800000h - PlayerDeviceHelp pl2Btk ,JoyBOrig,80000000h - PlayerDeviceHelp pl2Ltk ,JoyBOrig,00200000h - PlayerDeviceHelp pl2Rtk ,JoyBOrig,00100000h -.noswitch2 - ProcessKeyComb 1,JoyBOrig - or dword[JoyBOrig],00008000h ; Joystick Enable -.noinput2 - mov dword[JoyCOrig],0 - cmp byte[pl3contrl],0 - je near .noinput3 - ; Get Player3 input device - PlayerDeviceHelp pl3Bk ,JoyCOrig,80000000h - PlayerDeviceHelp pl3Yk ,JoyCOrig,40000000h - PlayerDeviceHelp pl3selk ,JoyCOrig,20000000h - PlayerDeviceHelp pl3startk,JoyCOrig,10000000h - PlayerDeviceHelp pl3upk ,JoyCOrig,08000000h - PlayerDeviceHelp pl3downk ,JoyCOrig,04000000h - PlayerDeviceHelp pl3leftk ,JoyCOrig,02000000h - PlayerDeviceHelp pl3rightk,JoyCOrig,01000000h - PlayerDeviceHelp pl3Ak ,JoyCOrig,00800000h - PlayerDeviceHelp pl3Xk ,JoyCOrig,00400000h - PlayerDeviceHelp pl3Lk ,JoyCOrig,00200000h - PlayerDeviceHelp pl3Rk ,JoyCOrig,00100000h - PlayerDeviceHelp pl3ULk ,JoyCOrig,0A000000h - PlayerDeviceHelp pl3URk ,JoyCOrig,09000000h - PlayerDeviceHelp pl3DLk ,JoyCOrig,06000000h - PlayerDeviceHelp pl3DRk ,JoyCOrig,05000000h - PlayerDeviceFix JoyCOrig - mov al,[TurboCB] - test byte[TurboSw],al - jnz near .noswitch3 - PlayerDeviceHelp pl3Xtk ,JoyCOrig,00400000h - PlayerDeviceHelp pl3Ytk ,JoyCOrig,40000000h - PlayerDeviceHelp pl3Atk ,JoyCOrig,00800000h - PlayerDeviceHelp pl3Btk ,JoyCOrig,80000000h - PlayerDeviceHelp pl3Ltk ,JoyCOrig,00200000h - PlayerDeviceHelp pl3Rtk ,JoyCOrig,00100000h -.noswitch3 - ProcessKeyComb 2,JoyCOrig - or dword[JoyCOrig],00008000h ; Joystick Enable -.noinput3 - mov dword[JoyDOrig],0 - cmp byte[pl4contrl],0 - je near .noinput4 - ; Get Player4 input device - PlayerDeviceHelp pl4Bk ,JoyDOrig,80000000h - PlayerDeviceHelp pl4Yk ,JoyDOrig,40000000h - PlayerDeviceHelp pl4selk ,JoyDOrig,20000000h - PlayerDeviceHelp pl4startk,JoyDOrig,10000000h - PlayerDeviceHelp pl4upk ,JoyDOrig,08000000h - PlayerDeviceHelp pl4downk ,JoyDOrig,04000000h - PlayerDeviceHelp pl4leftk ,JoyDOrig,02000000h - PlayerDeviceHelp pl4rightk,JoyDOrig,01000000h - PlayerDeviceHelp pl4Ak ,JoyDOrig,00800000h - PlayerDeviceHelp pl4Xk ,JoyDOrig,00400000h - PlayerDeviceHelp pl4Lk ,JoyDOrig,00200000h - PlayerDeviceHelp pl4Rk ,JoyDOrig,00100000h - PlayerDeviceHelp pl4ULk ,JoyDOrig,0A000000h - PlayerDeviceHelp pl4URk ,JoyDOrig,09000000h - PlayerDeviceHelp pl4DLk ,JoyDOrig,06000000h - PlayerDeviceHelp pl4DRk ,JoyDOrig,05000000h - PlayerDeviceFix JoyDOrig - mov al,[TurboCB] - test byte[TurboSw],al - jnz near .noswitch4 - PlayerDeviceHelp pl4Xtk ,JoyDOrig,00400000h - PlayerDeviceHelp pl4Ytk ,JoyDOrig,40000000h - PlayerDeviceHelp pl4Atk ,JoyDOrig,00800000h - PlayerDeviceHelp pl4Btk ,JoyDOrig,80000000h - PlayerDeviceHelp pl4Ltk ,JoyDOrig,00200000h - PlayerDeviceHelp pl4Rtk ,JoyDOrig,00100000h -.noswitch4 - ProcessKeyComb 3,JoyDOrig - or dword[JoyDOrig],00008000h ; Joystick Enable -.noinput4 - mov dword[JoyEOrig],0 - cmp byte[pl5contrl],0 - je near .noinput5 - ; Get Player4 input device - PlayerDeviceHelp pl5Bk ,JoyEOrig,80000000h - PlayerDeviceHelp pl5Yk ,JoyEOrig,40000000h - PlayerDeviceHelp pl5selk ,JoyEOrig,20000000h - PlayerDeviceHelp pl5startk,JoyEOrig,10000000h - PlayerDeviceHelp pl5upk ,JoyEOrig,08000000h - PlayerDeviceHelp pl5downk ,JoyEOrig,04000000h - PlayerDeviceHelp pl5leftk ,JoyEOrig,02000000h - PlayerDeviceHelp pl5rightk,JoyEOrig,01000000h - PlayerDeviceHelp pl5Ak ,JoyEOrig,00800000h - PlayerDeviceHelp pl5Xk ,JoyEOrig,00400000h - PlayerDeviceHelp pl5Lk ,JoyEOrig,00200000h - PlayerDeviceHelp pl5Rk ,JoyEOrig,00100000h - PlayerDeviceHelp pl5ULk ,JoyEOrig,0A000000h - PlayerDeviceHelp pl5URk ,JoyEOrig,09000000h - PlayerDeviceHelp pl5DLk ,JoyEOrig,06000000h - PlayerDeviceHelp pl5DRk ,JoyEOrig,05000000h - PlayerDeviceFix JoyEOrig - mov al,[TurboCB] - test byte[TurboSw],al - jnz near .noswitch5 - PlayerDeviceHelp pl5Xtk ,JoyEOrig,00400000h - PlayerDeviceHelp pl5Ytk ,JoyEOrig,40000000h - PlayerDeviceHelp pl5Atk ,JoyEOrig,00800000h - PlayerDeviceHelp pl5Btk ,JoyEOrig,80000000h - PlayerDeviceHelp pl5Ltk ,JoyEOrig,00200000h - PlayerDeviceHelp pl5Rtk ,JoyEOrig,00100000h -.noswitch5 - ProcessKeyComb 4,JoyEOrig - or dword[JoyEOrig],00008000h ; Joystick Enable -.noinput5 - cmp byte[pl12s34],1 - je .pl1234 -.nopl1234 - ret -.pl1234 - cmp byte[snesmouse],4 - je .nopl1234 - cmp byte[snesmouse],1 - je .nopl13 - mov eax,[JoyCOrig] - or [JoyAOrig],eax -.nopl13 - cmp byte[snesmouse],2 - je .nopl24 - cmp byte[snesmouse],3 - je .nopl24 - mov eax,[JoyDOrig] - or [JoyBOrig],eax -.nopl24 - ret - -;******************************************************* -; Init 65816 Initializes the Registers -;******************************************************* - -SECTION .data -NEWSYM disablehdma, db 0 -NEWSYM disableeffects, db 0 -NEWSYM hdmaearlstart, db 0 -NEWSYM disable65816sh, db 0 -NEWSYM disablespcclr, db 0 -NEWSYM virqnodisable, db 0 -NEWSYM numspcvblleft, dd 0 -NEWSYM spc700idle, dd 0 -NEWSYM IRQHack, dw 0 -NEWSYM CacheCheckSkip, db 0 -NEWSYM HIRQSkip, db 0 -NEWSYM ClearScreenSkip, db 0 -NEWSYM ENVDisable, db 0 -SECTION .text - -NEWSYM idledetectspc - inc dword[numspcvblleft] - cmp byte[SPCStallSetting],2 - jae .fullstall - inc byte[SPCStallSetting] - mov byte[ReturnFromSPCStall],1 - ret -.fullstall - mov dword[spc700idle],29 - mov dword[Msgptr],.unableskip - mov eax,[MsgCount] - mov [MessageOn],eax - ret - -SECTION .data -.unableskip db 'SPC700 STALL DETECTED.',0 - -SECTION .bss -NEWSYM ReturnFromSPCStall, resb 1 -NEWSYM SPCStallSetting, resb 1 -NEWSYM SPCSkipXtraROM, resb 1 -NEWSYM WindowDisables, resd 1 -SECTION .text - -%macro helpclearmem 2 - mov edi,%1 - mov ecx,%2 - rep stosb -%endmacro - -NEWSYM init65816 - mov byte[osm2dis],0 - mov byte[bgfixer2],0 - cmp byte[SA1Enable],0 - je .nosa1init - call SA1Reset - pushad - call SetAddressingModesSA1 - popad -.nosa1init - cmp byte[OBCEnable],0 - je .noobcinit - call InitOBC -.noobcinit - cmp byte[C4Enable],0 - je .noc4init - mov byte[osm2dis],1 - mov byte[bgfixer2],1 - call InitC4 -.noc4init - cmp byte[RTCEnable],0 - je .noRTCinit - call RTCinit -.noRTCinit - cmp byte[SPC7110Enable],0 - je .nospc7110init - call SPC7110init - mov dword[memtabler8+50h*4],memaccessspc7110r8 - mov dword[memtabler16+50h*4],memaccessspc7110r16 - mov dword[memtablew8+50h*4],memaccessspc7110w8 - mov dword[memtablew16+50h*4],memaccessspc7110w16 - mov eax,[romdata] - add eax,510000h - mov [snesmmap+50h*4],eax - mov [snesmap2+50h*4],eax - mov ecx,16384 -.spc7110clear - mov dword[eax],0 - add eax,4 - dec ecx - jnz .spc7110clear -.nospc7110init - mov byte[cycpb268],117 - mov byte[cycpb358],127 - mov byte[cycpbl2],117 - mov byte[cycpblt2],117 - mov byte[cycpbl],117 - mov byte[cycpblt],117 - - mov byte[SPCSkipXtraROM],0 - cmp byte[ReturnFromSPCStall],1 - jne near .nostall - mov byte[cycpb268],69 - mov byte[cycpb358],81 - mov byte[cycpbl2],69 - mov byte[cycpblt2],69 - mov byte[cycpbl],69 - mov byte[cycpblt],69 - mov byte[SPCSkipXtraROM],1 - cmp byte[SPCStallSetting],2 - jne .nostall2 - mov byte[cycpb268],240 - mov byte[cycpb358],240 - mov byte[cycpbl],240 - mov byte[cycpblt],240 - mov byte[cycpbl2],240 - mov byte[cycpblt2],240 - mov byte[SPCSkipXtraROM],0 -.nostall2 - jmp .stalled -.nostall - mov byte[SPCStallSetting],0 -.stalled - mov dword[numspcvblleft],60*8 - mov dword[SPC700write],0 - mov dword[SPC700read],0 - cmp dword[spc700read],0 - mov dword[spc700idle],0 - xor esi,esi -.loopa - mov al,[SPCROM+esi] - mov byte[spcextraram+esi],0FFh - mov [SPCRAM+0FFC0h+esi],al - inc esi - cmp esi,040h - jne .loopa - - ; Clear SPC Memory - pushad - call clearSPCRAM - call clearvidsound - popad - - mov byte[prevoamptr],0FFh - mov byte[disablehdma],0 - mov byte[disableeffects],0 - mov al,[opexec268b] - mov [opexec268],al - mov al,[opexec358b] - mov [opexec358],al - mov al,[opexec268cphb] - mov [opexec268cph],al - mov al,[opexec358cphb] - mov [opexec358cph],al - - mov dword[FIRTAPVal0],7Fh - mov dword[FIRTAPVal1],0 - mov dword[FIRTAPVal2],0 - mov dword[FIRTAPVal3],0 - mov dword[FIRTAPVal4],0 - mov dword[FIRTAPVal5],0 - mov dword[FIRTAPVal6],0 - mov dword[FIRTAPVal7],0 - mov byte[disable65816sh],0 - - ; Check Headers - pushad - call headerhack - popad - - mov byte[SPCRAM+0F4h],0 - mov byte[SPCRAM+0F5h],0 - mov byte[SPCRAM+0F6h],0 - mov byte[SPCRAM+0F7h],0 - mov byte[reg1read],0 - mov byte[reg2read],0 - mov byte[reg3read],0 - mov byte[reg4read],0 - mov dword[cycpbl],0 - mov byte[spcnumread],0 - mov dword[coladdr],0 - mov byte[NMIEnab],1 - mov word[VIRQLoc],0 - mov byte[doirqnext],0 - mov dword[reg1read],0 - mov word[resolutn],224 - mov byte[vidbright],0 - mov byte[forceblnk],0 - mov byte[spcP],0 - mov byte[timeron],0 - mov byte[JoyAPos],0 - mov byte[JoyBPos],0 - mov byte[coladdr],0 - mov byte[coladdg],0 - mov byte[coladdb],0 - - mov byte[INTEnab],0 - mov word[xa],0 - mov byte[xdb],0 - mov byte[xpb],0 - mov byte[xirqb],0 - mov word[xs],01FFh - mov word[xd],0 - mov word[xx],0 - mov word[xy],0 - mov dword[SDD1BankA],03020100h - mov byte[xp],00110100b ; NVMXDIZC - - push ebx - mov byte[xe],1 ; E - xor eax,eax - mov ax,[resetv] - mov [xpc],ax - mov ebx,[romdata] - add eax,ebx - pop ebx - mov byte[intrset],0 - cmp byte[romtype],1 - je .nohirom - mov byte[xpb],00h - mov byte[xirqb],00h -.nohirom - cmp word[xpc],8000h - jae .n - add word[xpc],8000h -; mov byte[xpb],40h -.n - mov al,[opexec268] - mov [cycpl],al ; 2.68 Mhz / 3.58 Mhz = 228 - mov [curcyc],al - mov al,[opexec268cph] - mov [cycphb],al ; 2.68 Mhz / 3.58 Mhz = 56 - mov byte[cycpbl],110 ; 3.58Mhz = 175 - mov byte[cycpblt],110 - mov word[curypos],0 - mov eax,tableD - mov [Curtableaddr],eax - mov byte[scrndis],00h - mov word[stackand],01FFh - mov word[stackor],0100h - - mov dword[nmiprevaddrl],0 - mov dword[nmiprevaddrh],0 - mov byte[nmirept],0 - mov byte[nmiprevline],224 - mov byte[nmistatus],0 - - cmp byte[GUIReset],1 - jne .notreseting - mov byte[GUIReset],0 - jmp .afterramclear -.notreseting - mov eax,055555555h - helpclearmem wramdataa, 65536 - helpclearmem ram7fa, 65536 -.afterramclear - cmp byte[BSEnable],1 - jne .notbsx2 - mov eax,0FFFFFFFFh - helpclearmem wramdataa, 65536 - helpclearmem ram7fa, 65536 - cmp byte[romtype],1 ;Hack for BS HiROMs - jne .notbsx2 - mov dword[ram7fa+65528],01010101h - mov dword[ram7fa+65532],01010101h -.notbsx2 - mov dword[wramreadptr],getwram1fff - mov dword[wramwriteptr],setwram1fff - ret - -SECTION .data -.boffound db '.....',0 -SECTION .text - -getwram1fff: - mov al,[wramdataa+1fffh] - ret -setwram1fff: - mov [wramdata+1fffh],al - ret - -;******************************************************* -; Init SNES Sets the pointers, etc. -;******************************************************* -; Set banks according to : -; Banks 00-3F,80-BF : WRAM (0000h-7FFFh), ROM Data (8000h-FFFFh) -; Banks 40-7F,C0-FF : ROM Data (0000h-FFFFh) -; Bank 70-77 : SRAM (0000h-7FFFh) -; Bank 7E : WRAM (0000h-FFFFh) -; Bank 7F : ExtendRAM (0000h-FFFFh) - -SECTION .bss -NEWSYM curromsize, resb 1 -NEWSYM cromptradd, resd 1 -NEWSYM lorommapmode2, resb 1 -SECTION .text - -NEWSYM initsnes - mov byte[ForceNewGfxOff],0 - - mov esi,[romdata] - add esi,7FC0h - cmp byte[BSEnable],0 - je .notbsx3 - cmp byte[romtype],1 ;Hack for BS HiROMs - je near .bslorom -.notbsx3 - mov esi,[romdata] - add esi,[infoloc] - add esi,22 - mov byte[MultiTap],1 - cmp byte[pl12s34],1 - je .nomtap - cmp byte[pl3contrl],0 - jne .mtap - cmp byte[pl4contrl],0 - jne .mtap - cmp byte[pl5contrl],0 - jne .mtap -.nomtap - mov byte[MultiTap],0 -.mtap - - cmp byte[romtype],1 - jne .nosfx - cmp byte[SFXEnable],1 - je near .sfx -.nosfx - cmp byte[SA1Enable],1 - je near SA1memmap - cmp byte[SDD1Enable],1 - je near SDD1memmap - - cmp byte[SPC7110Enable],1 - je near .hirom - ;Should catch DKJM2 here, but need to fix mem map as well - cmp byte[curromsize],13 - je near .lorom48 - cmp byte[romtype],1 - jne near .hirom - - ; set addresses 8000-FFFF - ; set banks 00-3F (40h x 32KB ROM banks @ 8000h) - mov edi,snesmmap - mov eax,[romdata] - sub eax,8000h - mov ecx,40h -.loopa - stosd - add eax,8000h - dec ecx - jnz .loopa - ; set banks 40-6F (30h x 64KB ROM banks @ 0000h) - mov ecx,40h -.loopb - stosd - add eax,8000h - dec ecx - jnz .loopb - ; set banks 80-BF (40h x 32KB ROM banks @ 8000h) - mov eax,[romdata] - cmp byte[lorommapmode2],0 - je .notlorommode2 - add eax,200000h -.notlorommode2 - sub eax,8000h - mov cx,20h -.loopc - stosd - add eax,8000h - dec ecx - jnz .loopc - cmp byte[lorommapmode2],0 - je .notlorommode2b - sub eax,200000h -.notlorommode2b - mov cx,20h -.loopclr - stosd - add eax,8000h - dec ecx - jnz .loopclr - ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) - mov ecx,40h -.loopd - stosd - add eax,8000h - dec ecx - jnz .loopd - ; set addresses 0000-7FFF (01h x 32KB WRAM @ 0000h) - ; set banks 00-3F - mov edi,snesmap2 - mov eax,[wramdata] - mov ecx,40h -.loopa2 - stosd - dec ecx - jnz .loopa2 - ; set banks 40-6F (30h x 64KB ROM banks @ 0000h) - mov eax,[romdata] - add eax,200000h - mov ecx,40h -.loopb2 - stosd - add eax,8000h - dec ecx - jnz .loopb2 - ; set banks 80-BF (01h x 32KB WRAM @ 0000h) - mov eax,[wramdata] - mov ecx,40h -.loopc2 - stosd - dec ecx - jnz .loopc2 - ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) - mov eax,[romdata] - add eax,200000h - mov ecx,40h -.loopd2 - stosd - add eax,8000h - dec ecx - jnz .loopd2 - ; set bank 70 - mov eax,[sram] - xor ebx,ebx - mov bl,70h -.nextsram - mov [snesmap2+ebx*4],eax - inc bl - cmp bl,77h - jbe .nextsram - ; set bank 7E - mov eax,[wramdata] - mov [snesmmap+7Eh*4],eax - mov [snesmap2+7Eh*4],eax - ; set bank 7F - mov eax,[ram7f] - mov [snesmmap+7Fh*4],eax - mov [snesmap2+7Fh*4],eax - ret - -.bslorom - ; set addresses 8000-FFFF - ; set banks 00-3F (40h x 32KB ROM banks @ 8000h) - mov edi,snesmmap - mov eax,[romdata] - sub eax,8000h - mov ecx,40h -.loopas - stosd - add eax,8000h - dec ecx - jnz .loopas - ; set banks 40-6F (30h x 64KB ROM banks @ 0000h) - mov ecx,40h -.loopbs - stosd - add eax,8000h - dec ecx - jnz .loopbs - ; set banks 80-BF (40h x 32KB ROM banks @ 8000h) - mov eax,[romdata] - sub eax,8000h - mov cx,40h -.loopcs - stosd - add eax,8000h - dec ecx - jnz .loopcs - ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) - mov eax,[romdata] - add eax,8000h - mov ecx,40h -.loopds - stosd - add eax,8000h - dec ecx - jnz .loopds - ; set addresses 0000-7FFF (01h x 32KB WRAM @ 0000h) - ; set banks 00-3F - mov edi,snesmap2 - mov eax,[wramdata] - mov ecx,40h -.loopa2s - stosd - dec ecx - jnz .loopa2s - ; set banks 40-6F (30h x 64KB ROM banks @ 0000h) - mov eax,[romdata] - add eax,200000h - mov ecx,40h -.loopb2s - stosd - add eax,8000h - dec ecx - jnz .loopb2s - ; set banks 80-BF (01h x 32KB WRAM @ 0000h) - mov eax,[wramdata] - mov ecx,40h -.loopc2s - stosd - dec ecx - jnz .loopc2s - ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) - mov eax,[romdata] - add eax,8000h - mov ecx,40h -.loopd2s - stosd - add eax,8000h - dec ecx - jnz .loopd2s - ; set bank 70 - mov eax,[sram] - xor ebx,ebx - mov bl,70h -.nextsrams - mov [snesmap2+ebx*4],eax - inc bl - cmp bl,77h - jbe .nextsrams - ; set bank 7E - mov eax,[wramdata] - mov [snesmmap+7Eh*4],eax - mov [snesmap2+7Eh*4],eax - ; set bank 7F - mov eax,[ram7f] - mov [snesmmap+7Fh*4],eax - mov [snesmap2+7Fh*4],eax - ret - -.lorom48 - mov byte[cycpb268],94 - mov byte[cycpb358],94 - mov byte[cycpbl2],94 - mov byte[cycpblt2],94 - mov byte[cycpbl],94 - mov byte[cycpblt],94 - mov byte[opexec268],183 - mov byte[opexec358],187 - mov byte[opexec268cph],30 - mov byte[opexec358cph],30 - - 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 - ; set addresses 8000-FFFF - ; set banks 00-3F (40h x 32KB ROM banks @ 8000h) - mov edi,snesmmap - mov eax,[romdata] - sub eax,8000h - mov ecx,40h -.loopa3 - stosd - add eax,8000h - dec ecx - jnz .loopa3 - ; set banks 40-6F (30h x 64KB ROM banks @ 8000h) - mov eax,[romdata] - sub eax,8000h - mov ecx,40h -.loopb32 - stosd - add eax,8000h - dec ecx - jnz .loopb32 - ; set banks 80-BF (40h x 32KB ROM banks @ 8000h) - mov eax,[romdata] - sub eax,8000h - mov cx,40h -.loopc3 - stosd - add eax,8000h - dec ecx - jnz .loopc3 - ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) - mov eax,[romdata] - add eax,200000h - mov ecx,40h -.loopd3 - stosd - add eax,10000h - dec ecx - jnz .loopd3 - ; set addresses 0000-7FFF (01h x 32KB WRAM @ 0000h) - ; set banks 00-3F - mov edi,snesmap2 - mov eax,[wramdata] - mov ecx,40h -.loopa23 - stosd - dec ecx - jnz .loopa23 - ; set banks 40-6F (30h x 64KB ROM banks @ 0000h) - mov eax,[romdata] - add eax,100000h - mov ecx,40h -.loopb3 - stosd - add eax,8000h - dec ecx - jnz .loopb3 - ; set banks 80-BF (01h x 32KB WRAM @ 0000h) - mov eax,[wramdata] - mov ecx,40h -.loopc23 - stosd - dec ecx - jnz .loopc23 - ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) - mov eax,[romdata] - add eax,200000h - mov ecx,40h -.loopd23 - stosd - add eax,10000h - dec ecx - jnz .loopd23 - ; set bank 70 - mov eax,[sram] - xor ebx,ebx - mov bl,70h -.nextsram3 - mov [snesmap2+ebx*4],eax - inc bl - cmp bl,77h - jbe .nextsram3 - ; set bank 7E - mov eax,[wramdata] - mov [snesmmap+7Eh*4],eax - mov [snesmap2+7Eh*4],eax - ; set bank 7F - mov eax,[ram7f] - mov [snesmmap+7Fh*4],eax - mov [snesmap2+7Fh*4],eax - pushad - call IntlEHi ;Interleave 48Mb ROM, because the map is broken - popad - ret -.hirom - ; set addresses 8000-FFFF - ; set banks 00-3F (40h x 32KB ROM banks @ 8000h) - mov edi,snesmmap - mov eax,[romdata] - mov ecx,40h -.loopab - stosd - add eax,10000h - dec ecx - jnz .loopab - ; set banks 40-6F (30h x 64KB ROM banks @ 0000h) - mov eax,[romdata] - mov ecx,40h -.loopbb - stosd - add eax,10000h - dec ecx - jnz .loopbb - ; set banks 80-BF (40h x 32KB ROM banks @ 8000h) - mov eax,[romdata] - mov ecx,40h -.loopcb - stosd - add eax,10000h - dec ecx - jnz .loopcb - ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) - mov eax,[romdata] - mov ecx,40h -.loopdb - stosd - add eax,10000h - dec ecx - jnz .loopdb - ; set addresses 0000-7FFF (01h x 32KB WRAM @ 0000h) - ; set banks 00-3F - mov edi,snesmap2 - mov eax,[wramdata] - mov ecx,40h -.loopa2b - stosd - dec ecx - jnz .loopa2b - ; set banks 40-6F (30h x 64KB ROM banks @ 0000h) - mov eax,[romdata] - mov cx,40h -.loopb2b - stosd - add eax,10000h - dec ecx - jnz .loopb2b - ; set banks 80-BF (01h x 32KB WRAM @ 0000h) - mov eax,[wramdata] - mov cx,40h -.loopc2b - stosd - dec ecx - jnz .loopc2b - ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) - mov eax,[romdata] - mov cx,40h -.loopd2b - stosd - add eax,10000h - dec ecx - jnz .loopd2b - ; set bank 70 - mov eax,[sram] - xor ebx,ebx - mov bl,70h -.nextsramb - mov [snesmap2+ebx*4],eax - inc bl - cmp bl,77h - jbe .nextsramb - ; set bank 7E - mov eax,[wramdata] - mov [snesmmap+7Eh*4],eax - mov [snesmap2+7Eh*4],eax - ; set bank 7F - mov eax,[ram7f] - mov [snesmmap+7Fh*4],eax - mov [snesmap2+7Fh*4],eax - ret - -.sfx - mov byte[MultiTap],0 - ; Clear sfxregisters - mov edi,SfxR0 - mov ecx,16 - xor eax,eax - rep stosd - ; set addresses 8000-FFFF - ; set banks 00-3F (40h x 32KB ROM banks @ 8000h) - mov edi,snesmmap - mov eax,[romdata] -; sub eax,8000h - mov ecx,40h -.loopa3s - stosd - add eax,10000h - dec ecx - jnz .loopa3s - ; set banks 40-6F (30h x 64KB ROM banks @ 0000h) - mov eax,[romdata] -; add eax,200000h - add eax,8000h - mov ecx,40h -.loopb3s - stosd - add eax,20000h - dec ecx - jnz .loopb3s - ; set banks 80-BF (40h x 32KB ROM banks @ 8000h) - mov eax,[romdata] -; sub eax,8000h - mov cx,40h -.loopc3s - stosd - add eax,10000h - dec ecx - jnz .loopc3s - ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) - mov eax,[romdata] -; add eax,200000h - add eax,8000h - mov ecx,40h -.loopd3s - stosd - add eax,20000h - dec ecx - jnz .loopd3s - ; set addresses 0000-7FFF (01h x 32KB WRAM @ 0000h) - ; set banks 00-3F - mov edi,snesmap2 - mov eax,[wramdata] - mov ecx,40h -.loopa23s - stosd - dec ecx - jnz .loopa23s - ; set banks 40-6F (30h x 64KB ROM banks @ 0000h) - mov eax,[romdata] - add eax,8000h - mov ecx,40h -.loopb23s - stosd - add eax,20000h - dec ecx - jnz .loopb23s - ; set banks 80-BF (01h x 32KB WRAM @ 0000h) - mov eax,[wramdata] - mov ecx,40h -.loopc23s - stosd - dec ecx - jnz .loopc23s - ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) - mov eax,[romdata] - add eax,8000h - mov ecx,40h -.loopd23s - stosd - add eax,20000h - dec ecx - jnz .loopd23s - ; set bank 70 - mov eax,[sram] - mov [snesmap2+78h*4],eax - mov [snesmap2+79h*4],eax - mov eax,[sfxramdata] - mov [snesmap2+70h*4],eax - add eax,65536 - mov [snesmap2+71h*4],eax - add eax,65536 - mov [snesmap2+72h*4],eax - add eax,65536 - mov [snesmap2+73h*4],eax - ; set bank 7E - mov eax,[wramdata] - mov [snesmmap+7Eh*4],eax - mov [snesmap2+7Eh*4],eax - ; set bank 7F - mov eax,[ram7f] - mov [snesmmap+7Fh*4],eax - mov [snesmap2+7Fh*4],eax - call preparesfx - ret - -SA1memmap: - mov eax,[romdata] - cmp dword[eax+0B95h],0ADCF10A9h - jne .nosuccess - mov byte[eax+0B96h],0 -.nosuccess - mov byte[MultiTap],0 - ; set addresses 8000-FFFF - ; set banks 00-3F (40h x 32KB ROM banks @ 8000h) - mov edi,snesmmap - mov eax,[romdata] - sub eax,8000h - mov ecx,40h -.loopa3s - stosd - add eax,8000h - dec ecx - jnz .loopa3s - ; set banks 40-6F (30h x 64KB ROM banks @ 0000h) - mov eax,[romdata] -; add eax,400000h - mov ecx,40h -.loopb3s - stosd - add eax,10000h - dec ecx - jnz .loopb3s - ; set banks 80-BF (40h x 32KB ROM banks @ 8000h) - mov eax,[romdata] - add eax,200000h - sub eax,8000h - mov cx,40h -.loopc3s - stosd - add eax,8000h - dec ecx - jnz .loopc3s - ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) - mov eax,[romdata] - add eax,00000h - mov ecx,40h -.loopd3s - stosd - add eax,10000h - dec ecx - jnz .loopd3s - ; set addresses 0000-7FFF (01h x 32KB WRAM @ 0000h) - ; set banks 00-3F - mov edi,snesmap2 - mov eax,[wramdata] - mov ecx,40h -.loopa23s - stosd - dec ecx - jnz .loopa23s - ; set banks 40-6F (30h x 64KB ROM banks @ 0000h) - mov eax,[romdata] - add eax,400000h - mov ecx,40h -.loopb23s - stosd - add eax,10000h - dec ecx - jnz .loopb23s - ; set banks 80-BF (01h x 32KB WRAM @ 0000h) - mov eax,[wramdata] - mov ecx,40h -.loopc23s - stosd - dec ecx - jnz .loopc23s - ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) - mov eax,[romdata] - add eax,00000h - mov ecx,40h -.loopd23s - stosd - add eax,10000h - dec ecx - jnz .loopd23s - ; set bank 7E - mov eax,[wramdata] - mov [snesmmap+7Eh*4],eax - mov [snesmap2+7Eh*4],eax - ; set bank 7F - mov eax,[ram7f] - mov [snesmmap+7Fh*4],eax - mov [snesmap2+7Fh*4],eax - ret - -SDD1memmap: - mov eax,[romdata] - cmp dword[eax+0B95h],0ADCF10A9h - jne .nosuccess - mov byte[eax+0B96h],0 -.nosuccess - mov byte[MultiTap],0 - ; set addresses 8000-FFFF - ; set banks 00-3F (40h x 32KB ROM banks @ 8000h) - mov edi,snesmmap - mov eax,[romdata] - sub eax,8000h - mov ecx,40h -.loopa3s - stosd - add eax,8000h - dec ecx - jnz .loopa3s - ; set banks 40-6F (30h x 64KB ROM banks @ 0000h) - mov eax,[romdata] -; add eax,400000h - mov ecx,40h -.loopb3s - stosd - add eax,10000h - dec ecx - jnz .loopb3s - ; set banks 80-BF (40h x 32KB ROM banks @ 8000h) - mov eax,[romdata] -; add eax,200000h - sub eax,8000h - mov cx,40h -.loopc3s - stosd - add eax,8000h - dec ecx - jnz .loopc3s - ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) - mov eax,[romdata] - add eax,00000h - mov ecx,40h -.loopd3s - stosd - add eax,10000h - dec ecx - jnz .loopd3s - ; set addresses 0000-7FFF (01h x 32KB WRAM @ 0000h) - ; set banks 00-3F - mov edi,snesmap2 - mov eax,[wramdata] - mov ecx,40h -.loopa23s - stosd - dec ecx - jnz .loopa23s - ; set banks 40-6F (30h x 64KB ROM banks @ 0000h) - mov eax,[romdata] - add eax,400000h - mov ecx,40h -.loopb23s - stosd - add eax,10000h - dec ecx - jnz .loopb23s - ; set banks 80-BF (01h x 32KB WRAM @ 0000h) - mov eax,[wramdata] - mov ecx,40h -.loopc23s - stosd - dec ecx - jnz .loopc23s - ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) - mov eax,[romdata] - add eax,00000h - mov ecx,40h -.loopd23s - stosd - add eax,10000h - dec ecx - jnz .loopd23s - ; set bank 7E - mov eax,[wramdata] - mov [snesmmap+7Eh*4],eax - mov [snesmap2+7Eh*4],eax - ; set bank 7F - mov eax,[ram7f] - mov [snesmmap+7Fh*4],eax - mov [snesmap2+7Fh*4],eax - ret - -SECTION .data -NEWSYM SFXCounter, dd 0 - -SECTION .text - -NEWSYM preparesfx - mov byte[SFXCounter],0 - mov esi,[romdata] - add esi,07FC0h - cmp dword[esi],'FX S' - je .yessfxcounter - cmp dword[esi],'DIRT' - je .yessfxcounter - cmp dword[esi],'Stun' - jne .nosfxcounter - mov byte[ForceNewGfxOff],1 -.yessfxcounter - mov byte[SFXCounter],1 -.nosfxcounter - - ; make table - mov byte[SfxAC],0 - mov eax,[romdata] - cmp dword[eax+02B80h],0AB6CAB6Ch - jne .noac - mov byte[SfxAC],1 -.noac - ; duplicate sfx data - mov esi,[romdata] - mov edi,[romdata] - add esi,1F8000h - add edi,3F0000h - mov dl,40h -.swaploopb - mov ecx,32768 -.swaploop - mov al,[esi] - mov [edi],al - mov [edi+32768],al - inc esi - inc edi - dec ecx - jnz .swaploop - sub edi,65536+32768 - sub esi,65536 - dec dl - jnz .swaploopb - ret - - ; copy address 0 to 200000h - ; make table 1 (0 .. 127) - mov esi,[romdata] - mov edi,[romdata] - add edi,200000h - mov ecx,200000h -.n - mov al,[esi] - mov [edi],al - inc esi - inc edi - dec ecx - jnz .n - ret - -;******************************************************* -; Print Hexadecimal (16-bit/8-bit) -;******************************************************* -NEWSYM printhex - mov ecx,4 - xor ebx,ebx -.loopa - mov bx,ax - and bx,0F000h - shr bx,12 - mov dl,[.hexdat+ebx] - push ax - mov ah,02h - call Output_Text - pop ax - shl ax,4 - dec ecx - jnz .loopa - ret - -SECTION .data -.hexdat db '0123456789ABCDEF' -SECTION .text - -NEWSYM printhex8 - mov ecx,2 - xor ebx,ebx -.loopb - mov bx,ax - and bx,0F0h - shr bx,4 - mov dl,[printhex.hexdat+ebx] - push ax - mov ah,02h - call Output_Text - pop ax - shl ax,4 - dec ecx - jnz .loopb - ret - -;******************************************************* -; Load File -;******************************************************* -; Search for header size first which is filesize MOD 32768 - -NEWSYM PatchIPS -%ifdef __UNIXSDL__ - pushad - call pushdir - popad -%endif - mov eax,fname+1 - ; search for . or 0 -.next - cmp byte[eax],0 - je .foundend - inc eax - jmp .next -.foundend - mov ebx,eax -.findnext2 - dec eax - cmp eax,fname - je .failfound -%ifdef __UNIXSDL__ - cmp byte[eax],'/' -%else - cmp byte[eax],'\' -%endif - je .failfound - cmp byte[eax],'.' - je .foundokay - jmp .findnext2 -.failfound - mov eax,ebx -.foundokay - mov ebx,[eax] - mov [Prevextn],ebx - mov dword[eax],'.ips' - mov byte[eax+4],0 - push eax -%ifdef __UNIXSDL__ - cmp byte[ZipSupport], 1 - je .nochangedir - mov ebx,LoadDir - call Change_Dir -.nochangedir: -%endif - mov edx,fname+1 - mov [patchfile],edx - pushad - call PatchUsingIPS - popad - pop eax - mov ebx,[Prevextn] - mov [eax],ebx -%ifdef __UNIXSDL__ - pushad - call popdir - popad -%endif - ret - -SECTION .bss -NEWSYM Prevextn, resd 1 -NEWSYM IPSPatched, resb 1 -SECTION .text - -OpenCombFile: - mov edx,fnames+1 -.next - cmp byte[edx],0 - je .found - inc edx - jmp .next -.found - dec edx - cmp byte[edx],'.' - je .found2 - jmp .found -.found2 - mov dword[edx],'.cmb' - push edx - mov dword[NumComboLocl],0 - mov edx,fnames+1 - call Open_File - jc .failb - mov bx,ax - mov edx,ComboBlHeader - mov ecx,23 - call Read_File - mov al,[ComboBlHeader+22] - or al,al - jz .done - mov [NumComboLocl],al - mov ecx,[NumComboLocl] - mov edx,ecx - shl ecx,6 - add ecx,edx - add ecx,edx - mov edx,CombinDataLocl - call Read_File -.done - call Close_File -.failb - pop edx - mov dword[edx],'.srm' - ret - -NEWSYM SaveCombFile - cmp byte[romloadskip],0 - jne near .notfound - mov edx,fnames+1 -.next - cmp byte[edx],0 - je .found - inc edx - jmp .next -.found - dec edx - cmp byte[edx],'.' - je .found2 - jmp .found -.found2 - mov dword[edx],'.cmb' - push edx - mov al,[NumComboLocl] - or al,al - jz .failb - mov [ComboHeader+22],al - mov edx,fnames+1 - call Create_File - jc .failb - mov bx,ax - mov edx,ComboHeader - mov ecx,23 - call Write_File - mov ecx,[NumComboLocl] - mov edx,ecx - shl ecx,6 - add ecx,edx - add ecx,edx - mov edx,CombinDataLocl - call Write_File - call Close_File -.failb - pop edx - mov dword[edx],'.srm' -.notfound - ret - -NEWSYM loadfile - mov byte[TextFile], 0 - call GetCurDir - mov byte[InGUI],0 -%ifdef __UNIXSDL__ - mov dl,[InitDrive] - mov ebx,InitDir - call Change_Dir -%endif - - jmp loadfileGUI.nogui - -SECTION .data -.failop db 'Error opening file!',13,10,0 -.opened db 'File opened successfully!',13,10,0 -.mult db 'Multiple file format detected.',13,10,13,10,0 -SECTION .bss -.cchar resb 1 -.dotpos resd 1 -.curfileofs resd 1 -.filehand resw 1 -.temp resb 1 -.fail resb 1 - - -NEWSYM Checksumvalue, resw 1 -NEWSYM Checksumvalue2, resw 1 ;outdated, but needed for the command line loader -NEWSYM CRC32, resd 1 -NEWSYM SramExists, resb 1 -NEWSYM NumofBanks, resd 1 -NEWSYM NumofBytes, resd 1 -NEWSYM ZipSupport, resb 1 -InGUI resb 1 - -SECTION .data - -PrevDir db '..',0 -GUIfindBlank db '*.',0 - -SECTION .bss -ZipError resb 1 - -SECTION .data - -SPC7110DirEntry db '*.bin',0 -spc7110notfound db 'DECOMPRESSED PACK NOT FOUND',0 - -SECTION .bss - -SPC7110Allocated resb 1 -SPC7110CPtr resd 1 -SPC7110CPtr2 resd 1 -NEWSYM SPC7110Entries, resd 1 - -SECTION .text - -NEWSYM SPC7110Load - mov dword[SPC7110Entries],0 - mov esi,[romdata] - add esi,32704+22 - add esi,8000h - mov al,[esi] - cmp byte[romtype],2 - jne .nothirom - cmp al,0F9h - je .spc7110 - cmp al,0F5h - je .spc7110 -.nothirom - ret -.spc7110 - pushad - call SPC7PackIndexLoad - popad - cmp dword[SPC7110IndexSize],0 - je .nodir - ret -.nodir - mov dword[Msgptr],spc7110notfound - mov dword[MessageOn],60*6 - ret - -NEWSYM loadfileGUI - mov byte[InGUI],1 -.nogui - mov byte[spcon],0 - cmp byte[SPCDisable],1 - je .nosound - mov byte[spcon],1 -.nosound - - mov byte[TextFile], 0 - mov dword[MessageOn],0 - mov byte[loadedfromgui],1 - mov byte[yesoutofmemory],0 - mov byte[.fail],0 - mov byte[IPSPatched],0 - mov byte[GUIloadfailed],0 - - mov edx,fname+1 - mov [ZOpenFileName],edx - - pushad - call loadROM - popad - - cmp dword[curromspace],0 - je near .failed - - call convertsram - mov byte[SramExists],0 - - ; change to sram dir - pushad - call SRAMChdir - popad - - ; open .srm file - mov edx,fnames+1 - call Open_File - jc .notexist - mov byte[SramExists],1 - mov bx,ax - mov ecx,65536 - mov edx,[sram] - call Read_File - call Close_File - jc near .failed2 -.notexist - call OpenCombFile - cmp byte[InGUI],1 - je .inguib - mov edx,.opened - mov ah,9 - call Output_Text -.inguib - - mov eax,[curromspace] - mov [.curfileofs],eax - mov [NumofBytes],eax - shr eax,15 - mov [NumofBanks],eax - - cmp byte[.fail],0 - je .notfailed - mov byte[yesoutofmemory],1 -.notfailed - - ; copy fnames to fname - cmp byte[InGUI],1 - je .nosramtof - mov eax,fname+1 - mov ebx,fnames+1 -.loopsc - mov dl,[ebx] - mov [eax],dl - inc ebx - inc eax - or dl,dl - jnz .loopsc -.nosramtof - mov byte[TextFile], 1 - cmp byte[IPSPatched],0 - jne .patched - call PatchIPS -.patched - ret - -.failed -.failed2 - mov byte[TextFile], 1 - cmp byte[InGUI],1 - je .noguic - mov edx,.failop - mov ah,9 - call Output_Text - jmp DosExit -.noguic - mov byte[GUIloadfailed],1 - ret - -SECTION .data -.failop db 'Error opening file!',13,10,0 -.opened db 'File opened successfully!',13,10,0 -.mult db 'Multiple file format detected.',13,10,13,10,0 - -SECTION .bss - -.cchar resb 1 -.dotpos resd 1 -.curfileofs resd 1 -.filehand resw 1 -.temp resb 1 -.fail resb 1 -NEWSYM GUIloadfailed, resb 1 - -SECTION .text - -NEWSYM convertsram - cmp byte[cfgloadsdir],1 - je .sdrivechange - ret -.sdrivechange - ; copy fnames/fnamest to not have any '\' in them - mov esi,fnames+1 - mov ebx,0 -.next - mov al,[esi] - cmp al,0 - je .fincutoff - cmp al,'\' - je .cutoff - cmp al,'/' - je .cutoff - cmp al,':' - je .cutoff - inc esi - jmp .next -.cutoff - inc esi - mov ebx,esi - jmp .next -.fincutoff - cmp ebx,0 - je .nocutoff - mov esi,ebx - mov edi,fnames+1 -.next2 - mov al,[esi] - mov [edi],al - inc esi - inc edi - cmp al,0 - jne .next2 -.nocutoff - mov esi,fnamest+1 - mov ebx,0 -.nextb - mov al,[esi] - cmp al,0 - je .fincutoffb - cmp al,'\' - je .cutoffb - cmp al,'/' - je .cutoffb - cmp al,':' - je .cutoffb - inc esi - jmp .nextb -.cutoffb - inc esi - mov ebx,esi - jmp .nextb -.fincutoffb - cmp ebx,0 - je .nocutoffb - mov esi,ebx - sub esi,fnamest+1 - sub [statefileloc],esi - mov esi,ebx - mov edi,fnamest+1 -.next2b - mov al,[esi] - mov [edi],al - inc esi - inc edi - cmp al,0 - jne .next2b -.nocutoffb - ; change to sram directory - pushad - call SRAMChdir - popad - ret - -SECTION .data -NEWSYM CSStatus, db ' TYPE: ',0 -NEWSYM CSStatus2, db 'INTERLEAVED: BANK: CHKSUM: ',0 -NEWSYM CSStatus3, db 'VIDEO: CRC32: ',0 - -;******************************************************* -; Show Information -;******************************************************* -; -; Maker Code = FFB0-FFB1 -; Game Code = FFB2-FFB5 -; Expansion RAM Size = FFBD (0=none, 1=16kbit, 3=64kbit, 5=256kbit,etc. -; Map Mode = FFD5 2.68-20h=map20h,21h=map21h,22h=reserved,23h=SA-1,25h=map25h -; 3.58-30h=map20h,31h=map21h,35h=map25h,highspeed -; Rom Mask Version = FFDB -; FFD6 (ROM Type) : 0*=DSP,1*=SFX,2*=OBC1,3*=SA-1,E*-F*=other -; *3=ROM,*4=ROM+RAM,*5=ROM+RAM+BATTERY,*6=ROM+BATTERY -; F3=C4 - - -SECTION .bss -NEWSYM DSP1Type, resb 1 -NEWSYM intldone, resb 1 -NEWSYM C4RamR, resd 1 -NEWSYM C4RamW, resd 1 -NEWSYM C4Ram, resd 1 -NEWSYM ROMTypeNOTFound, resb 1 -NEWSYM Interleaved, resb 1 -SECTION .text - -NEWSYM outofmemfix - mov esi,[romdata] - cmp byte[romtype],2 - jne .nhirom - add esi,8000h -.nhirom - mov word[resetv],8000h - mov word[xpc],8000h - mov byte[esi],58h - mov byte[esi+1],80h - mov byte[esi+2],0FEh - mov dword[Msgptr],outofmemoryerror - cmp byte[newgfx16b],1 - jne .notso - mov dword[Msgptr],outofmemoryerror2 -.notso - mov dword[MessageOn],0FFFFFFFFh - ret - -SECTION .bss -NEWSYM yesoutofmemory, resb 1 -SECTION .data -NEWSYM outofmemoryerror, db 'OUT OF MEMORY.',0 -NEWSYM outofmemoryerror2, db 'ROM IS TOO BIG.',0 +;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 DosExit,UpdateDevices,Makemode7Table,MusicRelVol,MusicVol,makesprprtable +EXTSYM romloadskip,start65816,startdebugger,SfxR0,showinfogui,inittable +EXTSYM SA1inittable,MessageOn,Msgptr,MsgCount,sndrot,SnowTimer,inittableb +EXTSYM inittablec,newgfx16b,cfgreinittime,Open_File,Read_File,Write_File +EXTSYM Close_File,Output_Text,Change_Dir,Create_File,SPCDisable,osm2dis +EXTSYM BackupSystemVars,SnowData,SnowVelDist,cvidmode,newengen,cfgnewgfx +EXTSYM GUI16VID,NewEngEnForce,TextFile,Setper2exec,JoyRead,pressed,pl3Ak,pl3Bk +EXTSYM pl3Lk,pl3Rk,pl3Xk,pl3Yk,pl3contrl,pl3downk,pl3leftk,pl3rightk,pl3selk +EXTSYM pl3startk,pl3upk,pl4Ak,pl4Bk,pl4Lk,pl4Rk,pl4Xk,pl4Yk,pl4contrl,pl4downk +EXTSYM pl4leftk,pl4rightk,pl4selk,pl4startk,pl4upk,mousebuttons,mousexdir,pl5Ak +EXTSYM pl5Bk,pl5Lk,pl5Rk,pl5Xk,pl5Yk,pl5contrl,pl5downk,pl5leftk,pl5rightk +EXTSYM pl5selk,pl5startk,pl5upk,mouseydir,mousexpos,mouseypos,snesmouse,sram +EXTSYM processmouse,ssautosw,GUIDelayB,pl12s34,pl1Xtk,pl1Ytk,pl1Atk,pl1Btk +EXTSYM pl2Xtk,pl2Ytk,pl2Atk,pl2Btk,pl3Xtk,pl3Ytk,pl3Atk,pl3Btk,pl4Xtk,pl4Ytk +EXTSYM pl4Atk,pl4Btk,pl1ULk,pl1URk,pl1DLk,pl1DRk,pl2ULk,pl2URk,pl2DLk,pl2DRk +EXTSYM pl3ULk,pl3URk,pl3DLk,pl3DRk,pl4ULk,pl4URk,pl4DLk,pl4DRk,pl5ULk,pl5URk +EXTSYM pl5DLk,pl5DRk,pl5Xtk,pl5Ytk,pl5Atk,pl5Btk,pl1Ltk,pl1Rtk,pl2Ltk,pl2Rtk +EXTSYM pl3Ltk,pl3Rtk,pl4Ltk,pl4Rtk,pl5Ltk,pl5Rtk,Turbo30hz,NumComboLocl +EXTSYM ComboBlHeader,ComboHeader,CombinDataLocl,CombinDataGlob,NumCombo +EXTSYM GUIComboGameSpec,mousexloc,mouseyloc,extlatch,FIRTAPVal0,FIRTAPVal1 +EXTSYM FIRTAPVal2,FIRTAPVal3,FIRTAPVal4,FIRTAPVal5,FIRTAPVal6,FIRTAPVal7,INTEnab +EXTSYM JoyAPos,JoyBPos,NMIEnab,SPCROM,VIRQLoc,coladdb,coladdg,coladdr,doirqnext +EXTSYM forceblnk,nmiprevaddrh,nmiprevaddrl,nmiprevline,nmirept,nmistatus +EXTSYM opexec268,opexec268b,opexec268cph,opexec268cphb,opexec358,opexec358b +EXTSYM opexec358cph,spcextraram,opexec358cphb,prevoamptr,reg1read,reg2read +EXTSYM reg3read,reg4read,resolutn,romdata,scrndis,spcP,SPCRAM,spcnumread +EXTSYM tableD,timeron,vidbright,SPC700read,SPC700write,spc700read +EXTSYM GUIReset,InitC4,SA1Reset,SetAddressingModesSA1,SDD1BankA,SPC7110init +EXTSYM RTCinit,InitOBC,memaccessspc7110r8,memaccessspc7110r16,memaccessspc7110w8 +EXTSYM memaccessspc7110w16,ram7f,snesmap2,snesmmap,MultiTap,memaccessbankr848mb +EXTSYM memaccessbankr1648mb,procexecloop,ram7fa,wramdata,wramdataa,fname,fnames +EXTSYM GetCurDir,SRAMChdir,cfgloadsdir,fnamest,statefileloc,InitDir,InitDrive +EXTSYM curromspace,infoloc,patchfile,romispal,initregr,initregw,memtabler16 +EXTSYM memtabler8,memtablew16,memtablew8,sfxramdata,wramreadptr +EXTSYM wramwriteptr,loadstate2,CMovieExt,MoviePlay,MovieDumpRaw,AllowUDLR + +;initc.c +EXTSYM clearmem,clearSPCRAM,PatchUsingIPS,ZOpenFileName,loadROM,SPC7110IndexSize +EXTSYM SPC7PackIndexLoad,IntlEHi,C4Enable,SPC7110Enable,RTCEnable,SA1Enable +EXTSYM SDD1Enable,OBCEnable,SFXEnable,BSEnable,clearvidsound,headerhack,SetupROM + +%ifdef __UNIXSDL__ +EXTSYM LoadDir,popdir,pushdir +%endif + +; Initiation + +SECTION .data +NEWSYM regsbackup, times 3019 db 0 +NEWSYM forceromtype, db 0 +NEWSYM loadedfromgui, db 0 +NEWSYM SnowOn, db 0 +NEWSYM bgfixer, db 0 +NEWSYM bgfixer2, db 0 +NEWSYM ReInitLength, dd 0 +NEWSYM ForceNewGfxOff, dd 0 +NEWSYM SfxAC, db 0 +blah times 450 db 0 +; FIX STATMAT +NEWSYM autoloadstate, db 0 ; auto load state slot number +NEWSYM autoloadmovie, db 0 +NEWSYM ZMVRawDump, db 0 + +NEWSYM EndMessage + db ' ',13,10,0 + +SECTION .text + +EXTSYM cpalval +NEWSYM init + ; prevents a crash if cpalval gets accessed before initializing + mov eax,cpalval + mov ecx,256 +.looppal + mov dword[eax],cpalval + add eax,4 + dec ecx + jnz .looppal + + ; Initialize snow stuff + mov ecx,400 + xor edx,edx +.snowloop + shl word[SnowData+edx*2],8 + and byte[SnowVelDist+edx],0F7h + cmp dword[SnowTimer],0 + jne .skip + or byte[SnowVelDist+edx],08h +.skip + inc edx + dec ecx + jnz .snowloop + + pushad + call BackupSystemVars + popad + + xor eax,eax + mov al,[cfgreinittime] + mov ebx,50 + mul ebx + mov [ReInitLength],eax + + xor eax,eax + mov al,[romtype] + mov [forceromtype],al + mov byte[romtype],0 + mov ax,ds + mov es,ax + mov eax,regsbackup + mov ebx,sndrot + mov ecx,3019 +.rbackupl + mov dl,[ebx] + mov [eax],dl + inc ebx + inc eax + dec ecx + jnz .rbackupl + mov byte[virqnodisable],0 + pushad + call clearmem + popad + call inittable + call inittableb + call inittablec + call SA1inittable + ; SPC Init + pushad + call procexecloop + popad + ; SNES Init + pushad + call Setper2exec + popad + call Makemode7Table + call makesprprtable + cmp byte[fname],0 + jne .found + cmp byte[romloadskip],1 + je .noloadfile +.found + mov byte[romloadskip],0 + call loadfile + pushad + call SetupROM + call showinfogui + popad +.noloadfile + call UpdateDevices + call init65816 + call initregr + call initregw + call initsnes + + ; Initialize volume + xor eax,eax + xor edx,edx + mov al,[MusicRelVol] + shl eax,7 + mov ebx,0A3D70A3Dh + mul ebx + shr edx,6 + cmp dl,127 + jb .noof + mov dl,127 +.noof + mov [MusicVol],dl + +; FIX STATMAT + ; Here's the auto-load ZST file stuff + cmp byte[autoloadstate],1 + jl .noautoloadstate + je .enddigits + mov ebx,[statefileloc] + sub byte[autoloadstate],1 + cmp byte[autoloadstate],10 + jge .2digits + mov al,[autoloadstate] + add al,48 + mov [fnamest+ebx],al + jmp .enddigits +.2digits + xor eax,eax + mov al,[autoloadstate] + mov dl,10 + div dl + add al,48 + add ah,48 + mov [fnamest+ebx-1],al + mov [fnamest+ebx],ah +.enddigits + + ; Load the specified state file + pushad + call loadstate2 + popad + + ; Just skip the extension re-setup below if we don't need to do it + cmp byte[autoloadstate],9 + jbe .noautoloadstate + + ; Put back the 'ST' on the end of the extension as we changed it + ; above (by placing two digits in the extension). This is so + ; as not to break any other code later on which depends + ; on it being present. + mov ebx,[statefileloc] +%ifdef __UNIXSDL__ + mov word[fnamest+ebx-1],'st' +%else + mov word[fnamest+ebx-1],'ST' +%endif + +.noautoloadstate + + cmp byte[autoloadmovie],1 + jb .noautloadmovie + cmp byte[autoloadmovie],10 + ja .noautloadmovie + mov al,[autoloadmovie] + add al,'0'-1 + cmp al,'0' + jne .notzero1 + mov al,'v' +.notzero1 + mov [CMovieExt],al + + pushad + cmp byte[ZMVRawDump],1 + jne .norawdump + call MovieDumpRaw + jmp .aftermovieplay +.norawdump + call MoviePlay +.aftermovieplay + popad + +.noautloadmovie + + xor eax,eax + mov al,[cvidmode] + cmp byte[GUI16VID+eax],1 + je .yes16b + mov byte[newengen],1 + mov byte[cfgnewgfx],1 +.yes16b + cmp byte[NewEngEnForce],1 + jne .noforce + mov byte[NewEngEnForce],0 + mov byte[newengen],1 + mov byte[cfgnewgfx],1 +.noforce + mov ebx,ebm + mov eax,EndMessage + mov dh,17h + mov ch,67 + mov cl,1 +.loopen + mov dl,[ebx] + rol dl,cl + xor dl,dh + mov [eax],dl + rol dh,1 + inc cl + or cl,cl + jne .notzero + inc cl +.notzero + and cl,07h + inc eax + inc ebx + dec ch + jnz .loopen + + cmp byte[yesoutofmemory],1 + jne .noout + call outofmemfix +.noout + cmp byte[debugger],0 + je near start65816 + cmp byte[romloadskip],1 + je near start65816 + jmp startdebugger + +EndMessageB + +; global variables + +SECTION .data + +; Controls +;FIXME: define pl3contrl, pl4contrl and pl5contrl here? +;Christophe 2001/03/10 +NEWSYM numjoy, db 0 ; number of joysticks (1 = 1, 2 = 2) +; 0 = Disable, 1 = Keyboard, 2 = Joystick, 3 = Gamepad +; 4 = 4-button 5 = 6-button 6 = sidewinder +NEWSYM pl1contrl, db 1 ; player 1 device +NEWSYM pl1keya, dd 0 +NEWSYM pl1keyb, dd 0 +%ifdef __MSDOS__ +NEWSYM pl1selk, dd 54 +NEWSYM pl1startk, dd 28 +NEWSYM pl1upk, dd 72 +NEWSYM pl1downk, dd 80 +NEWSYM pl1leftk, dd 75 +NEWSYM pl1rightk, dd 77 +%else +NEWSYM pl1selk, dd 54 +NEWSYM pl1startk, dd 28 +NEWSYM pl1upk, dd 200 +NEWSYM pl1downk, dd 208 +NEWSYM pl1leftk, dd 203 +NEWSYM pl1rightk, dd 205 +%endif +NEWSYM pl1Xk, dd 31 +NEWSYM pl1Ak, dd 45 +NEWSYM pl1Lk, dd 32 +NEWSYM pl1Yk, dd 30 +NEWSYM pl1Bk, dd 44 +NEWSYM pl1Rk, dd 46 +NEWSYM pl2contrl, db 0 ; player 2 device +NEWSYM pl2keya, dd 0 +NEWSYM pl2keyb, dd 0 +NEWSYM pl2selk, dd 27 +NEWSYM pl2startk, dd 26 +NEWSYM pl2upk, dd 199 +NEWSYM pl2downk, dd 207 +NEWSYM pl2leftk, dd 211 +NEWSYM pl2rightk, dd 209 +NEWSYM pl2Xk, dd 24 +NEWSYM pl2Ak, dd 25 +NEWSYM pl2Lk, dd 23 +NEWSYM pl2Yk, dd 37 +NEWSYM pl2Bk, dd 38 +NEWSYM pl2Rk, dd 36 +NEWSYM JoyStart, db 0 +NEWSYM JoySelec, db 0 +NEWSYM JoyBC, db 1 +NEWSYM JoyYC, db 3 +NEWSYM JoyAC, db 2 +NEWSYM JoyXC, db 4 +NEWSYM JoyLC, db 5 +NEWSYM JoyRC, db 6 +NEWSYM TurboSw, db 0 + +NEWSYM romtype, db 0 ; ROM type in bytes +NEWSYM resetv, dw 0 ; reset vector +NEWSYM abortv, dw 0 ; abort vector +NEWSYM nmiv2, dw 0 ; nmi vector +NEWSYM nmiv, dw 0 ; nmi vector +NEWSYM irqv, dw 0 ; irq vector +NEWSYM irqv2, dw 0 ; irq vector +NEWSYM brkv, dw 0 ; brk vector +NEWSYM copv, dw 0 ; cop vector +NEWSYM abortv8, dw 0 ; abort vector emulation mode +NEWSYM nmiv8, dw 0 ; nmi vector emulation mode +NEWSYM irqv8, dw 0 ; irq vector emulation mode +NEWSYM brkv8, dw 0 ; brk vector emulation mode +NEWSYM copv8, dw 0 ; cop vector emulation mode +NEWSYM cycpb268, db 109 ; 110 +NEWSYM cycpb358, db 149 ; 155 +NEWSYM cycpbl2, db 109 ; percentage left of CPU/SPC to run (3.58 = 175) +NEWSYM cycpblt2, db 149 ; percentage of CPU/SPC to run +NEWSYM writeon, db 0 ; Write enable/disable on snes rom memory +NEWSYM totlines, dw 263 ; total # of lines +NEWSYM soundon, db 0 ; Current sound enabled (1=enabled) + +;This is saved in states +NEWSYM curcyc, db 0 ; cycles left in scanline +NEWSYM curypos, dw 0 ; current y position +NEWSYM cacheud, db 1 ; update cache every ? frames +NEWSYM ccud, db 0 ; current cache increment +NEWSYM intrset, db 0 ; interrupt set +NEWSYM cycpl, db 0 ; cycles per scanline +NEWSYM cycphb, db 0 ; cycles per hblank +NEWSYM spcon, db 0 ; SPC Enable (1=enabled) +NEWSYM stackand,dw 01FFh; value to and stack to keep it from going to the wrong area +NEWSYM stackor, dw 0100h; value to or stack to keep it from going to the wrong area + +; 65816 registers + +NEWSYM xat, dw 0 +NEWSYM xdbt, db 0 +NEWSYM xpbt, db 0 +NEWSYM xst, dw 0 +NEWSYM xdt, dw 0 +NEWSYM xxt, dw 0 +NEWSYM xyt, dw 0 +NEWSYM xp, db 0 +NEWSYM xe, db 0 +NEWSYM xpc, dw 0 +NEWSYM xirqb, db 0 ; which bank the irqs start at +NEWSYM debugger, db 0 ; Start with debugger (1=yes,0=no) +NEWSYM Curtableaddr, dd 0 ; Current table address +NEWSYM curnmi, db 0 ; if in NMI(1) or not(0) +; pharos - equ hack *sigh* +n65816regsize equ $-curcyc + +ALIGN32 +NEWSYM cycpbl, dd 110 ; percentage left of CPU/SPC to run (3.58 = 175) +NEWSYM cycpblt, dd 110 ; percentage of CPU/SPC to run + +NEWSYM PH65816regsize, dd n65816regsize + +; SNES memory map ROM locations + +NEWSYM cpuoverptr, dd 0 ; pointer to cpuover +;snesmmap times 256 dd 0 ; addresses 8000-FFFF +;snesmap2 times 256 dd 0 ; addresses 0000-7FFF +;NEWSYM exeloopa, times 128 db 0 ; execloop should be stored here +;NEWSYM exeloopb, times 128 db 0 ; execloopns should be stored here +;NEWSYM exeloopc, times 128 db 0 ; execloops should be stored here +;NEWSYM exeloopd, times 128 db 0 ; execloopn should be stored here +;NEWSYM prevcrash, times 250 db 0 + + +ALIGN32 +NEWSYM xa, dd 0 +NEWSYM xdb, dd 0 +NEWSYM xpb, dd 0 +NEWSYM xs, dd 0 +NEWSYM xd, dd 0 +NEWSYM xx, dd 0 +NEWSYM xy, dd 0 +NEWSYM flagnz, dd 0 +NEWSYM flago, dd 0 +NEWSYM flagc, dd 0 +NEWSYM bankkp, dd 0 +NEWSYM Sflagnz, dd 0 +NEWSYM Sflago, dd 0 +NEWSYM Sflagc, dd 0 + +ebm db 166,95,66,223,17,11,103,180,156,68,108,120,138,55,203,205 + db 178,210,39,252,128,66,65,167,155,151,197,125,176,66,73,230 + db 61,210,7,137,152,110,203,241,50,89,70,29,176,42,99,167 + db 155,92,3,221,224,54,53,167,155,211,70,205,138,202,91,234 + db 178,80,229,13,10 + +SECTION .text + + +;******************************************************* +; Read Input Device Reads from Keyboard, etc. +;******************************************************* + +SECTION .bss +NEWSYM WhichSW, resb 1 +NEWSYM WhichGR, resb 1 +NEWSYM autofr, resb 1 +TurboCB resb 1 + +NEWSYM JoyAOrig, resd 1 +NEWSYM JoyBOrig, resd 1 +NEWSYM JoyCOrig, resd 1 +NEWSYM JoyDOrig, resd 1 +NEWSYM JoyEOrig, resd 1 +NEWSYM JoyANow, resd 1 +NEWSYM JoyBNow, resd 1 +NEWSYM JoyCNow, resd 1 +NEWSYM JoyDNow, resd 1 +NEWSYM JoyENow, resd 1 +NEWSYM PJoyAOrig, resd 1 +NEWSYM PJoyBOrig, resd 1 +NEWSYM PJoyCOrig, resd 1 +NEWSYM PJoyDOrig, resd 1 +NEWSYM PJoyEOrig, resd 1 +NEWSYM LethEnData, resd 1 +NEWSYM ComboCounter, resb 1 +SECTION .text + +%macro PlayerDeviceHelp 3 + mov eax,[%1] + cmp byte[pressed+eax],1 + jne %%no + or dword[%2],%3 +%%no +%endmacro + +%macro ProcSNESMouse 1 + test byte[mousebuttons],02h + jz %%n + or dword[%1],00000000100000000000000000000000b + mov al,1 +%%n + test byte[mousebuttons],01h + jz %%n2 + or dword[%1],00000000010000000000000000000000b +%%n2 + or dword[%1],00000000000000010000000000000000b + mov al,[mouseypos] + and al,7Fh + or byte[%1+1],al + mov al,[mousexpos] + and al,7Fh + or byte[%1],al + test byte[mouseydir],01h + jz %%n3 + or dword[%1],00000000000000001000000000000000b +%%n3 + test byte[mousexdir],01h + jz %%n4 + or dword[%1],00000000000000000000000010000000b +%%n4 +%endmacro + +%macro ProcessKeyComb 2 + cmp dword[NumCombo],0 + je near %%nocomb + mov eax,CombinDataGlob + cmp byte[GUIComboGameSpec],0 + je %%local + mov eax,CombinDataLocl +%%local + push ecx + push ebx + xor ebx,ebx + cmp byte[ComboProg+%1],0 + jne near %%progressing + test dword[%2],01000000h + jz %%noright + mov dword[CombDirSwap],0 +%%noright + test dword[%2],02000000h + jz %%noleft + mov dword[CombDirSwap],1 +%%noleft + mov ecx,[NumCombo] +%%loop + mov bx,[eax+62] + cmp byte[pressed+ebx],1 + jne %%nopress + cmp byte[eax+64],%1 + je %%startprogress +%%nopress + add eax,66 + dec ecx + jnz %%loop + jmp %%endcomb +%%startprogress + mov byte[pressed+ebx],2 + inc byte[ComboCounter] + mov byte[ComboProg+%1],1 + mov byte[ComboPtr+%1],0 + mov dword[PressComb+%1*4],0 + mov dword[HoldComb+%1*4],0 + mov dword[CombCont+%1*4],CombContDatN + cmp dword[CombDirSwap],0 + je %%NoSwapLeftRight + cmp byte[eax+65],0 + je %%NoSwapLeftRight + mov dword[CombCont+%1*4],CombContDatR +%%NoSwapLeftRight + add eax,20 + mov [StartComb+%1*4],eax +%%progressing + mov ecx,%1 + mov eax,[StartComb+%1*4] + call ProcessCombo + mov [StartComb+%1*4],eax + or ebx,ebx + jz %%proccomb + mov byte[ComboProg+%1],0 +%%proccomb + mov dword[%2],0 + mov eax,[HoldComb+%1*4] + or dword[%2],eax + mov eax,[PressComb+%1*4] + or dword[%2],eax +%%endcomb + pop ebx + pop ecx +%%nocomb +%endmacro + +ProcessCombo: + mov dword[KeyLPress],0 + cmp dword[CombDelay+ecx*4],0 + jne .delay +.nextsession + xor ebx,ebx + cmp byte[eax],0 + je .finish + mov bl,[eax] + cmp bl,37 + jb .keypress + cmp bl,48 + ja .finish + sub ebx,37 + shl ebx,2 + add ebx,CombTDelN + cmp byte[romispal],0 + je .ntsc + sub ebx,CombTDelN + add ebx,CombTDelP +.ntsc + mov ebx,[ebx] + mov [CombDelay+ecx*4],ebx + inc eax + inc byte[ComboPtr+ecx] + cmp byte[ComboPtr+ecx],42 + je .finish +.delay + dec dword[CombDelay+ecx*4] + xor ebx,ebx + ret +.finish + mov ebx,1 + ret +.keypress + cmp dword[KeyLPress],0 + jne .alreadyproc + mov dword[PressComb+ecx*4],0 + mov dword[KeyLPress],1 +.alreadyproc + dec ebx + cmp ebx,12 + jae .pressonly + shl ebx,2 + add ebx,[CombCont+ecx*4] + mov ebx,[ebx] + or [PressComb+ecx*4],ebx + jmp .finkeyproc +.pressonly + sub ebx,12 + cmp ebx,12 + jae .releaseonly + shl ebx,2 + add ebx,[CombCont+ecx*4] + mov ebx,[ebx] + or [HoldComb+ecx*4],ebx + jmp .finkeyproc +.releaseonly + sub ebx,12 ; <- bugfix from Maxim + shl ebx,2 + add ebx,[CombCont+ecx*4] + mov ebx,[ebx] + xor ebx,0FFFFFFFFh + and [HoldComb+ecx*4],ebx + and [PressComb+ecx*4],ebx ; <- buxfix from Maxim +.finkeyproc + inc eax + inc byte[ComboPtr+ecx] + cmp byte[ComboPtr+ecx],42 + je near .finish + jmp .nextsession + +SECTION .data +ComboProg times 5 db 0 +ComboPtr times 5 db 0 +KeyLPress dd 0 +CombDirSwap dd 0 +CombDelay times 5 dd 0 +StartComb times 5 dd 0 +HoldComb times 5 dd 0 +PressComb times 5 dd 0 +CombCont times 5 dd 0 +CombTDelN dd 1,2,3,4,5,9,30,60,120,180,240,300 +CombTDelP dd 1,2,3,4,5,9,25,50,100,150,200,250 +CombContDatN dd 08000000h,04000000h,02000000h,01000000h,00800000h,80000000h + dd 00400000h,40000000h,00200000h,00100000h,10000000h,20000000h +CombContDatR dd 08000000h,04000000h,01000000h,02000000h,00800000h,80000000h + dd 00400000h,40000000h,00200000h,00100000h,10000000h,20000000h + +EXTSYM MouseToRead,multimouse + +SECTION .text + +%macro PlayerDeviceFix 1 + cmp byte[AllowUDLR],1 + je %%noleftright + mov eax,[%1] + and eax,0C000000h + cmp eax,0C000000h + jne %%noupdown + and dword[%1],0F3FFFFFFh +%%noupdown + mov eax,[%1] + and eax,03000000h + cmp eax,03000000h + jne %%noleftright + and dword[%1],0FCFFFFFFh +%%noleftright +%endmacro + +NEWSYM ReadInputDevice + mov byte[WhichSW],1 + mov byte[WhichGR],0 + inc byte[TurboSw] + mov byte[TurboCB],01h + cmp byte[Turbo30hz],0 + je .noturbo30 + mov byte[TurboCB],02h +.noturbo30 + ; Read External Devices (Joystick, PPort, etc.) + call JoyRead + ; Process Data + mov dword[JoyAOrig],0 + ; Get Player1 input device + cmp byte[multimouse],1 + je .multimouse1 + cmp byte[snesmouse],1 + jne .nomouse1 +.multimouse1 + mov byte[MouseToRead],1 + call processmouse + ProcSNESMouse JoyAOrig + jmp .noinput1 +.nomouse1 + PlayerDeviceHelp pl1Bk ,JoyAOrig,80000000h + PlayerDeviceHelp pl1Yk ,JoyAOrig,40000000h + PlayerDeviceHelp pl1selk ,JoyAOrig,20000000h + PlayerDeviceHelp pl1startk,JoyAOrig,10000000h + PlayerDeviceHelp pl1upk ,JoyAOrig,08000000h + PlayerDeviceHelp pl1downk ,JoyAOrig,04000000h + PlayerDeviceHelp pl1leftk ,JoyAOrig,02000000h + PlayerDeviceHelp pl1rightk,JoyAOrig,01000000h + PlayerDeviceHelp pl1Ak ,JoyAOrig,00800000h + PlayerDeviceHelp pl1Xk ,JoyAOrig,00400000h + PlayerDeviceHelp pl1Lk ,JoyAOrig,00200000h + PlayerDeviceHelp pl1Rk ,JoyAOrig,00100000h + PlayerDeviceHelp pl1ULk ,JoyAOrig,0A000000h + PlayerDeviceHelp pl1URk ,JoyAOrig,09000000h + PlayerDeviceHelp pl1DLk ,JoyAOrig,06000000h + PlayerDeviceHelp pl1DRk ,JoyAOrig,05000000h + PlayerDeviceFix JoyAOrig + mov al,[TurboCB] + test byte[TurboSw],al + jnz near .noswitch + PlayerDeviceHelp pl1Xtk ,JoyAOrig,00400000h + PlayerDeviceHelp pl1Ytk ,JoyAOrig,40000000h + PlayerDeviceHelp pl1Atk ,JoyAOrig,00800000h + PlayerDeviceHelp pl1Btk ,JoyAOrig,80000000h + PlayerDeviceHelp pl1Ltk ,JoyAOrig,00200000h + PlayerDeviceHelp pl1Rtk ,JoyAOrig,00100000h +.noswitch + mov byte[ComboCounter],0 + ProcessKeyComb 0,JoyAOrig + or dword[JoyAOrig],00008000h ; Joystick Enable + cmp byte[GUIDelayB],0 + je .noinput1 + cmp byte[GUIDelayB],1 + jne .inputbd + test dword[JoyAOrig],80000000h + jnz .inputbdcb + dec byte[GUIDelayB] + jmp .noinput1 +.inputbd + dec byte[GUIDelayB] +.inputbdcb + and dword[JoyAOrig],7FFFFFFFh +.noinput1 + mov dword[JoyBOrig],0 + cmp byte[multimouse],1 + je .multimouse2 + cmp byte[snesmouse],2 + jne .nomouse2 +.multimouse2 + mov byte[MouseToRead],2 + call processmouse + ProcSNESMouse JoyBOrig + jmp .noinput2 +.nomouse2 + cmp byte[snesmouse],3 + jne .nosuperscope + call processmouse + mov byte[JoyBOrig+2],0FFh + mov al,[ssautosw] + test byte[mousebuttons],01h + jz .nobutton1 + or al,80h +.nobutton1 + cmp byte[pressed+14],0 + jz .nobutton3 + or al,10h +.nobutton3 + test byte[mousebuttons],02h + jz .nobutton4 + or al,40h +.nobutton4 + mov [JoyBOrig+3],al + jmp .noinput2 +.nosuperscope + cmp byte[snesmouse],4 + jne .nolethalen + call processmouse + mov eax,[romdata] + cmp dword[eax+1000h],0AD20C203h + jne .not + mov eax,[wramdata] + cmp byte[eax],26 + je .not + mov bl,[mousexloc] + mov [eax+40Ah],bl + mov bl,[mouseyloc] + mov [eax+40Eh],bl +.not +; mov word[JoyBOrig+2],000Eh +; and dword[LethEnData],0000000FFh +; or dword[LethEnData],055010000h +; inc byte[LethEnData] + test byte[LethEnData],1 + jz .n1 +; mov byte[LethEnData+2],8 + mov byte[extlatch],0 +.n1 + test byte[mousebuttons],01h + jz .nobutton1b +; or dword[LethEnData+2],10h + or byte[JoyAOrig+3],80h +.nobutton1b + cmp byte[pressed+14],0 + jz .nobutton3b +; or byte[LethEnData+2],40h +.nobutton3b + test byte[mousebuttons],02h + jz .nobutton4b +; or byte[LethEnData+2],40h + or byte[JoyAOrig+2],80h +.nobutton4b + jmp .noinput2 +.nolethalen + cmp byte[pl2contrl],0 + je near .noinput2 + ; Get Player2 input device + PlayerDeviceHelp pl2Bk ,JoyBOrig,80000000h + PlayerDeviceHelp pl2Yk ,JoyBOrig,40000000h + PlayerDeviceHelp pl2selk ,JoyBOrig,20000000h + PlayerDeviceHelp pl2startk,JoyBOrig,10000000h + PlayerDeviceHelp pl2upk ,JoyBOrig,08000000h + PlayerDeviceHelp pl2downk ,JoyBOrig,04000000h + PlayerDeviceHelp pl2leftk ,JoyBOrig,02000000h + PlayerDeviceHelp pl2rightk,JoyBOrig,01000000h + PlayerDeviceHelp pl2Ak ,JoyBOrig,00800000h + PlayerDeviceHelp pl2Xk ,JoyBOrig,00400000h + PlayerDeviceHelp pl2Lk ,JoyBOrig,00200000h + PlayerDeviceHelp pl2Rk ,JoyBOrig,00100000h + PlayerDeviceHelp pl2ULk ,JoyBOrig,0A000000h + PlayerDeviceHelp pl2URk ,JoyBOrig,09000000h + PlayerDeviceHelp pl2DLk ,JoyBOrig,06000000h + PlayerDeviceHelp pl2DRk ,JoyBOrig,05000000h + PlayerDeviceFix JoyBOrig + mov al,[TurboCB] + test byte[TurboSw],al + jnz near .noswitch2 + PlayerDeviceHelp pl2Xtk ,JoyBOrig,00400000h + PlayerDeviceHelp pl2Ytk ,JoyBOrig,40000000h + PlayerDeviceHelp pl2Atk ,JoyBOrig,00800000h + PlayerDeviceHelp pl2Btk ,JoyBOrig,80000000h + PlayerDeviceHelp pl2Ltk ,JoyBOrig,00200000h + PlayerDeviceHelp pl2Rtk ,JoyBOrig,00100000h +.noswitch2 + ProcessKeyComb 1,JoyBOrig + or dword[JoyBOrig],00008000h ; Joystick Enable +.noinput2 + mov dword[JoyCOrig],0 + cmp byte[pl3contrl],0 + je near .noinput3 + ; Get Player3 input device + PlayerDeviceHelp pl3Bk ,JoyCOrig,80000000h + PlayerDeviceHelp pl3Yk ,JoyCOrig,40000000h + PlayerDeviceHelp pl3selk ,JoyCOrig,20000000h + PlayerDeviceHelp pl3startk,JoyCOrig,10000000h + PlayerDeviceHelp pl3upk ,JoyCOrig,08000000h + PlayerDeviceHelp pl3downk ,JoyCOrig,04000000h + PlayerDeviceHelp pl3leftk ,JoyCOrig,02000000h + PlayerDeviceHelp pl3rightk,JoyCOrig,01000000h + PlayerDeviceHelp pl3Ak ,JoyCOrig,00800000h + PlayerDeviceHelp pl3Xk ,JoyCOrig,00400000h + PlayerDeviceHelp pl3Lk ,JoyCOrig,00200000h + PlayerDeviceHelp pl3Rk ,JoyCOrig,00100000h + PlayerDeviceHelp pl3ULk ,JoyCOrig,0A000000h + PlayerDeviceHelp pl3URk ,JoyCOrig,09000000h + PlayerDeviceHelp pl3DLk ,JoyCOrig,06000000h + PlayerDeviceHelp pl3DRk ,JoyCOrig,05000000h + PlayerDeviceFix JoyCOrig + mov al,[TurboCB] + test byte[TurboSw],al + jnz near .noswitch3 + PlayerDeviceHelp pl3Xtk ,JoyCOrig,00400000h + PlayerDeviceHelp pl3Ytk ,JoyCOrig,40000000h + PlayerDeviceHelp pl3Atk ,JoyCOrig,00800000h + PlayerDeviceHelp pl3Btk ,JoyCOrig,80000000h + PlayerDeviceHelp pl3Ltk ,JoyCOrig,00200000h + PlayerDeviceHelp pl3Rtk ,JoyCOrig,00100000h +.noswitch3 + ProcessKeyComb 2,JoyCOrig + or dword[JoyCOrig],00008000h ; Joystick Enable +.noinput3 + mov dword[JoyDOrig],0 + cmp byte[pl4contrl],0 + je near .noinput4 + ; Get Player4 input device + PlayerDeviceHelp pl4Bk ,JoyDOrig,80000000h + PlayerDeviceHelp pl4Yk ,JoyDOrig,40000000h + PlayerDeviceHelp pl4selk ,JoyDOrig,20000000h + PlayerDeviceHelp pl4startk,JoyDOrig,10000000h + PlayerDeviceHelp pl4upk ,JoyDOrig,08000000h + PlayerDeviceHelp pl4downk ,JoyDOrig,04000000h + PlayerDeviceHelp pl4leftk ,JoyDOrig,02000000h + PlayerDeviceHelp pl4rightk,JoyDOrig,01000000h + PlayerDeviceHelp pl4Ak ,JoyDOrig,00800000h + PlayerDeviceHelp pl4Xk ,JoyDOrig,00400000h + PlayerDeviceHelp pl4Lk ,JoyDOrig,00200000h + PlayerDeviceHelp pl4Rk ,JoyDOrig,00100000h + PlayerDeviceHelp pl4ULk ,JoyDOrig,0A000000h + PlayerDeviceHelp pl4URk ,JoyDOrig,09000000h + PlayerDeviceHelp pl4DLk ,JoyDOrig,06000000h + PlayerDeviceHelp pl4DRk ,JoyDOrig,05000000h + PlayerDeviceFix JoyDOrig + mov al,[TurboCB] + test byte[TurboSw],al + jnz near .noswitch4 + PlayerDeviceHelp pl4Xtk ,JoyDOrig,00400000h + PlayerDeviceHelp pl4Ytk ,JoyDOrig,40000000h + PlayerDeviceHelp pl4Atk ,JoyDOrig,00800000h + PlayerDeviceHelp pl4Btk ,JoyDOrig,80000000h + PlayerDeviceHelp pl4Ltk ,JoyDOrig,00200000h + PlayerDeviceHelp pl4Rtk ,JoyDOrig,00100000h +.noswitch4 + ProcessKeyComb 3,JoyDOrig + or dword[JoyDOrig],00008000h ; Joystick Enable +.noinput4 + mov dword[JoyEOrig],0 + cmp byte[pl5contrl],0 + je near .noinput5 + ; Get Player4 input device + PlayerDeviceHelp pl5Bk ,JoyEOrig,80000000h + PlayerDeviceHelp pl5Yk ,JoyEOrig,40000000h + PlayerDeviceHelp pl5selk ,JoyEOrig,20000000h + PlayerDeviceHelp pl5startk,JoyEOrig,10000000h + PlayerDeviceHelp pl5upk ,JoyEOrig,08000000h + PlayerDeviceHelp pl5downk ,JoyEOrig,04000000h + PlayerDeviceHelp pl5leftk ,JoyEOrig,02000000h + PlayerDeviceHelp pl5rightk,JoyEOrig,01000000h + PlayerDeviceHelp pl5Ak ,JoyEOrig,00800000h + PlayerDeviceHelp pl5Xk ,JoyEOrig,00400000h + PlayerDeviceHelp pl5Lk ,JoyEOrig,00200000h + PlayerDeviceHelp pl5Rk ,JoyEOrig,00100000h + PlayerDeviceHelp pl5ULk ,JoyEOrig,0A000000h + PlayerDeviceHelp pl5URk ,JoyEOrig,09000000h + PlayerDeviceHelp pl5DLk ,JoyEOrig,06000000h + PlayerDeviceHelp pl5DRk ,JoyEOrig,05000000h + PlayerDeviceFix JoyEOrig + mov al,[TurboCB] + test byte[TurboSw],al + jnz near .noswitch5 + PlayerDeviceHelp pl5Xtk ,JoyEOrig,00400000h + PlayerDeviceHelp pl5Ytk ,JoyEOrig,40000000h + PlayerDeviceHelp pl5Atk ,JoyEOrig,00800000h + PlayerDeviceHelp pl5Btk ,JoyEOrig,80000000h + PlayerDeviceHelp pl5Ltk ,JoyEOrig,00200000h + PlayerDeviceHelp pl5Rtk ,JoyEOrig,00100000h +.noswitch5 + ProcessKeyComb 4,JoyEOrig + or dword[JoyEOrig],00008000h ; Joystick Enable +.noinput5 + cmp byte[pl12s34],1 + je .pl1234 +.nopl1234 + ret +.pl1234 + cmp byte[snesmouse],4 + je .nopl1234 + cmp byte[snesmouse],1 + je .nopl13 + mov eax,[JoyCOrig] + or [JoyAOrig],eax +.nopl13 + cmp byte[snesmouse],2 + je .nopl24 + cmp byte[snesmouse],3 + je .nopl24 + mov eax,[JoyDOrig] + or [JoyBOrig],eax +.nopl24 + ret + +;******************************************************* +; Init 65816 Initializes the Registers +;******************************************************* + +SECTION .data +NEWSYM disablehdma, db 0 +NEWSYM disableeffects, db 0 +NEWSYM hdmaearlstart, db 0 +NEWSYM disable65816sh, db 0 +NEWSYM disablespcclr, db 0 +NEWSYM virqnodisable, db 0 +NEWSYM numspcvblleft, dd 0 +NEWSYM spc700idle, dd 0 +NEWSYM IRQHack, dw 0 +NEWSYM CacheCheckSkip, db 0 +NEWSYM HIRQSkip, db 0 +NEWSYM ClearScreenSkip, db 0 +NEWSYM ENVDisable, db 0 +SECTION .text + +NEWSYM idledetectspc + inc dword[numspcvblleft] + cmp byte[SPCStallSetting],2 + jae .fullstall + inc byte[SPCStallSetting] + mov byte[ReturnFromSPCStall],1 + ret +.fullstall + mov dword[spc700idle],29 + mov dword[Msgptr],.unableskip + mov eax,[MsgCount] + mov [MessageOn],eax + ret + +SECTION .data +.unableskip db 'SPC700 STALL DETECTED.',0 + +SECTION .bss +NEWSYM ReturnFromSPCStall, resb 1 +NEWSYM SPCStallSetting, resb 1 +NEWSYM SPCSkipXtraROM, resb 1 +NEWSYM WindowDisables, resd 1 +SECTION .text + +%macro helpclearmem 2 + mov edi,%1 + mov ecx,%2 + rep stosb +%endmacro + +NEWSYM init65816 + mov byte[osm2dis],0 + mov byte[bgfixer2],0 + cmp byte[SA1Enable],0 + je .nosa1init + call SA1Reset + pushad + call SetAddressingModesSA1 + popad +.nosa1init + cmp byte[OBCEnable],0 + je .noobcinit + call InitOBC +.noobcinit + cmp byte[C4Enable],0 + je .noc4init + mov byte[osm2dis],1 + mov byte[bgfixer2],1 + call InitC4 +.noc4init + cmp byte[RTCEnable],0 + je .noRTCinit + call RTCinit +.noRTCinit + cmp byte[SPC7110Enable],0 + je .nospc7110init + call SPC7110init + mov dword[memtabler8+50h*4],memaccessspc7110r8 + mov dword[memtabler16+50h*4],memaccessspc7110r16 + mov dword[memtablew8+50h*4],memaccessspc7110w8 + mov dword[memtablew16+50h*4],memaccessspc7110w16 + mov eax,[romdata] + add eax,510000h + mov [snesmmap+50h*4],eax + mov [snesmap2+50h*4],eax + mov ecx,16384 +.spc7110clear + mov dword[eax],0 + add eax,4 + dec ecx + jnz .spc7110clear +.nospc7110init + mov byte[cycpb268],117 + mov byte[cycpb358],127 + mov byte[cycpbl2],117 + mov byte[cycpblt2],117 + mov byte[cycpbl],117 + mov byte[cycpblt],117 + + mov byte[SPCSkipXtraROM],0 + cmp byte[ReturnFromSPCStall],1 + jne near .nostall + mov byte[cycpb268],69 + mov byte[cycpb358],81 + mov byte[cycpbl2],69 + mov byte[cycpblt2],69 + mov byte[cycpbl],69 + mov byte[cycpblt],69 + mov byte[SPCSkipXtraROM],1 + cmp byte[SPCStallSetting],2 + jne .nostall2 + mov byte[cycpb268],240 + mov byte[cycpb358],240 + mov byte[cycpbl],240 + mov byte[cycpblt],240 + mov byte[cycpbl2],240 + mov byte[cycpblt2],240 + mov byte[SPCSkipXtraROM],0 +.nostall2 + jmp .stalled +.nostall + mov byte[SPCStallSetting],0 +.stalled + mov dword[numspcvblleft],60*8 + mov dword[SPC700write],0 + mov dword[SPC700read],0 + cmp dword[spc700read],0 + mov dword[spc700idle],0 + xor esi,esi +.loopa + mov al,[SPCROM+esi] + mov byte[spcextraram+esi],0FFh + mov [SPCRAM+0FFC0h+esi],al + inc esi + cmp esi,040h + jne .loopa + + ; Clear SPC Memory + pushad + call clearSPCRAM + call clearvidsound + popad + + mov byte[prevoamptr],0FFh + mov byte[disablehdma],0 + mov byte[disableeffects],0 + mov al,[opexec268b] + mov [opexec268],al + mov al,[opexec358b] + mov [opexec358],al + mov al,[opexec268cphb] + mov [opexec268cph],al + mov al,[opexec358cphb] + mov [opexec358cph],al + + mov dword[FIRTAPVal0],7Fh + mov dword[FIRTAPVal1],0 + mov dword[FIRTAPVal2],0 + mov dword[FIRTAPVal3],0 + mov dword[FIRTAPVal4],0 + mov dword[FIRTAPVal5],0 + mov dword[FIRTAPVal6],0 + mov dword[FIRTAPVal7],0 + mov byte[disable65816sh],0 + + ; Check Headers + pushad + call headerhack + popad + + mov byte[SPCRAM+0F4h],0 + mov byte[SPCRAM+0F5h],0 + mov byte[SPCRAM+0F6h],0 + mov byte[SPCRAM+0F7h],0 + mov byte[reg1read],0 + mov byte[reg2read],0 + mov byte[reg3read],0 + mov byte[reg4read],0 + mov dword[cycpbl],0 + mov byte[spcnumread],0 + mov dword[coladdr],0 + mov byte[NMIEnab],1 + mov word[VIRQLoc],0 + mov byte[doirqnext],0 + mov dword[reg1read],0 + mov word[resolutn],224 + mov byte[vidbright],0 + mov byte[forceblnk],0 + mov byte[spcP],0 + mov byte[timeron],0 + mov byte[JoyAPos],0 + mov byte[JoyBPos],0 + mov byte[coladdr],0 + mov byte[coladdg],0 + mov byte[coladdb],0 + + mov byte[INTEnab],0 + mov word[xa],0 + mov byte[xdb],0 + mov byte[xpb],0 + mov byte[xirqb],0 + mov word[xs],01FFh + mov word[xd],0 + mov word[xx],0 + mov word[xy],0 + mov dword[SDD1BankA],03020100h + mov byte[xp],00110100b ; NVMXDIZC + + push ebx + mov byte[xe],1 ; E + xor eax,eax + mov ax,[resetv] + mov [xpc],ax + mov ebx,[romdata] + add eax,ebx + pop ebx + mov byte[intrset],0 + cmp byte[romtype],1 + je .nohirom + mov byte[xpb],00h + mov byte[xirqb],00h +.nohirom + cmp word[xpc],8000h + jae .n + add word[xpc],8000h +; mov byte[xpb],40h +.n + mov al,[opexec268] + mov [cycpl],al ; 2.68 Mhz / 3.58 Mhz = 228 + mov [curcyc],al + mov al,[opexec268cph] + mov [cycphb],al ; 2.68 Mhz / 3.58 Mhz = 56 + mov byte[cycpbl],110 ; 3.58Mhz = 175 + mov byte[cycpblt],110 + mov word[curypos],0 + mov eax,tableD + mov [Curtableaddr],eax + mov byte[scrndis],00h + mov word[stackand],01FFh + mov word[stackor],0100h + + mov dword[nmiprevaddrl],0 + mov dword[nmiprevaddrh],0 + mov byte[nmirept],0 + mov byte[nmiprevline],224 + mov byte[nmistatus],0 + + cmp byte[GUIReset],1 + jne .notreseting + mov byte[GUIReset],0 + jmp .afterramclear +.notreseting + mov eax,055555555h + helpclearmem wramdataa, 65536 + helpclearmem ram7fa, 65536 +.afterramclear + cmp byte[BSEnable],1 + jne .notbsx2 + mov eax,0FFFFFFFFh + helpclearmem wramdataa, 65536 + helpclearmem ram7fa, 65536 + cmp byte[romtype],1 ;Hack for BS HiROMs + jne .notbsx2 + mov dword[ram7fa+65528],01010101h + mov dword[ram7fa+65532],01010101h +.notbsx2 + mov dword[wramreadptr],getwram1fff + mov dword[wramwriteptr],setwram1fff + ret + +SECTION .data +.boffound db '.....',0 +SECTION .text + +getwram1fff: + mov al,[wramdataa+1fffh] + ret +setwram1fff: + mov [wramdata+1fffh],al + ret + +;******************************************************* +; Init SNES Sets the pointers, etc. +;******************************************************* +; Set banks according to : +; Banks 00-3F,80-BF : WRAM (0000h-7FFFh), ROM Data (8000h-FFFFh) +; Banks 40-7F,C0-FF : ROM Data (0000h-FFFFh) +; Bank 70-77 : SRAM (0000h-7FFFh) +; Bank 7E : WRAM (0000h-FFFFh) +; Bank 7F : ExtendRAM (0000h-FFFFh) + +SECTION .bss +NEWSYM curromsize, resb 1 +NEWSYM cromptradd, resd 1 +NEWSYM lorommapmode2, resb 1 +SECTION .text + +NEWSYM initsnes + mov byte[ForceNewGfxOff],0 + + mov esi,[romdata] + add esi,7FC0h + cmp byte[BSEnable],0 + je .notbsx3 + cmp byte[romtype],1 ;Hack for BS HiROMs + je near .bslorom +.notbsx3 + mov esi,[romdata] + add esi,[infoloc] + add esi,22 + mov byte[MultiTap],1 + cmp byte[pl12s34],1 + je .nomtap + cmp byte[pl3contrl],0 + jne .mtap + cmp byte[pl4contrl],0 + jne .mtap + cmp byte[pl5contrl],0 + jne .mtap +.nomtap + mov byte[MultiTap],0 +.mtap + + cmp byte[romtype],1 + jne .nosfx + cmp byte[SFXEnable],1 + je near .sfx +.nosfx + cmp byte[SA1Enable],1 + je near SA1memmap + cmp byte[SDD1Enable],1 + je near SDD1memmap + + cmp byte[SPC7110Enable],1 + je near .hirom + ;Should catch DKJM2 here, but need to fix mem map as well + cmp byte[curromsize],13 + je near .lorom48 + cmp byte[romtype],1 + jne near .hirom + + ; set addresses 8000-FFFF + ; set banks 00-3F (40h x 32KB ROM banks @ 8000h) + mov edi,snesmmap + mov eax,[romdata] + sub eax,8000h + mov ecx,40h +.loopa + stosd + add eax,8000h + dec ecx + jnz .loopa + ; set banks 40-6F (30h x 64KB ROM banks @ 0000h) + mov ecx,40h +.loopb + stosd + add eax,8000h + dec ecx + jnz .loopb + ; set banks 80-BF (40h x 32KB ROM banks @ 8000h) + mov eax,[romdata] + cmp byte[lorommapmode2],0 + je .notlorommode2 + add eax,200000h +.notlorommode2 + sub eax,8000h + mov cx,20h +.loopc + stosd + add eax,8000h + dec ecx + jnz .loopc + cmp byte[lorommapmode2],0 + je .notlorommode2b + sub eax,200000h +.notlorommode2b + mov cx,20h +.loopclr + stosd + add eax,8000h + dec ecx + jnz .loopclr + ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) + mov ecx,40h +.loopd + stosd + add eax,8000h + dec ecx + jnz .loopd + ; set addresses 0000-7FFF (01h x 32KB WRAM @ 0000h) + ; set banks 00-3F + mov edi,snesmap2 + mov eax,[wramdata] + mov ecx,40h +.loopa2 + stosd + dec ecx + jnz .loopa2 + ; set banks 40-6F (30h x 64KB ROM banks @ 0000h) + mov eax,[romdata] + add eax,200000h + mov ecx,40h +.loopb2 + stosd + add eax,8000h + dec ecx + jnz .loopb2 + ; set banks 80-BF (01h x 32KB WRAM @ 0000h) + mov eax,[wramdata] + mov ecx,40h +.loopc2 + stosd + dec ecx + jnz .loopc2 + ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) + mov eax,[romdata] + add eax,200000h + mov ecx,40h +.loopd2 + stosd + add eax,8000h + dec ecx + jnz .loopd2 + ; set bank 70 + mov eax,[sram] + xor ebx,ebx + mov bl,70h +.nextsram + mov [snesmap2+ebx*4],eax + inc bl + cmp bl,77h + jbe .nextsram + ; set bank 7E + mov eax,[wramdata] + mov [snesmmap+7Eh*4],eax + mov [snesmap2+7Eh*4],eax + ; set bank 7F + mov eax,[ram7f] + mov [snesmmap+7Fh*4],eax + mov [snesmap2+7Fh*4],eax + ret + +.bslorom + ; set addresses 8000-FFFF + ; set banks 00-3F (40h x 32KB ROM banks @ 8000h) + mov edi,snesmmap + mov eax,[romdata] + sub eax,8000h + mov ecx,40h +.loopas + stosd + add eax,8000h + dec ecx + jnz .loopas + ; set banks 40-6F (30h x 64KB ROM banks @ 0000h) + mov ecx,40h +.loopbs + stosd + add eax,8000h + dec ecx + jnz .loopbs + ; set banks 80-BF (40h x 32KB ROM banks @ 8000h) + mov eax,[romdata] + sub eax,8000h + mov cx,40h +.loopcs + stosd + add eax,8000h + dec ecx + jnz .loopcs + ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) + mov eax,[romdata] + add eax,8000h + mov ecx,40h +.loopds + stosd + add eax,8000h + dec ecx + jnz .loopds + ; set addresses 0000-7FFF (01h x 32KB WRAM @ 0000h) + ; set banks 00-3F + mov edi,snesmap2 + mov eax,[wramdata] + mov ecx,40h +.loopa2s + stosd + dec ecx + jnz .loopa2s + ; set banks 40-6F (30h x 64KB ROM banks @ 0000h) + mov eax,[romdata] + add eax,200000h + mov ecx,40h +.loopb2s + stosd + add eax,8000h + dec ecx + jnz .loopb2s + ; set banks 80-BF (01h x 32KB WRAM @ 0000h) + mov eax,[wramdata] + mov ecx,40h +.loopc2s + stosd + dec ecx + jnz .loopc2s + ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) + mov eax,[romdata] + add eax,8000h + mov ecx,40h +.loopd2s + stosd + add eax,8000h + dec ecx + jnz .loopd2s + ; set bank 70 + mov eax,[sram] + xor ebx,ebx + mov bl,70h +.nextsrams + mov [snesmap2+ebx*4],eax + inc bl + cmp bl,77h + jbe .nextsrams + ; set bank 7E + mov eax,[wramdata] + mov [snesmmap+7Eh*4],eax + mov [snesmap2+7Eh*4],eax + ; set bank 7F + mov eax,[ram7f] + mov [snesmmap+7Fh*4],eax + mov [snesmap2+7Fh*4],eax + ret + +.lorom48 + mov byte[cycpb268],94 + mov byte[cycpb358],94 + mov byte[cycpbl2],94 + mov byte[cycpblt2],94 + mov byte[cycpbl],94 + mov byte[cycpblt],94 + mov byte[opexec268],183 + mov byte[opexec358],187 + mov byte[opexec268cph],30 + mov byte[opexec358cph],30 + + 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 + ; set addresses 8000-FFFF + ; set banks 00-3F (40h x 32KB ROM banks @ 8000h) + mov edi,snesmmap + mov eax,[romdata] + sub eax,8000h + mov ecx,40h +.loopa3 + stosd + add eax,8000h + dec ecx + jnz .loopa3 + ; set banks 40-6F (30h x 64KB ROM banks @ 8000h) + mov eax,[romdata] + sub eax,8000h + mov ecx,40h +.loopb32 + stosd + add eax,8000h + dec ecx + jnz .loopb32 + ; set banks 80-BF (40h x 32KB ROM banks @ 8000h) + mov eax,[romdata] + sub eax,8000h + mov cx,40h +.loopc3 + stosd + add eax,8000h + dec ecx + jnz .loopc3 + ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) + mov eax,[romdata] + add eax,200000h + mov ecx,40h +.loopd3 + stosd + add eax,10000h + dec ecx + jnz .loopd3 + ; set addresses 0000-7FFF (01h x 32KB WRAM @ 0000h) + ; set banks 00-3F + mov edi,snesmap2 + mov eax,[wramdata] + mov ecx,40h +.loopa23 + stosd + dec ecx + jnz .loopa23 + ; set banks 40-6F (30h x 64KB ROM banks @ 0000h) + mov eax,[romdata] + add eax,100000h + mov ecx,40h +.loopb3 + stosd + add eax,8000h + dec ecx + jnz .loopb3 + ; set banks 80-BF (01h x 32KB WRAM @ 0000h) + mov eax,[wramdata] + mov ecx,40h +.loopc23 + stosd + dec ecx + jnz .loopc23 + ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) + mov eax,[romdata] + add eax,200000h + mov ecx,40h +.loopd23 + stosd + add eax,10000h + dec ecx + jnz .loopd23 + ; set bank 70 + mov eax,[sram] + xor ebx,ebx + mov bl,70h +.nextsram3 + mov [snesmap2+ebx*4],eax + inc bl + cmp bl,77h + jbe .nextsram3 + ; set bank 7E + mov eax,[wramdata] + mov [snesmmap+7Eh*4],eax + mov [snesmap2+7Eh*4],eax + ; set bank 7F + mov eax,[ram7f] + mov [snesmmap+7Fh*4],eax + mov [snesmap2+7Fh*4],eax + pushad + call IntlEHi ;Interleave 48Mb ROM, because the map is broken + popad + ret +.hirom + ; set addresses 8000-FFFF + ; set banks 00-3F (40h x 32KB ROM banks @ 8000h) + mov edi,snesmmap + mov eax,[romdata] + mov ecx,40h +.loopab + stosd + add eax,10000h + dec ecx + jnz .loopab + ; set banks 40-6F (30h x 64KB ROM banks @ 0000h) + mov eax,[romdata] + mov ecx,40h +.loopbb + stosd + add eax,10000h + dec ecx + jnz .loopbb + ; set banks 80-BF (40h x 32KB ROM banks @ 8000h) + mov eax,[romdata] + mov ecx,40h +.loopcb + stosd + add eax,10000h + dec ecx + jnz .loopcb + ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) + mov eax,[romdata] + mov ecx,40h +.loopdb + stosd + add eax,10000h + dec ecx + jnz .loopdb + ; set addresses 0000-7FFF (01h x 32KB WRAM @ 0000h) + ; set banks 00-3F + mov edi,snesmap2 + mov eax,[wramdata] + mov ecx,40h +.loopa2b + stosd + dec ecx + jnz .loopa2b + ; set banks 40-6F (30h x 64KB ROM banks @ 0000h) + mov eax,[romdata] + mov cx,40h +.loopb2b + stosd + add eax,10000h + dec ecx + jnz .loopb2b + ; set banks 80-BF (01h x 32KB WRAM @ 0000h) + mov eax,[wramdata] + mov cx,40h +.loopc2b + stosd + dec ecx + jnz .loopc2b + ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) + mov eax,[romdata] + mov cx,40h +.loopd2b + stosd + add eax,10000h + dec ecx + jnz .loopd2b + ; set bank 70 + mov eax,[sram] + xor ebx,ebx + mov bl,70h +.nextsramb + mov [snesmap2+ebx*4],eax + inc bl + cmp bl,77h + jbe .nextsramb + ; set bank 7E + mov eax,[wramdata] + mov [snesmmap+7Eh*4],eax + mov [snesmap2+7Eh*4],eax + ; set bank 7F + mov eax,[ram7f] + mov [snesmmap+7Fh*4],eax + mov [snesmap2+7Fh*4],eax + ret + +.sfx + mov byte[MultiTap],0 + ; Clear sfxregisters + mov edi,SfxR0 + mov ecx,16 + xor eax,eax + rep stosd + ; set addresses 8000-FFFF + ; set banks 00-3F (40h x 32KB ROM banks @ 8000h) + mov edi,snesmmap + mov eax,[romdata] +; sub eax,8000h + mov ecx,40h +.loopa3s + stosd + add eax,10000h + dec ecx + jnz .loopa3s + ; set banks 40-6F (30h x 64KB ROM banks @ 0000h) + mov eax,[romdata] +; add eax,200000h + add eax,8000h + mov ecx,40h +.loopb3s + stosd + add eax,20000h + dec ecx + jnz .loopb3s + ; set banks 80-BF (40h x 32KB ROM banks @ 8000h) + mov eax,[romdata] +; sub eax,8000h + mov cx,40h +.loopc3s + stosd + add eax,10000h + dec ecx + jnz .loopc3s + ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) + mov eax,[romdata] +; add eax,200000h + add eax,8000h + mov ecx,40h +.loopd3s + stosd + add eax,20000h + dec ecx + jnz .loopd3s + ; set addresses 0000-7FFF (01h x 32KB WRAM @ 0000h) + ; set banks 00-3F + mov edi,snesmap2 + mov eax,[wramdata] + mov ecx,40h +.loopa23s + stosd + dec ecx + jnz .loopa23s + ; set banks 40-6F (30h x 64KB ROM banks @ 0000h) + mov eax,[romdata] + add eax,8000h + mov ecx,40h +.loopb23s + stosd + add eax,20000h + dec ecx + jnz .loopb23s + ; set banks 80-BF (01h x 32KB WRAM @ 0000h) + mov eax,[wramdata] + mov ecx,40h +.loopc23s + stosd + dec ecx + jnz .loopc23s + ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) + mov eax,[romdata] + add eax,8000h + mov ecx,40h +.loopd23s + stosd + add eax,20000h + dec ecx + jnz .loopd23s + ; set bank 70 + mov eax,[sram] + mov [snesmap2+78h*4],eax + mov [snesmap2+79h*4],eax + mov eax,[sfxramdata] + mov [snesmap2+70h*4],eax + add eax,65536 + mov [snesmap2+71h*4],eax + add eax,65536 + mov [snesmap2+72h*4],eax + add eax,65536 + mov [snesmap2+73h*4],eax + ; set bank 7E + mov eax,[wramdata] + mov [snesmmap+7Eh*4],eax + mov [snesmap2+7Eh*4],eax + ; set bank 7F + mov eax,[ram7f] + mov [snesmmap+7Fh*4],eax + mov [snesmap2+7Fh*4],eax + call preparesfx + ret + +SA1memmap: + mov eax,[romdata] + cmp dword[eax+0B95h],0ADCF10A9h + jne .nosuccess + mov byte[eax+0B96h],0 +.nosuccess + mov byte[MultiTap],0 + ; set addresses 8000-FFFF + ; set banks 00-3F (40h x 32KB ROM banks @ 8000h) + mov edi,snesmmap + mov eax,[romdata] + sub eax,8000h + mov ecx,40h +.loopa3s + stosd + add eax,8000h + dec ecx + jnz .loopa3s + ; set banks 40-6F (30h x 64KB ROM banks @ 0000h) + mov eax,[romdata] +; add eax,400000h + mov ecx,40h +.loopb3s + stosd + add eax,10000h + dec ecx + jnz .loopb3s + ; set banks 80-BF (40h x 32KB ROM banks @ 8000h) + mov eax,[romdata] + add eax,200000h + sub eax,8000h + mov cx,40h +.loopc3s + stosd + add eax,8000h + dec ecx + jnz .loopc3s + ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) + mov eax,[romdata] + add eax,00000h + mov ecx,40h +.loopd3s + stosd + add eax,10000h + dec ecx + jnz .loopd3s + ; set addresses 0000-7FFF (01h x 32KB WRAM @ 0000h) + ; set banks 00-3F + mov edi,snesmap2 + mov eax,[wramdata] + mov ecx,40h +.loopa23s + stosd + dec ecx + jnz .loopa23s + ; set banks 40-6F (30h x 64KB ROM banks @ 0000h) + mov eax,[romdata] + add eax,400000h + mov ecx,40h +.loopb23s + stosd + add eax,10000h + dec ecx + jnz .loopb23s + ; set banks 80-BF (01h x 32KB WRAM @ 0000h) + mov eax,[wramdata] + mov ecx,40h +.loopc23s + stosd + dec ecx + jnz .loopc23s + ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) + mov eax,[romdata] + add eax,00000h + mov ecx,40h +.loopd23s + stosd + add eax,10000h + dec ecx + jnz .loopd23s + ; set bank 7E + mov eax,[wramdata] + mov [snesmmap+7Eh*4],eax + mov [snesmap2+7Eh*4],eax + ; set bank 7F + mov eax,[ram7f] + mov [snesmmap+7Fh*4],eax + mov [snesmap2+7Fh*4],eax + ret + +SDD1memmap: + mov eax,[romdata] + cmp dword[eax+0B95h],0ADCF10A9h + jne .nosuccess + mov byte[eax+0B96h],0 +.nosuccess + mov byte[MultiTap],0 + ; set addresses 8000-FFFF + ; set banks 00-3F (40h x 32KB ROM banks @ 8000h) + mov edi,snesmmap + mov eax,[romdata] + sub eax,8000h + mov ecx,40h +.loopa3s + stosd + add eax,8000h + dec ecx + jnz .loopa3s + ; set banks 40-6F (30h x 64KB ROM banks @ 0000h) + mov eax,[romdata] +; add eax,400000h + mov ecx,40h +.loopb3s + stosd + add eax,10000h + dec ecx + jnz .loopb3s + ; set banks 80-BF (40h x 32KB ROM banks @ 8000h) + mov eax,[romdata] +; add eax,200000h + sub eax,8000h + mov cx,40h +.loopc3s + stosd + add eax,8000h + dec ecx + jnz .loopc3s + ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) + mov eax,[romdata] + add eax,00000h + mov ecx,40h +.loopd3s + stosd + add eax,10000h + dec ecx + jnz .loopd3s + ; set addresses 0000-7FFF (01h x 32KB WRAM @ 0000h) + ; set banks 00-3F + mov edi,snesmap2 + mov eax,[wramdata] + mov ecx,40h +.loopa23s + stosd + dec ecx + jnz .loopa23s + ; set banks 40-6F (30h x 64KB ROM banks @ 0000h) + mov eax,[romdata] + add eax,400000h + mov ecx,40h +.loopb23s + stosd + add eax,10000h + dec ecx + jnz .loopb23s + ; set banks 80-BF (01h x 32KB WRAM @ 0000h) + mov eax,[wramdata] + mov ecx,40h +.loopc23s + stosd + dec ecx + jnz .loopc23s + ; set banks C0-FF (40h x 64KB ROM banks @ 0000h) + mov eax,[romdata] + add eax,00000h + mov ecx,40h +.loopd23s + stosd + add eax,10000h + dec ecx + jnz .loopd23s + ; set bank 7E + mov eax,[wramdata] + mov [snesmmap+7Eh*4],eax + mov [snesmap2+7Eh*4],eax + ; set bank 7F + mov eax,[ram7f] + mov [snesmmap+7Fh*4],eax + mov [snesmap2+7Fh*4],eax + ret + +SECTION .data +NEWSYM SFXCounter, dd 0 + +SECTION .text + +NEWSYM preparesfx + mov byte[SFXCounter],0 + mov esi,[romdata] + add esi,07FC0h + cmp dword[esi],'FX S' + je .yessfxcounter + cmp dword[esi],'DIRT' + je .yessfxcounter + cmp dword[esi],'Stun' + jne .nosfxcounter + mov byte[ForceNewGfxOff],1 +.yessfxcounter + mov byte[SFXCounter],1 +.nosfxcounter + + ; make table + mov byte[SfxAC],0 + mov eax,[romdata] + cmp dword[eax+02B80h],0AB6CAB6Ch + jne .noac + mov byte[SfxAC],1 +.noac + ; duplicate sfx data + mov esi,[romdata] + mov edi,[romdata] + add esi,1F8000h + add edi,3F0000h + mov dl,40h +.swaploopb + mov ecx,32768 +.swaploop + mov al,[esi] + mov [edi],al + mov [edi+32768],al + inc esi + inc edi + dec ecx + jnz .swaploop + sub edi,65536+32768 + sub esi,65536 + dec dl + jnz .swaploopb + ret + + ; copy address 0 to 200000h + ; make table 1 (0 .. 127) + mov esi,[romdata] + mov edi,[romdata] + add edi,200000h + mov ecx,200000h +.n + mov al,[esi] + mov [edi],al + inc esi + inc edi + dec ecx + jnz .n + ret + +;******************************************************* +; Print Hexadecimal (16-bit/8-bit) +;******************************************************* +NEWSYM printhex + mov ecx,4 + xor ebx,ebx +.loopa + mov bx,ax + and bx,0F000h + shr bx,12 + mov dl,[.hexdat+ebx] + push ax + mov ah,02h + call Output_Text + pop ax + shl ax,4 + dec ecx + jnz .loopa + ret + +SECTION .data +.hexdat db '0123456789ABCDEF' +SECTION .text + +NEWSYM printhex8 + mov ecx,2 + xor ebx,ebx +.loopb + mov bx,ax + and bx,0F0h + shr bx,4 + mov dl,[printhex.hexdat+ebx] + push ax + mov ah,02h + call Output_Text + pop ax + shl ax,4 + dec ecx + jnz .loopb + ret + +;******************************************************* +; Load File +;******************************************************* +; Search for header size first which is filesize MOD 32768 + +NEWSYM PatchIPS +%ifdef __UNIXSDL__ + pushad + call pushdir + popad +%endif + mov eax,fname+1 + ; search for . or 0 +.next + cmp byte[eax],0 + je .foundend + inc eax + jmp .next +.foundend + mov ebx,eax +.findnext2 + dec eax + cmp eax,fname + je .failfound +%ifdef __UNIXSDL__ + cmp byte[eax],'/' +%else + cmp byte[eax],'\' +%endif + je .failfound + cmp byte[eax],'.' + je .foundokay + jmp .findnext2 +.failfound + mov eax,ebx +.foundokay + mov ebx,[eax] + mov [Prevextn],ebx + mov dword[eax],'.ips' + mov byte[eax+4],0 + push eax +%ifdef __UNIXSDL__ + cmp byte[ZipSupport], 1 + je .nochangedir + mov ebx,LoadDir + call Change_Dir +.nochangedir: +%endif + mov edx,fname+1 + mov [patchfile],edx + pushad + call PatchUsingIPS + popad + pop eax + mov ebx,[Prevextn] + mov [eax],ebx +%ifdef __UNIXSDL__ + pushad + call popdir + popad +%endif + ret + +SECTION .bss +NEWSYM Prevextn, resd 1 +NEWSYM IPSPatched, resb 1 +SECTION .text + +OpenCombFile: + mov edx,fnames+1 +.next + cmp byte[edx],0 + je .found + inc edx + jmp .next +.found + dec edx + cmp byte[edx],'.' + je .found2 + jmp .found +.found2 + mov dword[edx],'.cmb' + push edx + mov dword[NumComboLocl],0 + mov edx,fnames+1 + call Open_File + jc .failb + mov bx,ax + mov edx,ComboBlHeader + mov ecx,23 + call Read_File + mov al,[ComboBlHeader+22] + or al,al + jz .done + mov [NumComboLocl],al + mov ecx,[NumComboLocl] + mov edx,ecx + shl ecx,6 + add ecx,edx + add ecx,edx + mov edx,CombinDataLocl + call Read_File +.done + call Close_File +.failb + pop edx + mov dword[edx],'.srm' + ret + +NEWSYM SaveCombFile + cmp byte[romloadskip],0 + jne near .notfound + mov edx,fnames+1 +.next + cmp byte[edx],0 + je .found + inc edx + jmp .next +.found + dec edx + cmp byte[edx],'.' + je .found2 + jmp .found +.found2 + mov dword[edx],'.cmb' + push edx + mov al,[NumComboLocl] + or al,al + jz .failb + mov [ComboHeader+22],al + mov edx,fnames+1 + call Create_File + jc .failb + mov bx,ax + mov edx,ComboHeader + mov ecx,23 + call Write_File + mov ecx,[NumComboLocl] + mov edx,ecx + shl ecx,6 + add ecx,edx + add ecx,edx + mov edx,CombinDataLocl + call Write_File + call Close_File +.failb + pop edx + mov dword[edx],'.srm' +.notfound + ret + +NEWSYM loadfile + mov byte[TextFile], 0 + call GetCurDir + mov byte[InGUI],0 +%ifdef __UNIXSDL__ + mov dl,[InitDrive] + mov ebx,InitDir + call Change_Dir +%endif + + jmp loadfileGUI.nogui + +SECTION .data +.failop db 'Error opening file!',13,10,0 +.opened db 'File opened successfully!',13,10,0 +.mult db 'Multiple file format detected.',13,10,13,10,0 +SECTION .bss +.cchar resb 1 +.dotpos resd 1 +.curfileofs resd 1 +.filehand resw 1 +.temp resb 1 +.fail resb 1 + + +NEWSYM Checksumvalue, resw 1 +NEWSYM Checksumvalue2, resw 1 ;outdated, but needed for the command line loader +NEWSYM CRC32, resd 1 +NEWSYM SramExists, resb 1 +NEWSYM NumofBanks, resd 1 +NEWSYM NumofBytes, resd 1 +NEWSYM ZipSupport, resb 1 +InGUI resb 1 + +SECTION .data + +PrevDir db '..',0 +GUIfindBlank db '*.',0 + +SECTION .bss +ZipError resb 1 + +SECTION .data + +SPC7110DirEntry db '*.bin',0 +spc7110notfound db 'DECOMPRESSED PACK NOT FOUND',0 + +SECTION .bss + +SPC7110Allocated resb 1 +SPC7110CPtr resd 1 +SPC7110CPtr2 resd 1 +NEWSYM SPC7110Entries, resd 1 + +SECTION .text + +NEWSYM SPC7110Load + mov dword[SPC7110Entries],0 + mov esi,[romdata] + add esi,32704+22 + add esi,8000h + mov al,[esi] + cmp byte[romtype],2 + jne .nothirom + cmp al,0F9h + je .spc7110 + cmp al,0F5h + je .spc7110 +.nothirom + ret +.spc7110 + pushad + call SPC7PackIndexLoad + popad + cmp dword[SPC7110IndexSize],0 + je .nodir + ret +.nodir + mov dword[Msgptr],spc7110notfound + mov dword[MessageOn],60*6 + ret + +NEWSYM loadfileGUI + mov byte[InGUI],1 +.nogui + mov byte[spcon],0 + cmp byte[SPCDisable],1 + je .nosound + mov byte[spcon],1 +.nosound + + mov byte[TextFile], 0 + mov dword[MessageOn],0 + mov byte[loadedfromgui],1 + mov byte[yesoutofmemory],0 + mov byte[.fail],0 + mov byte[IPSPatched],0 + mov byte[GUIloadfailed],0 + + mov edx,fname+1 + mov [ZOpenFileName],edx + + pushad + call loadROM + popad + + cmp dword[curromspace],0 + je near .failed + + call convertsram + mov byte[SramExists],0 + + ; change to sram dir + pushad + call SRAMChdir + popad + + ; open .srm file + mov edx,fnames+1 + call Open_File + jc .notexist + mov byte[SramExists],1 + mov bx,ax + mov ecx,65536 + mov edx,[sram] + call Read_File + call Close_File + jc near .failed2 +.notexist + call OpenCombFile + cmp byte[InGUI],1 + je .inguib + mov edx,.opened + mov ah,9 + call Output_Text +.inguib + + mov eax,[curromspace] + mov [.curfileofs],eax + mov [NumofBytes],eax + shr eax,15 + mov [NumofBanks],eax + + cmp byte[.fail],0 + je .notfailed + mov byte[yesoutofmemory],1 +.notfailed + + ; copy fnames to fname + cmp byte[InGUI],1 + je .nosramtof + mov eax,fname+1 + mov ebx,fnames+1 +.loopsc + mov dl,[ebx] + mov [eax],dl + inc ebx + inc eax + or dl,dl + jnz .loopsc +.nosramtof + mov byte[TextFile], 1 + cmp byte[IPSPatched],0 + jne .patched + call PatchIPS +.patched + ret + +.failed +.failed2 + mov byte[TextFile], 1 + cmp byte[InGUI],1 + je .noguic + mov edx,.failop + mov ah,9 + call Output_Text + jmp DosExit +.noguic + mov byte[GUIloadfailed],1 + ret + +SECTION .data +.failop db 'Error opening file!',13,10,0 +.opened db 'File opened successfully!',13,10,0 +.mult db 'Multiple file format detected.',13,10,13,10,0 + +SECTION .bss + +.cchar resb 1 +.dotpos resd 1 +.curfileofs resd 1 +.filehand resw 1 +.temp resb 1 +.fail resb 1 +NEWSYM GUIloadfailed, resb 1 + +SECTION .text + +NEWSYM convertsram + cmp byte[cfgloadsdir],1 + je .sdrivechange + ret +.sdrivechange + ; copy fnames/fnamest to not have any '\' in them + mov esi,fnames+1 + mov ebx,0 +.next + mov al,[esi] + cmp al,0 + je .fincutoff + cmp al,'\' + je .cutoff + cmp al,'/' + je .cutoff + cmp al,':' + je .cutoff + inc esi + jmp .next +.cutoff + inc esi + mov ebx,esi + jmp .next +.fincutoff + cmp ebx,0 + je .nocutoff + mov esi,ebx + mov edi,fnames+1 +.next2 + mov al,[esi] + mov [edi],al + inc esi + inc edi + cmp al,0 + jne .next2 +.nocutoff + mov esi,fnamest+1 + mov ebx,0 +.nextb + mov al,[esi] + cmp al,0 + je .fincutoffb + cmp al,'\' + je .cutoffb + cmp al,'/' + je .cutoffb + cmp al,':' + je .cutoffb + inc esi + jmp .nextb +.cutoffb + inc esi + mov ebx,esi + jmp .nextb +.fincutoffb + cmp ebx,0 + je .nocutoffb + mov esi,ebx + sub esi,fnamest+1 + sub [statefileloc],esi + mov esi,ebx + mov edi,fnamest+1 +.next2b + mov al,[esi] + mov [edi],al + inc esi + inc edi + cmp al,0 + jne .next2b +.nocutoffb + ; change to sram directory + pushad + call SRAMChdir + popad + ret + +SECTION .data +NEWSYM CSStatus, db ' TYPE: ',0 +NEWSYM CSStatus2, db 'INTERLEAVED: BANK: CHKSUM: ',0 +NEWSYM CSStatus3, db 'VIDEO: CRC32: ',0 + +;******************************************************* +; Show Information +;******************************************************* +; +; Maker Code = FFB0-FFB1 +; Game Code = FFB2-FFB5 +; Expansion RAM Size = FFBD (0=none, 1=16kbit, 3=64kbit, 5=256kbit,etc. +; Map Mode = FFD5 2.68-20h=map20h,21h=map21h,22h=reserved,23h=SA-1,25h=map25h +; 3.58-30h=map20h,31h=map21h,35h=map25h,highspeed +; Rom Mask Version = FFDB +; FFD6 (ROM Type) : 0*=DSP,1*=SFX,2*=OBC1,3*=SA-1,E*-F*=other +; *3=ROM,*4=ROM+RAM,*5=ROM+RAM+BATTERY,*6=ROM+BATTERY +; F3=C4 + + +SECTION .bss +NEWSYM DSP1Type, resb 1 +NEWSYM intldone, resb 1 +NEWSYM C4RamR, resd 1 +NEWSYM C4RamW, resd 1 +NEWSYM C4Ram, resd 1 +NEWSYM ROMTypeNOTFound, resb 1 +NEWSYM Interleaved, resb 1 +SECTION .text + +NEWSYM outofmemfix + mov esi,[romdata] + cmp byte[romtype],2 + jne .nhirom + add esi,8000h +.nhirom + mov word[resetv],8000h + mov word[xpc],8000h + mov byte[esi],58h + mov byte[esi+1],80h + mov byte[esi+2],0FEh + mov dword[Msgptr],outofmemoryerror + cmp byte[newgfx16b],1 + jne .notso + mov dword[Msgptr],outofmemoryerror2 +.notso + mov dword[MessageOn],0FFFFFFFFh + ret + +SECTION .bss +NEWSYM yesoutofmemory, resb 1 +SECTION .data +NEWSYM outofmemoryerror, db 'OUT OF MEMORY.',0 +NEWSYM outofmemoryerror2, db 'ROM IS TOO BIG.',0 diff --git a/zsnes/src/linux_evdev.c b/zsnes/src/linux_evdev.c new file mode 100644 index 00000000..b116881b --- /dev/null +++ b/zsnes/src/linux_evdev.c @@ -0,0 +1,337 @@ +/* + * Support for Linux evdevs...the /dev/input/event* devices. + * + * Please see the file LICENSE in the source's root directory. + * + * This file written by Ryan C. Gordon. + */ + +#ifdef __linux__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include /* evdev interface... */ + +#include "manymouse.h" + +#define test_bit(array, bit) (array[bit/8] & (1<<(bit%8))) + +/* linux allows 32 evdev nodes currently. */ +#define MAX_MICE 32 +typedef struct +{ + int fd; + int min_x; + int min_y; + int max_x; + int max_y; + char name[64]; +} MouseStruct; + +static MouseStruct mice[MAX_MICE]; +static unsigned int available_mice = 0; + + +static int poll_mouse(MouseStruct *mouse, ManyMouseEvent *outevent) +{ + int unhandled = 1; + while (unhandled) /* read until failure or valid event. */ + { + struct input_event event; + int br = read(mouse->fd, &event, sizeof (event)); + if (br == -1) + { + if (errno == EAGAIN) + return(0); /* just no new data at the moment. */ + + /* mouse was unplugged? */ + close(mouse->fd); /* stop reading from this mouse. */ + mouse->fd = -1; + outevent->type = MANYMOUSE_EVENT_DISCONNECT; + return(1); + } /* if */ + + if (br != sizeof (event)) + return(0); /* oh well. */ + + unhandled = 0; /* will reset if necessary. */ + outevent->value = event.value; + if (event.type == EV_REL) + { + outevent->type = MANYMOUSE_EVENT_RELMOTION; + if ((event.code == REL_X) || (event.code == REL_DIAL)) + outevent->item = 0; + else if (event.code == REL_Y) + outevent->item = 1; + + else if (event.code == REL_WHEEL) + { + outevent->type = MANYMOUSE_EVENT_SCROLL; + outevent->item = 0; + } /* else if */ + + else if (event.code == REL_HWHEEL) + { + outevent->type = MANYMOUSE_EVENT_SCROLL; + outevent->item = 1; + } /* else if */ + + else + { + unhandled = 1; + } /* else */ + } /* if */ + + else if (event.type == EV_ABS) + { + outevent->type = MANYMOUSE_EVENT_ABSMOTION; + if (event.code == ABS_X) + { + outevent->item = 0; + outevent->minval = mouse->min_x; + outevent->maxval = mouse->max_x; + } /* if */ + else if (event.code == ABS_Y) + { + outevent->item = 1; + outevent->minval = mouse->min_y; + outevent->maxval = mouse->max_y; + } /* if */ + else + { + unhandled = 1; + } /* else */ + } /* else if */ + + else if (event.type == EV_KEY) + { + outevent->type = MANYMOUSE_EVENT_BUTTON; + if ((event.code >= BTN_LEFT) && (event.code <= BTN_BACK)) + outevent->item = event.code - BTN_MOUSE; + + /* just in case some device uses this block of events instead... */ + else if ((event.code >= BTN_MISC) && (event.code <= BTN_LEFT)) + outevent->item = (event.code - BTN_MISC); + + else if (event.code == BTN_TOUCH) /* tablet... */ + outevent->item = 0; + else if (event.code == BTN_STYLUS) /* tablet... */ + outevent->item = 1; + else if (event.code == BTN_STYLUS2) /* tablet... */ + outevent->item = 2; + + else + { + /*printf("unhandled mouse button: 0x%X\n", event.code);*/ + unhandled = 1; + } /* else */ + } /* else if */ + else + { + unhandled = 1; + } /* else */ + } /* while */ + + return(1); /* got a valid event */ +} /* poll_mouse */ + + +static int init_mouse(const char *fname, int fd) +{ + MouseStruct *mouse = &mice[available_mice]; + int has_absolutes = 0; + int is_mouse = 0; + unsigned char relcaps[(REL_MAX / 8) + 1]; + unsigned char abscaps[(ABS_MAX / 8) + 1]; + unsigned char keycaps[(KEY_MAX / 8) + 1]; + + memset(relcaps, '\0', sizeof (relcaps)); + memset(abscaps, '\0', sizeof (abscaps)); + memset(keycaps, '\0', sizeof (keycaps)); + + if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof (keycaps)), keycaps) == -1) + return 0; /* gotta have some buttons! :) */ + + if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof (relcaps)), relcaps) != -1) + { + if ( (test_bit(relcaps, REL_X)) && (test_bit(relcaps, REL_Y)) ) + { + if (test_bit(keycaps, BTN_MOUSE)) + is_mouse = 1; + } /* if */ + + #if ALLOW_DIALS_TO_BE_MICE + if (test_bit(relcaps, REL_DIAL)) + is_mouse = 1; // griffin powermate? + #endif + } /* if */ + + if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof (abscaps)), abscaps) != -1) + { + if ( (test_bit(abscaps, ABS_X)) && (test_bit(abscaps, ABS_Y)) ) + { + /* might be a touchpad... */ + if (test_bit(keycaps, BTN_TOUCH)) + { + is_mouse = 1; /* touchpad, touchscreen, or tablet. */ + has_absolutes = 1; + } /* if */ + } /* if */ + } /* if */ + + if (!is_mouse) + return 0; + + mouse->min_x = mouse->min_y = mouse->max_x = mouse->max_y = 0; + if (has_absolutes) + { + struct input_absinfo absinfo; + if (ioctl(fd, EVIOCGABS(ABS_X), &absinfo) == -1) + return 0; + mouse->min_x = absinfo.minimum; + mouse->max_x = absinfo.maximum; + + if (ioctl(fd, EVIOCGABS(ABS_Y), &absinfo) == -1) + return 0; + mouse->min_y = absinfo.minimum; + mouse->max_y = absinfo.maximum; + } /* if */ + + if (ioctl(fd, EVIOCGNAME(sizeof (mouse->name)), mouse->name) == -1) + snprintf(mouse->name, sizeof (mouse->name), "Unknown device"); + + mouse->fd = fd; + + return 1; /* we're golden. */ +} /* init_mouse */ + + +/* Return a file descriptor if this is really a mouse, -1 otherwise. */ +static int open_if_mouse(const char *fname) +{ + struct stat statbuf; + int fd; + int devmajor, devminor; + + if (stat(fname, &statbuf) == -1) + return 0; + + if (S_ISCHR(statbuf.st_mode) == 0) + return 0; /* not a character device... */ + + /* evdev node ids are major 13, minor 64-96. Is this safe to check? */ + devmajor = (statbuf.st_rdev & 0xFF00) >> 8; + devminor = (statbuf.st_rdev & 0x00FF); + if ( (devmajor != 13) || (devminor < 64) || (devminor > 96) ) + return 0; /* not an evdev. */ + + if ((fd = open(fname, O_RDONLY | O_NONBLOCK)) == -1) + return 0; + + if (init_mouse(fname, fd)) + return 1; + + close(fd); + return 0; +} /* open_if_mouse */ + + +static int linux_evdev_init(void) +{ + DIR *dirp; + struct dirent *dent; + int i; + + for (i = 0; i < MAX_MICE; i++) + mice[i].fd = -1; + + dirp = opendir("/dev/input"); + if (!dirp) + return 0; + + while ((dent = readdir(dirp)) != NULL) + { + char fname[128]; + snprintf(fname, sizeof (fname), "/dev/input/%s", dent->d_name); + if (open_if_mouse(fname)) + available_mice++; + } /* while */ + + closedir(dirp); + + return available_mice; +} /* linux_evdev_init */ + + +static void linux_evdev_quit(void) +{ + while (available_mice) + { + int fd = mice[available_mice--].fd; + if (fd != -1) + close(fd); + } /* while */ +} /* linux_evdev_quit */ + + +static const char *linux_evdev_name(unsigned int index) +{ + if (index < available_mice) + return(mice[index].name); + return(NULL); +} /* linux_evdev_name */ + + +static int linux_evdev_poll(ManyMouseEvent *event) +{ + /* + * (i) is static so we iterate through all mice round-robin. This + * prevents a chatty mouse from dominating the queue. + */ + static unsigned int i = 0; + + if (i >= available_mice) + i = 0; /* handle reset condition. */ + + if (event != NULL) + { + while (i < available_mice) + { + MouseStruct *mouse = &mice[i]; + if (mouse->fd != -1) + { + if (poll_mouse(mouse, event)) + { + event->device = i; + return(1); + } /* if */ + } /* if */ + i++; + } /* while */ + } /* if */ + + return(0); /* no new events */ +} /* linux_evdev_poll */ + + +ManyMouseDriver ManyMouseDriver_evdev = +{ + linux_evdev_init, + linux_evdev_quit, + linux_evdev_name, + linux_evdev_poll +}; + +#endif /* defined __linux__ */ + +/* end of linux_evdev.c ... */ + diff --git a/zsnes/src/manymouse.c b/zsnes/src/manymouse.c new file mode 100644 index 00000000..7b531eb0 --- /dev/null +++ b/zsnes/src/manymouse.c @@ -0,0 +1,92 @@ +/* + * ManyMouse foundation code; apps talks to this and it talks to the lowlevel + * code for various platforms. + * + * Please see the file LICENSE in the source's root directory. + * + * This file written by Ryan C. Gordon. + */ + +#include +#include "manymouse.h" + +static const char *manymouse_copyright = + "ManyMouse " MANYMOUSE_VERSION " (c) 2005 Ryan C. Gordon."; + +extern const ManyMouseDriver ManyMouseDriver_windows; +extern const ManyMouseDriver ManyMouseDriver_evdev; +extern const ManyMouseDriver ManyMouseDriver_mousedev; +extern const ManyMouseDriver ManyMouseDriver_hidmanager; +extern const ManyMouseDriver ManyMouseDriver_xinput; + +static const ManyMouseDriver *mice_drivers[] = +{ + #if SUPPORT_XINPUT + &ManyMouseDriver_xinput, + #endif + #if ((defined _WIN32) || defined(__CYGWIN__)) + &ManyMouseDriver_windows, + #endif + #ifdef __linux__ + &ManyMouseDriver_evdev, + /*&ManyMouseDriver_mousedev,*/ + #endif + #if ( (defined(__MACH__)) && (defined(__APPLE__)) ) + &ManyMouseDriver_hidmanager, + #endif + NULL +}; + + +static const ManyMouseDriver *driver = NULL; + +int ManyMouse_Init(void) +{ + int i; + + /* impossible test to keep manymouse_copyright linked into the binary. */ + if ((char *) driver == (const char *) manymouse_copyright) + return(-1); + + if (driver != NULL) + return(-1); + + for (i = 0; mice_drivers[i]; i++) + { + int mice = mice_drivers[i]->init(); + if (mice >= 0) + { + driver = mice_drivers[i]; + return(mice); + } /* if */ + } /* for */ + + return(-1); +} /* ManyMouse_Init */ + + +void ManyMouse_Quit(void) +{ + if (driver != NULL) + driver->quit(); + driver = NULL; +} /* ManyMouse_Quit */ + + +const char *ManyMouse_DeviceName(unsigned int index) +{ + if (driver != NULL) + return(driver->name(index)); + return(NULL); +} /* ManyMouse_PollEvent */ + + +int ManyMouse_PollEvent(ManyMouseEvent *event) +{ + if (driver != NULL) + return(driver->poll(event)); + return(0); +} /* ManyMouse_PollEvent */ + +/* end of manymouse.c ... */ + diff --git a/zsnes/src/manymouse.h b/zsnes/src/manymouse.h new file mode 100644 index 00000000..c854d0bd --- /dev/null +++ b/zsnes/src/manymouse.h @@ -0,0 +1,61 @@ +/* + * ManyMouse main header. Include this from your app. + * + * Please see the file LICENSE in the source's root directory. + * + * This file written by Ryan C. Gordon. + */ + +#ifndef _INCLUDE_MANYMOUSE_H_ +#define _INCLUDE_MANYMOUSE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define MANYMOUSE_VERSION "0.0.1" + +typedef enum +{ + MANYMOUSE_EVENT_ABSMOTION = 0, + MANYMOUSE_EVENT_RELMOTION, + MANYMOUSE_EVENT_BUTTON, + MANYMOUSE_EVENT_SCROLL, + MANYMOUSE_EVENT_DISCONNECT, + MANYMOUSE_EVENT_MAX +} ManyMouseEventType; + +typedef struct +{ + ManyMouseEventType type; + unsigned int device; + unsigned int item; + int value; + int minval; + int maxval; +} ManyMouseEvent; + + +/* internal use only. */ +typedef struct +{ + int (*init)(void); + void (*quit)(void); + const char *(*name)(unsigned int index); + int (*poll)(ManyMouseEvent *event); +} ManyMouseDriver; + + +int ManyMouse_Init(void); +void ManyMouse_Quit(void); +const char *ManyMouse_DeviceName(unsigned int index); +int ManyMouse_PollEvent(ManyMouseEvent *event); + +#ifdef __cplusplus +} +#endif + +#endif /* !defined _INCLUDE_MANYMOUSE_H_ */ + +/* end of manymouse.h ... */ + diff --git a/zsnes/src/uic.c b/zsnes/src/uic.c index b61a072e..7f322cda 100644 --- a/zsnes/src/uic.c +++ b/zsnes/src/uic.c @@ -1,417 +1,467 @@ -/* -Copyright (C) 1997-2005 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 -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. -*/ - - -#ifdef __UNIXSDL__ -#include "gblhdr.h" -#else -#include -#include -#include -#endif - -#include "asm_call.h" - -//C++ style code in C -#define bool unsigned char -#define true 1 -#define false 0 - -extern unsigned char *vbufaptr; -extern unsigned char *vbufeptr; -extern unsigned char *ngwinptrb; -extern unsigned char *vbufdptr; -extern unsigned char *romaptr; -extern unsigned char mydebug[2]; -extern unsigned char outofmem[51]; -extern unsigned char YesMMX[34]; - -// Global Variables ported from ASM - -unsigned int per2exec = 100; // percentage of opcodes to execute - -#ifdef __MSDOS__ -unsigned char cvidmode = 4; // video mode -#else -unsigned char cvidmode = 1; -#endif - -unsigned char string[512]; -unsigned char fname[512]; -unsigned char fnames[512]; // sram filename -unsigned char fnamest[512]; // state filename - -unsigned short selc0040; -unsigned short selcA000; -unsigned short selcB800; -unsigned char filefound; // Parameter String Found -unsigned char frameskip; // 0 = Auto, 1-10 = Skip 0 .. 9 -unsigned char *vidbuffer; // video buffer (1024x239 = 244736) -unsigned char *ngwinptr; -unsigned char *vidbufferm; // video buffer mirror -unsigned char *vidbufferofsa; // offset 1 -unsigned char *vidbufferofsb; // offset 2 -unsigned char *vidbufferofsc; // offset 3 -unsigned char *vidbufferofsmos; // mosaic offset for new graphics engine -unsigned char *headdata; -unsigned char *romdata; // rom data (4MB = 4194304) -unsigned char *sfxramdata; // SuperFX Ram Data -unsigned char *setaramdata; // Seta ST010/ST011 SRam Data -unsigned char *wramdata; // stack (64K = 32768) -unsigned char *ram7f; // ram @ 7f = 65536 -unsigned char *vram; // vram = 65536 -unsigned char *sram; // sram = 32768 -unsigned char *spritetablea; -unsigned char *spcBuffera; -unsigned char *debugbuf; // debug buffer = 38x1000 = 38000 -void (**regptr)(); // pointer to registers -void (**regptw)(); // pointer to registers -unsigned char *vcache2b; // 2-bit video cache -unsigned char *vcache4b; // 4-bit video cache -unsigned char *vcache8b; // 8-bit video cache -unsigned char *vcache2bs; // 2-bit video secondary cache -unsigned char *vcache4bs; // 4-bit video secondary cache -unsigned char *vcache8bs; // 8-bit video secondary cache -unsigned char romispal; // 0 = NTSC, 1 = PAL -unsigned char enterpress; // if enter is to be issued (0 = yes) -unsigned char newgfx16b; -unsigned char *BitConv32Ptr; -unsigned char *RGBtoYUVPtr; - -unsigned char previdmode; // previous video mode -unsigned char cbitmode; // bit mode, 0=8bit, 1=16bit - -unsigned char opexec268 = 155; // # of opcodes/scanline in 2.68Mhz mode -unsigned char opexec358 = 172; // # of opcodes/scanline in 3.58Mhz mode (228/180) -unsigned char opexec268cph = 42; // # of opcodes/hblank in 2.68Mhz mode -unsigned char opexec358cph = 45; // # of opcodes/hblank in 3.58Mhz mode (56/50) -unsigned char opexec268b = 155; // # of opcodes/scanline in 2.68Mhz mode -unsigned char opexec358b = 172; // # of opcodes/scanline in 3.58Mhz mode (228/180) -unsigned char opexec268cphb = 42; // # of opcodes/hblank in 2.68Mhz mode -unsigned char opexec358cphb = 45; // # of opcodes/hblank in 3.58Mhz mode (56/50) -unsigned char debugdisble = 1; // debugger disable. 0 = no, 1 = yes -unsigned char gammalevel = 0; // gamma level (8-bit engine) -unsigned char gammalevel16b = 0; // gamma level (16-bit engine) -unsigned char scanlines = 0; // scanlines on/off -unsigned char vsyncon = 0; // vsync on/off -unsigned char guioff = 0; // gui on/off (1 = off) -unsigned char AddSub256 = 0; // screen add/sub in 256 colors -unsigned char Sup48mbit = 1; // Support 48mbit roms -unsigned char Sup16mbit = 0; // Support 16mbit roms -unsigned char dmadeddis = 0; // DMA deduction -unsigned char antienab = 0; // Interpolation Enabled -unsigned char snesmouse = 0; // Mouse status (1 = enabled) -unsigned char OldStyle = 1; // Old style joystick on -unsigned char SecondPort = 0; // Secondary Joystick Port Enabled (209h) (DOS port only) - -// New Variables -unsigned char ForcePal = 0; // 1 = NTSC, 2 = PAL -unsigned char Force8b = 0; // Force 8-bit sound on -unsigned char Doublevbuf = 1; // Double video buffer -unsigned char V8Mode = 0; // Vegetable mode! =) (Greyscale mode) -unsigned char fastmemptr = 0; -unsigned char showallext = 0; // Show all extensions in GUI load dialog -unsigned char finterleave = 0; -unsigned char DSPDisable = 0; // Disable DSP emulation -unsigned char Palette0 = 0; -unsigned char DisplayS = 0; -unsigned char *spc7110romptr; - -unsigned char MusicRelVol = 75; -unsigned char MusicVol = 0; -unsigned char MMXextSupport = 0; -extern char *Msgptr; - -void outofmemory(); -void init(); -void WaitForKey(); -void MMXCheck(); -void allocmem(); -void InitSPC(); -void SystemInit(); -void StartUp(); - -void *doMemAlloc(size_t size) -{ - void *ptr = NULL; - ptr = malloc(size); - if (!ptr) - { - asm_call(outofmemory); - } - return(ptr); -} - -void allocspc7110() -{ - spc7110romptr = (unsigned char *)doMemAlloc(8192*1024+4096); -} - -extern bool input1gp; -extern bool input1mouse; -extern bool input2gp; -extern bool input2mouse; -extern bool input2scope; -extern bool input2just; -extern unsigned char snesmouse; -void cycleinputdevice() -{ - for (;;) - { - snesmouse++; - if (snesmouse >= 5) - { - snesmouse = 0; - } - if (snesmouse == 0) - { - if (input1gp && input2gp) { return; } - snesmouse++; - } - if (snesmouse == 1) - { - if (input1mouse) { return; } - snesmouse++; - } - if (snesmouse == 2) - { - if (input2mouse) { return; } - snesmouse++; - } - if (snesmouse == 3) - { - if (input2scope) { return; } - snesmouse++; - } - if (snesmouse == 4) - { - if (input2just) { return; } - } - } -} - -unsigned char NoiseData[32768]; -const unsigned char samplenoise[128] = { - 27,232,234,138,187,246,176, 81, 25,241, 1,127,154,190,195,103, - 231,165,220,238,232,189, 57,201,123, 75, 63,143,145,159, 13,236, - 191,142, 56,164,222, 80, 88, 13,148,118,162,212,157,146,176, 0, - 241, 88,244,238, 51,235,149, 50, 77,212,186,241, 88, 32, 23,206, - 1, 24, 48,244,248,210,253, 77, 19,100, 83,222,108, 68, 11, 58, - 152,161,223,245, 4,105, 3, 82, 15,130,171,242,141, 2,172,218, - 152, 97,223,157, 93, 75, 83,238,104,238,131, 70, 22,252,180, 82, - 110,123,106,133,183,209, 48,230,157,205, 27, 21,107, 63, 85,164}; - -void setnoise() -{ - unsigned short ctr1, ctr2, ptr1=0; - unsigned char ptr2=0, ptr3=0; - - for(ctr1=256;ctr1>0;ctr1--) - { - for(ctr2=128;ctr2>0;ctr2--,ptr1++) - { - NoiseData[ptr1] = (samplenoise[ptr2] + samplenoise[ptr3]); - ptr2=(ptr2+1)&0x7f; - ptr3=(ptr3-1)&0x7f; - } - ptr3=(ptr3-1)&0x7f; - } -} - - -extern unsigned int xa; -extern unsigned char soundon, SPCDisable, spcon, FPSOn, FPSAtStart; - -const unsigned int versionNumber = 0x0000008F; // 1.43 -char *ZVERSION = "Pre 1.43"; -unsigned char txtfailedalignd[25] = "Data Alignment Failure : "; -unsigned char txtfailedalignc[25] = "Code Alignment Failure : "; - -void zstart () -{ - unsigned int ptr; - - asm_call(StartUp); - - printf("%s", mydebug); - - // Print welcome message. - printf("ZSNES v%s, (c) 1997-2005, ZSNES Team\n", ZVERSION); - puts("Be sure to check http://www.zsnes.com/ for the latest version."); - puts("Please report crashes to zsnes-devel@lists.sourceforge.net.\n"); - puts("ZSNES is written by the ZSNES Team (See AUTHORS.TXT)"); - puts("ZSNES comes with ABSOLUTELY NO WARRANTY. This is free software,"); - puts("and you are welcome to redistribute it under certain conditions;"); - puts("please read 'LICENSE.TXT' thoroughly before doing so.\n"); - puts("Use ZSNES -? for command line definitions.\n"); - -#ifndef __RELEASE__ - puts("This is a work in progress build. It contains code which"); - puts("May or may not be complete"); -#endif - - asm_call(SystemInit); - - -#ifdef OPENSPC - OSPC_Init(); -#else - setnoise(); - asm_call(InitSPC); -#endif - - asm_call(allocmem); - - if (!soundon && (SPCDisable != 1)) - { - soundon = 1; - spcon = 1; - DSPDisable = 1; - } - - if (SPCDisable) - { - soundon = 0; - spcon = 0; - } - - if (!frameskip) - { - FPSOn = FPSAtStart; - } - - gammalevel16b = gammalevel >> 1; - - asm_call(MMXCheck); - - ptr = (unsigned int)&outofmemory; - - if ((ptr & 3)) - { - printf("%s%d", txtfailedalignc, (ptr & 0x1F)); - - asm_call(WaitForKey); - } - - ptr = (unsigned int)&xa; - - if ((ptr & 3)) - { - printf("%s%d", txtfailedalignd, (ptr & 0x1F)); - - asm_call(WaitForKey); - } - - asm_call(init); -} - -static char *seconds_to_asc(unsigned int seconds) -{ - static char buffer[50]; - char *p = buffer; - unsigned int hours, minutes; - - hours = seconds/3600; - seconds -= hours*3600; - minutes = seconds/60; - seconds -= minutes*60; - *buffer = 0; - - if (hours) - { - sprintf(p, "%u hours ", hours); - p += strlen(p); - } - if (minutes) - { - sprintf(p, "%u min ", minutes); - p += strlen(p); - } - if (seconds) - { - sprintf(p, "%u sec", seconds); - p += strlen(p); - } - if (!*buffer) - { - strcpy(buffer, "0 sec"); - } - return(buffer); -} - -extern unsigned int MessageOn; -extern unsigned int MsgCount; -extern char CSStatus[70]; -extern char CSStatus2[70]; -extern char CSStatus3[70]; - -void DisplayBatteryStatus() -{ -#ifndef __MSDOS__ - int CheckBattery(); - int CheckBatteryTime(); - int CheckBatteryPercent(); - - *CSStatus2 = 0; - *CSStatus3 = 0; - - switch (CheckBattery()) - { - case -1: //No battery - strcpy(CSStatus, "No battery present"); - break; - - case 0: //Plugged in - { - int percent = CheckBatteryPercent(); - - strcpy(CSStatus, "PC is plugged in"); - if (percent > 0) - { - sprintf(CSStatus2, "%d%% charged", percent); - } - } - break; - - case 1: //Not plugged in - { - int percent = CheckBatteryPercent(); - int battery_time = CheckBatteryTime(); - - strcpy(CSStatus, "PC is running off of battery"); - if (battery_time > 0) - { - sprintf(CSStatus2, "Time remaining: %s", seconds_to_asc(battery_time)); - } - if (percent > 0) - { - sprintf(CSStatus3, "%d%% remaining", percent); - } - } - break; - } - - Msgptr = CSStatus; - MessageOn = 100; - -#endif -} +/* +Copyright (C) 1997-2005 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 +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. +*/ + + +#ifdef __UNIXSDL__ +#include "gblhdr.h" +#else +#include +#include +#include +#endif + +#include "asm_call.h" +#include "manymouse.h" + +//C++ style code in C +#define bool unsigned char +#define true 1 +#define false 0 + +extern unsigned char *vbufaptr; +extern unsigned char *vbufeptr; +extern unsigned char *ngwinptrb; +extern unsigned char *vbufdptr; +extern unsigned char *romaptr; +extern unsigned char mydebug[2]; +extern unsigned char outofmem[51]; +extern unsigned char YesMMX[34]; + +// Global Variables ported from ASM + +unsigned int per2exec = 100; // percentage of opcodes to execute + +#ifdef __MSDOS__ +unsigned char cvidmode = 4; // video mode +#else +unsigned char cvidmode = 1; +#endif + +unsigned char string[512]; +unsigned char fname[512]; +unsigned char fnames[512]; // sram filename +unsigned char fnamest[512]; // state filename + +unsigned short selc0040; +unsigned short selcA000; +unsigned short selcB800; +unsigned char filefound; // Parameter String Found +unsigned char frameskip; // 0 = Auto, 1-10 = Skip 0 .. 9 +unsigned char *vidbuffer; // video buffer (1024x239 = 244736) +unsigned char *ngwinptr; +unsigned char *vidbufferm; // video buffer mirror +unsigned char *vidbufferofsa; // offset 1 +unsigned char *vidbufferofsb; // offset 2 +unsigned char *vidbufferofsc; // offset 3 +unsigned char *vidbufferofsmos; // mosaic offset for new graphics engine +unsigned char *headdata; +unsigned char *romdata; // rom data (4MB = 4194304) +unsigned char *sfxramdata; // SuperFX Ram Data +unsigned char *setaramdata; // Seta ST010/ST011 SRam Data +unsigned char *wramdata; // stack (64K = 32768) +unsigned char *ram7f; // ram @ 7f = 65536 +unsigned char *vram; // vram = 65536 +unsigned char *sram; // sram = 32768 +unsigned char *spritetablea; +unsigned char *spcBuffera; +unsigned char *debugbuf; // debug buffer = 38x1000 = 38000 +void (**regptr)(); // pointer to registers +void (**regptw)(); // pointer to registers +unsigned char *vcache2b; // 2-bit video cache +unsigned char *vcache4b; // 4-bit video cache +unsigned char *vcache8b; // 8-bit video cache +unsigned char *vcache2bs; // 2-bit video secondary cache +unsigned char *vcache4bs; // 4-bit video secondary cache +unsigned char *vcache8bs; // 8-bit video secondary cache +unsigned char romispal; // 0 = NTSC, 1 = PAL +unsigned char enterpress; // if enter is to be issued (0 = yes) +unsigned char newgfx16b; +unsigned char *BitConv32Ptr; +unsigned char *RGBtoYUVPtr; + +unsigned char previdmode; // previous video mode +unsigned char cbitmode; // bit mode, 0=8bit, 1=16bit + +unsigned char opexec268 = 155; // # of opcodes/scanline in 2.68Mhz mode +unsigned char opexec358 = 142; // # of opcodes/scanline in 3.58Mhz mode (228/180) +unsigned char opexec268cph = 42; // # of opcodes/hblank in 2.68Mhz mode +unsigned char opexec358cph = 45; // # of opcodes/hblank in 3.58Mhz mode (56/50) +unsigned char opexec268b = 142; // # of opcodes/scanline in 2.68Mhz mode +unsigned char opexec358b = 155; // # of opcodes/scanline in 3.58Mhz mode (228/180) +unsigned char opexec268cphb = 42; // # of opcodes/hblank in 2.68Mhz mode +unsigned char opexec358cphb = 45; // # of opcodes/hblank in 3.58Mhz mode (56/50) +unsigned char debugdisble = 1; // debugger disable. 0 = no, 1 = yes +unsigned char gammalevel = 0; // gamma level (8-bit engine) +unsigned char gammalevel16b = 0; // gamma level (16-bit engine) +unsigned char scanlines = 0; // scanlines on/off +unsigned char vsyncon = 0; // vsync on/off +unsigned char guioff = 0; // gui on/off (1 = off) +unsigned char AddSub256 = 0; // screen add/sub in 256 colors +unsigned char Sup48mbit = 1; // Support 48mbit roms +unsigned char Sup16mbit = 0; // Support 16mbit roms +unsigned char dmadeddis = 0; // DMA deduction +unsigned char antienab = 0; // Interpolation Enabled +unsigned char snesmouse = 0; // Mouse status (1 = enabled) +unsigned char OldStyle = 1; // Old style joystick on +unsigned char SecondPort = 0; // Secondary Joystick Port Enabled (209h) (DOS port only) + +// New Variables +unsigned char ForcePal = 0; // 1 = NTSC, 2 = PAL +unsigned char Force8b = 0; // Force 8-bit sound on +unsigned char Doublevbuf = 1; // Double video buffer +unsigned char V8Mode = 0; // Vegetable mode! =) (Greyscale mode) +unsigned char fastmemptr = 0; +unsigned char showallext = 0; // Show all extensions in GUI load dialog +unsigned char finterleave = 0; +unsigned char DSPDisable = 0; // Disable DSP emulation +unsigned char Palette0 = 0; +unsigned char DisplayS = 0; +unsigned char *spc7110romptr; + +unsigned char MusicRelVol = 75; +unsigned char MusicVol = 0; +unsigned char MMXextSupport = 0; +extern char *Msgptr; + +void outofmemory(); +void init(); +void WaitForKey(); +void MMXCheck(); +void allocmem(); +void InitSPC(); +void SystemInit(); +void StartUp(); +void MultiMouseInit(); + +void *doMemAlloc(size_t size) +{ + void *ptr = NULL; + ptr = malloc(size); + if (!ptr) + { + asm_call(outofmemory); + } + return(ptr); +} + +void allocspc7110() +{ + spc7110romptr = (unsigned char *)doMemAlloc(8192*1024+4096); +} + +extern bool input1gp; +extern bool input1mouse; +extern bool input2gp; +extern bool input2mouse; +extern bool input2scope; +extern bool input2just; +extern unsigned char snesmouse; +void cycleinputdevice() +{ + for (;;) + { + snesmouse++; + if (snesmouse >= 5) + { + snesmouse = 0; + } + if (snesmouse == 0) + { + if (input1gp && input2gp) { return; } + snesmouse++; + } + if (snesmouse == 1) + { + if (input1mouse) { return; } + snesmouse++; + } + if (snesmouse == 2) + { + if (input2mouse) { return; } + snesmouse++; + } + if (snesmouse == 3) + { + if (input2scope) { return; } + snesmouse++; + } + if (snesmouse == 4) + { + if (input2just) { return; } + } + } +} + +unsigned char NoiseData[32768]; +const unsigned char samplenoise[128] = { + 27,232,234,138,187,246,176, 81, 25,241, 1,127,154,190,195,103, + 231,165,220,238,232,189, 57,201,123, 75, 63,143,145,159, 13,236, + 191,142, 56,164,222, 80, 88, 13,148,118,162,212,157,146,176, 0, + 241, 88,244,238, 51,235,149, 50, 77,212,186,241, 88, 32, 23,206, + 1, 24, 48,244,248,210,253, 77, 19,100, 83,222,108, 68, 11, 58, + 152,161,223,245, 4,105, 3, 82, 15,130,171,242,141, 2,172,218, + 152, 97,223,157, 93, 75, 83,238,104,238,131, 70, 22,252,180, 82, + 110,123,106,133,183,209, 48,230,157,205, 27, 21,107, 63, 85,164}; + +void setnoise() +{ + unsigned short ctr1, ctr2, ptr1=0; + unsigned char ptr2=0, ptr3=0; + + for(ctr1=256;ctr1>0;ctr1--) + { + for(ctr2=128;ctr2>0;ctr2--,ptr1++) + { + NoiseData[ptr1] = (samplenoise[ptr2] + samplenoise[ptr3]); + ptr2=(ptr2+1)&0x7f; + ptr3=(ptr3-1)&0x7f; + } + ptr3=(ptr3-1)&0x7f; + } +} + + +extern unsigned int xa; +extern unsigned char soundon, SPCDisable, spcon, FPSOn, FPSAtStart; + +const unsigned int versionNumber = 0x0000008F; // 1.43 +char *ZVERSION = "Pre 1.43"; +unsigned char txtfailedalignd[25] = "Data Alignment Failure : "; +unsigned char txtfailedalignc[25] = "Code Alignment Failure : "; + +void zstart () +{ + unsigned int ptr; + + asm_call(StartUp); + + printf("%s", mydebug); + + // Print welcome message. + printf("ZSNES v%s, (c) 1997-2005, ZSNES Team\n", ZVERSION); + puts("Be sure to check http://www.zsnes.com/ for the latest version."); + puts("Please report crashes to zsnes-devel@lists.sourceforge.net.\n"); + puts("ZSNES is written by the ZSNES Team (See AUTHORS.TXT)"); + puts("ZSNES comes with ABSOLUTELY NO WARRANTY. This is free software,"); + puts("and you are welcome to redistribute it under certain conditions;"); + puts("please read 'LICENSE.TXT' thoroughly before doing so.\n"); + puts("Use ZSNES -? for command line definitions.\n"); + +#ifndef __RELEASE__ + puts("This is a work in progress build. It contains code which"); + puts("May or may not be complete"); +#endif + +#ifndef __MSDOS__ + MultiMouseInit(); +#endif + + asm_call(SystemInit); + + +#ifdef OPENSPC + OSPC_Init(); +#else + setnoise(); + asm_call(InitSPC); +#endif + + asm_call(allocmem); + + if (!soundon && (SPCDisable != 1)) + { + soundon = 1; + spcon = 1; + DSPDisable = 1; + } + + if (SPCDisable) + { + soundon = 0; + spcon = 0; + } + + if (!frameskip) + { + FPSOn = FPSAtStart; + } + + gammalevel16b = gammalevel >> 1; + + asm_call(MMXCheck); + + ptr = (unsigned int)&outofmemory; + + if ((ptr & 3)) + { + printf("%s%d", txtfailedalignc, (ptr & 0x1F)); + + asm_call(WaitForKey); + } + + ptr = (unsigned int)&xa; + + if ((ptr & 3)) + { + printf("%s%d", txtfailedalignd, (ptr & 0x1F)); + + asm_call(WaitForKey); + } + + asm_call(init); +} + +static char *seconds_to_asc(unsigned int seconds) +{ + static char buffer[50]; + char *p = buffer; + unsigned int hours, minutes; + + hours = seconds/3600; + seconds -= hours*3600; + minutes = seconds/60; + seconds -= minutes*60; + *buffer = 0; + + if (hours) + { + sprintf(p, "%u hours ", hours); + p += strlen(p); + } + if (minutes) + { + sprintf(p, "%u min ", minutes); + p += strlen(p); + } + if (seconds) + { + sprintf(p, "%u sec", seconds); + p += strlen(p); + } + if (!*buffer) + { + strcpy(buffer, "0 sec"); + } + return(buffer); +} + +unsigned char multiMouseMode = 0; + +extern unsigned int MessageOn; +extern unsigned int MsgCount; +extern char CSStatus[70]; +extern char CSStatus2[70]; +extern char CSStatus3[70]; + +void DisplayBatteryStatus() +{ +#ifndef __MSDOS__ + int CheckBattery(); + int CheckBatteryTime(); + int CheckBatteryPercent(); + + *CSStatus2 = 0; + *CSStatus3 = 0; + + switch (CheckBattery()) + { + case -1: //No battery + strcpy(CSStatus, "No battery present"); + break; + + case 0: //Plugged in + { + int percent = CheckBatteryPercent(); + + strcpy(CSStatus, "PC is plugged in"); + if (percent > 0) + { + sprintf(CSStatus2, "%d%% charged", percent); + } + } + break; + + case 1: //Not plugged in + { + int percent = CheckBatteryPercent(); + int battery_time = CheckBatteryTime(); + + strcpy(CSStatus, "PC is running off of battery"); + if (battery_time > 0) + { + sprintf(CSStatus2, "Time remaining: %s", seconds_to_asc(battery_time)); + } + if (percent > 0) + { + sprintf(CSStatus3, "%d%% remaining", percent); + } + } + break; + } + + Msgptr = CSStatus; + MessageOn = 100; + +#endif +} + +void MultiMouseShutdown() +{ + multiMouseMode = 0; + ManyMouse_Quit(); + +} + +// Make use of multiple mice. + +int numMice = 0; +int Mouse1MoveX = 0; +int Mouse2MoveX = 0; +int Mouse1MoveY = 0; +int Mouse2MoveY = 0; +unsigned char MouseToRead = 0; +unsigned char multimouse = 1; // Enabled + +extern void WriteLine(); + +void MultiMouseInit() +{ + int mice = ManyMouse_Init(); + printf("ManyMouse: %d mice detected.", mice); + multiMouseMode = 1; +} + +void MultiMouseProcess() +{ + ManyMouseEvent event; + + ManyMouse_PollEvent(&event); + + if (event.type == MANYMOUSE_EVENT_RELMOTION) + { + if (event.device == 0) + if (event.item == 0) { Mouse1MoveX = event.value; } else { Mouse1MoveY = event.value; } + else + if (event.item == 0) { Mouse2MoveX = event.value; } else { Mouse2MoveY = event.value; } + + } +} diff --git a/zsnes/src/video/procvid.asm b/zsnes/src/video/procvid.asm index 4b1bb5d6..7f1a8172 100644 --- a/zsnes/src/video/procvid.asm +++ b/zsnes/src/video/procvid.asm @@ -1,3432 +1,3450 @@ -;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 BGMA,V8Mode,antienab,cacheud,cbitmode,ccud,cfield,cgram,coladdb,coladdg -EXTSYM coladdr,curblank,curfps,cvidmode,delay,extlatch,fnamest,En2xSaI -EXTSYM gammalevel,hirestiledat,ignor512,latchx,latchy,maxbr,ForceNewGfxOff -EXTSYM newengen,nextframe,objptr,pressed,prevpal,res512switch,resolutn -EXTSYM romispal,scaddtype,scanlines,selcA000,snesmouse,t1cc,vcache4b,vesa2_bpos -EXTSYM spritetablea,vesa2_clbit,vesa2_gpos,vesa2_rpos,vesa2red10,vesa2selec -EXTSYM vidbuffer,vram,KeyStateSelct,soundon,Open_File,Read_File -EXTSYM Close_File,Create_File,Write_File,Get_File_Date,makepal -EXTSYM changepal,saveselectpal,displayfpspal,superscopepal,DrawScreen,MMXSupport -EXTSYM Get_MouseData,Get_MousePositionDisplacement,GUIEnableTransp,GUIFontData -EXTSYM StopSound,StartSound,PrevPicture,File_Seek,File_Seek_End,nggposng -EXTSYM Palette0,GetTimeInSeconds,bg3ptr,bg3scroly,bg3scrolx,C4Ram,dsp1array -EXTSYM genfulladdtab,genfulladdtabng,TimerEnable,ShowTimer,debugdisble,GUIOn -EXTSYM FilteredGUI,HalfTrans,SmallMsgText,ClearScreen,Mode7HiRes,mosenng,mosszng -EXTSYM intrlng,mode7hr,newgfx16b,vesa2_clbitng,vesa2_clbitng2,CSStatus -EXTSYM CSStatus2,CSStatus3,SpecialLine,Clear2xSaIBuffer,vidbufferofsb,bg1scroly -EXTSYM bg1objptr,DecompAPtr,HalfTransB,HalfTransC,cur_zst_size,old_zst_size -EXTSYM MovieProcessing,mzt_chdir,UpChdir,MovieFrameStr,GetMovieFrameStr -EXTSYM MovieDisplayFrame - -%ifdef __MSDOS__ -EXTSYM SB_blank,vsyncon,Triplebufen,granadd -%endif - -SECTION .bss -NEWSYM ScreenScale, resb 1 ; If horizontal is scaled or not -NEWSYM TempDebugV, resw 1 ; Temporary Debugging variable -SECTION .text - - -%macro MMXStuff 0 -%%1 - movq mm0,[esi] - movq [es:edi],mm0 - movq mm1,[esi+8] - movq [es:edi+8],mm1 - add esi,16 - add edi,16 - dec ecx - jnz %%1 -%endmacro - -%macro FPUStuff 1 - FILD QWORD[ESI+%1*16] - FILD QWORD[ESI+8+%1*16] - FISTP QWORD[ES:EDI+8+%1*16] - FISTP QWORD[ES:EDI+%1*16] -%endmacro - -%MACRO CopyFPU 0 -%ENDMACRO - -%include "video/2xsaimmx.inc" -%include "video/copyvid.inc" - -SECTION .text -NEWSYM FPUZero -%if 0 - -; omg this is lame ;P - mov [.Zero],eax - mov [.Zero+4],eax - mov [.Zero2],eax - mov [.Zero2+4],eax -.TopOfLoop - FILD QWORD[.Zero] - FILD QWORD[.Zero2] - FXCH - FISTP QWORD[EDI] - FISTP QWORD[EDI+8] - ADD EDI,16 - DEC ECX - JNZ .TopOfLoop -%else - fld1 - fsub st0,st0 -.TopOfLoop - fst qword[edi] - fst qword[edi+8] - add edi,16 - dec ecx - jnz .TopOfLoop - fstp st0 -%endif - ret - -%if 0 -SECTION .bss -.Zero resd 2 -.Zero2 resd 2 -SECTION .text -%endif - -;******************************************************* -; ShowVideo Processes & displays video -;******************************************************* - -NEWSYM showvideo - push esi - push edi - push edx - push ebx - push ebp - inc byte[ccud] - mov bl,[ccud] - cmp byte[cacheud],bl - je .noinc - mov byte[ccud],0 -.noinc - call copyvid - mov eax,[KeyStateSelct] - test byte[pressed+eax],1 - jz .nosavesel - call saveselect -.nosavesel - xor ecx,ecx - pop ebp - pop ebx - pop edx - pop edi - pop esi - ret - - - -NEWSYM processmouse - push esi - push edi - push edx - push ebx - call Get_MouseData - mov [mousebuttons],bx - cmp byte[snesmouse],3 - jne .ss - cmp byte[pressed+13],0 - je .noautosw - cmp byte[ssautoswb],1 - je .ss - xor byte[ssautosw],20h - mov byte[ssautoswb],1 - mov dword[Msgptr],.ssautoen - cmp byte[ssautosw],0 - jne .nononauto - mov dword[Msgptr],.ssautodi -.nononauto - mov eax,[MsgCount] - mov [MessageOn],eax - jmp .ss -.noautosw - mov byte[ssautoswb],0 -.ss - call Get_MousePositionDisplacement - cmp byte[snesmouse],4 - je .le - cmp byte[snesmouse],3 - jne .ss2 -.le - add word[mousexloc],cx - test word[mousexloc],8000h - jz .nowrapleft - mov word[mousexloc],0 -.nowrapleft - cmp word[mousexloc],255 - jbe .nowrapright - mov word[mousexloc],255 -.nowrapright - mov ax,[mousexloc] - add ax,40 - mov [latchx],ax - mov byte[extlatch],40h -.ss2 - mov word[mousexpos],0 - cmp cx,0 - je .noxchange - mov byte[mousexdir],0 - cmp cx,0 - jge .noneg - mov byte[mousexdir],1 - neg cx -.noneg - mov [mousexpos],cx -.noxchange - cmp byte[snesmouse],4 - je .le2 - cmp byte[snesmouse],3 - jne .ss3 -.le2 - add word[mouseyloc],dx - test word[mouseyloc],8000h - jz .nowrapup - mov word[mouseyloc],0 -.nowrapup - cmp word[mouseyloc],223 - jbe .nowrapdown - mov word[mouseyloc],223 -.nowrapdown - mov ax,[mouseyloc] - mov [latchy],ax -.ss3 - mov word[mouseypos],0 - cmp dx,0 - je .noychange - mov byte[mouseydir],0 - cmp dx,0 - jge .noneg2 - mov byte[mouseydir],1 - neg dx -.noneg2 - mov [mouseypos],dx -.noychange - xor ecx,ecx - pop ebx - pop edx - pop edi - pop esi - ret - -SECTION .data -.ssautoen db 'AUTOFIRE ENABLED.',0 -.ssautodi db 'AUTOFIRE DISABLED.',0 - -NEWSYM ssautosw, db 20h - -NEWSYM mousexloc, dw 128 -NEWSYM mouseyloc, dw 112 - -SECTION .bss -NEWSYM ssautoswb, resb 1 -NEWSYM mousebuttons, resw 1 -NEWSYM mousexpos, resw 1 -NEWSYM mousexdir, resb 1 -NEWSYM mouseypos, resw 1 -NEWSYM mouseydir, resb 1 -NEWSYM mousechan, resb 1 -SECTION .text - -;******************************************************* -; Output Hex Outputs the hex in al @ esi -;******************************************************* - -NEWSYM outputhex - push edi - push esi - push eax - push ebx - push ecx - push esi - mov edi,FontData - xor ebx,ebx - mov bl,al - shr bl,4 - shl ebx,3 - add edi,ebx - add edi,8 - mov cl,8 -.loopa - mov ah,[edi] - mov ch,8 -.loopb - test ah,80h - jz .nowrite - mov byte[esi],128 - mov byte[esi+289],192 -.nowrite - shl ah,1 - inc esi - dec ch - jnz .loopb - add esi,280 - inc edi - dec cl - jnz .loopa - pop esi - add esi,8 - mov edi,FontData - xor ebx,ebx - mov bl,al - and bl,0Fh - shl ebx,3 - add edi,ebx - add edi,8 - mov cl,8 -.loopa2 - mov ah,[edi] - mov ch,8 -.loopb2 - test ah,80h - jz .nowrite2 - mov byte[esi],128 - mov byte[esi+289],192 -.nowrite2 - shl ah,1 - inc esi - dec ch - jnz .loopb2 - add esi,280 - inc edi - dec cl - jnz .loopa2 - pop ecx - pop ebx - pop eax - pop esi - pop edi - ret - -OutputText16b: - cmp byte[ForceNonTransp],1 - je near OutText16bnt - cmp byte[GUIEnableTransp],0 - je near OutText16bnt - ; output text in edi to esi - push ebx - push eax - mov cl,9 -.loopa - mov ch,9 - xor eax,eax - cmp cl,1 - je .not1 - mov al,[edi] - shl eax,1 -.not1 - xor ebx,ebx - cmp cl,9 - je .loopb - mov bl,[edi-1] -.loopb - test ax,100h - jz .nowrite - push eax - and word[esi],dx - shr word[esi],1 - and word[esi+75036*4],dx - shr word[esi+75036*4],1 - ror edx,16 - add word[esi],dx - add word[esi+75036*4],dx - ror edx,16 - pop eax - jmp .nowrite2 -.nowrite - test bx,100h - jz .nowrite2 - and word[esi],dx - shr word[esi],1 - and word[esi+75036*4],dx - shr word[esi+75036*4],1 -.nowrite2 - shl ax,1 - shl bx,1 - add esi,2 - dec ch - jnz .loopb - add esi,279*2 - inc edi - dec cl - jnz .loopa - pop eax - pop ebx - ret - -OutText16bnt: - ; output text in edi to esi - push ebx - push eax - mov cl,9 -.loopa - mov ch,9 - xor eax,eax - cmp cl,1 - je .not1 - mov al,[edi] - shl eax,1 -.not1 - xor ebx,ebx - cmp cl,9 - je .loopb - mov bl,[edi-1] -.loopb - test ax,100h - jz .nowrite - mov word[esi],0FFFFh - mov word[esi+75036*4],0FFFFh - jmp .nowrite2 -.nowrite - test bx,100h - jz .nowrite2 - and word[esi],dx - and word[esi+75036*4],dx - shr word[esi],1 - shr word[esi+75036*4],1 -.nowrite2 - shl ax,1 - shl bx,1 - add esi,2 - dec ch - jnz .loopb - add esi,279*2 - inc edi - dec cl - jnz .loopa - pop eax - pop ebx - ret - -NEWSYM outputhex16 - push edi - push esi - push eax - push ebx - push ecx - push edx - push esi - mov dx,[vesa2_clbitng] - ror edx,16 - mov dx,[vesa2_clbitng] - shr dx,1 - ror edx,16 - - mov edi,FontData - xor ebx,ebx - mov bl,al - shr bl,4 - shl ebx,3 - add edi,ebx - add edi,8 - call OutputText16b - pop esi - add esi,16 - mov edi,FontData - xor ebx,ebx - mov bl,al - and bl,0Fh - shl ebx,3 - add edi,ebx - add edi,8 - call OutputText16b - pop edx - pop ecx - pop ebx - pop eax - pop esi - pop edi - ret - -SECTION .data -NEWSYM ASCII2Font - db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h - db 00h,00h,00h,00h,00h,00h,00h,00h,00h,30h,00h,00h,00h,00h,00h,00h - db 00h,3Eh,33h,31h,3Fh,37h,2Fh,3Dh,3Ah,3Bh,35h,38h,39h,25h,28h,29h - db 01h,02h,03h,04h,05h,06h,07h,08h,09h,0Ah,2Eh,40h,2Ah,32h,2Bh,36h - db 3Ch,0Bh,0Ch,0Dh,0Eh,0Fh,10h,11h,12h,13h,14h,15h,16h,17h,18h,19h - db 1Ah,1Bh,1Ch,1Dh,1Eh,1Fh,20h,21h,22h,23h,24h,2Ch,34h,2Dh,42h,26h - db 41h,0Bh,0Ch,0Dh,0Eh,0Fh,10h,11h,12h,13h,14h,15h,16h,17h,18h,19h - db 1Ah,1Bh,1Ch,1Dh,1Eh,1Fh,20h,21h,22h,23h,24h,43h,00h,44h,27h,00h - db 0Dh,1Fh,0Fh,0Bh,0Bh,0Bh,0Bh,0Dh,0Fh,0Fh,0Fh,13h,13h,13h,0Bh,0Bh - db 0Fh,0Bh,0Bh,19h,19h,19h,1Fh,1Fh,23h,19h,1Fh,0Dh,10h,23h,1Ah,10h - db 0Bh,4Eh,4Fh,50h,51h,52h,53h,54h,55h,56h,57h,58h,59h,5Ah,5Bh,5Ch - db 5Dh,5Eh,5Fh,60h,61h,62h,63h,64h,65h,66h,67h,68h,69h,6Ah,6Bh,6Ch - db 6Dh,6Eh,6Fh,70h,71h,72h,73h,74h,75h,76h,77h,78h,79h,7Ah,7Bh,7Ch - db 7Dh,7Eh,7Fh,80h,81h,82h,83h,84h,85h,86h,87h,88h,89h,8Ah,8Bh,8Ch - db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h - db 00h,00h,00h,00h,00h,00h,00h,4Dh,4Ch,4Bh,4Ah,45h,46h,47h,48h,49h - -NEWSYM FontData - db 0,0,0,0,0,0,0,0 - db 01111100b,11000110b,11001110b,11010110b ; 0, 01 - db 11100110b,11000110b,01111100b,00000000b - db 00011000b,00111000b,01111000b,00011000b ; 1, 02 - db 00011000b,00011000b,01111110b,00000000b - db 01111100b,11000110b,00001100b,00011000b ; 2, 03 - db 00110000b,01100110b,11111110b,00000000b - db 01111100b,11000110b,00000110b,00111100b ; 3, 04 - db 00000110b,11000110b,01111100b,00000000b - db 00111100b,01101100b,11001100b,11111110b ; 4, 05 - db 00001100b,00001100b,00001100b,00000000b - db 11111110b,11000000b,11000000b,11111100b ; 5, 06 - db 00000110b,11000110b,01111100b,00000000b - db 00111100b,01100000b,11000000b,11111100b ; 6, 07 - db 11000110b,11000110b,01111100b,00000000b - db 11111110b,11000110b,00000110b,00001100b ; 7, 08 - db 00011000b,00011000b,00011000b,00000000b - db 01111100b,11000110b,11000110b,01111100b ; 8, 09 - db 11000110b,11000110b,01111100b,00000000b - db 01111100b,11000110b,11000110b,01111110b ; 9, 0A - db 00000110b,11000110b,01111100b,00000000b - db 00111000b,01101100b,11000110b,11111110b ; A, 0B - db 11000110b,11000110b,11000110b,00000000b - db 11111100b,11000110b,11000110b,11111100b ; B, 0C - db 11000110b,11000110b,11111100b,00000000b - db 01111100b,11000110b,11000000b,11000000b ; C, 0D - db 11000000b,11000110b,01111100b,00000000b - db 11111100b,11000110b,11000110b,11000110b ; D, 0E - db 11000110b,11000110b,11111100b,00000000b - db 11111110b,11000000b,11000000b,11111000b ; E, 0F - db 11000000b,11000000b,11111110b,00000000b - db 11111110b,11000000b,11000000b,11111000b ; F, 10 - db 11000000b,11000000b,11000000b,00000000b - db 01111100b,11000110b,11000000b,11000000b ; G, 11 - db 11001110b,11000110b,01111100b,00000000b - db 11000110b,11000110b,11000110b,11111110b ; H, 12 - db 11000110b,11000110b,11000110b,00000000b - db 00111100b,00011000b,00011000b,00011000b ; I, 13 - db 00011000b,00011000b,00111100b,00000000b - db 00011110b,00001100b,00001100b,00001100b ; J, 14 - db 00001100b,11001100b,00111100b,00000000b - db 11001100b,11011000b,11110000b,11100000b ; K, 15 - db 11110000b,11011000b,11001100b,00000000b - db 11000000b,11000000b,11000000b,11000000b ; L, 16 - db 11000000b,11000000b,11111110b,00000000b - db 11000110b,11101110b,11111110b,11010110b ; M, 17 - db 11000110b,11000110b,11000110b,00000000b - db 11000110b,11100110b,11110110b,11011110b ; N, 18 - db 11001110b,11000110b,11000110b,00000000b - db 01111100b,11000110b,11000110b,11000110b ; O, 19 - db 11000110b,11000110b,01111100b,00000000b - db 11111100b,11000110b,11000110b,11111100b ; P, 1A - db 11000000b,11000000b,11000000b,00000000b - db 01111100b,11000110b,11000110b,11000110b ; Q, 1B - db 11010110b,11001110b,01111110b,00000000b - db 11111100b,11000110b,11000110b,11111100b ; R, 1C - db 11001100b,11000110b,11000110b,00000000b - db 01111100b,11000110b,11000000b,01111100b ; S, 1D - db 00000110b,11000110b,01111100b,00000000b - db 01111110b,00011000b,00011000b,00011000b ; T, 1E - db 00011000b,00011000b,00011000b,00000000b - db 11000110b,11000110b,11000110b,11000110b ; U, 1F - db 11000110b,11000110b,01111100b,00000000b - db 11000110b,11000110b,11000110b,11000110b ; V, 20 - db 01101100b,00111000b,00010000b,00000000b - db 11000110b,11000110b,11000110b,11010110b ; W, 21 - db 11010110b,11111110b,01101100b,00000000b - db 11000110b,01101100b,00111000b,00010000b ; X, 22 - db 00111000b,01101100b,11000110b,00000000b - db 11001100b,11001100b,01111000b,00110000b ; Y, 23 - db 00110000b,00110000b,00110000b,00000000b - db 11111100b,10001100b,00011000b,00110000b ; Z, 24 - db 01100000b,11000100b,11111100b,00000000b - db 00000000b,00000000b,00000000b,11111110b ; -, 25 - db 00000000b,00000000b,00000000b,00000000b - db 00000000b,00000000b,00000000b,00000000b ; _, 26 - db 00000000b,00000000b,11111110b,00000000b - db 01110000b,11011100b,00000110b,00000000b ; ~, 27 - db 00000000b,00000000b,00000000b,00000000b - db 00000000b,00000000b,00000000b,00000000b ; ., 28 - db 00000000b,00110000b,00110000b,00000000b - db 00000010b,00000100b,00001000b,00010000b ; /, 29 - db 00100000b,01000000b,10000000b,00000000b - db 00001100b,00011000b,00110000b,01100000b ; <, 2A - db 00110000b,00011000b,00001100b,00000000b - db 01100000b,00110000b,00011000b,00001100b ; >, 2B - db 00011000b,00110000b,01100000b,00000000b - db 00111000b,00100000b,00100000b,00100000b ; [, 2C - db 00100000b,00100000b,00111000b,00000000b - db 00111000b,00001000b,00001000b,00001000b ; ], 2D - db 00001000b,00001000b,00111000b,00000000b - db 00000000b,00011000b,00011000b,00000000b ; :, 2E - db 00011000b,00011000b,00000000b,00000000b - db 00011000b,00100100b,00011000b,00111010b ; &, 2F - db 01000100b,01000110b,00111010b,00000000b - ; Arrow, 30 - ; #, 31 (, 3A {, 43 - ; =, 32 ), 3B }, 44 - ; ", 33 @, 3C Up,45 - ; \, 34 ', 3D Dn,46 - ; *, 35 !, 3E Lt,47 - ; ?, 36 $, 3F Rt,48 - ; %, 37 ;, 40 Bk,49 - ; +, 38 `, 41 .5,4A - ; ,, 39 ^, 42 - -SECTION .text - -;******************************************************* -; Output Char Outputs char in al @ esi -;******************************************************* - -NEWSYM outputchar - push edi - push esi - push eax - mov edi,FontData - xor ebx,ebx - mov bl,al - shl ebx,3 - add edi,ebx - mov cl,8 -.loopa - mov ah,[edi] - mov ch,8 -.loopb - test ah,80h - jz .nowrite - mov al,[textcolor] - mov [esi],al - mov byte[esi+289],192 -.nowrite - shl ah,1 - inc esi - dec ch - jnz .loopb - add esi,280 - inc edi - dec cl - jnz .loopa - pop eax - pop esi - pop edi - ret - -NEWSYM outputchar16b - push edi - push esi - push eax - push edx - push ecx - mov dx,[vesa2_clbitng] - ror edx,16 - mov dx,[vesa2_clbitng] - shr dx,1 - ror edx,16 - - mov edi,FontData - xor ebx,ebx - mov bl,al - shl ebx,3 - add edi,ebx - call OutputText16b - pop ecx - pop edx - pop eax - pop esi - pop edi - ret - -SECTION .data -NEWSYM textcolor, db 128 -NEWSYM textcolor16b, dw 0FFFFh -SECTION .text - -NEWSYM outputchar5x5 - push edi - push esi - push eax - mov edi,GUIFontData - xor ebx,ebx - mov bl,al - shl ebx,2 - add edi,ebx - xor ebx,ebx - mov bl,al - add edi,ebx - mov cl,5 -.loopa - mov ah,[edi] - mov ch,5 -.loopb - test ah,80h - jz .nowrite - mov al,[textcolor] - mov [esi],al -.nowrite - shl ah,1 - inc esi - dec ch - jnz .loopb - add esi,283 - inc edi - dec cl - jnz .loopa - pop eax - pop esi - pop edi - ret - -NEWSYM outputchar16b5x5 - push edi - push esi - push eax - mov edi,GUIFontData - xor ebx,ebx - mov bl,al - shl ebx,2 - add edi,ebx - xor ebx,ebx - mov bl,al - add edi,ebx - mov cl,5 -.loopa - mov ah,[edi] - mov ch,5 -.loopb - test ah,80h - jz .nowrite - push eax - mov ax,[textcolor16b] - mov [esi],ax - mov [esi+75036*4],ax - pop eax -.nowrite - shl ah,1 - add esi,2 - dec ch - jnz .loopb - add esi,283*2 - inc edi - dec cl - jnz .loopa - pop eax - pop esi - pop edi - ret - -NEWSYM outputchar16b5x52 - push edi - push esi - push eax - mov edi,GUIFontData - xor ebx,ebx - mov bl,al - shl ebx,2 - add edi,ebx - xor ebx,ebx - mov bl,al - add edi,ebx - mov word[esi-288*2],0 - mov word[esi+2-288*2],0 - mov word[esi+4-288*2],0 - mov word[esi+6-288*2],0 - mov word[esi+8-288*2],0 - mov word[esi+10-288*2],0 - mov word[esi-288*2+75036*4],0 - mov word[esi+2-288*2+75036*4],0 - mov word[esi+4-288*2+75036*4],0 - mov word[esi+6-288*2+75036*4],0 - mov word[esi+8-288*2+75036*4],0 - mov word[esi+10-288*2+75036*4],0 - mov cl,5 -.loopa - mov ah,[edi] - mov ch,5 -.loopb - mov word[esi],0 - mov word[esi+2],0 - mov word[esi+75036*4],0 - mov word[esi+2+75036*4],0 - test ah,80h - jz .nowrite - push eax - mov ax,[textcolor16b] - mov [esi],ax - mov [esi+75036*4],ax - pop eax -.nowrite - shl ah,1 - add esi,2 - dec ch - jnz .loopb - add esi,283*2 - inc edi - dec cl - jnz .loopa - mov word[esi],0 - mov word[esi+2],0 - mov word[esi+4],0 - mov word[esi+6],0 - mov word[esi+8],0 - mov word[esi+10],0 - mov word[esi+75036*4],0 - mov word[esi+2+75036*4],0 - mov word[esi+4+75036*4],0 - mov word[esi+6+75036*4],0 - mov word[esi+8+75036*4],0 - mov word[esi+10+75036*4],0 - pop eax - pop esi - pop edi - ret - -;******************************************************* -; Output Graphic String Outputs String from edi to esi -;******************************************************* - -NEWSYM OutputGraphicString - cmp byte[cbitmode],1 - je .do16b -.no16bit - xor eax,eax -.nextstr - mov al,[edi] - cmp al,0 - je .nomore - mov al,[ASCII2Font+eax] - call outputchar - add esi,8 - inc edi - jmp .nextstr -.nomore - ret - -.do16b - sub esi,[vidbuffer] - shl esi,1 - add esi,[vidbuffer] - cmp byte[textcolor],128 - jne .no128 - mov word[textcolor16b],0FFFFh -.no128 - cmp byte[textcolor],129 - jne .no129 - mov word[textcolor16b],0 -.no129 - cmp byte[textcolor],130 - jne .no130 - xor ax,ax - xor bx,bx - mov cl,[vesa2_rpos] - mov bx,20 - shl bx,cl - add ax,bx - mov cl,[vesa2_gpos] - mov bx,20 - shl bx,cl - add ax,bx - mov cl,[vesa2_bpos] - mov bx,20 - shl bx,cl - add ax,bx - mov [textcolor16b],ax -.no130 - ; Color #131, Red - cmp byte[textcolor],131 - jne .no131 - xor ax,ax - xor bx,bx - mov cl,[vesa2_rpos] - mov bx,22 - shl bx,cl - add ax,bx - mov cl,[vesa2_gpos] - mov bx,5 - shl bx,cl - add ax,bx - mov cl,[vesa2_bpos] - mov bx,5 - shl bx,cl - add ax,bx - mov [textcolor16b],ax -.no131 - jmp OutputGraphicString16b - -NEWSYM OutputGraphicString16b - xor eax,eax -.nextstr - mov al,[edi] - cmp al,0 - je .nomore - mov al,[ASCII2Font+eax] - call outputchar16b - add esi,16 - inc edi - jmp .nextstr -.nomore - ret - -NEWSYM OutputGraphicString5x5 - cmp byte[cbitmode],1 - je .do16b -.no16bit - xor eax,eax -.nextstr - mov al,[edi] - cmp al,0 - je .nomore - mov al,[ASCII2Font+eax] - call outputchar5x5 - add esi,6 - inc edi - jmp .nextstr -.nomore - ret - -.do16b - sub esi,[vidbuffer] - shl esi,1 - add esi,[vidbuffer] - cmp byte[textcolor],128 - jne .no128 - mov word[textcolor16b],0FFFFh -.no128 - cmp byte[textcolor],129 - jne .no129 - mov word[textcolor16b],0 -.no129 - cmp byte[textcolor],130 - jne .no130 - xor ax,ax - xor bx,bx - mov cl,[vesa2_rpos] - mov bx,20 - shl bx,cl - add ax,bx - mov cl,[vesa2_gpos] - mov bx,20 - shl bx,cl - add ax,bx - mov cl,[vesa2_bpos] - mov bx,20 - shl bx,cl - add ax,bx - mov [textcolor16b],ax -.no130 - ; Color #131, Red - cmp byte[textcolor],131 - jne .no131 - xor ax,ax - xor bx,bx - mov cl,[vesa2_rpos] - mov bx,22 - shl bx,cl - add ax,bx - mov cl,[vesa2_gpos] - mov bx,5 - shl bx,cl - add ax,bx - mov cl,[vesa2_bpos] - mov bx,5 - shl bx,cl - add ax,bx - mov [textcolor16b],ax -.no131 - jmp OutputGraphicString16b5x5 - -NEWSYM OutputGraphicString16b5x5 - xor eax,eax -.nextstr - mov al,[edi] - cmp al,0 - je .nomore - mov al,[ASCII2Font+eax] - call outputchar16b5x5 - add esi,12 - inc edi - jmp .nextstr -.nomore - ret - -NEWSYM OutputGraphicString16b5x52 - xor eax,eax -.nextstr - mov al,[edi] - cmp al,0 - je .nomore - mov al,[ASCII2Font+eax] - call outputchar16b5x52 - add esi,12 - inc edi - jmp .nextstr -.nomore - ret - -NEWSYM OutputGraphicStringb - cmp byte[cbitmode],1 - je near .do16b - xor eax,eax - cmp byte[edi-1],1 - je .dir - cmp byte[edi-1],2 - je near .drive - sub esi,8 -.nextstr - mov al,[edi] - cmp al,0 - je .nomore - mov al,[ASCII2Font+eax] - call outputchar - add esi,8 - inc edi - jmp .nextstr -.nomore - ret -.dir - sub esi,8 - mov al,'<' - mov al,[ASCII2Font+eax] - call outputchar - add esi,8 -.nextstr2 - mov al,[edi] - cmp al,0 - je .nomore2 - mov al,[ASCII2Font+eax] - call outputchar - add esi,8 - inc edi - jmp .nextstr2 -.nomore2 - mov al,'>' - mov al,[ASCII2Font+eax] - call outputchar - ret -.drive - sub esi,8 - mov al,'[' - mov al,[ASCII2Font+eax] - call outputchar - add esi,8 -.nextstr3 - mov al,[edi] - cmp al,0 - je .nomore3 - mov al,[ASCII2Font+eax] - call outputchar - add esi,8 - inc edi - jmp .nextstr3 -.nomore3 - mov al,']' - mov al,[ASCII2Font+eax] - call outputchar - ret -.do16b - sub esi,[vidbuffer] - shl esi,1 - add esi,[vidbuffer] - cmp byte[textcolor],128 - jne .no128 - mov word[textcolor16b],0FFFFh -.no128 - cmp byte[textcolor],129 - jne .no129 - mov word[textcolor16b],0 -.no129 - cmp byte[textcolor],130 - jne .no130 - xor ax,ax - xor bx,bx - mov cl,[vesa2_rpos] - mov bx,20 - shl bx,cl - add ax,bx - mov cl,[vesa2_gpos] - mov bx,20 - shl bx,cl - add ax,bx - mov cl,[vesa2_bpos] - mov bx,20 - shl bx,cl - add ax,bx - mov [textcolor16b],ax -.no130 - ; Color #131, Red - cmp byte[textcolor],131 - jne .no131 - xor ax,ax - xor bx,bx - mov cl,[vesa2_rpos] - mov bx,22 - shl bx,cl - add ax,bx - mov cl,[vesa2_gpos] - mov bx,5 - shl bx,cl - add ax,bx - mov cl,[vesa2_bpos] - mov bx,5 - shl bx,cl - add ax,bx - mov [textcolor16b],ax -.no131 -NEWSYM OutputGraphicString16bb - xor eax,eax - cmp byte[edi-1],1 - je .dir - cmp byte[edi-1],2 - je near .drive - xor eax,eax - sub esi,16 -.nextstr - mov al,[edi] - cmp al,0 - je .nomore - mov al,[ASCII2Font+eax] - call outputchar16b - add esi,16 - inc edi - jmp .nextstr -.nomore - ret -.dir - sub esi,16 - mov al,'<' - mov al,[ASCII2Font+eax] - call outputchar16b - add esi,16 -.nextstr2 - mov al,[edi] - cmp al,0 - je .nomore2 - mov al,[ASCII2Font+eax] - call outputchar16b - add esi,16 - inc edi - jmp .nextstr2 -.nomore2 - mov al,'>' - mov al,[ASCII2Font+eax] - call outputchar16b - ret -.drive - sub esi,16 - mov al,'[' - mov al,[ASCII2Font+eax] - call outputchar16b - add esi,16 -.nextstr3 - mov al,[edi] - cmp al,0 - je .nomore3 - mov al,[ASCII2Font+eax] - call outputchar16b - add esi,16 - inc edi - jmp .nextstr3 -.nomore3 - mov al,']' - mov al,[ASCII2Font+eax] - call outputchar16b - ret - -;******************************************************* -; Save Select Allows user to select save state slot -;******************************************************* -; For Save State - -SECTION .bss -NEWSYM csounddisable, resb 1 -NEWSYM statefileloc, resd 1 -newestfileloc resb 1 -newestfiledate resd 1 -f3menuen resb 1 -PrevPictureVal resb 1 -CurPictureVal resb 1 -SECTION .text - -NEWSYM drawhline -.loop - mov [esi],al - inc esi - dec ecx - jnz .loop - ret - -NEWSYM drawhline16b -.loop - mov [esi],ax - add esi,2 - dec ecx - jnz .loop - ret - -NEWSYM drawvline -.loop - mov [esi],al - add esi,288 - dec ecx - jnz .loop - ret - -NEWSYM drawvline16b -.loop - mov [esi],ax - add esi,288*2 - dec ecx - jnz .loop - ret - -%macro determinenewhelp 2 - mov bl,%1 - mov byte[fnamest+eax],%2 - call DetermineNew -%endmacro - -DetermineNew: - push eax - push ebx - mov edx,fnamest+1 - call Open_File - jc near .nodraw - mov bx,ax - mov edx,fnamest+1 - call Get_File_Date -%ifdef __MSDOS__ - shl edx,16 - mov dx,cx -%endif - push edx - call Close_File - pop edx - pop ebx - pop eax - ; date = edx, position = bl - cmp edx,[newestfiledate] - jbe .notlatest - mov [newestfiledate],edx - mov [newestfileloc],bl -.notlatest - ret -.nodraw - pop ebx - pop eax - ret - -DetermineNewest: - mov dword[newestfiledate],0 - mov byte[newestfileloc],0 - - determinenewhelp 0,'t' - determinenewhelp 1,'1' - determinenewhelp 2,'2' - determinenewhelp 3,'3' - determinenewhelp 4,'4' - determinenewhelp 5,'5' - determinenewhelp 6,'6' - determinenewhelp 7,'7' - determinenewhelp 8,'8' - determinenewhelp 9,'9' - ret - -GetPicture: - mov cl,[CurPictureVal] - cmp [PrevPictureVal],cl - jne .notskip - ret -.notskip - mov [PrevPictureVal],cl - mov edx,PrevPicture - mov ecx,64*56*2 -.loop - mov byte[edx],0 - inc edx - dec ecx - jnz .loop - mov edx,fnamest+1 - call Open_File - jc near .nodraw2 - mov bx,ax - xor cx,cx - xor dx,dx - call File_Seek_End - shl edx,16 - mov dx,ax - push eax - sub edx,64*56*2 ;Size of thumbnail - mov eax,[cur_zst_size] - cmp edx,eax - je .draw - mov eax,[old_zst_size] - cmp edx,eax - je .draw - pop eax - jmp .nodraw -.draw - pop eax - mov ax,dx - shr edx,16 - mov cx,dx - mov dx,ax - call File_Seek - mov ecx,64*56*2 - mov edx,PrevPicture - call Read_File -.nodraw - call Close_File -.nodraw2 - ; convert to 1:5:5:5 - cmp byte[newengen],0 - je .noneweng - cmp byte[nggposng],5 - jne .noneweng - mov edx,PrevPicture - mov ecx,64*56 -.loop2 - mov ax,[edx] - mov bx,ax - and ax,1111111111000000b - and bx,0000000000011111b - shr ax,1 - or bx,ax - mov [edx],bx - add edx,2 - dec ecx - jnz .loop2 -.noneweng - ; draw border - mov esi,75*2+9*288*2 - add esi,[vidbuffer] - mov edx,58 -.ploopa - mov ecx,66 - push esi -.ploopb - mov word[esi],0FFFFh - add esi,2 - dec ecx - jnz .ploopb - pop esi - add esi,288*2 - dec edx - jnz .ploopa - ; draw picture - mov esi,76*2+10*288*2 - add esi,[vidbuffer] - mov edx,56 - mov edi,PrevPicture -.ploopa2 - mov ecx,64 - push esi -.ploopb2 - mov ax,[edi] - mov [esi],ax - add esi,2 - add edi,2 - dec ecx - jnz .ploopb2 - pop esi - add esi,288*2 - dec edx - jnz .ploopa2 - ret - -NEWSYM drawfillboxsc - push eax - push ebx - mov edx,fnamest+1 - call Open_File - jc near .nodraw - mov bx,ax - call Close_File - pop ebx - ; draws a 10x10 filled box according to position bl and color dl - xor eax,eax - mov al,11 - mul bl - mov esi,76+94*288 - add esi,[vidbuffer] - add esi,eax - mov ecx,10 - mov al,176 - cmp [newestfileloc],bl - jne .next - mov al,208 -.next - push esi - push ecx - mov ecx,10 - call drawhline - pop ecx - pop esi - add esi,288 - dec ecx - jnz .next - pop eax - ret -.nodraw - pop ebx - pop eax - ret - -NEWSYM drawfillboxsc16b - push eax - push ebx - mov edx,fnamest+1 - call Open_File - jc near .nodraw - mov bx,ax - call Close_File - pop ebx - ; draws a 10x10 filled box according to position bl and color dl - xor eax,eax - mov al,11 - mul bl - mov esi,76*2+94*288*2 - add esi,[vidbuffer] - add esi,eax - add esi,eax - mov ecx,10 - mov ax,[saveselect.allgrn] - cmp [newestfileloc],bl - jne .next - mov ax,[saveselect.allgrnb] -.next - push esi - push ecx - mov ecx,10 - call drawhline16b - pop ecx - pop esi - add esi,288*2 - dec ecx - jnz .next - pop eax - ret -.nodraw - pop ebx - pop eax - ret - -NEWSYM drawbox - ; draws a box according to position bl and color dl - xor eax,eax - mov al,11 - mul bl - mov esi,75+93*288 - add esi,[vidbuffer] - add esi,eax - mov al,dl - push esi - mov ecx,12 - call drawhline - pop esi - push esi - mov ecx,12 - call drawvline - pop esi - push esi - add esi,11 - mov ecx,12 - call drawvline - pop esi - add esi,11*288 - mov ecx,12 - call drawhline - ret - -NEWSYM drawbox16b - ; draws a box according to position bl and color dx - xor eax,eax - mov al,11 - mul bl - mov esi,75*2+93*288*2 - add esi,[vidbuffer] - add esi,eax - add esi,eax - mov ax,dx - push esi - mov ecx,12 - call drawhline16b - pop esi - push esi - mov ecx,12 - call drawvline16b - pop esi - push esi - add esi,11*2 - mov ecx,12 - call drawvline16b - pop esi - add esi,11*288*2 - mov ecx,12 - call drawhline16b - ret - -%macro drawfillboxhelp 2 - mov bl,%1 - mov byte[fnamest+eax],%2 - call drawfillboxsc -%endmacro - -%macro drawfillboxhelp16b 2 - mov bl,%1 - mov byte[fnamest+eax],%2 - call drawfillboxsc16b -%endmacro - - -NEWSYM saveselect - cmp byte[MovieProcessing],0 - jz .nomovie - pushad - call mzt_chdir - popad -.nomovie - mov byte[f3menuen],1 - mov byte[ForceNonTransp],1 - cmp byte[ForceNewGfxOff],0 - jne .nong16b - cmp byte[cbitmode],0 - je .nong16b -%ifdef __MSDOS__ - call GetScreen -%endif -.nong16b - cmp dword[MessageOn],0 - je .nochangem - mov dword[MessageOn],1 -.nochangem - mov al,[newengen] - mov byte[newengen],0 - push eax - call copyvid - pop eax - mov [newengen],al - call StopSound - cmp byte[soundon],0 - je .nosound - mov byte[csounddisable],1 -%ifdef __MSDOS__ - call SB_blank -%endif -.nosound - cmp byte[cbitmode],1 - je near .16b - call saveselectpal - ; draw a small blue box with a white border - mov esi,70+70*288 - add esi,[vidbuffer] - mov ecx,150 - mov al,70 -.loop - mov byte[esi],144 - inc esi - dec ecx - jnz .loop - add esi,288-150 - dec al - mov ecx,150 - jnz .loop - ; draw filled boxes for existing files - mov eax,[statefileloc] - mov bl,[fnamest+eax] - push ebx - call DetermineNewest - drawfillboxhelp 0,'t' - drawfillboxhelp 1,'1' - drawfillboxhelp 2,'2' - drawfillboxhelp 3,'3' - drawfillboxhelp 4,'4' - drawfillboxhelp 5,'5' - drawfillboxhelp 6,'6' - drawfillboxhelp 7,'7' - drawfillboxhelp 8,'8' - drawfillboxhelp 9,'9' - pop ebx - mov eax,[statefileloc] - mov [fnamest+eax],bl - - mov esi,75+73*288 - add esi,[vidbuffer] - mov edi,.stringa - call OutputGraphicString - mov esi,75+83*288 - add esi,[vidbuffer] - mov edi,.stringb - call OutputGraphicString - mov esi,75+108*288 - add esi,[vidbuffer] - mov edi,.stringc - call OutputGraphicString - mov esi,75+118*288 - add esi,[vidbuffer] - mov edi,.stringd - call OutputGraphicString - mov esi,75+128*288 - add esi,[vidbuffer] - mov edi,.stringe - call OutputGraphicString - mov al,128 - mov esi,70+70*288 - add esi,[vidbuffer] - mov ecx,150 - call drawhline - mov esi,70+70*288 - add esi,[vidbuffer] - mov ecx,70 - call drawvline - mov esi,70+139*288 - add esi,[vidbuffer] - mov ecx,150 - call drawhline - mov esi,219+70*288 - add esi,[vidbuffer] - mov ecx,70 - call drawvline - mov esi,75+93*288 - add esi,[vidbuffer] - mov ecx,111 - call drawhline - mov esi,75+104*288 - add esi,[vidbuffer] - mov ecx,111 - call drawhline - mov esi,75+94*288 - add esi,[vidbuffer] - mov bl,11 -.nextvline - mov ecx,10 - push esi - push ebx - call drawvline - pop ebx - pop esi - add esi,11 - dec bl - jnz .nextvline - mov esi,78+96*288 - add esi,[vidbuffer] - mov al,1 - call outputchar - mov bl,9 -.nextnumchar - add esi,11 - inc al - push ebx - call outputchar - pop ebx - dec bl - jnz .nextnumchar - mov byte[curblank],0h - mov bl,0 - mov ebx,[statefileloc] - mov al,[fnamest+ebx] - cmp al,'t' - jne .noT - mov bl,0 - jmp .nexter -.noT - mov bl,al - sub bl,48 -.nexter - mov dl,160 - call drawbox - push ebx - call copyvid - pop ebx - ; wait until esc/enter is pressed -.noesc - mov dl,128 - call drawbox - mov ecx,2500 - call delay - call testpressed8b - test byte[pressed+1],1 - jnz near .esc - test byte[pressed+28],1 - jnz near .enter - mov ecx,2500 - call delay - call testpressed8b - test byte[pressed+1],1 - jnz near .esc - test byte[pressed+28],1 - jnz near .enter - push ebx - call copyvid - pop ebx - mov ecx,2500 - call delay - call testpressed8b - test byte[pressed+1],1 - jnz near .esc - test byte[pressed+28],1 - jnz near .enter - mov ecx,2500 - call delay - call testpressed8b - test byte[pressed+1],1 - jnz near .esc - test byte[pressed+28],1 - jnz near .enter - mov dl,160 - call drawbox - push ebx - call copyvid - pop ebx - jmp .noesc -.enter - mov byte[pressed+28],2 - cmp bl,0 - jne .nozero - mov al,'t' - jmp .save -.nozero - add bl,48 - mov al,bl -.save - mov ebx,[statefileloc] - mov [fnamest+ebx],al -.esc - - mov eax,pressed - mov ecx,256 -.looppr - cmp byte[eax],1 - jne .notpr - mov byte[eax],2 -.notpr - inc eax - dec ecx - jnz .looppr -%ifdef __MSDOS__ - mov byte[pressed+1],0 -%endif - - mov word[t1cc],0 - mov byte[csounddisable],0 - call StartSound - - call makepal - mov byte[f3menuen],0 - mov byte[ForceNonTransp],0 - cmp byte[MovieProcessing],0 - jz .nomovie2 - pushad - call UpChdir - popad -.nomovie2 - ret - -SECTION .bss -.allred resw 1 -.allgrn resw 1 -.allgrnb resw 1 -.blue resw 1 -.stepb resw 1 -SECTION .text - -; Start 16-bit stuff here -.16b - cmp byte[newengen],0 - je .notng - mov byte[GUIOn],1 -.notng - ; draw shadow behind box - mov esi,80*2+80*288*2 - add esi,[vidbuffer] - mov ecx,150 - mov al,70 - mov ah,5 -.loop16b2 - mov dx,[esi] - and dx,[vesa2_clbit] - shr dx,1 - mov [esi],dx - add esi,2 - dec ecx - jnz .loop16b2 - add esi,288*2-150*2 - dec al - mov ecx,150 - jnz .loop16b2 - - mov ax,018h - mov cl,[vesa2_rpos] - shl ax,cl - mov [.allgrn],ax - - mov ax,25 - mov cl,[vesa2_rpos] - shl ax,cl - mov [.allgrnb],ax - mov ax,12 - mov cl,[vesa2_gpos] - shl ax,cl - or [.allgrnb],ax - - mov ax,01Fh - mov cl,[vesa2_rpos] - shl ax,cl - mov [.allred],ax - mov ax,012h - mov cl,[vesa2_bpos] - shl ax,cl - mov dx,ax - mov ax,01h - mov cl,[vesa2_gpos] - shl ax,cl - mov bx,ax - mov ax,01h - mov cl,[vesa2_rpos] - shl ax,cl - or bx,ax - - ; draw a small blue box with a white border - mov esi,70*2+70*288*2 - add esi,[vidbuffer] - mov ecx,150 - mov al,70 - mov ah,5 -.loop16b - mov [esi],dx - add esi,2 - dec ecx - jnz .loop16b - add esi,288*2-150*2 - dec ah - jnz .nocolinc16b - add dx,bx - mov ah,5 -.nocolinc16b - dec al - mov ecx,150 - jnz .loop16b - - ; draw filled boxes for existing files - mov eax,[statefileloc] - mov bl,[fnamest+eax] - push ebx - call DetermineNewest - drawfillboxhelp16b 0,'t' - drawfillboxhelp16b 1,'1' - drawfillboxhelp16b 2,'2' - drawfillboxhelp16b 3,'3' - drawfillboxhelp16b 4,'4' - drawfillboxhelp16b 5,'5' - drawfillboxhelp16b 6,'6' - drawfillboxhelp16b 7,'7' - drawfillboxhelp16b 8,'8' - drawfillboxhelp16b 9,'9' - pop ebx - mov eax,[statefileloc] - mov [fnamest+eax],bl - - mov esi,75*2+73*288*2 - add esi,[vidbuffer] - mov edi,.stringa - call OutputGraphicString16b - mov esi,75*2+83*288*2 - add esi,[vidbuffer] - mov edi,.stringb - call OutputGraphicString16b - mov esi,75*2+108*288*2 - add esi,[vidbuffer] - mov edi,.stringc - call OutputGraphicString16b - mov esi,75*2+118*288*2 - add esi,[vidbuffer] - mov edi,.stringd - call OutputGraphicString16b - mov esi,75*2+128*288*2 - add esi,[vidbuffer] - mov edi,.stringe - call OutputGraphicString16b - mov ax,0FFFFh - mov esi,70*2+70*288*2 - add esi,[vidbuffer] - mov ecx,150 - call drawhline16b - mov esi,70*2+70*288*2 - add esi,[vidbuffer] - mov ecx,70 - call drawvline16b - mov esi,70*2+139*288*2 - add esi,[vidbuffer] - mov ecx,150 - call drawhline16b - mov esi,219*2+70*288*2 - add esi,[vidbuffer] - mov ecx,70 - call drawvline16b - mov esi,75*2+93*288*2 - add esi,[vidbuffer] - mov ecx,111 - call drawhline16b - mov esi,75*2+104*288*2 - add esi,[vidbuffer] - mov ecx,111 - call drawhline16b - mov esi,75*2+94*288*2 - add esi,[vidbuffer] - mov bl,11 -.nextvline16b - mov ecx,10 - push esi - push ebx - call drawvline16b - pop ebx - pop esi - add esi,22 - dec bl - jnz .nextvline16b - mov esi,78*2+96*288*2 - add esi,[vidbuffer] - mov al,1 - call outputchar16b - mov bl,9 -.nextnumchar16b - add esi,22 - inc al - push ebx - call outputchar16b - pop ebx - dec bl - jnz .nextnumchar16b - - mov byte[curblank],0h - mov bl,0 - mov ebx,[statefileloc] - mov al,[fnamest+ebx] - cmp al,'t' - jne .noT16b - mov bl,0 - jmp .nexter16b -.noT16b - mov bl,al - sub bl,48 -.nexter16b - mov dx,[.allred] - call drawbox16b - push ebx - mov al,[newengen] - mov byte[newengen],0 - push eax - call copyvid - pop eax - mov [newengen],al - pop ebx - ; wait until esc/enter is pressed - - mov byte[PrevPictureVal],0FFh -.noesc16b - mov [CurPictureVal],bl - pushad - mov eax,[statefileloc] - mov cl,[fnamest+eax] - push ecx - cmp bl,0 - jne .nozero16b2 - mov cl,'t' - jmp .save16b2 -.nozero16b2 - mov cl,bl - add cl,48 -.save16b2 - mov [fnamest+eax],cl - call GetPicture - pop ecx - mov eax,[statefileloc] - mov [fnamest+eax],cl - popad - - mov dx,0FFFFh - call drawbox16b - mov ecx,2500 - call delay - call testpressed8b - test byte[pressed+1],1 - jnz near .esc16b - test byte[pressed+28],1 - jnz near .enter16b - mov ecx,2500 - call delay - call testpressed8b - test byte[pressed+1],1 - jnz near .esc16b - test byte[pressed+28],1 - jnz near .enter16b - push ebx - mov al,[newengen] - mov byte[newengen],0 - push eax - call copyvid - pop eax - mov [newengen],al - pop ebx - mov ecx,2500 - call delay - call testpressed8b - test byte[pressed+1],1 - jnz near .esc16b - test byte[pressed+28],1 - jnz near .enter16b - mov ecx,2500 - call delay - call testpressed8b - test byte[pressed+1],1 - jnz near .esc16b - test byte[pressed+28],1 - jnz near .enter16b - mov dx,[.allred] - call drawbox16b - push ebx - mov al,[newengen] - mov byte[newengen],0 - push eax - call copyvid - pop eax - mov [newengen],al - pop ebx - jmp .noesc16b -.enter16b - mov byte[pressed+28],2 - cmp bl,0 - jne .nozero16b - mov al,'t' - jmp .save16b -.nozero16b - add bl,48 - mov al,bl -.save16b - mov ebx,[statefileloc] - mov [fnamest+ebx],al -.esc16b - mov eax,pressed - mov ecx,256 -.looppr2 - cmp byte[eax],1 - jne .notpr2 - mov byte[eax],2 -.notpr2 - inc eax - dec ecx - jnz .looppr2 -.prwin -%ifdef __MSDOS__ - mov byte[pressed+1],0 -%endif - mov word[t1cc],0 - mov byte[csounddisable],0 - call StartSound - mov byte[f3menuen],0 - mov byte[ForceNonTransp],0 - mov byte[GUIOn],0 - pushad - call Clear2xSaIBuffer - popad - cmp byte[MovieProcessing],0 - jz .nomovie3 - pushad - call UpChdir - popad -.nomovie3 - ret - -SECTION .data -.stringa db 'PLEASE SELECT',0 -.stringb db 'SAVE STATE SLOT',0 -.stringc db 'USE CURSOR KEYS',0 -.stringd db 'TO MOVE AND',0 -.stringe db 'ENTER TO SELECT',0 - -SECTION .bss -NEWSYM ForceNonTransp, resb 1 - -SECTION .text - -NEWSYM testpressed8b - test byte[pressed+2],1 - jz .no1 - mov bl,1 -.no1 - test byte[pressed+3],1 - jz .no2 - mov bl,2 -.no2 - test byte[pressed+4],1 - jz .no3 - mov bl,3 -.no3 - test byte[pressed+5],1 - jz .no4 - mov bl,4 -.no4 - test byte[pressed+6],1 - jz .no5 - mov bl,5 -.no5 - test byte[pressed+7],1 - jz .no6 - mov bl,6 -.no6 - test byte[pressed+8],1 - jz .no7 - mov bl,7 -.no7 - test byte[pressed+9],1 - jz .no8 - mov bl,8 -.no8 - test byte[pressed+10],1 - jz .no9 - mov bl,9 -.no9 - test byte[pressed+11],1 - jz .no0 - mov bl,0 -.no0 - test byte[pressed+75],1 - jz .noleft - cmp bl,0 - je .noleft - dec bl - mov byte[pressed+75],2 -.noleft - test byte[pressed+77],1 - jz .noright - cmp bl,9 - je .noright - inc bl - mov byte[pressed+77],2 -.noright -%ifndef __MSDOS__ -%ifdef __UNIXSDL__ - test byte[pressed+92],1 -%else - test byte[pressed+0CBh],1 -%endif - jz .noleft2 - cmp bl,0 - je .noleft2 - dec bl -%ifdef __UNIXSDL__ - mov byte[pressed+92],2 -%else - mov byte[pressed+0CBh],2 -%endif -.noleft2 -%ifdef __UNIXSDL__ - test byte[pressed+94],1 -%else - test byte[pressed+0CDh],1 -%endif - jz .noright2 - cmp bl,9 - je .noright2 - inc bl -%ifdef __UNIXSDL__ - mov byte[pressed+94],2 -%else - mov byte[pressed+0CDh],2 -%endif -.noright2 -;.nowin32 -%endif - ret - -;******************************************************* -; MakePal Changes the entire palette -;******************************************************* -; set the brightness with [maxbr] -SECTION .bss -NEWSYM cgramback, resw 256 -SECTION .text - -NEWSYM doveg - pushad - ; backup cgram - mov ecx,128 - xor ebx,ebx -.loop - mov eax,[cgram+ebx] - mov [cgramback+ebx],eax - add ebx,4 - dec ecx - jnz .loop - xor eax,eax - mov al,[coladdr] - add al,[coladdg] - add al,[coladdb] - xor dx,dx - mov bx,3 - div bx - and ax,011111b - mov [coladdr],al - mov [coladdg],al - mov [coladdb],al - xor eax,eax -.next - push eax - mov ax,[cgram+eax] - mov bx,ax - mov cx,ax - and bx,011111b - and cx,1111100000b - shr cx,5 - add bx,cx - mov cx,ax - and cx,111110000000000b - shr cx,10 - add bx,cx - mov ax,bx - xor dx,dx - mov bx,3 - div bx - and ax,011111b - mov cx,ax - mov bx,ax - shl bx,5 - or ax,bx - shl cx,10 - or ax,cx - mov bx,ax - pop eax - mov [cgram+eax],bx - add eax,2 - cmp eax,200h - jne .next - popad - ret - -NEWSYM dovegrest - pushad - ; backup cgram - mov ecx,128 - xor ebx,ebx -.loop - mov eax,[cgramback+ebx] - mov [cgram+ebx],eax - add ebx,4 - dec ecx - jnz .loop - popad - ret - -SECTION .bss -blahblahblah resw 1 -SECTION .text - -NEWSYM dosmakepal - cmp byte[V8Mode],1 - jne .noveg - call doveg -.noveg - mov ax,[cgram] - mov [tempco0],ax - test byte[scaddtype],00100000b - jz near .noaddition - test byte[scaddtype],10000000b - jnz near .noaddition - mov cx,[cgram] - mov ax,cx - and ax,001Fh - add al,[coladdr] - cmp al,01Fh - jb .noadd - mov al,01Fh -.noadd - mov bx,ax - mov ax,cx - shr ax,5 - and ax,001Fh - add al,[coladdg] - cmp al,01Fh - jb .noaddb - mov al,01Fh -.noaddb - shl ax,5 - add bx,ax - mov ax,cx - shr ax,10 - and ax,001Fh - add al,[coladdb] - cmp al,01Fh - jb .noaddc - mov al,01Fh -.noaddc - shl ax,10 - add bx,ax - mov [cgram],bx -.noaddition - cmp byte[Palette0],0 - je .nocol0mod - mov word[cgram],0 -.nocol0mod -NEWSYM makepalb - mov edi,cgram - mov ebx,prevpal - xor ah,ah -.loopa - mov cx,[edi] - push eax - push ebx - mov [ebx],cx - mov al,ah - mov dx,03C8h - out dx,al - mov ax,cx - and al,01Fh - mov bh,[maxbr] - mov bl,bh - mul bl - mov bl,15 - div bl - shl al,1 - mov dx,03C9h - add al,[gammalevel] - cmp al,63 - jbe .nor - mov al,63 -.nor - out dx,al - mov ax,cx - shr ax,5 - and al,01Fh - mov bl,bh - mul bl - mov bl,15 - div bl - shl al,1 - add al,[gammalevel] - cmp al,63 - jbe .nog - mov al,63 -.nog - out dx,al - mov ax,cx - shr ax,10 - and al,01Fh - mov bl,bh - mul bl - mov bl,15 - div bl - shl al,1 - add al,[gammalevel] - cmp al,63 - jbe .nob - mov al,63 -.nob - out dx,al - pop ebx - pop eax - add edi,2 - add ebx,2 - inc ah - jnz near .loopa - mov al,[maxbr] - mov [prevbright],al - mov ax,[tempco0] - mov [cgram],ax - cmp byte[MessageOn],0 - je .nochange128 - mov dx,03C8h - mov al,128 - out dx,al - mov al,63 - inc dx - out dx,al - out dx,al - out dx,al - mov dx,03C8h - mov al,128+64 - out dx,al - mov al,0 - inc dx - out dx,al - out dx,al - out dx,al -.nochange128 - cmp byte[V8Mode],1 - jne .noveg2 - call dovegrest -.noveg2 - ret - -SECTION .bss -NEWSYM tempco0, resw 1 -SECTION .text - -;******************************************************* -; ChangePal Sets up the palette -;******************************************************* - -NEWSYM doschangepal - cmp byte[V8Mode],1 - jne .noveg - call doveg -.noveg - mov ax,[cgram] - mov [tempco0],ax - test byte[scaddtype],00100000b - jz near .noaddition - test byte[scaddtype],10000000b - jnz near .noaddition - mov cx,[cgram] - mov ax,cx - and ax,001Fh - add al,[coladdr] - cmp al,01Fh - jb .noadd - mov al,01Fh -.noadd - mov bx,ax - mov ax,cx - shr ax,5 - and ax,001Fh - add al,[coladdg] - cmp al,01Fh - jb .noaddb - mov al,01Fh -.noaddb - shl ax,5 - add bx,ax - mov ax,cx - shr ax,10 - and ax,001Fh - add al,[coladdb] - cmp al,01Fh - jb .noaddc - mov al,01Fh -.noaddc - shl ax,10 - add bx,ax - mov [cgram],bx -.noaddition - cmp byte[Palette0],0 - je .nocol0mod - mov word[cgram],0 -.nocol0mod - ; check if brightness differs - mov al,[maxbr] - cmp al,[prevbright] - jne near makepalb - ; check for duplicate palette (Compare prevpal with cgram) - mov ebx,prevpal - mov edi,cgram - xor ah,ah -.loopa - mov cx,[edi] - cmp cx,[ebx] - je .nochange - push eax - push ebx - push eax - pop eax - mov [ebx],cx - mov al,ah - mov dx,03C8h - out dx,al - mov ax,cx - and al,01Fh - mov bh,[maxbr] - mov bl,bh - mul bl - mov bl,15 - div bl - shl al,1 - add al,[gammalevel] - cmp al,63 - jbe .nor - mov al,63 -.nor - inc dx - out dx,al - mov ax,cx - shr ax,5 - and al,01Fh - mov bl,bh - mul bl - mov bl,15 - div bl - shl al,1 - add al,[gammalevel] - cmp al,63 - jbe .nog - mov al,63 -.nog - out dx,al - mov ax,cx - shr ax,10 - and al,01Fh - mov bl,bh - mul bl - mov bl,15 - div bl - shl al,1 - add al,[gammalevel] - cmp al,63 - jbe .nob - mov al,63 -.nob - out dx,al - pop ebx - pop eax -.nochange - add edi,2 - add ebx,2 - inc ah - jnz near .loopa - mov ax,[tempco0] - mov [cgram],ax - cmp byte[MessageOn],0 - je .nochange128 - mov dx,03C8h - mov al,128 - out dx,al - mov al,63 - inc dx - out dx,al - out dx,al - out dx,al -.nochange128 - cmp byte[V8Mode],1 - jne .noveg2 - call dovegrest -.noveg2 - ret - -SECTION .bss -NEWSYM prevbright, resb 1 ; previous brightness -SECTION .text - -;******************************************************* -; CopyVid Copies buffer into video -;******************************************************* - -NEWSYM showfps - mov cl,50 - cmp byte[romispal],0 - jne .nontsc - mov cl,60 -.nontsc - inc byte[curfps] - cmp byte[nextframe],cl - jb .nofrc - mov al,[curfps] - mov [lastfps],al - mov al,[curfps2] - mov [lastfps2],al - mov byte[curfps],0 - mov byte[curfps2],0 - sub byte[nextframe],cl -.nofrc - - cmp byte[cbitmode],1 - je near .do16b - - call displayfpspal - - mov al,[lastfps] - mov bl,10 - xor ah,ah - div bl - shl al,4 - add ah,al - mov al,ah - mov esi,208*288+32 - add esi,[vidbuffer] - push ecx - call outputhex - - mov esi,208*288+48 - add esi,[vidbuffer] - mov al,29h - call outputchar - pop ecx - - mov al,cl - mov bl,10 - xor ah,ah - div bl - shl al,4 - add ah,al - mov al,ah - mov esi,208*288+56 - add esi,[vidbuffer] - call outputhex - ret - -.do16b - mov al,[lastfps] - mov bl,10 - xor ah,ah - div bl - shl al,4 - add ah,al - mov al,ah - mov esi,208*288*2+32*2 - add esi,[vidbuffer] - push ecx - call outputhex16 - - mov esi,208*288*2+48*2 - add esi,[vidbuffer] - mov al,29h - call outputchar16b - pop ecx - - mov al,cl - mov bl,10 - xor ah,ah - div bl - shl al,4 - add ah,al - mov al,ah - mov esi,208*288*2+56*2 - add esi,[vidbuffer] - call outputhex16 - ret - -.ng16b - mov byte[ngfont],1 - - mov al,[lastfps] - mov bl,10 - xor ah,ah - div bl - shl al,4 - add ah,al - mov al,ah - mov esi,208*288+32 - add esi,[vidbuffer] - push ecx - call outputhex - - mov esi,208*288+48 - add esi,[vidbuffer] - mov al,29h - call outputchar - pop ecx - - mov al,cl - mov bl,10 - xor ah,ah - div bl - shl al,4 - add ah,al - mov al,ah - mov esi,208*288+56 - add esi,[vidbuffer] - call outputhex - ret - -SECTION .bss -NEWSYM spcdebugaddr, resd 1 -NEWSYM tempoffset, resw 1 - -NEWSYM Testval, resd 1 -SECTION .text - - -NEWSYM ClockOutput - cmp byte[cbitmode],1 - je near .do16b3 -.no16b3 - mov byte[ngfont],1 - call displayfpspal - mov esi,215*288+32+192 - add esi,[vidbuffer] - mov ebx,7 -.loop2 - mov ecx,12 - mov byte[esi-1],0C0h -.loop - mov dword[esi],0C0C0C0C0h - add esi,4 - dec ecx - jnz .loop - add esi,288-48 - dec ebx - jnz .loop2 - jmp .do8b -.do16b3 - mov esi,215*288*2+32*2+192*2 - add esi,[vidbuffer] - mov ebx,7 -.loop2b - mov ecx,24 - mov word[esi-2],0 - mov word[esi-2+75036*4],0 -.loopb - mov dword[esi],0 - mov dword[esi+75036*4],0 - add esi,4 - dec ecx - jnz .loopb - add esi,288*2-48*2 - dec ebx - jnz .loop2b -.do8b - call GetTimeInSeconds - xor edx,edx - mov ebx,60 - div ebx - push eax - ; edx = seconds - mov eax,edx - xor edx,edx - mov ebx,10 - div ebx - mov esi,216*288+32+228 - call .output - pop eax - mov ebx,60 - xor edx,edx - div ebx - push eax - ; edx = minutes - mov eax,edx - xor edx,edx - mov ebx,10 - div ebx - mov esi,216*288+32+210 - call .output - pop eax - ; eax = hours - xor edx,edx - mov ebx,10 - div ebx - mov esi,216*288+32+192 - call .output - cmp byte[cbitmode],1 - je .do16b2 -.no16b4 - mov esi,216*288+32+222 - add esi,[vidbuffer] - xor eax,eax - add al,':' - mov al,[ASCII2Font+eax] - pushad - call outputchar5x5 - popad - mov esi,216*288+32+204 - add esi,[vidbuffer] - xor eax,eax - add al,':' - mov al,[ASCII2Font+eax] - pushad - call outputchar5x5 - popad - ret - -.do16b2 - mov esi,216*288*2+32*2+222*2 - add esi,[vidbuffer] - xor eax,eax - add al,':' - mov al,[ASCII2Font+eax] - pushad - call outputchar16b5x5 - popad - mov esi,216*288*2+32*2+204*2 - add esi,[vidbuffer] - xor eax,eax - add al,':' - mov al,[ASCII2Font+eax] - pushad - call outputchar16b5x5 - popad - ret -.output - ; output char value at al and dl - cmp byte[cbitmode],1 - je .do16b -.no16b5 - add esi,[vidbuffer] - and eax,0FFh - add al,48 - mov al,[ASCII2Font+eax] - pushad - call outputchar5x5 - popad - xor eax,eax - mov al,dl - add al,48 - mov al,[ASCII2Font+eax] - add esi,6 - pushad - call outputchar5x5 - popad - ret -.do16b - add esi,esi - add esi,[vidbuffer] - and eax,0FFh - add al,48 - mov al,[ASCII2Font+eax] - pushad - call outputchar16b5x5 - popad - xor eax,eax - mov al,dl - add al,48 - mov al,[ASCII2Font+eax] - add esi,12 - pushad - call outputchar16b5x5 - popad - ret - -NEWSYM ClockOutputB - cmp byte[cbitmode],1 - je near .do16b3 -.no16b3 - mov byte[ngfont],1 - call displayfpspal - mov esi,208*288+32+192 - add esi,[vidbuffer] - mov ebx,7 -.loop2 - mov ecx,12 - mov byte[esi-1],0C0h -.loop - mov dword[esi],0C0C0C0C0h - add esi,4 - dec ecx - jnz .loop - add esi,288-48 - dec ebx - jnz .loop2 - jmp .do8b -.do16b3 - mov esi,208*288*2+32*2+192*2 - add esi,[vidbuffer] - mov ebx,7 -.loop2b - mov ecx,24 - mov word[esi-2],0 - mov word[esi-2+75036*4],0 -.loopb - mov dword[esi],0 - mov dword[esi+75036*4],0 - add esi,4 - dec ecx - jnz .loopb - add esi,288*2-48*2 - dec ebx - jnz .loop2b -.do8b - call GetTimeInSeconds - xor edx,edx - mov ebx,60 - div ebx - push eax - ; edx = seconds - mov eax,edx - xor edx,edx - mov ebx,10 - div ebx - mov esi,209*288+32+228 - call .output - pop eax - mov ebx,60 - xor edx,edx - div ebx - push eax - ; edx = minutes - mov eax,edx - xor edx,edx - mov ebx,10 - div ebx - mov esi,209*288+32+210 - call .output - pop eax - ; eax = hours - xor edx,edx - mov ebx,10 - div ebx - mov esi,209*288+32+192 - call .output - cmp byte[cbitmode],1 - je .do16b2 -.no16b4 - mov esi,209*288+32+222 - add esi,[vidbuffer] - xor eax,eax - add al,':' - mov al,[ASCII2Font+eax] - pushad - call outputchar5x5 - popad - mov esi,209*288+32+204 - add esi,[vidbuffer] - xor eax,eax - add al,':' - mov al,[ASCII2Font+eax] - pushad - call outputchar5x5 - popad - ret -.do16b2 - mov esi,209*288*2+32*2+222*2 - add esi,[vidbuffer] - xor eax,eax - add al,':' - mov al,[ASCII2Font+eax] - pushad - call outputchar16b5x5 - popad - mov esi,209*288*2+32*2+204*2 - add esi,[vidbuffer] - xor eax,eax - add al,':' - mov al,[ASCII2Font+eax] - pushad - call outputchar16b5x5 - popad - ret -.output - ; output char value at al and dl - cmp byte[cbitmode],1 - je .do16b -.no16b5 - add esi,[vidbuffer] - and eax,0FFh - add al,48 - mov al,[ASCII2Font+eax] - pushad - call outputchar5x5 - popad - xor eax,eax - mov al,dl - add al,48 - mov al,[ASCII2Font+eax] - add esi,6 - pushad - call outputchar5x5 - popad - ret -.do16b - add esi,esi - add esi,[vidbuffer] - and eax,0FFh - add al,48 - mov al,[ASCII2Font+eax] - pushad - call outputchar16b5x5 - popad - xor eax,eax - mov al,dl - add al,48 - mov al,[ASCII2Font+eax] - add esi,12 - pushad - call outputchar16b5x5 - popad - ret - -SECTION .data -hextestfilen db 'DSP1DUMP.DAT',0 - -SECTION .bss -NEWSYM SoundTest, resb 1 - - -blahrnr resw 1 - -SECTION .text - -NEWSYM hextestoutput - - mov dx,[bg3scroly] -; and dx,0F8h - shr edx,3 - shl edx,6 - xor eax,eax - mov ax,[bg3ptr] - add ax,dx - xor edx,edx - mov dx,[bg3scrolx] - and dx,0F8h - shr edx,3 - shl edx,1 - add ax,dx - mov dx,[bg3scrolx] - test dx,8000h - jz .nooma - and dx,0F000h - shr dx,5 - add ax,dx -.nooma - add eax,40h - mov edx,eax - mov [Testval],edx - cmp byte[pressed+25],1 - jne .nopress25 - jmp .nopress25 - pushad - mov edx,hextestfilen - call Create_File - jc .failed - mov bx,ax - mov edx,dsp1array - mov ecx,4096 - call Write_File - call Close_File -.failed - popad - mov byte[pressed+25],2 -.nopress25 - call displayfpspal - - mov esi,[vram] - mov ax,0 - mov ecx,400h -.loop -; mov word[esi],ax - add esi,2 - dec ecx - jnz .loop - inc word[blahrnr] - mov esi,216*288+32 - add esi,[vidbuffer] - xor eax,eax - ; 4F00h - mov ebx,[C4Ram] - mov ebx,[vram] - mov al,[DecompAPtr+1h] - call outputhex - mov esi,216*288+32+16 - add esi,[vidbuffer] - xor eax,eax - mov ebx,[C4Ram] - mov ebx,[vram] - mov al,[DecompAPtr] - call outputhex - mov esi,216*288+70 - add esi,[vidbuffer] - xor eax,eax - mov ebx,[C4Ram] - mov al,[bg1objptr+1] - call outputhex - mov esi,216*288+70+16 - add esi,[vidbuffer] - xor eax,eax - mov ebx,[C4Ram] - mov al,[bg1objptr] - call outputhex - mov esi,216*288+108 - add esi,[vidbuffer] - xor eax,eax - mov ebx,[C4Ram] - mov al,[ebx+4] - call outputhex - mov esi,216*288+108+16 - add esi,[vidbuffer] - xor eax,eax - mov ebx,[C4Ram] - mov al,[ebx+9] - call outputhex - mov esi,216*288+146 - add esi,[vidbuffer] - xor eax,eax - mov ebx,[C4Ram] - mov al,[ebx+10] - call outputhex - xor eax,eax - mov esi,216*288+146+16 - add esi,[vidbuffer] - or al,[bg1scroly] - mov ebx,[C4Ram] - mov al,[ebx+11] - call outputhex - ret - -SECTION .bss -NEWSYM SoundPlayed0, resb 1 -NEWSYM SoundPlayed1, resb 1 -NEWSYM SoundPlayed2, resb 1 -NEWSYM SoundPlayed3, resb 1 -NEWSYM SoundPlayed4, resb 1 -NEWSYM SoundPlayed5, resb 1 -NEWSYM SoundPlayed6, resb 1 -NEWSYM SoundPlayed7, resb 1 -NEWSYM ngfont, resb 1 -SECTION .text - -NEWSYM ShowSound - add esi,[vidbuffer] -.next - mov [esi],ebx - mov [esi+4],ebx - mov [esi+8],bx - sub esi,288 - dec al - jnz .next - ret - -NEWSYM sounddisplay - call displayfpspal - - push esi - push ebx - push eax - mov ebx,80808080h - cmp byte[SoundPlayed0],0 - je .nosnd0 - mov al,[SoundPlayed0] - mov esi,223*288+16 - call ShowSound - sub byte[SoundPlayed0],2 -.nosnd0 - cmp byte[SoundPlayed1],0 - je .nosnd1 - mov al,[SoundPlayed1] - mov esi,223*288+28 - call ShowSound - sub byte[SoundPlayed1],2 -.nosnd1 - cmp byte[SoundPlayed2],0 - je .nosnd2 - mov al,[SoundPlayed2] - mov esi,223*288+40 - call ShowSound - sub byte[SoundPlayed2],2 -.nosnd2 - cmp byte[SoundPlayed3],0 - je .nosnd3 - mov al,[SoundPlayed3] - mov esi,223*288+52 - call ShowSound - sub byte[SoundPlayed3],2 -.nosnd3 - cmp byte[SoundPlayed4],0 - je .nosnd4 - mov al,[SoundPlayed4] - mov esi,223*288+64 - call ShowSound - sub byte[SoundPlayed4],2 -.nosnd4 - cmp byte[SoundPlayed5],0 - je .nosnd5 - mov al,[SoundPlayed5] - mov esi,223*288+76 - call ShowSound - sub byte[SoundPlayed5],2 -.nosnd5 - cmp byte[SoundPlayed6],0 - je .nosnd6 - mov al,[SoundPlayed6] - mov esi,223*288+88 - call ShowSound - sub byte[SoundPlayed6],2 -.nosnd6 - cmp byte[SoundPlayed7],0 - je .nosnd7 - mov al,[SoundPlayed7] - mov esi,223*288+100 - call ShowSound - sub byte[SoundPlayed7],2 -.nosnd7 - pop eax - pop esi - pop ebx - ret - -NEWSYM waitvsync - mov dx,3DAh ;VGA status port -;.loop -; in al,dx -; test al,8 ;check VR bit -; jnz .loop ;in middle of VR, better wait for next one -.loop2 - in al,dx - test al,8 - jz .loop2 ;updating the screen - ret - -SECTION .data -NEWSYM prevengval, db 10 - - -SECTION .text - -NEWSYM copyvid - mov byte[ngfont],0 - mov dword[.sdrawptr],0 - ; Test if add table needs updating - cmp byte[cbitmode],0 - je .notatud - cmp byte[vesa2red10],0 - je .notatud - mov al,[newengen] - cmp [prevengval],al - je .notatud - mov [prevengval],al - call genfulladdtab - jmp .notatud -.redadd - call genfulladdtabng -.notatud - cmp dword[MessageOn],0 - je near .nomsg - cmp byte[cbitmode],1 - je near .do16b -.no16b - mov byte[ngfont],1 - mov edi,[Msgptr] - mov esi,200*288+32 - add esi,[vidbuffer] - cmp edi,CSStatus - je .fivex5b - cmp byte[SmallMsgText],1 - je .smallmsgtext - call OutputGraphicString.no16bit - jmp .nfivex5b -.fivex5b - call OutputGraphicString5x5 - mov edi,CSStatus2 - mov esi,208*288+32 - add esi,[vidbuffer] - call OutputGraphicString5x5 - mov edi,CSStatus3 - mov esi,216*288+32 - add esi,[vidbuffer] - call OutputGraphicString5x5 - jmp .nfivex5b -.smallmsgtext - call OutputGraphicString5x5 -.nfivex5b - dec dword[MessageOn] - jnz .nomsg - cmp byte[cbitmode],1 - je .nomsg - call makepal - jmp .nomsg -.do16b - mov edi,[Msgptr] - mov esi,200*288*2+32*2 - add esi,[vidbuffer] - cmp edi,CSStatus - je .fivex5 - cmp byte[SmallMsgText],1 - je .smallmsgtext2 - call OutputGraphicString16b - jmp .nfivex5 -.fivex5 - call OutputGraphicString16b5x5 - mov edi,CSStatus2 - mov esi,208*288*2+32*2 - add esi,[vidbuffer] - call OutputGraphicString16b5x5 - mov edi,CSStatus3 - mov esi,216*288*2+32*2 - add esi,[vidbuffer] - call OutputGraphicString16b5x5 - jmp .nfivex5 -.smallmsgtext2 - call OutputGraphicString16b5x5 -.nfivex5 - dec dword[MessageOn] -.nomsg - cmp byte[MovieProcessing],0 - jz .nomovie4 - cmp byte[MovieDisplayFrame],0 - jz .nomovie4 - pushad - call GetMovieFrameStr - popad - mov edi,MovieFrameStr - cmp byte[cbitmode],1 - jne .not16bframe - mov esi,216*288*2+32*2 - add esi,[vidbuffer] - call OutputGraphicString16b5x5 - jmp .nomovie4 -.not16bframe - mov esi,216*288+32 - add esi,[vidbuffer] - call OutputGraphicString5x5 -.nomovie4 - jmp vidpaste -SECTION .bss -.sdrawptr resd 1 -SECTION .text - -NEWSYM vidpaste -%ifdef __MSDOS__ - cmp byte[vsyncon],0 - je .novsync - cmp byte[Triplebufen],0 - jne .novsync - cmp byte[curblank],0h - jne .novsync - call waitvsync -.novsync -%endif - cmp byte[cbitmode],1 - je .nopal - cmp byte[curblank],0 - jne .nopal - call changepal -.nopal - cmp byte[FPSOn],0 - je .nofps - cmp byte[curblank],0 - jne .nofps - call showfps -.nofps -; call ClockOutputB - - cmp byte[TimerEnable],0 - je .noclock - cmp byte[ShowTimer],0 - je .noclock - call ClockOutput -.noclock - cmp byte[snesmouse],3 - je near .drawss -; cmp byte[snesmouse],4 -; je near .drawss -.returnfromdraw - mov ax,[resolutn] - cmp [prevresolutn],ax - je .noclear - mov [prevresolutn],ax - call ClearScreen -.noclear - jmp DrawScreen - -.drawss - cmp byte[cbitmode],1 - je .noss8b - call superscopepal -.noss8b - xor eax,eax - mov al,[mouseyloc] - mov ebx,288 - mul ebx - mov esi,[vidbuffer] - mov edi,SScopeCursor - xor ebx,ebx - mov bl,[mousexloc] - add ebx,6 - cmp byte[cbitmode],1 - je near .ss16b - mov cl,20 -.ssloop - mov ch,20 -.ssloop2 - cmp byte[edi],0 - je .nodraw - mov edx,eax - add edx,ebx - sub edx,288*10 - jb .nodraw - mov byte[esi+edx],128+16 -.nodraw - inc ebx - inc edi - dec ch - jnz .ssloop2 - sub ebx,20 - add eax,288 - dec cl - jnz .ssloop - jmp .returnfromdraw - -.ss16b - push ebx - mov cl,[vesa2_rpos] - mov bx,31 - shl bx,cl - mov [.SSRedCo],bx - pop ebx - shl eax,1 - shl ebx,1 - mov cl,20 -.ssloopb - mov ch,20 -.ssloopb2 - cmp byte[edi],0 - je .nodrawb - mov edx,eax - add edx,ebx - sub edx,288*10*2 - jb .nodrawb - push eax - mov ax,[.SSRedCo] - mov [esi+edx],ax - pop eax -.nodrawb - add ebx,2 - inc edi - dec ch - jnz .ssloopb2 - sub ebx,40 - add eax,288*2 - dec cl - jnz .ssloopb - jmp .returnfromdraw - -SECTION .bss -.SSRedCo resw 1 - -SECTION .data -NEWSYM MsgCount, dd 120 ; How long message will stay (PAL = 100) - -SECTION .bss -NEWSYM lastfps, resb 1 ; stores the last fps encountered -NEWSYM lastfps2, resb 1 ; stores the last fps encountered -NEWSYM curfps2, resb 1 ; current video refresh fps -NEWSYM Msgptr, resd 1 ; Pointer to message -NEWSYM MessageOn, resd 1 ; Message On Countdown -NEWSYM FPSOn, resb 1 - -SECTION .data -prevresolutn dd 224 - -NEWSYM SScopeCursor -db 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0 -db 0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0 -db 0,0,0,0,0,1,1,0,0,1,0,0,1,1,0,0,0,0,0,0 -db 0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0 -db 0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0 -db 0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0 -db 0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0 -db 0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0 -db 0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0 -db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 -db 0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0 -db 0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0 -db 0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0 -db 0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0 -db 0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0 -db 0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0 -db 0,0,0,0,0,1,1,0,0,1,0,0,1,1,0,0,0,0,0,0 -db 0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0 -db 0,0,0,0,0,0,0,0,0,1,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,0,0,0,0 +;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 BGMA,V8Mode,antienab,cacheud,cbitmode,ccud,cfield,cgram,coladdb,coladdg +EXTSYM coladdr,curblank,curfps,cvidmode,delay,extlatch,fnamest,En2xSaI +EXTSYM gammalevel,hirestiledat,ignor512,latchx,latchy,maxbr,ForceNewGfxOff +EXTSYM newengen,nextframe,objptr,pressed,prevpal,res512switch,resolutn +EXTSYM romispal,scaddtype,scanlines,selcA000,snesmouse,t1cc,vcache4b,vesa2_bpos +EXTSYM spritetablea,vesa2_clbit,vesa2_gpos,vesa2_rpos,vesa2red10,vesa2selec +EXTSYM vidbuffer,vram,KeyStateSelct,soundon,Open_File,Read_File +EXTSYM Close_File,Create_File,Write_File,Get_File_Date,makepal +EXTSYM changepal,saveselectpal,displayfpspal,superscopepal,DrawScreen,MMXSupport +EXTSYM Get_MouseData,Get_MousePositionDisplacement,GUIEnableTransp,GUIFontData +EXTSYM StopSound,StartSound,PrevPicture,File_Seek,File_Seek_End,nggposng +EXTSYM Palette0,GetTimeInSeconds,bg3ptr,bg3scroly,bg3scrolx,C4Ram,dsp1array +EXTSYM genfulladdtab,genfulladdtabng,TimerEnable,ShowTimer,debugdisble,GUIOn +EXTSYM FilteredGUI,HalfTrans,SmallMsgText,ClearScreen,Mode7HiRes,mosenng,mosszng +EXTSYM intrlng,mode7hr,newgfx16b,vesa2_clbitng,vesa2_clbitng2,CSStatus +EXTSYM CSStatus2,CSStatus3,SpecialLine,Clear2xSaIBuffer,vidbufferofsb,bg1scroly +EXTSYM bg1objptr,DecompAPtr,HalfTransB,HalfTransC,cur_zst_size,old_zst_size +EXTSYM MovieProcessing,mzt_chdir,UpChdir,MovieFrameStr,GetMovieFrameStr +EXTSYM MovieDisplayFrame + +%ifdef __MSDOS__ +EXTSYM SB_blank,vsyncon,Triplebufen,granadd +%endif + +SECTION .bss +NEWSYM ScreenScale, resb 1 ; If horizontal is scaled or not +NEWSYM TempDebugV, resw 1 ; Temporary Debugging variable +SECTION .text + + +%macro MMXStuff 0 +%%1 + movq mm0,[esi] + movq [es:edi],mm0 + movq mm1,[esi+8] + movq [es:edi+8],mm1 + add esi,16 + add edi,16 + dec ecx + jnz %%1 +%endmacro + +%macro FPUStuff 1 + FILD QWORD[ESI+%1*16] + FILD QWORD[ESI+8+%1*16] + FISTP QWORD[ES:EDI+8+%1*16] + FISTP QWORD[ES:EDI+%1*16] +%endmacro + +%MACRO CopyFPU 0 +%ENDMACRO + +%include "video/2xsaimmx.inc" +%include "video/copyvid.inc" + +SECTION .text +NEWSYM FPUZero +%if 0 + +; omg this is lame ;P + mov [.Zero],eax + mov [.Zero+4],eax + mov [.Zero2],eax + mov [.Zero2+4],eax +.TopOfLoop + FILD QWORD[.Zero] + FILD QWORD[.Zero2] + FXCH + FISTP QWORD[EDI] + FISTP QWORD[EDI+8] + ADD EDI,16 + DEC ECX + JNZ .TopOfLoop +%else + fld1 + fsub st0,st0 +.TopOfLoop + fst qword[edi] + fst qword[edi+8] + add edi,16 + dec ecx + jnz .TopOfLoop + fstp st0 +%endif + ret + +%if 0 +SECTION .bss +.Zero resd 2 +.Zero2 resd 2 +SECTION .text +%endif + +;******************************************************* +; ShowVideo Processes & displays video +;******************************************************* + +NEWSYM showvideo + push esi + push edi + push edx + push ebx + push ebp + inc byte[ccud] + mov bl,[ccud] + cmp byte[cacheud],bl + je .noinc + mov byte[ccud],0 +.noinc + call copyvid + mov eax,[KeyStateSelct] + test byte[pressed+eax],1 + jz .nosavesel + call saveselect +.nosavesel + xor ecx,ecx + pop ebp + pop ebx + pop edx + pop edi + pop esi + ret + +%ifndef __MSDOS__ +EXTSYM multiMouseMode,Mouse1MoveX,Mouse1MoveY,Mouse2MoveX,Mouse2MoveY,MultiMouseProcess,MouseToRead +%endif + +NEWSYM processmouse + push esi + push edi + push edx + push ebx + call Get_MouseData + mov [mousebuttons],bx + cmp byte[snesmouse],3 + jne .ss + cmp byte[pressed+13],0 + je .noautosw + cmp byte[ssautoswb],1 + je .ss + xor byte[ssautosw],20h + mov byte[ssautoswb],1 + mov dword[Msgptr],.ssautoen + cmp byte[ssautosw],0 + jne .nononauto + mov dword[Msgptr],.ssautodi +.nononauto + mov eax,[MsgCount] + mov [MessageOn],eax + jmp .ss +.noautosw + mov byte[ssautoswb],0 +.ss +; cmp byte[multiMouseMode],0 +; je .nomultimouse + pushad + call MultiMouseProcess + popad + cmp byte[MouseToRead],2 +; je .getmouse2 + mov cx,[Mouse1MoveX] + mov dx,[Mouse1MoveY] + jmp .mousestuff +.getmouse2 + mov cx,[Mouse2MoveX] + mov dx,[Mouse2MoveY] + jmp .mousestuff +.nomultimouse + call Get_MousePositionDisplacement +.mousestuff + cmp byte[snesmouse],4 + je .le + cmp byte[snesmouse],3 + jne .ss2 +.le + add word[mousexloc],cx + test word[mousexloc],8000h + jz .nowrapleft + mov word[mousexloc],0 +.nowrapleft + cmp word[mousexloc],255 + jbe .nowrapright + mov word[mousexloc],255 +.nowrapright + mov ax,[mousexloc] + add ax,40 + mov [latchx],ax + mov byte[extlatch],40h +.ss2 + mov word[mousexpos],0 + cmp cx,0 + je .noxchange + mov byte[mousexdir],0 + cmp cx,0 + jge .noneg + mov byte[mousexdir],1 + neg cx +.noneg + mov [mousexpos],cx +.noxchange + cmp byte[snesmouse],4 + je .le2 + cmp byte[snesmouse],3 + jne .ss3 +.le2 + add word[mouseyloc],dx + test word[mouseyloc],8000h + jz .nowrapup + mov word[mouseyloc],0 +.nowrapup + cmp word[mouseyloc],223 + jbe .nowrapdown + mov word[mouseyloc],223 +.nowrapdown + mov ax,[mouseyloc] + mov [latchy],ax +.ss3 + mov word[mouseypos],0 + cmp dx,0 + je .noychange + mov byte[mouseydir],0 + cmp dx,0 + jge .noneg2 + mov byte[mouseydir],1 + neg dx +.noneg2 + mov [mouseypos],dx +.noychange + xor ecx,ecx + pop ebx + pop edx + pop edi + pop esi + ret + +SECTION .data +.ssautoen db 'AUTOFIRE ENABLED.',0 +.ssautodi db 'AUTOFIRE DISABLED.',0 + +NEWSYM ssautosw, db 20h + +NEWSYM mousexloc, dw 128 +NEWSYM mouseyloc, dw 112 + +SECTION .bss +NEWSYM ssautoswb, resb 1 +NEWSYM mousebuttons, resw 1 +NEWSYM mousexpos, resw 1 +NEWSYM mousexdir, resb 1 +NEWSYM mouseypos, resw 1 +NEWSYM mouseydir, resb 1 +NEWSYM mousechan, resb 1 +SECTION .text + +;******************************************************* +; Output Hex Outputs the hex in al @ esi +;******************************************************* + +NEWSYM outputhex + push edi + push esi + push eax + push ebx + push ecx + push esi + mov edi,FontData + xor ebx,ebx + mov bl,al + shr bl,4 + shl ebx,3 + add edi,ebx + add edi,8 + mov cl,8 +.loopa + mov ah,[edi] + mov ch,8 +.loopb + test ah,80h + jz .nowrite + mov byte[esi],128 + mov byte[esi+289],192 +.nowrite + shl ah,1 + inc esi + dec ch + jnz .loopb + add esi,280 + inc edi + dec cl + jnz .loopa + pop esi + add esi,8 + mov edi,FontData + xor ebx,ebx + mov bl,al + and bl,0Fh + shl ebx,3 + add edi,ebx + add edi,8 + mov cl,8 +.loopa2 + mov ah,[edi] + mov ch,8 +.loopb2 + test ah,80h + jz .nowrite2 + mov byte[esi],128 + mov byte[esi+289],192 +.nowrite2 + shl ah,1 + inc esi + dec ch + jnz .loopb2 + add esi,280 + inc edi + dec cl + jnz .loopa2 + pop ecx + pop ebx + pop eax + pop esi + pop edi + ret + +OutputText16b: + cmp byte[ForceNonTransp],1 + je near OutText16bnt + cmp byte[GUIEnableTransp],0 + je near OutText16bnt + ; output text in edi to esi + push ebx + push eax + mov cl,9 +.loopa + mov ch,9 + xor eax,eax + cmp cl,1 + je .not1 + mov al,[edi] + shl eax,1 +.not1 + xor ebx,ebx + cmp cl,9 + je .loopb + mov bl,[edi-1] +.loopb + test ax,100h + jz .nowrite + push eax + and word[esi],dx + shr word[esi],1 + and word[esi+75036*4],dx + shr word[esi+75036*4],1 + ror edx,16 + add word[esi],dx + add word[esi+75036*4],dx + ror edx,16 + pop eax + jmp .nowrite2 +.nowrite + test bx,100h + jz .nowrite2 + and word[esi],dx + shr word[esi],1 + and word[esi+75036*4],dx + shr word[esi+75036*4],1 +.nowrite2 + shl ax,1 + shl bx,1 + add esi,2 + dec ch + jnz .loopb + add esi,279*2 + inc edi + dec cl + jnz .loopa + pop eax + pop ebx + ret + +OutText16bnt: + ; output text in edi to esi + push ebx + push eax + mov cl,9 +.loopa + mov ch,9 + xor eax,eax + cmp cl,1 + je .not1 + mov al,[edi] + shl eax,1 +.not1 + xor ebx,ebx + cmp cl,9 + je .loopb + mov bl,[edi-1] +.loopb + test ax,100h + jz .nowrite + mov word[esi],0FFFFh + mov word[esi+75036*4],0FFFFh + jmp .nowrite2 +.nowrite + test bx,100h + jz .nowrite2 + and word[esi],dx + and word[esi+75036*4],dx + shr word[esi],1 + shr word[esi+75036*4],1 +.nowrite2 + shl ax,1 + shl bx,1 + add esi,2 + dec ch + jnz .loopb + add esi,279*2 + inc edi + dec cl + jnz .loopa + pop eax + pop ebx + ret + +NEWSYM outputhex16 + push edi + push esi + push eax + push ebx + push ecx + push edx + push esi + mov dx,[vesa2_clbitng] + ror edx,16 + mov dx,[vesa2_clbitng] + shr dx,1 + ror edx,16 + + mov edi,FontData + xor ebx,ebx + mov bl,al + shr bl,4 + shl ebx,3 + add edi,ebx + add edi,8 + call OutputText16b + pop esi + add esi,16 + mov edi,FontData + xor ebx,ebx + mov bl,al + and bl,0Fh + shl ebx,3 + add edi,ebx + add edi,8 + call OutputText16b + pop edx + pop ecx + pop ebx + pop eax + pop esi + pop edi + ret + +SECTION .data +NEWSYM ASCII2Font + db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h + db 00h,00h,00h,00h,00h,00h,00h,00h,00h,30h,00h,00h,00h,00h,00h,00h + db 00h,3Eh,33h,31h,3Fh,37h,2Fh,3Dh,3Ah,3Bh,35h,38h,39h,25h,28h,29h + db 01h,02h,03h,04h,05h,06h,07h,08h,09h,0Ah,2Eh,40h,2Ah,32h,2Bh,36h + db 3Ch,0Bh,0Ch,0Dh,0Eh,0Fh,10h,11h,12h,13h,14h,15h,16h,17h,18h,19h + db 1Ah,1Bh,1Ch,1Dh,1Eh,1Fh,20h,21h,22h,23h,24h,2Ch,34h,2Dh,42h,26h + db 41h,0Bh,0Ch,0Dh,0Eh,0Fh,10h,11h,12h,13h,14h,15h,16h,17h,18h,19h + db 1Ah,1Bh,1Ch,1Dh,1Eh,1Fh,20h,21h,22h,23h,24h,43h,00h,44h,27h,00h + db 0Dh,1Fh,0Fh,0Bh,0Bh,0Bh,0Bh,0Dh,0Fh,0Fh,0Fh,13h,13h,13h,0Bh,0Bh + db 0Fh,0Bh,0Bh,19h,19h,19h,1Fh,1Fh,23h,19h,1Fh,0Dh,10h,23h,1Ah,10h + db 0Bh,4Eh,4Fh,50h,51h,52h,53h,54h,55h,56h,57h,58h,59h,5Ah,5Bh,5Ch + db 5Dh,5Eh,5Fh,60h,61h,62h,63h,64h,65h,66h,67h,68h,69h,6Ah,6Bh,6Ch + db 6Dh,6Eh,6Fh,70h,71h,72h,73h,74h,75h,76h,77h,78h,79h,7Ah,7Bh,7Ch + db 7Dh,7Eh,7Fh,80h,81h,82h,83h,84h,85h,86h,87h,88h,89h,8Ah,8Bh,8Ch + db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h + db 00h,00h,00h,00h,00h,00h,00h,4Dh,4Ch,4Bh,4Ah,45h,46h,47h,48h,49h + +NEWSYM FontData + db 0,0,0,0,0,0,0,0 + db 01111100b,11000110b,11001110b,11010110b ; 0, 01 + db 11100110b,11000110b,01111100b,00000000b + db 00011000b,00111000b,01111000b,00011000b ; 1, 02 + db 00011000b,00011000b,01111110b,00000000b + db 01111100b,11000110b,00001100b,00011000b ; 2, 03 + db 00110000b,01100110b,11111110b,00000000b + db 01111100b,11000110b,00000110b,00111100b ; 3, 04 + db 00000110b,11000110b,01111100b,00000000b + db 00111100b,01101100b,11001100b,11111110b ; 4, 05 + db 00001100b,00001100b,00001100b,00000000b + db 11111110b,11000000b,11000000b,11111100b ; 5, 06 + db 00000110b,11000110b,01111100b,00000000b + db 00111100b,01100000b,11000000b,11111100b ; 6, 07 + db 11000110b,11000110b,01111100b,00000000b + db 11111110b,11000110b,00000110b,00001100b ; 7, 08 + db 00011000b,00011000b,00011000b,00000000b + db 01111100b,11000110b,11000110b,01111100b ; 8, 09 + db 11000110b,11000110b,01111100b,00000000b + db 01111100b,11000110b,11000110b,01111110b ; 9, 0A + db 00000110b,11000110b,01111100b,00000000b + db 00111000b,01101100b,11000110b,11111110b ; A, 0B + db 11000110b,11000110b,11000110b,00000000b + db 11111100b,11000110b,11000110b,11111100b ; B, 0C + db 11000110b,11000110b,11111100b,00000000b + db 01111100b,11000110b,11000000b,11000000b ; C, 0D + db 11000000b,11000110b,01111100b,00000000b + db 11111100b,11000110b,11000110b,11000110b ; D, 0E + db 11000110b,11000110b,11111100b,00000000b + db 11111110b,11000000b,11000000b,11111000b ; E, 0F + db 11000000b,11000000b,11111110b,00000000b + db 11111110b,11000000b,11000000b,11111000b ; F, 10 + db 11000000b,11000000b,11000000b,00000000b + db 01111100b,11000110b,11000000b,11000000b ; G, 11 + db 11001110b,11000110b,01111100b,00000000b + db 11000110b,11000110b,11000110b,11111110b ; H, 12 + db 11000110b,11000110b,11000110b,00000000b + db 00111100b,00011000b,00011000b,00011000b ; I, 13 + db 00011000b,00011000b,00111100b,00000000b + db 00011110b,00001100b,00001100b,00001100b ; J, 14 + db 00001100b,11001100b,00111100b,00000000b + db 11001100b,11011000b,11110000b,11100000b ; K, 15 + db 11110000b,11011000b,11001100b,00000000b + db 11000000b,11000000b,11000000b,11000000b ; L, 16 + db 11000000b,11000000b,11111110b,00000000b + db 11000110b,11101110b,11111110b,11010110b ; M, 17 + db 11000110b,11000110b,11000110b,00000000b + db 11000110b,11100110b,11110110b,11011110b ; N, 18 + db 11001110b,11000110b,11000110b,00000000b + db 01111100b,11000110b,11000110b,11000110b ; O, 19 + db 11000110b,11000110b,01111100b,00000000b + db 11111100b,11000110b,11000110b,11111100b ; P, 1A + db 11000000b,11000000b,11000000b,00000000b + db 01111100b,11000110b,11000110b,11000110b ; Q, 1B + db 11010110b,11001110b,01111110b,00000000b + db 11111100b,11000110b,11000110b,11111100b ; R, 1C + db 11001100b,11000110b,11000110b,00000000b + db 01111100b,11000110b,11000000b,01111100b ; S, 1D + db 00000110b,11000110b,01111100b,00000000b + db 01111110b,00011000b,00011000b,00011000b ; T, 1E + db 00011000b,00011000b,00011000b,00000000b + db 11000110b,11000110b,11000110b,11000110b ; U, 1F + db 11000110b,11000110b,01111100b,00000000b + db 11000110b,11000110b,11000110b,11000110b ; V, 20 + db 01101100b,00111000b,00010000b,00000000b + db 11000110b,11000110b,11000110b,11010110b ; W, 21 + db 11010110b,11111110b,01101100b,00000000b + db 11000110b,01101100b,00111000b,00010000b ; X, 22 + db 00111000b,01101100b,11000110b,00000000b + db 11001100b,11001100b,01111000b,00110000b ; Y, 23 + db 00110000b,00110000b,00110000b,00000000b + db 11111100b,10001100b,00011000b,00110000b ; Z, 24 + db 01100000b,11000100b,11111100b,00000000b + db 00000000b,00000000b,00000000b,11111110b ; -, 25 + db 00000000b,00000000b,00000000b,00000000b + db 00000000b,00000000b,00000000b,00000000b ; _, 26 + db 00000000b,00000000b,11111110b,00000000b + db 01110000b,11011100b,00000110b,00000000b ; ~, 27 + db 00000000b,00000000b,00000000b,00000000b + db 00000000b,00000000b,00000000b,00000000b ; ., 28 + db 00000000b,00110000b,00110000b,00000000b + db 00000010b,00000100b,00001000b,00010000b ; /, 29 + db 00100000b,01000000b,10000000b,00000000b + db 00001100b,00011000b,00110000b,01100000b ; <, 2A + db 00110000b,00011000b,00001100b,00000000b + db 01100000b,00110000b,00011000b,00001100b ; >, 2B + db 00011000b,00110000b,01100000b,00000000b + db 00111000b,00100000b,00100000b,00100000b ; [, 2C + db 00100000b,00100000b,00111000b,00000000b + db 00111000b,00001000b,00001000b,00001000b ; ], 2D + db 00001000b,00001000b,00111000b,00000000b + db 00000000b,00011000b,00011000b,00000000b ; :, 2E + db 00011000b,00011000b,00000000b,00000000b + db 00011000b,00100100b,00011000b,00111010b ; &, 2F + db 01000100b,01000110b,00111010b,00000000b + ; Arrow, 30 + ; #, 31 (, 3A {, 43 + ; =, 32 ), 3B }, 44 + ; ", 33 @, 3C Up,45 + ; \, 34 ', 3D Dn,46 + ; *, 35 !, 3E Lt,47 + ; ?, 36 $, 3F Rt,48 + ; %, 37 ;, 40 Bk,49 + ; +, 38 `, 41 .5,4A + ; ,, 39 ^, 42 + +SECTION .text + +;******************************************************* +; Output Char Outputs char in al @ esi +;******************************************************* + +NEWSYM outputchar + push edi + push esi + push eax + mov edi,FontData + xor ebx,ebx + mov bl,al + shl ebx,3 + add edi,ebx + mov cl,8 +.loopa + mov ah,[edi] + mov ch,8 +.loopb + test ah,80h + jz .nowrite + mov al,[textcolor] + mov [esi],al + mov byte[esi+289],192 +.nowrite + shl ah,1 + inc esi + dec ch + jnz .loopb + add esi,280 + inc edi + dec cl + jnz .loopa + pop eax + pop esi + pop edi + ret + +NEWSYM outputchar16b + push edi + push esi + push eax + push edx + push ecx + mov dx,[vesa2_clbitng] + ror edx,16 + mov dx,[vesa2_clbitng] + shr dx,1 + ror edx,16 + + mov edi,FontData + xor ebx,ebx + mov bl,al + shl ebx,3 + add edi,ebx + call OutputText16b + pop ecx + pop edx + pop eax + pop esi + pop edi + ret + +SECTION .data +NEWSYM textcolor, db 128 +NEWSYM textcolor16b, dw 0FFFFh +SECTION .text + +NEWSYM outputchar5x5 + push edi + push esi + push eax + mov edi,GUIFontData + xor ebx,ebx + mov bl,al + shl ebx,2 + add edi,ebx + xor ebx,ebx + mov bl,al + add edi,ebx + mov cl,5 +.loopa + mov ah,[edi] + mov ch,5 +.loopb + test ah,80h + jz .nowrite + mov al,[textcolor] + mov [esi],al +.nowrite + shl ah,1 + inc esi + dec ch + jnz .loopb + add esi,283 + inc edi + dec cl + jnz .loopa + pop eax + pop esi + pop edi + ret + +NEWSYM outputchar16b5x5 + push edi + push esi + push eax + mov edi,GUIFontData + xor ebx,ebx + mov bl,al + shl ebx,2 + add edi,ebx + xor ebx,ebx + mov bl,al + add edi,ebx + mov cl,5 +.loopa + mov ah,[edi] + mov ch,5 +.loopb + test ah,80h + jz .nowrite + push eax + mov ax,[textcolor16b] + mov [esi],ax + mov [esi+75036*4],ax + pop eax +.nowrite + shl ah,1 + add esi,2 + dec ch + jnz .loopb + add esi,283*2 + inc edi + dec cl + jnz .loopa + pop eax + pop esi + pop edi + ret + +NEWSYM outputchar16b5x52 + push edi + push esi + push eax + mov edi,GUIFontData + xor ebx,ebx + mov bl,al + shl ebx,2 + add edi,ebx + xor ebx,ebx + mov bl,al + add edi,ebx + mov word[esi-288*2],0 + mov word[esi+2-288*2],0 + mov word[esi+4-288*2],0 + mov word[esi+6-288*2],0 + mov word[esi+8-288*2],0 + mov word[esi+10-288*2],0 + mov word[esi-288*2+75036*4],0 + mov word[esi+2-288*2+75036*4],0 + mov word[esi+4-288*2+75036*4],0 + mov word[esi+6-288*2+75036*4],0 + mov word[esi+8-288*2+75036*4],0 + mov word[esi+10-288*2+75036*4],0 + mov cl,5 +.loopa + mov ah,[edi] + mov ch,5 +.loopb + mov word[esi],0 + mov word[esi+2],0 + mov word[esi+75036*4],0 + mov word[esi+2+75036*4],0 + test ah,80h + jz .nowrite + push eax + mov ax,[textcolor16b] + mov [esi],ax + mov [esi+75036*4],ax + pop eax +.nowrite + shl ah,1 + add esi,2 + dec ch + jnz .loopb + add esi,283*2 + inc edi + dec cl + jnz .loopa + mov word[esi],0 + mov word[esi+2],0 + mov word[esi+4],0 + mov word[esi+6],0 + mov word[esi+8],0 + mov word[esi+10],0 + mov word[esi+75036*4],0 + mov word[esi+2+75036*4],0 + mov word[esi+4+75036*4],0 + mov word[esi+6+75036*4],0 + mov word[esi+8+75036*4],0 + mov word[esi+10+75036*4],0 + pop eax + pop esi + pop edi + ret + +;******************************************************* +; Output Graphic String Outputs String from edi to esi +;******************************************************* + +NEWSYM OutputGraphicString + cmp byte[cbitmode],1 + je .do16b +.no16bit + xor eax,eax +.nextstr + mov al,[edi] + cmp al,0 + je .nomore + mov al,[ASCII2Font+eax] + call outputchar + add esi,8 + inc edi + jmp .nextstr +.nomore + ret + +.do16b + sub esi,[vidbuffer] + shl esi,1 + add esi,[vidbuffer] + cmp byte[textcolor],128 + jne .no128 + mov word[textcolor16b],0FFFFh +.no128 + cmp byte[textcolor],129 + jne .no129 + mov word[textcolor16b],0 +.no129 + cmp byte[textcolor],130 + jne .no130 + xor ax,ax + xor bx,bx + mov cl,[vesa2_rpos] + mov bx,20 + shl bx,cl + add ax,bx + mov cl,[vesa2_gpos] + mov bx,20 + shl bx,cl + add ax,bx + mov cl,[vesa2_bpos] + mov bx,20 + shl bx,cl + add ax,bx + mov [textcolor16b],ax +.no130 + ; Color #131, Red + cmp byte[textcolor],131 + jne .no131 + xor ax,ax + xor bx,bx + mov cl,[vesa2_rpos] + mov bx,22 + shl bx,cl + add ax,bx + mov cl,[vesa2_gpos] + mov bx,5 + shl bx,cl + add ax,bx + mov cl,[vesa2_bpos] + mov bx,5 + shl bx,cl + add ax,bx + mov [textcolor16b],ax +.no131 + jmp OutputGraphicString16b + +NEWSYM OutputGraphicString16b + xor eax,eax +.nextstr + mov al,[edi] + cmp al,0 + je .nomore + mov al,[ASCII2Font+eax] + call outputchar16b + add esi,16 + inc edi + jmp .nextstr +.nomore + ret + +NEWSYM OutputGraphicString5x5 + cmp byte[cbitmode],1 + je .do16b +.no16bit + xor eax,eax +.nextstr + mov al,[edi] + cmp al,0 + je .nomore + mov al,[ASCII2Font+eax] + call outputchar5x5 + add esi,6 + inc edi + jmp .nextstr +.nomore + ret + +.do16b + sub esi,[vidbuffer] + shl esi,1 + add esi,[vidbuffer] + cmp byte[textcolor],128 + jne .no128 + mov word[textcolor16b],0FFFFh +.no128 + cmp byte[textcolor],129 + jne .no129 + mov word[textcolor16b],0 +.no129 + cmp byte[textcolor],130 + jne .no130 + xor ax,ax + xor bx,bx + mov cl,[vesa2_rpos] + mov bx,20 + shl bx,cl + add ax,bx + mov cl,[vesa2_gpos] + mov bx,20 + shl bx,cl + add ax,bx + mov cl,[vesa2_bpos] + mov bx,20 + shl bx,cl + add ax,bx + mov [textcolor16b],ax +.no130 + ; Color #131, Red + cmp byte[textcolor],131 + jne .no131 + xor ax,ax + xor bx,bx + mov cl,[vesa2_rpos] + mov bx,22 + shl bx,cl + add ax,bx + mov cl,[vesa2_gpos] + mov bx,5 + shl bx,cl + add ax,bx + mov cl,[vesa2_bpos] + mov bx,5 + shl bx,cl + add ax,bx + mov [textcolor16b],ax +.no131 + jmp OutputGraphicString16b5x5 + +NEWSYM OutputGraphicString16b5x5 + xor eax,eax +.nextstr + mov al,[edi] + cmp al,0 + je .nomore + mov al,[ASCII2Font+eax] + call outputchar16b5x5 + add esi,12 + inc edi + jmp .nextstr +.nomore + ret + +NEWSYM OutputGraphicString16b5x52 + xor eax,eax +.nextstr + mov al,[edi] + cmp al,0 + je .nomore + mov al,[ASCII2Font+eax] + call outputchar16b5x52 + add esi,12 + inc edi + jmp .nextstr +.nomore + ret + +NEWSYM OutputGraphicStringb + cmp byte[cbitmode],1 + je near .do16b + xor eax,eax + cmp byte[edi-1],1 + je .dir + cmp byte[edi-1],2 + je near .drive + sub esi,8 +.nextstr + mov al,[edi] + cmp al,0 + je .nomore + mov al,[ASCII2Font+eax] + call outputchar + add esi,8 + inc edi + jmp .nextstr +.nomore + ret +.dir + sub esi,8 + mov al,'<' + mov al,[ASCII2Font+eax] + call outputchar + add esi,8 +.nextstr2 + mov al,[edi] + cmp al,0 + je .nomore2 + mov al,[ASCII2Font+eax] + call outputchar + add esi,8 + inc edi + jmp .nextstr2 +.nomore2 + mov al,'>' + mov al,[ASCII2Font+eax] + call outputchar + ret +.drive + sub esi,8 + mov al,'[' + mov al,[ASCII2Font+eax] + call outputchar + add esi,8 +.nextstr3 + mov al,[edi] + cmp al,0 + je .nomore3 + mov al,[ASCII2Font+eax] + call outputchar + add esi,8 + inc edi + jmp .nextstr3 +.nomore3 + mov al,']' + mov al,[ASCII2Font+eax] + call outputchar + ret +.do16b + sub esi,[vidbuffer] + shl esi,1 + add esi,[vidbuffer] + cmp byte[textcolor],128 + jne .no128 + mov word[textcolor16b],0FFFFh +.no128 + cmp byte[textcolor],129 + jne .no129 + mov word[textcolor16b],0 +.no129 + cmp byte[textcolor],130 + jne .no130 + xor ax,ax + xor bx,bx + mov cl,[vesa2_rpos] + mov bx,20 + shl bx,cl + add ax,bx + mov cl,[vesa2_gpos] + mov bx,20 + shl bx,cl + add ax,bx + mov cl,[vesa2_bpos] + mov bx,20 + shl bx,cl + add ax,bx + mov [textcolor16b],ax +.no130 + ; Color #131, Red + cmp byte[textcolor],131 + jne .no131 + xor ax,ax + xor bx,bx + mov cl,[vesa2_rpos] + mov bx,22 + shl bx,cl + add ax,bx + mov cl,[vesa2_gpos] + mov bx,5 + shl bx,cl + add ax,bx + mov cl,[vesa2_bpos] + mov bx,5 + shl bx,cl + add ax,bx + mov [textcolor16b],ax +.no131 +NEWSYM OutputGraphicString16bb + xor eax,eax + cmp byte[edi-1],1 + je .dir + cmp byte[edi-1],2 + je near .drive + xor eax,eax + sub esi,16 +.nextstr + mov al,[edi] + cmp al,0 + je .nomore + mov al,[ASCII2Font+eax] + call outputchar16b + add esi,16 + inc edi + jmp .nextstr +.nomore + ret +.dir + sub esi,16 + mov al,'<' + mov al,[ASCII2Font+eax] + call outputchar16b + add esi,16 +.nextstr2 + mov al,[edi] + cmp al,0 + je .nomore2 + mov al,[ASCII2Font+eax] + call outputchar16b + add esi,16 + inc edi + jmp .nextstr2 +.nomore2 + mov al,'>' + mov al,[ASCII2Font+eax] + call outputchar16b + ret +.drive + sub esi,16 + mov al,'[' + mov al,[ASCII2Font+eax] + call outputchar16b + add esi,16 +.nextstr3 + mov al,[edi] + cmp al,0 + je .nomore3 + mov al,[ASCII2Font+eax] + call outputchar16b + add esi,16 + inc edi + jmp .nextstr3 +.nomore3 + mov al,']' + mov al,[ASCII2Font+eax] + call outputchar16b + ret + +;******************************************************* +; Save Select Allows user to select save state slot +;******************************************************* +; For Save State + +SECTION .bss +NEWSYM csounddisable, resb 1 +NEWSYM statefileloc, resd 1 +newestfileloc resb 1 +newestfiledate resd 1 +f3menuen resb 1 +PrevPictureVal resb 1 +CurPictureVal resb 1 +SECTION .text + +NEWSYM drawhline +.loop + mov [esi],al + inc esi + dec ecx + jnz .loop + ret + +NEWSYM drawhline16b +.loop + mov [esi],ax + add esi,2 + dec ecx + jnz .loop + ret + +NEWSYM drawvline +.loop + mov [esi],al + add esi,288 + dec ecx + jnz .loop + ret + +NEWSYM drawvline16b +.loop + mov [esi],ax + add esi,288*2 + dec ecx + jnz .loop + ret + +%macro determinenewhelp 2 + mov bl,%1 + mov byte[fnamest+eax],%2 + call DetermineNew +%endmacro + +DetermineNew: + push eax + push ebx + mov edx,fnamest+1 + call Open_File + jc near .nodraw + mov bx,ax + mov edx,fnamest+1 + call Get_File_Date +%ifdef __MSDOS__ + shl edx,16 + mov dx,cx +%endif + push edx + call Close_File + pop edx + pop ebx + pop eax + ; date = edx, position = bl + cmp edx,[newestfiledate] + jbe .notlatest + mov [newestfiledate],edx + mov [newestfileloc],bl +.notlatest + ret +.nodraw + pop ebx + pop eax + ret + +DetermineNewest: + mov dword[newestfiledate],0 + mov byte[newestfileloc],0 + + determinenewhelp 0,'t' + determinenewhelp 1,'1' + determinenewhelp 2,'2' + determinenewhelp 3,'3' + determinenewhelp 4,'4' + determinenewhelp 5,'5' + determinenewhelp 6,'6' + determinenewhelp 7,'7' + determinenewhelp 8,'8' + determinenewhelp 9,'9' + ret + +GetPicture: + mov cl,[CurPictureVal] + cmp [PrevPictureVal],cl + jne .notskip + ret +.notskip + mov [PrevPictureVal],cl + mov edx,PrevPicture + mov ecx,64*56*2 +.loop + mov byte[edx],0 + inc edx + dec ecx + jnz .loop + mov edx,fnamest+1 + call Open_File + jc near .nodraw2 + mov bx,ax + xor cx,cx + xor dx,dx + call File_Seek_End + shl edx,16 + mov dx,ax + push eax + sub edx,64*56*2 ;Size of thumbnail + mov eax,[cur_zst_size] + cmp edx,eax + je .draw + mov eax,[old_zst_size] + cmp edx,eax + je .draw + pop eax + jmp .nodraw +.draw + pop eax + mov ax,dx + shr edx,16 + mov cx,dx + mov dx,ax + call File_Seek + mov ecx,64*56*2 + mov edx,PrevPicture + call Read_File +.nodraw + call Close_File +.nodraw2 + ; convert to 1:5:5:5 + cmp byte[newengen],0 + je .noneweng + cmp byte[nggposng],5 + jne .noneweng + mov edx,PrevPicture + mov ecx,64*56 +.loop2 + mov ax,[edx] + mov bx,ax + and ax,1111111111000000b + and bx,0000000000011111b + shr ax,1 + or bx,ax + mov [edx],bx + add edx,2 + dec ecx + jnz .loop2 +.noneweng + ; draw border + mov esi,75*2+9*288*2 + add esi,[vidbuffer] + mov edx,58 +.ploopa + mov ecx,66 + push esi +.ploopb + mov word[esi],0FFFFh + add esi,2 + dec ecx + jnz .ploopb + pop esi + add esi,288*2 + dec edx + jnz .ploopa + ; draw picture + mov esi,76*2+10*288*2 + add esi,[vidbuffer] + mov edx,56 + mov edi,PrevPicture +.ploopa2 + mov ecx,64 + push esi +.ploopb2 + mov ax,[edi] + mov [esi],ax + add esi,2 + add edi,2 + dec ecx + jnz .ploopb2 + pop esi + add esi,288*2 + dec edx + jnz .ploopa2 + ret + +NEWSYM drawfillboxsc + push eax + push ebx + mov edx,fnamest+1 + call Open_File + jc near .nodraw + mov bx,ax + call Close_File + pop ebx + ; draws a 10x10 filled box according to position bl and color dl + xor eax,eax + mov al,11 + mul bl + mov esi,76+94*288 + add esi,[vidbuffer] + add esi,eax + mov ecx,10 + mov al,176 + cmp [newestfileloc],bl + jne .next + mov al,208 +.next + push esi + push ecx + mov ecx,10 + call drawhline + pop ecx + pop esi + add esi,288 + dec ecx + jnz .next + pop eax + ret +.nodraw + pop ebx + pop eax + ret + +NEWSYM drawfillboxsc16b + push eax + push ebx + mov edx,fnamest+1 + call Open_File + jc near .nodraw + mov bx,ax + call Close_File + pop ebx + ; draws a 10x10 filled box according to position bl and color dl + xor eax,eax + mov al,11 + mul bl + mov esi,76*2+94*288*2 + add esi,[vidbuffer] + add esi,eax + add esi,eax + mov ecx,10 + mov ax,[saveselect.allgrn] + cmp [newestfileloc],bl + jne .next + mov ax,[saveselect.allgrnb] +.next + push esi + push ecx + mov ecx,10 + call drawhline16b + pop ecx + pop esi + add esi,288*2 + dec ecx + jnz .next + pop eax + ret +.nodraw + pop ebx + pop eax + ret + +NEWSYM drawbox + ; draws a box according to position bl and color dl + xor eax,eax + mov al,11 + mul bl + mov esi,75+93*288 + add esi,[vidbuffer] + add esi,eax + mov al,dl + push esi + mov ecx,12 + call drawhline + pop esi + push esi + mov ecx,12 + call drawvline + pop esi + push esi + add esi,11 + mov ecx,12 + call drawvline + pop esi + add esi,11*288 + mov ecx,12 + call drawhline + ret + +NEWSYM drawbox16b + ; draws a box according to position bl and color dx + xor eax,eax + mov al,11 + mul bl + mov esi,75*2+93*288*2 + add esi,[vidbuffer] + add esi,eax + add esi,eax + mov ax,dx + push esi + mov ecx,12 + call drawhline16b + pop esi + push esi + mov ecx,12 + call drawvline16b + pop esi + push esi + add esi,11*2 + mov ecx,12 + call drawvline16b + pop esi + add esi,11*288*2 + mov ecx,12 + call drawhline16b + ret + +%macro drawfillboxhelp 2 + mov bl,%1 + mov byte[fnamest+eax],%2 + call drawfillboxsc +%endmacro + +%macro drawfillboxhelp16b 2 + mov bl,%1 + mov byte[fnamest+eax],%2 + call drawfillboxsc16b +%endmacro + + +NEWSYM saveselect + cmp byte[MovieProcessing],0 + jz .nomovie + pushad + call mzt_chdir + popad +.nomovie + mov byte[f3menuen],1 + mov byte[ForceNonTransp],1 + cmp byte[ForceNewGfxOff],0 + jne .nong16b + cmp byte[cbitmode],0 + je .nong16b +%ifdef __MSDOS__ + call GetScreen +%endif +.nong16b + cmp dword[MessageOn],0 + je .nochangem + mov dword[MessageOn],1 +.nochangem + mov al,[newengen] + mov byte[newengen],0 + push eax + call copyvid + pop eax + mov [newengen],al + call StopSound + cmp byte[soundon],0 + je .nosound + mov byte[csounddisable],1 +%ifdef __MSDOS__ + call SB_blank +%endif +.nosound + cmp byte[cbitmode],1 + je near .16b + call saveselectpal + ; draw a small blue box with a white border + mov esi,70+70*288 + add esi,[vidbuffer] + mov ecx,150 + mov al,70 +.loop + mov byte[esi],144 + inc esi + dec ecx + jnz .loop + add esi,288-150 + dec al + mov ecx,150 + jnz .loop + ; draw filled boxes for existing files + mov eax,[statefileloc] + mov bl,[fnamest+eax] + push ebx + call DetermineNewest + drawfillboxhelp 0,'t' + drawfillboxhelp 1,'1' + drawfillboxhelp 2,'2' + drawfillboxhelp 3,'3' + drawfillboxhelp 4,'4' + drawfillboxhelp 5,'5' + drawfillboxhelp 6,'6' + drawfillboxhelp 7,'7' + drawfillboxhelp 8,'8' + drawfillboxhelp 9,'9' + pop ebx + mov eax,[statefileloc] + mov [fnamest+eax],bl + + mov esi,75+73*288 + add esi,[vidbuffer] + mov edi,.stringa + call OutputGraphicString + mov esi,75+83*288 + add esi,[vidbuffer] + mov edi,.stringb + call OutputGraphicString + mov esi,75+108*288 + add esi,[vidbuffer] + mov edi,.stringc + call OutputGraphicString + mov esi,75+118*288 + add esi,[vidbuffer] + mov edi,.stringd + call OutputGraphicString + mov esi,75+128*288 + add esi,[vidbuffer] + mov edi,.stringe + call OutputGraphicString + mov al,128 + mov esi,70+70*288 + add esi,[vidbuffer] + mov ecx,150 + call drawhline + mov esi,70+70*288 + add esi,[vidbuffer] + mov ecx,70 + call drawvline + mov esi,70+139*288 + add esi,[vidbuffer] + mov ecx,150 + call drawhline + mov esi,219+70*288 + add esi,[vidbuffer] + mov ecx,70 + call drawvline + mov esi,75+93*288 + add esi,[vidbuffer] + mov ecx,111 + call drawhline + mov esi,75+104*288 + add esi,[vidbuffer] + mov ecx,111 + call drawhline + mov esi,75+94*288 + add esi,[vidbuffer] + mov bl,11 +.nextvline + mov ecx,10 + push esi + push ebx + call drawvline + pop ebx + pop esi + add esi,11 + dec bl + jnz .nextvline + mov esi,78+96*288 + add esi,[vidbuffer] + mov al,1 + call outputchar + mov bl,9 +.nextnumchar + add esi,11 + inc al + push ebx + call outputchar + pop ebx + dec bl + jnz .nextnumchar + mov byte[curblank],0h + mov bl,0 + mov ebx,[statefileloc] + mov al,[fnamest+ebx] + cmp al,'t' + jne .noT + mov bl,0 + jmp .nexter +.noT + mov bl,al + sub bl,48 +.nexter + mov dl,160 + call drawbox + push ebx + call copyvid + pop ebx + ; wait until esc/enter is pressed +.noesc + mov dl,128 + call drawbox + mov ecx,2500 + call delay + call testpressed8b + test byte[pressed+1],1 + jnz near .esc + test byte[pressed+28],1 + jnz near .enter + mov ecx,2500 + call delay + call testpressed8b + test byte[pressed+1],1 + jnz near .esc + test byte[pressed+28],1 + jnz near .enter + push ebx + call copyvid + pop ebx + mov ecx,2500 + call delay + call testpressed8b + test byte[pressed+1],1 + jnz near .esc + test byte[pressed+28],1 + jnz near .enter + mov ecx,2500 + call delay + call testpressed8b + test byte[pressed+1],1 + jnz near .esc + test byte[pressed+28],1 + jnz near .enter + mov dl,160 + call drawbox + push ebx + call copyvid + pop ebx + jmp .noesc +.enter + mov byte[pressed+28],2 + cmp bl,0 + jne .nozero + mov al,'t' + jmp .save +.nozero + add bl,48 + mov al,bl +.save + mov ebx,[statefileloc] + mov [fnamest+ebx],al +.esc + + mov eax,pressed + mov ecx,256 +.looppr + cmp byte[eax],1 + jne .notpr + mov byte[eax],2 +.notpr + inc eax + dec ecx + jnz .looppr +%ifdef __MSDOS__ + mov byte[pressed+1],0 +%endif + + mov word[t1cc],0 + mov byte[csounddisable],0 + call StartSound + + call makepal + mov byte[f3menuen],0 + mov byte[ForceNonTransp],0 + cmp byte[MovieProcessing],0 + jz .nomovie2 + pushad + call UpChdir + popad +.nomovie2 + ret + +SECTION .bss +.allred resw 1 +.allgrn resw 1 +.allgrnb resw 1 +.blue resw 1 +.stepb resw 1 +SECTION .text + +; Start 16-bit stuff here +.16b + cmp byte[newengen],0 + je .notng + mov byte[GUIOn],1 +.notng + ; draw shadow behind box + mov esi,80*2+80*288*2 + add esi,[vidbuffer] + mov ecx,150 + mov al,70 + mov ah,5 +.loop16b2 + mov dx,[esi] + and dx,[vesa2_clbit] + shr dx,1 + mov [esi],dx + add esi,2 + dec ecx + jnz .loop16b2 + add esi,288*2-150*2 + dec al + mov ecx,150 + jnz .loop16b2 + + mov ax,018h + mov cl,[vesa2_rpos] + shl ax,cl + mov [.allgrn],ax + + mov ax,25 + mov cl,[vesa2_rpos] + shl ax,cl + mov [.allgrnb],ax + mov ax,12 + mov cl,[vesa2_gpos] + shl ax,cl + or [.allgrnb],ax + + mov ax,01Fh + mov cl,[vesa2_rpos] + shl ax,cl + mov [.allred],ax + mov ax,012h + mov cl,[vesa2_bpos] + shl ax,cl + mov dx,ax + mov ax,01h + mov cl,[vesa2_gpos] + shl ax,cl + mov bx,ax + mov ax,01h + mov cl,[vesa2_rpos] + shl ax,cl + or bx,ax + + ; draw a small blue box with a white border + mov esi,70*2+70*288*2 + add esi,[vidbuffer] + mov ecx,150 + mov al,70 + mov ah,5 +.loop16b + mov [esi],dx + add esi,2 + dec ecx + jnz .loop16b + add esi,288*2-150*2 + dec ah + jnz .nocolinc16b + add dx,bx + mov ah,5 +.nocolinc16b + dec al + mov ecx,150 + jnz .loop16b + + ; draw filled boxes for existing files + mov eax,[statefileloc] + mov bl,[fnamest+eax] + push ebx + call DetermineNewest + drawfillboxhelp16b 0,'t' + drawfillboxhelp16b 1,'1' + drawfillboxhelp16b 2,'2' + drawfillboxhelp16b 3,'3' + drawfillboxhelp16b 4,'4' + drawfillboxhelp16b 5,'5' + drawfillboxhelp16b 6,'6' + drawfillboxhelp16b 7,'7' + drawfillboxhelp16b 8,'8' + drawfillboxhelp16b 9,'9' + pop ebx + mov eax,[statefileloc] + mov [fnamest+eax],bl + + mov esi,75*2+73*288*2 + add esi,[vidbuffer] + mov edi,.stringa + call OutputGraphicString16b + mov esi,75*2+83*288*2 + add esi,[vidbuffer] + mov edi,.stringb + call OutputGraphicString16b + mov esi,75*2+108*288*2 + add esi,[vidbuffer] + mov edi,.stringc + call OutputGraphicString16b + mov esi,75*2+118*288*2 + add esi,[vidbuffer] + mov edi,.stringd + call OutputGraphicString16b + mov esi,75*2+128*288*2 + add esi,[vidbuffer] + mov edi,.stringe + call OutputGraphicString16b + mov ax,0FFFFh + mov esi,70*2+70*288*2 + add esi,[vidbuffer] + mov ecx,150 + call drawhline16b + mov esi,70*2+70*288*2 + add esi,[vidbuffer] + mov ecx,70 + call drawvline16b + mov esi,70*2+139*288*2 + add esi,[vidbuffer] + mov ecx,150 + call drawhline16b + mov esi,219*2+70*288*2 + add esi,[vidbuffer] + mov ecx,70 + call drawvline16b + mov esi,75*2+93*288*2 + add esi,[vidbuffer] + mov ecx,111 + call drawhline16b + mov esi,75*2+104*288*2 + add esi,[vidbuffer] + mov ecx,111 + call drawhline16b + mov esi,75*2+94*288*2 + add esi,[vidbuffer] + mov bl,11 +.nextvline16b + mov ecx,10 + push esi + push ebx + call drawvline16b + pop ebx + pop esi + add esi,22 + dec bl + jnz .nextvline16b + mov esi,78*2+96*288*2 + add esi,[vidbuffer] + mov al,1 + call outputchar16b + mov bl,9 +.nextnumchar16b + add esi,22 + inc al + push ebx + call outputchar16b + pop ebx + dec bl + jnz .nextnumchar16b + + mov byte[curblank],0h + mov bl,0 + mov ebx,[statefileloc] + mov al,[fnamest+ebx] + cmp al,'t' + jne .noT16b + mov bl,0 + jmp .nexter16b +.noT16b + mov bl,al + sub bl,48 +.nexter16b + mov dx,[.allred] + call drawbox16b + push ebx + mov al,[newengen] + mov byte[newengen],0 + push eax + call copyvid + pop eax + mov [newengen],al + pop ebx + ; wait until esc/enter is pressed + + mov byte[PrevPictureVal],0FFh +.noesc16b + mov [CurPictureVal],bl + pushad + mov eax,[statefileloc] + mov cl,[fnamest+eax] + push ecx + cmp bl,0 + jne .nozero16b2 + mov cl,'t' + jmp .save16b2 +.nozero16b2 + mov cl,bl + add cl,48 +.save16b2 + mov [fnamest+eax],cl + call GetPicture + pop ecx + mov eax,[statefileloc] + mov [fnamest+eax],cl + popad + + mov dx,0FFFFh + call drawbox16b + mov ecx,2500 + call delay + call testpressed8b + test byte[pressed+1],1 + jnz near .esc16b + test byte[pressed+28],1 + jnz near .enter16b + mov ecx,2500 + call delay + call testpressed8b + test byte[pressed+1],1 + jnz near .esc16b + test byte[pressed+28],1 + jnz near .enter16b + push ebx + mov al,[newengen] + mov byte[newengen],0 + push eax + call copyvid + pop eax + mov [newengen],al + pop ebx + mov ecx,2500 + call delay + call testpressed8b + test byte[pressed+1],1 + jnz near .esc16b + test byte[pressed+28],1 + jnz near .enter16b + mov ecx,2500 + call delay + call testpressed8b + test byte[pressed+1],1 + jnz near .esc16b + test byte[pressed+28],1 + jnz near .enter16b + mov dx,[.allred] + call drawbox16b + push ebx + mov al,[newengen] + mov byte[newengen],0 + push eax + call copyvid + pop eax + mov [newengen],al + pop ebx + jmp .noesc16b +.enter16b + mov byte[pressed+28],2 + cmp bl,0 + jne .nozero16b + mov al,'t' + jmp .save16b +.nozero16b + add bl,48 + mov al,bl +.save16b + mov ebx,[statefileloc] + mov [fnamest+ebx],al +.esc16b + mov eax,pressed + mov ecx,256 +.looppr2 + cmp byte[eax],1 + jne .notpr2 + mov byte[eax],2 +.notpr2 + inc eax + dec ecx + jnz .looppr2 +.prwin +%ifdef __MSDOS__ + mov byte[pressed+1],0 +%endif + mov word[t1cc],0 + mov byte[csounddisable],0 + call StartSound + mov byte[f3menuen],0 + mov byte[ForceNonTransp],0 + mov byte[GUIOn],0 + pushad + call Clear2xSaIBuffer + popad + cmp byte[MovieProcessing],0 + jz .nomovie3 + pushad + call UpChdir + popad +.nomovie3 + ret + +SECTION .data +.stringa db 'PLEASE SELECT',0 +.stringb db 'SAVE STATE SLOT',0 +.stringc db 'USE CURSOR KEYS',0 +.stringd db 'TO MOVE AND',0 +.stringe db 'ENTER TO SELECT',0 + +SECTION .bss +NEWSYM ForceNonTransp, resb 1 + +SECTION .text + +NEWSYM testpressed8b + test byte[pressed+2],1 + jz .no1 + mov bl,1 +.no1 + test byte[pressed+3],1 + jz .no2 + mov bl,2 +.no2 + test byte[pressed+4],1 + jz .no3 + mov bl,3 +.no3 + test byte[pressed+5],1 + jz .no4 + mov bl,4 +.no4 + test byte[pressed+6],1 + jz .no5 + mov bl,5 +.no5 + test byte[pressed+7],1 + jz .no6 + mov bl,6 +.no6 + test byte[pressed+8],1 + jz .no7 + mov bl,7 +.no7 + test byte[pressed+9],1 + jz .no8 + mov bl,8 +.no8 + test byte[pressed+10],1 + jz .no9 + mov bl,9 +.no9 + test byte[pressed+11],1 + jz .no0 + mov bl,0 +.no0 + test byte[pressed+75],1 + jz .noleft + cmp bl,0 + je .noleft + dec bl + mov byte[pressed+75],2 +.noleft + test byte[pressed+77],1 + jz .noright + cmp bl,9 + je .noright + inc bl + mov byte[pressed+77],2 +.noright +%ifndef __MSDOS__ +%ifdef __UNIXSDL__ + test byte[pressed+92],1 +%else + test byte[pressed+0CBh],1 +%endif + jz .noleft2 + cmp bl,0 + je .noleft2 + dec bl +%ifdef __UNIXSDL__ + mov byte[pressed+92],2 +%else + mov byte[pressed+0CBh],2 +%endif +.noleft2 +%ifdef __UNIXSDL__ + test byte[pressed+94],1 +%else + test byte[pressed+0CDh],1 +%endif + jz .noright2 + cmp bl,9 + je .noright2 + inc bl +%ifdef __UNIXSDL__ + mov byte[pressed+94],2 +%else + mov byte[pressed+0CDh],2 +%endif +.noright2 +;.nowin32 +%endif + ret + +;******************************************************* +; MakePal Changes the entire palette +;******************************************************* +; set the brightness with [maxbr] +SECTION .bss +NEWSYM cgramback, resw 256 +SECTION .text + +NEWSYM doveg + pushad + ; backup cgram + mov ecx,128 + xor ebx,ebx +.loop + mov eax,[cgram+ebx] + mov [cgramback+ebx],eax + add ebx,4 + dec ecx + jnz .loop + xor eax,eax + mov al,[coladdr] + add al,[coladdg] + add al,[coladdb] + xor dx,dx + mov bx,3 + div bx + and ax,011111b + mov [coladdr],al + mov [coladdg],al + mov [coladdb],al + xor eax,eax +.next + push eax + mov ax,[cgram+eax] + mov bx,ax + mov cx,ax + and bx,011111b + and cx,1111100000b + shr cx,5 + add bx,cx + mov cx,ax + and cx,111110000000000b + shr cx,10 + add bx,cx + mov ax,bx + xor dx,dx + mov bx,3 + div bx + and ax,011111b + mov cx,ax + mov bx,ax + shl bx,5 + or ax,bx + shl cx,10 + or ax,cx + mov bx,ax + pop eax + mov [cgram+eax],bx + add eax,2 + cmp eax,200h + jne .next + popad + ret + +NEWSYM dovegrest + pushad + ; backup cgram + mov ecx,128 + xor ebx,ebx +.loop + mov eax,[cgramback+ebx] + mov [cgram+ebx],eax + add ebx,4 + dec ecx + jnz .loop + popad + ret + +SECTION .bss +blahblahblah resw 1 +SECTION .text + +NEWSYM dosmakepal + cmp byte[V8Mode],1 + jne .noveg + call doveg +.noveg + mov ax,[cgram] + mov [tempco0],ax + test byte[scaddtype],00100000b + jz near .noaddition + test byte[scaddtype],10000000b + jnz near .noaddition + mov cx,[cgram] + mov ax,cx + and ax,001Fh + add al,[coladdr] + cmp al,01Fh + jb .noadd + mov al,01Fh +.noadd + mov bx,ax + mov ax,cx + shr ax,5 + and ax,001Fh + add al,[coladdg] + cmp al,01Fh + jb .noaddb + mov al,01Fh +.noaddb + shl ax,5 + add bx,ax + mov ax,cx + shr ax,10 + and ax,001Fh + add al,[coladdb] + cmp al,01Fh + jb .noaddc + mov al,01Fh +.noaddc + shl ax,10 + add bx,ax + mov [cgram],bx +.noaddition + cmp byte[Palette0],0 + je .nocol0mod + mov word[cgram],0 +.nocol0mod +NEWSYM makepalb + mov edi,cgram + mov ebx,prevpal + xor ah,ah +.loopa + mov cx,[edi] + push eax + push ebx + mov [ebx],cx + mov al,ah + mov dx,03C8h + out dx,al + mov ax,cx + and al,01Fh + mov bh,[maxbr] + mov bl,bh + mul bl + mov bl,15 + div bl + shl al,1 + mov dx,03C9h + add al,[gammalevel] + cmp al,63 + jbe .nor + mov al,63 +.nor + out dx,al + mov ax,cx + shr ax,5 + and al,01Fh + mov bl,bh + mul bl + mov bl,15 + div bl + shl al,1 + add al,[gammalevel] + cmp al,63 + jbe .nog + mov al,63 +.nog + out dx,al + mov ax,cx + shr ax,10 + and al,01Fh + mov bl,bh + mul bl + mov bl,15 + div bl + shl al,1 + add al,[gammalevel] + cmp al,63 + jbe .nob + mov al,63 +.nob + out dx,al + pop ebx + pop eax + add edi,2 + add ebx,2 + inc ah + jnz near .loopa + mov al,[maxbr] + mov [prevbright],al + mov ax,[tempco0] + mov [cgram],ax + cmp byte[MessageOn],0 + je .nochange128 + mov dx,03C8h + mov al,128 + out dx,al + mov al,63 + inc dx + out dx,al + out dx,al + out dx,al + mov dx,03C8h + mov al,128+64 + out dx,al + mov al,0 + inc dx + out dx,al + out dx,al + out dx,al +.nochange128 + cmp byte[V8Mode],1 + jne .noveg2 + call dovegrest +.noveg2 + ret + +SECTION .bss +NEWSYM tempco0, resw 1 +SECTION .text + +;******************************************************* +; ChangePal Sets up the palette +;******************************************************* + +NEWSYM doschangepal + cmp byte[V8Mode],1 + jne .noveg + call doveg +.noveg + mov ax,[cgram] + mov [tempco0],ax + test byte[scaddtype],00100000b + jz near .noaddition + test byte[scaddtype],10000000b + jnz near .noaddition + mov cx,[cgram] + mov ax,cx + and ax,001Fh + add al,[coladdr] + cmp al,01Fh + jb .noadd + mov al,01Fh +.noadd + mov bx,ax + mov ax,cx + shr ax,5 + and ax,001Fh + add al,[coladdg] + cmp al,01Fh + jb .noaddb + mov al,01Fh +.noaddb + shl ax,5 + add bx,ax + mov ax,cx + shr ax,10 + and ax,001Fh + add al,[coladdb] + cmp al,01Fh + jb .noaddc + mov al,01Fh +.noaddc + shl ax,10 + add bx,ax + mov [cgram],bx +.noaddition + cmp byte[Palette0],0 + je .nocol0mod + mov word[cgram],0 +.nocol0mod + ; check if brightness differs + mov al,[maxbr] + cmp al,[prevbright] + jne near makepalb + ; check for duplicate palette (Compare prevpal with cgram) + mov ebx,prevpal + mov edi,cgram + xor ah,ah +.loopa + mov cx,[edi] + cmp cx,[ebx] + je .nochange + push eax + push ebx + push eax + pop eax + mov [ebx],cx + mov al,ah + mov dx,03C8h + out dx,al + mov ax,cx + and al,01Fh + mov bh,[maxbr] + mov bl,bh + mul bl + mov bl,15 + div bl + shl al,1 + add al,[gammalevel] + cmp al,63 + jbe .nor + mov al,63 +.nor + inc dx + out dx,al + mov ax,cx + shr ax,5 + and al,01Fh + mov bl,bh + mul bl + mov bl,15 + div bl + shl al,1 + add al,[gammalevel] + cmp al,63 + jbe .nog + mov al,63 +.nog + out dx,al + mov ax,cx + shr ax,10 + and al,01Fh + mov bl,bh + mul bl + mov bl,15 + div bl + shl al,1 + add al,[gammalevel] + cmp al,63 + jbe .nob + mov al,63 +.nob + out dx,al + pop ebx + pop eax +.nochange + add edi,2 + add ebx,2 + inc ah + jnz near .loopa + mov ax,[tempco0] + mov [cgram],ax + cmp byte[MessageOn],0 + je .nochange128 + mov dx,03C8h + mov al,128 + out dx,al + mov al,63 + inc dx + out dx,al + out dx,al + out dx,al +.nochange128 + cmp byte[V8Mode],1 + jne .noveg2 + call dovegrest +.noveg2 + ret + +SECTION .bss +NEWSYM prevbright, resb 1 ; previous brightness +SECTION .text + +;******************************************************* +; CopyVid Copies buffer into video +;******************************************************* + +NEWSYM showfps + mov cl,50 + cmp byte[romispal],0 + jne .nontsc + mov cl,60 +.nontsc + inc byte[curfps] + cmp byte[nextframe],cl + jb .nofrc + mov al,[curfps] + mov [lastfps],al + mov al,[curfps2] + mov [lastfps2],al + mov byte[curfps],0 + mov byte[curfps2],0 + sub byte[nextframe],cl +.nofrc + + cmp byte[cbitmode],1 + je near .do16b + + call displayfpspal + + mov al,[lastfps] + mov bl,10 + xor ah,ah + div bl + shl al,4 + add ah,al + mov al,ah + mov esi,208*288+32 + add esi,[vidbuffer] + push ecx + call outputhex + + mov esi,208*288+48 + add esi,[vidbuffer] + mov al,29h + call outputchar + pop ecx + + mov al,cl + mov bl,10 + xor ah,ah + div bl + shl al,4 + add ah,al + mov al,ah + mov esi,208*288+56 + add esi,[vidbuffer] + call outputhex + ret + +.do16b + mov al,[lastfps] + mov bl,10 + xor ah,ah + div bl + shl al,4 + add ah,al + mov al,ah + mov esi,208*288*2+32*2 + add esi,[vidbuffer] + push ecx + call outputhex16 + + mov esi,208*288*2+48*2 + add esi,[vidbuffer] + mov al,29h + call outputchar16b + pop ecx + + mov al,cl + mov bl,10 + xor ah,ah + div bl + shl al,4 + add ah,al + mov al,ah + mov esi,208*288*2+56*2 + add esi,[vidbuffer] + call outputhex16 + ret + +.ng16b + mov byte[ngfont],1 + + mov al,[lastfps] + mov bl,10 + xor ah,ah + div bl + shl al,4 + add ah,al + mov al,ah + mov esi,208*288+32 + add esi,[vidbuffer] + push ecx + call outputhex + + mov esi,208*288+48 + add esi,[vidbuffer] + mov al,29h + call outputchar + pop ecx + + mov al,cl + mov bl,10 + xor ah,ah + div bl + shl al,4 + add ah,al + mov al,ah + mov esi,208*288+56 + add esi,[vidbuffer] + call outputhex + ret + +SECTION .bss +NEWSYM spcdebugaddr, resd 1 +NEWSYM tempoffset, resw 1 + +NEWSYM Testval, resd 1 +SECTION .text + + +NEWSYM ClockOutput + cmp byte[cbitmode],1 + je near .do16b3 +.no16b3 + mov byte[ngfont],1 + call displayfpspal + mov esi,215*288+32+192 + add esi,[vidbuffer] + mov ebx,7 +.loop2 + mov ecx,12 + mov byte[esi-1],0C0h +.loop + mov dword[esi],0C0C0C0C0h + add esi,4 + dec ecx + jnz .loop + add esi,288-48 + dec ebx + jnz .loop2 + jmp .do8b +.do16b3 + mov esi,215*288*2+32*2+192*2 + add esi,[vidbuffer] + mov ebx,7 +.loop2b + mov ecx,24 + mov word[esi-2],0 + mov word[esi-2+75036*4],0 +.loopb + mov dword[esi],0 + mov dword[esi+75036*4],0 + add esi,4 + dec ecx + jnz .loopb + add esi,288*2-48*2 + dec ebx + jnz .loop2b +.do8b + call GetTimeInSeconds + xor edx,edx + mov ebx,60 + div ebx + push eax + ; edx = seconds + mov eax,edx + xor edx,edx + mov ebx,10 + div ebx + mov esi,216*288+32+228 + call .output + pop eax + mov ebx,60 + xor edx,edx + div ebx + push eax + ; edx = minutes + mov eax,edx + xor edx,edx + mov ebx,10 + div ebx + mov esi,216*288+32+210 + call .output + pop eax + ; eax = hours + xor edx,edx + mov ebx,10 + div ebx + mov esi,216*288+32+192 + call .output + cmp byte[cbitmode],1 + je .do16b2 +.no16b4 + mov esi,216*288+32+222 + add esi,[vidbuffer] + xor eax,eax + add al,':' + mov al,[ASCII2Font+eax] + pushad + call outputchar5x5 + popad + mov esi,216*288+32+204 + add esi,[vidbuffer] + xor eax,eax + add al,':' + mov al,[ASCII2Font+eax] + pushad + call outputchar5x5 + popad + ret + +.do16b2 + mov esi,216*288*2+32*2+222*2 + add esi,[vidbuffer] + xor eax,eax + add al,':' + mov al,[ASCII2Font+eax] + pushad + call outputchar16b5x5 + popad + mov esi,216*288*2+32*2+204*2 + add esi,[vidbuffer] + xor eax,eax + add al,':' + mov al,[ASCII2Font+eax] + pushad + call outputchar16b5x5 + popad + ret +.output + ; output char value at al and dl + cmp byte[cbitmode],1 + je .do16b +.no16b5 + add esi,[vidbuffer] + and eax,0FFh + add al,48 + mov al,[ASCII2Font+eax] + pushad + call outputchar5x5 + popad + xor eax,eax + mov al,dl + add al,48 + mov al,[ASCII2Font+eax] + add esi,6 + pushad + call outputchar5x5 + popad + ret +.do16b + add esi,esi + add esi,[vidbuffer] + and eax,0FFh + add al,48 + mov al,[ASCII2Font+eax] + pushad + call outputchar16b5x5 + popad + xor eax,eax + mov al,dl + add al,48 + mov al,[ASCII2Font+eax] + add esi,12 + pushad + call outputchar16b5x5 + popad + ret + +NEWSYM ClockOutputB + cmp byte[cbitmode],1 + je near .do16b3 +.no16b3 + mov byte[ngfont],1 + call displayfpspal + mov esi,208*288+32+192 + add esi,[vidbuffer] + mov ebx,7 +.loop2 + mov ecx,12 + mov byte[esi-1],0C0h +.loop + mov dword[esi],0C0C0C0C0h + add esi,4 + dec ecx + jnz .loop + add esi,288-48 + dec ebx + jnz .loop2 + jmp .do8b +.do16b3 + mov esi,208*288*2+32*2+192*2 + add esi,[vidbuffer] + mov ebx,7 +.loop2b + mov ecx,24 + mov word[esi-2],0 + mov word[esi-2+75036*4],0 +.loopb + mov dword[esi],0 + mov dword[esi+75036*4],0 + add esi,4 + dec ecx + jnz .loopb + add esi,288*2-48*2 + dec ebx + jnz .loop2b +.do8b + call GetTimeInSeconds + xor edx,edx + mov ebx,60 + div ebx + push eax + ; edx = seconds + mov eax,edx + xor edx,edx + mov ebx,10 + div ebx + mov esi,209*288+32+228 + call .output + pop eax + mov ebx,60 + xor edx,edx + div ebx + push eax + ; edx = minutes + mov eax,edx + xor edx,edx + mov ebx,10 + div ebx + mov esi,209*288+32+210 + call .output + pop eax + ; eax = hours + xor edx,edx + mov ebx,10 + div ebx + mov esi,209*288+32+192 + call .output + cmp byte[cbitmode],1 + je .do16b2 +.no16b4 + mov esi,209*288+32+222 + add esi,[vidbuffer] + xor eax,eax + add al,':' + mov al,[ASCII2Font+eax] + pushad + call outputchar5x5 + popad + mov esi,209*288+32+204 + add esi,[vidbuffer] + xor eax,eax + add al,':' + mov al,[ASCII2Font+eax] + pushad + call outputchar5x5 + popad + ret +.do16b2 + mov esi,209*288*2+32*2+222*2 + add esi,[vidbuffer] + xor eax,eax + add al,':' + mov al,[ASCII2Font+eax] + pushad + call outputchar16b5x5 + popad + mov esi,209*288*2+32*2+204*2 + add esi,[vidbuffer] + xor eax,eax + add al,':' + mov al,[ASCII2Font+eax] + pushad + call outputchar16b5x5 + popad + ret +.output + ; output char value at al and dl + cmp byte[cbitmode],1 + je .do16b +.no16b5 + add esi,[vidbuffer] + and eax,0FFh + add al,48 + mov al,[ASCII2Font+eax] + pushad + call outputchar5x5 + popad + xor eax,eax + mov al,dl + add al,48 + mov al,[ASCII2Font+eax] + add esi,6 + pushad + call outputchar5x5 + popad + ret +.do16b + add esi,esi + add esi,[vidbuffer] + and eax,0FFh + add al,48 + mov al,[ASCII2Font+eax] + pushad + call outputchar16b5x5 + popad + xor eax,eax + mov al,dl + add al,48 + mov al,[ASCII2Font+eax] + add esi,12 + pushad + call outputchar16b5x5 + popad + ret + +SECTION .data +hextestfilen db 'DSP1DUMP.DAT',0 + +SECTION .bss +NEWSYM SoundTest, resb 1 + + +blahrnr resw 1 + +SECTION .text + +NEWSYM hextestoutput + + mov dx,[bg3scroly] +; and dx,0F8h + shr edx,3 + shl edx,6 + xor eax,eax + mov ax,[bg3ptr] + add ax,dx + xor edx,edx + mov dx,[bg3scrolx] + and dx,0F8h + shr edx,3 + shl edx,1 + add ax,dx + mov dx,[bg3scrolx] + test dx,8000h + jz .nooma + and dx,0F000h + shr dx,5 + add ax,dx +.nooma + add eax,40h + mov edx,eax + mov [Testval],edx + cmp byte[pressed+25],1 + jne .nopress25 + jmp .nopress25 + pushad + mov edx,hextestfilen + call Create_File + jc .failed + mov bx,ax + mov edx,dsp1array + mov ecx,4096 + call Write_File + call Close_File +.failed + popad + mov byte[pressed+25],2 +.nopress25 + call displayfpspal + + mov esi,[vram] + mov ax,0 + mov ecx,400h +.loop +; mov word[esi],ax + add esi,2 + dec ecx + jnz .loop + inc word[blahrnr] + mov esi,216*288+32 + add esi,[vidbuffer] + xor eax,eax + ; 4F00h + mov ebx,[C4Ram] + mov ebx,[vram] + mov al,[DecompAPtr+1h] + call outputhex + mov esi,216*288+32+16 + add esi,[vidbuffer] + xor eax,eax + mov ebx,[C4Ram] + mov ebx,[vram] + mov al,[DecompAPtr] + call outputhex + mov esi,216*288+70 + add esi,[vidbuffer] + xor eax,eax + mov ebx,[C4Ram] + mov al,[bg1objptr+1] + call outputhex + mov esi,216*288+70+16 + add esi,[vidbuffer] + xor eax,eax + mov ebx,[C4Ram] + mov al,[bg1objptr] + call outputhex + mov esi,216*288+108 + add esi,[vidbuffer] + xor eax,eax + mov ebx,[C4Ram] + mov al,[ebx+4] + call outputhex + mov esi,216*288+108+16 + add esi,[vidbuffer] + xor eax,eax + mov ebx,[C4Ram] + mov al,[ebx+9] + call outputhex + mov esi,216*288+146 + add esi,[vidbuffer] + xor eax,eax + mov ebx,[C4Ram] + mov al,[ebx+10] + call outputhex + xor eax,eax + mov esi,216*288+146+16 + add esi,[vidbuffer] + or al,[bg1scroly] + mov ebx,[C4Ram] + mov al,[ebx+11] + call outputhex + ret + +SECTION .bss +NEWSYM SoundPlayed0, resb 1 +NEWSYM SoundPlayed1, resb 1 +NEWSYM SoundPlayed2, resb 1 +NEWSYM SoundPlayed3, resb 1 +NEWSYM SoundPlayed4, resb 1 +NEWSYM SoundPlayed5, resb 1 +NEWSYM SoundPlayed6, resb 1 +NEWSYM SoundPlayed7, resb 1 +NEWSYM ngfont, resb 1 +SECTION .text + +NEWSYM ShowSound + add esi,[vidbuffer] +.next + mov [esi],ebx + mov [esi+4],ebx + mov [esi+8],bx + sub esi,288 + dec al + jnz .next + ret + +NEWSYM sounddisplay + call displayfpspal + + push esi + push ebx + push eax + mov ebx,80808080h + cmp byte[SoundPlayed0],0 + je .nosnd0 + mov al,[SoundPlayed0] + mov esi,223*288+16 + call ShowSound + sub byte[SoundPlayed0],2 +.nosnd0 + cmp byte[SoundPlayed1],0 + je .nosnd1 + mov al,[SoundPlayed1] + mov esi,223*288+28 + call ShowSound + sub byte[SoundPlayed1],2 +.nosnd1 + cmp byte[SoundPlayed2],0 + je .nosnd2 + mov al,[SoundPlayed2] + mov esi,223*288+40 + call ShowSound + sub byte[SoundPlayed2],2 +.nosnd2 + cmp byte[SoundPlayed3],0 + je .nosnd3 + mov al,[SoundPlayed3] + mov esi,223*288+52 + call ShowSound + sub byte[SoundPlayed3],2 +.nosnd3 + cmp byte[SoundPlayed4],0 + je .nosnd4 + mov al,[SoundPlayed4] + mov esi,223*288+64 + call ShowSound + sub byte[SoundPlayed4],2 +.nosnd4 + cmp byte[SoundPlayed5],0 + je .nosnd5 + mov al,[SoundPlayed5] + mov esi,223*288+76 + call ShowSound + sub byte[SoundPlayed5],2 +.nosnd5 + cmp byte[SoundPlayed6],0 + je .nosnd6 + mov al,[SoundPlayed6] + mov esi,223*288+88 + call ShowSound + sub byte[SoundPlayed6],2 +.nosnd6 + cmp byte[SoundPlayed7],0 + je .nosnd7 + mov al,[SoundPlayed7] + mov esi,223*288+100 + call ShowSound + sub byte[SoundPlayed7],2 +.nosnd7 + pop eax + pop esi + pop ebx + ret + +NEWSYM waitvsync + mov dx,3DAh ;VGA status port +;.loop +; in al,dx +; test al,8 ;check VR bit +; jnz .loop ;in middle of VR, better wait for next one +.loop2 + in al,dx + test al,8 + jz .loop2 ;updating the screen + ret + +SECTION .data +NEWSYM prevengval, db 10 + + +SECTION .text + +NEWSYM copyvid + mov byte[ngfont],0 + mov dword[.sdrawptr],0 + ; Test if add table needs updating + cmp byte[cbitmode],0 + je .notatud + cmp byte[vesa2red10],0 + je .notatud + mov al,[newengen] + cmp [prevengval],al + je .notatud + mov [prevengval],al + call genfulladdtab + jmp .notatud +.redadd + call genfulladdtabng +.notatud + cmp dword[MessageOn],0 + je near .nomsg + cmp byte[cbitmode],1 + je near .do16b +.no16b + mov byte[ngfont],1 + mov edi,[Msgptr] + mov esi,200*288+32 + add esi,[vidbuffer] + cmp edi,CSStatus + je .fivex5b + cmp byte[SmallMsgText],1 + je .smallmsgtext + call OutputGraphicString.no16bit + jmp .nfivex5b +.fivex5b + call OutputGraphicString5x5 + mov edi,CSStatus2 + mov esi,208*288+32 + add esi,[vidbuffer] + call OutputGraphicString5x5 + mov edi,CSStatus3 + mov esi,216*288+32 + add esi,[vidbuffer] + call OutputGraphicString5x5 + jmp .nfivex5b +.smallmsgtext + call OutputGraphicString5x5 +.nfivex5b + dec dword[MessageOn] + jnz .nomsg + cmp byte[cbitmode],1 + je .nomsg + call makepal + jmp .nomsg +.do16b + mov edi,[Msgptr] + mov esi,200*288*2+32*2 + add esi,[vidbuffer] + cmp edi,CSStatus + je .fivex5 + cmp byte[SmallMsgText],1 + je .smallmsgtext2 + call OutputGraphicString16b + jmp .nfivex5 +.fivex5 + call OutputGraphicString16b5x5 + mov edi,CSStatus2 + mov esi,208*288*2+32*2 + add esi,[vidbuffer] + call OutputGraphicString16b5x5 + mov edi,CSStatus3 + mov esi,216*288*2+32*2 + add esi,[vidbuffer] + call OutputGraphicString16b5x5 + jmp .nfivex5 +.smallmsgtext2 + call OutputGraphicString16b5x5 +.nfivex5 + dec dword[MessageOn] +.nomsg + cmp byte[MovieProcessing],0 + jz .nomovie4 + cmp byte[MovieDisplayFrame],0 + jz .nomovie4 + pushad + call GetMovieFrameStr + popad + mov edi,MovieFrameStr + cmp byte[cbitmode],1 + jne .not16bframe + mov esi,216*288*2+32*2 + add esi,[vidbuffer] + call OutputGraphicString16b5x5 + jmp .nomovie4 +.not16bframe + mov esi,216*288+32 + add esi,[vidbuffer] + call OutputGraphicString5x5 +.nomovie4 + jmp vidpaste +SECTION .bss +.sdrawptr resd 1 +SECTION .text + +NEWSYM vidpaste +%ifdef __MSDOS__ + cmp byte[vsyncon],0 + je .novsync + cmp byte[Triplebufen],0 + jne .novsync + cmp byte[curblank],0h + jne .novsync + call waitvsync +.novsync +%endif + cmp byte[cbitmode],1 + je .nopal + cmp byte[curblank],0 + jne .nopal + call changepal +.nopal + cmp byte[FPSOn],0 + je .nofps + cmp byte[curblank],0 + jne .nofps + call showfps +.nofps +; call ClockOutputB + + cmp byte[TimerEnable],0 + je .noclock + cmp byte[ShowTimer],0 + je .noclock + call ClockOutput +.noclock + cmp byte[snesmouse],3 + je near .drawss +; cmp byte[snesmouse],4 +; je near .drawss +.returnfromdraw + mov ax,[resolutn] + cmp [prevresolutn],ax + je .noclear + mov [prevresolutn],ax + call ClearScreen +.noclear + jmp DrawScreen + +.drawss + cmp byte[cbitmode],1 + je .noss8b + call superscopepal +.noss8b + xor eax,eax + mov al,[mouseyloc] + mov ebx,288 + mul ebx + mov esi,[vidbuffer] + mov edi,SScopeCursor + xor ebx,ebx + mov bl,[mousexloc] + add ebx,6 + cmp byte[cbitmode],1 + je near .ss16b + mov cl,20 +.ssloop + mov ch,20 +.ssloop2 + cmp byte[edi],0 + je .nodraw + mov edx,eax + add edx,ebx + sub edx,288*10 + jb .nodraw + mov byte[esi+edx],128+16 +.nodraw + inc ebx + inc edi + dec ch + jnz .ssloop2 + sub ebx,20 + add eax,288 + dec cl + jnz .ssloop + jmp .returnfromdraw + +.ss16b + push ebx + mov cl,[vesa2_rpos] + mov bx,31 + shl bx,cl + mov [.SSRedCo],bx + pop ebx + shl eax,1 + shl ebx,1 + mov cl,20 +.ssloopb + mov ch,20 +.ssloopb2 + cmp byte[edi],0 + je .nodrawb + mov edx,eax + add edx,ebx + sub edx,288*10*2 + jb .nodrawb + push eax + mov ax,[.SSRedCo] + mov [esi+edx],ax + pop eax +.nodrawb + add ebx,2 + inc edi + dec ch + jnz .ssloopb2 + sub ebx,40 + add eax,288*2 + dec cl + jnz .ssloopb + jmp .returnfromdraw + +SECTION .bss +.SSRedCo resw 1 + +SECTION .data +NEWSYM MsgCount, dd 120 ; How long message will stay (PAL = 100) + +SECTION .bss +NEWSYM lastfps, resb 1 ; stores the last fps encountered +NEWSYM lastfps2, resb 1 ; stores the last fps encountered +NEWSYM curfps2, resb 1 ; current video refresh fps +NEWSYM Msgptr, resd 1 ; Pointer to message +NEWSYM MessageOn, resd 1 ; Message On Countdown +NEWSYM FPSOn, resb 1 + +SECTION .data +prevresolutn dd 224 + +NEWSYM SScopeCursor +db 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0 +db 0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0 +db 0,0,0,0,0,1,1,0,0,1,0,0,1,1,0,0,0,0,0,0 +db 0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0 +db 0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0 +db 0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0 +db 0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0 +db 0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0 +db 0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0 +db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 +db 0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0 +db 0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0 +db 0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0 +db 0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0 +db 0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0 +db 0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0 +db 0,0,0,0,0,1,1,0,0,1,0,0,1,1,0,0,0,0,0,0 +db 0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0 +db 0,0,0,0,0,0,0,0,0,1,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,0,0,0,0 diff --git a/zsnes/src/windows_wminput.c b/zsnes/src/windows_wminput.c new file mode 100644 index 00000000..f43cb521 --- /dev/null +++ b/zsnes/src/windows_wminput.c @@ -0,0 +1,734 @@ +/* + * Support for Windows via the WM_INPUT message. + * + * Please see the file LICENSE in the source's root directory. + * + * This file written by Ryan C. Gordon. + */ + +#if (defined(_WIN32) || defined(__CYGWIN__)) + +/* WinUser.h won't include rawinput stuff without this... */ +#if (_WIN32_WINNT < 0x0501) +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x0501 +#endif + +#include +#include /* needed for alloca(). */ + +/* Cygwin's headers don't have WM_INPUT right now... */ +#ifndef WM_INPUT +#define WM_INPUT 0x00FF +#endif + +#include "manymouse.h" + +/* that should be enough, knock on wood. */ +#define MAX_MICE 32 + +/* + * Just trying to avoid malloc() here...we statically allocate a buffer + * for events and treat it as a ring buffer. + */ +/* !!! FIXME: tweak this? */ +#define MAX_EVENTS 1024 +static ManyMouseEvent input_events[MAX_EVENTS]; +static volatile int input_events_read = 0; +static volatile int input_events_write = 0; +static int available_mice = 0; +static int did_api_lookup = 0; +static HWND raw_hwnd = NULL; +static const char *class_name = "ManyMouseRawInputCatcher"; +static const char *win_name = "ManyMouseRawInputMsgWindow"; +static ATOM class_atom = 0; +static CRITICAL_SECTION mutex; + +typedef struct +{ + HANDLE handle; + char name[256]; +} MouseStruct; +static MouseStruct mice[MAX_MICE]; + + +/* + * The RawInput APIs only exist in Windows XP and later, so you want this + * to fail gracefully on earlier systems instead of refusing to start the + * process due to missing symbols. To this end, we do a symbol lookup on + * User32.dll, etc to get the entry points. + * + * A lot of these are available all the way back to the start of win32 in + * Windows 95 and WinNT 3.1, but just so you don't have to track down any + * import libraries, I've added those here, too. That fits well with the + * idea of just adding the sources to your build and going forward. + */ +static UINT (WINAPI *pGetRawInputDeviceList)( + PRAWINPUTDEVICELIST pRawInputDeviceList, + PUINT puiNumDevices, + UINT cbSize +); +/* !!! FIXME: use unicode version */ +static UINT (WINAPI *pGetRawInputDeviceInfoA)( + HANDLE hDevice, + UINT uiCommand, + LPVOID pData, + PUINT pcbSize +); +static BOOL (WINAPI *pRegisterRawInputDevices)( + PCRAWINPUTDEVICE pRawInputDevices, + UINT uiNumDevices, + UINT cbSize +); +static LRESULT (WINAPI *pDefRawInputProc)( + PRAWINPUT *paRawInput, + INT nInput, + UINT cbSizeHeader +); +static UINT (WINAPI *pGetRawInputBuffer)( + PRAWINPUT pData, + PUINT pcbSize, + UINT cbSizeHeader +); +static UINT (WINAPI *pGetRawInputData)( + HRAWINPUT hRawInput, + UINT uiCommand, + LPVOID pData, + PUINT pcbSize, + UINT cbSizeHeader +); +static LONG (WINAPI *pRegQueryValueExA)( + HKEY hKey, + LPCTSTR lpValueName, + LPDWORD lpReserved, + LPDWORD lpType, + LPBYTE lpData, + LPDWORD lpcbData +); +static LONG (WINAPI *pRegOpenKeyExA)( + HKEY hKey, + LPCTSTR lpSubKey, + DWORD ulOptions, + REGSAM samDesired, + PHKEY phkResult +); +static LONG (WINAPI *pRegCloseKey)( + HKEY hKey +); +static HWND (WINAPI *pCreateWindowExA)( + DWORD dwExStyle, + LPCTSTR lpClassName, + LPCTSTR lpWindowName, + DWORD dwStyle, + int x, + int y, + int nWidth, + int nHeight, + HWND hWndParent, + HMENU hMenu, + HINSTANCE hInstance, + LPVOID lpParam +); +static ATOM (WINAPI *pRegisterClassExA)( + CONST WNDCLASSEX *lpwcx +); +static LRESULT (WINAPI *pDefWindowProcA)( + HWND hWnd, + UINT Msg, + WPARAM wParam, + LPARAM lParam +); +static BOOL (WINAPI *pUnregisterClassA)( + LPCTSTR lpClassName, + HINSTANCE hInstance +); +static HMODULE (WINAPI *pGetModuleHandleA)( + LPCTSTR lpModuleName +); +static BOOL (WINAPI *pPeekMessageA)( + LPMSG lpMsg, + HWND hWnd, + UINT wMsgFilterMin, + UINT wMsgFilterMax, + UINT wRemoveMsg +); +static BOOL (WINAPI *pTranslateMessage)( + const MSG *lpMsg +); +static LRESULT (WINAPI *pDispatchMessageA)( + const MSG *lpmsg +); +static BOOL (WINAPI *pDestroyWindow)( + HWND hWnd +); +static void (WINAPI *pInitializeCriticalSection)( + LPCRITICAL_SECTION lpCriticalSection +); +static void (WINAPI *pEnterCriticalSection)( + LPCRITICAL_SECTION lpCriticalSection +); +static void (WINAPI *pLeaveCriticalSection)( + LPCRITICAL_SECTION lpCriticalSection +); +static void (WINAPI *pDeleteCriticalSection)( + LPCRITICAL_SECTION lpCriticalSection +); + +static int symlookup(HMODULE dll, void **addr, const char *sym) +{ + *addr = GetProcAddress(dll, sym); + if (*addr == NULL) + { + FreeLibrary(dll); + return(0); + } /* if */ + + return(1); +} /* symlookup */ + +static int find_api_symbols(void) +{ + HMODULE dll; + + if (did_api_lookup) + return(1); + + #define LOOKUP(x) { if (!symlookup(dll, (void **) &p##x, #x)) return(0); } + dll = LoadLibrary("user32.dll"); + if (dll == NULL) + return(0); + + LOOKUP(GetRawInputDeviceInfoA); + LOOKUP(RegisterRawInputDevices); + LOOKUP(GetRawInputDeviceList); + LOOKUP(DefRawInputProc); + LOOKUP(GetRawInputBuffer); + LOOKUP(GetRawInputData); + LOOKUP(CreateWindowExA); + LOOKUP(RegisterClassExA); + LOOKUP(UnregisterClassA); + LOOKUP(DefWindowProcA); + LOOKUP(PeekMessageA); + LOOKUP(TranslateMessage); + LOOKUP(DispatchMessageA); + LOOKUP(DestroyWindow); + + dll = LoadLibrary("advapi32.dll"); + if (dll == NULL) + return(0); + + LOOKUP(RegOpenKeyExA); + LOOKUP(RegQueryValueExA); + LOOKUP(RegCloseKey); + + dll = LoadLibrary("kernel32.dll"); + if (dll == NULL) + return(0); + + LOOKUP(GetModuleHandleA); + LOOKUP(InitializeCriticalSection); + LOOKUP(EnterCriticalSection); + LOOKUP(LeaveCriticalSection); + LOOKUP(DeleteCriticalSection); + + #undef LOOKUP + + did_api_lookup = 1; + return(1); +} /* find_api_symbols */ + + +static void queue_event(const ManyMouseEvent *event) +{ + /* copy the event info. We'll process it in ManyMouse_PollEvent(). */ + CopyMemory(&input_events[input_events_write], event, sizeof (ManyMouseEvent)); + + input_events_write = ((input_events_write + 1) % MAX_EVENTS); + + /* Ring buffer full? Lose oldest event. */ + if (input_events_write == input_events_read) + { + /* !!! FIXME: we need to not lose mouse buttons here. */ + input_events_read = ((input_events_read + 1) % MAX_EVENTS); + } /* if */ +} /* queue_event */ + + +static void queue_from_rawinput(const RAWINPUT *raw) +{ + int i; + const RAWINPUTHEADER *header = &raw->header; + const RAWMOUSE *mouse = &raw->data.mouse; + ManyMouseEvent event; + + if (raw->header.dwType != RIM_TYPEMOUSE) + return; + + for (i = 0; i < available_mice; i++) /* find the device for event. */ + { + if (mice[i].handle == header->hDevice) + break; + } /* for */ + + if (i == available_mice) + return; /* not found?! */ + + /* + * RAWINPUT packs a bunch of events into one, so we split it up into + * a bunch of ManyMouseEvents here and store them in an internal queue. + * Then ManyMouse_PollEvent() just shuffles items off that queue + * without any complicated processing. + */ + + event.device = i; + + pEnterCriticalSection(&mutex); + + if (mouse->usFlags & MOUSE_MOVE_ABSOLUTE) + { + /* !!! FIXME: How do we get the min and max values for absmotion? */ + event.type = MANYMOUSE_EVENT_ABSMOTION; + event.item = 0; + event.value = mouse->lLastX; + queue_event(&event); + event.item = 1; + event.value = mouse->lLastY; + queue_event(&event); + } /* if */ + + else /*if (mouse->usFlags & MOUSE_MOVE_RELATIVE)*/ + { + event.type = MANYMOUSE_EVENT_RELMOTION; + if (mouse->lLastX != 0) + { + event.item = 0; + event.value = mouse->lLastX; + queue_event(&event); + } /* if */ + + if (mouse->lLastY != 0) + { + event.item = 1; + event.value = mouse->lLastY; + queue_event(&event); + } /* if */ + } /* else if */ + + event.type = MANYMOUSE_EVENT_BUTTON; + + #define QUEUE_BUTTON(x) { \ + if (mouse->usButtonFlags & RI_MOUSE_BUTTON_##x##_DOWN) { \ + event.item = x-1; \ + event.value = 1; \ + queue_event(&event); \ + } \ + if (mouse->usButtonFlags & RI_MOUSE_BUTTON_##x##_UP) { \ + event.item = x-1; \ + event.value = 0; \ + queue_event(&event); \ + } \ + } + + QUEUE_BUTTON(1); + QUEUE_BUTTON(2); + QUEUE_BUTTON(3); + QUEUE_BUTTON(4); + QUEUE_BUTTON(5); + + #undef QUEUE_BUTTON + + if (mouse->usButtonFlags & RI_MOUSE_WHEEL) + { + if (mouse->usButtonData != 0) /* !!! FIXME: can this ever be zero? */ + { + event.type = MANYMOUSE_EVENT_SCROLL; + event.item = 0; /* !!! FIXME: horizontal wheel? */ + event.value = (mouse->usButtonData > 0) ? 1 : -1; + queue_event(&event); + } /* if */ + } /* if */ + + pLeaveCriticalSection(&mutex); +} /* queue_from_rawinput */ + + +static void wminput_handler(WPARAM wParam, LPARAM lParam) +{ + UINT dwSize = 0; + LPBYTE lpb; + + pGetRawInputData((HRAWINPUT) lParam, RID_INPUT, NULL, &dwSize, + sizeof (RAWINPUTHEADER)); + + if (dwSize < sizeof (RAWINPUT)) + return; /* unexpected packet? */ + + lpb = (LPBYTE) alloca(dwSize); + if (lpb == NULL) + return; + if (pGetRawInputData((HRAWINPUT) lParam, RID_INPUT, lpb, &dwSize, + sizeof (RAWINPUTHEADER)) != dwSize) + return; + + queue_from_rawinput((RAWINPUT *) lpb); +} /* wminput_handler */ + + +static LRESULT CALLBACK RawWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + if (Msg == WM_INPUT) + wminput_handler(wParam, lParam); + + else if (Msg == WM_DESTROY) + return(0); + + return pDefWindowProcA(hWnd, Msg, wParam, lParam); +} /* RawWndProc */ + + +static int init_event_queue(void) +{ + HINSTANCE hInstance = pGetModuleHandleA(NULL); + WNDCLASSEX wce; + RAWINPUTDEVICE rid; + + ZeroMemory(input_events, sizeof (input_events)); + input_events_read = input_events_write = 0; + + ZeroMemory(&wce, sizeof (wce)); + wce.cbSize = sizeof(WNDCLASSEX); + wce.lpfnWndProc = RawWndProc; + wce.lpszClassName = class_name; + wce.hInstance = hInstance; + class_atom = pRegisterClassExA(&wce); + if (class_atom == 0) + return(0); + + raw_hwnd = pCreateWindowExA(0, class_name, win_name, WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, HWND_MESSAGE, NULL, hInstance, NULL); + + if (raw_hwnd == NULL) + return(0); + + pInitializeCriticalSection(&mutex); + + ZeroMemory(&rid, sizeof (rid)); + rid.usUsagePage = 1; /* GenericDesktop page */ + rid.usUsage = 2; /* GeneralDestop Mouse usage. */ + rid.dwFlags = RIDEV_INPUTSINK; + rid.hwndTarget = raw_hwnd; + if (!pRegisterRawInputDevices(&rid, 1, sizeof (rid))) + { + pDeleteCriticalSection(&mutex); + return(0); + } /* if */ + + return(1); +} /* init_event_queue */ + + +static void cleanup_window(void) +{ + if (raw_hwnd) + { + MSG Msg; + pDestroyWindow(raw_hwnd); + while (pPeekMessageA(&Msg, raw_hwnd, 0, 0, PM_REMOVE)) + { + pTranslateMessage(&Msg); + pDispatchMessageA(&Msg); + } /* while */ + raw_hwnd = 0; + } /* if */ + + if (class_atom) + { + pUnregisterClassA(class_name, pGetModuleHandleA(NULL)); + class_atom = 0; + } /* if */ +} /* cleanup_window */ + + +static int accept_device(const RAWINPUTDEVICELIST *dev) +{ + const char rdp_ident[] = "\\??\\Root#RDP_MOU#0000#"; + char *buf = NULL; + UINT ct = 0; + + if (dev->dwType != RIM_TYPEMOUSE) + return(0); /* keyboard or some other fruity thing. */ + + if (pGetRawInputDeviceInfoA(dev->hDevice, RIDI_DEVICENAME, NULL, &ct) < 0) + return(0); + + /* ct == is chars, not bytes, but we used the ASCII version. */ + buf = (char *) alloca(ct); + if (buf == NULL) + return(0); + + if (pGetRawInputDeviceInfoA(dev->hDevice, RIDI_DEVICENAME, buf, &ct) < 0) + return(0); + + /* + * Apparently there's a fake "RDP" device...I guess this is + * "Remote Desktop Protocol" for controlling the system pointer + * remotely via Windows Remote Desktop, but that's just a guess. + * At any rate, we don't want that device, so skip it if detected. + * + * Idea for this found here: + * http://link.mywwwserver.com/~jstookey/arcade/rawmouse/raw_mouse.c + */ + + /* avoiding memcmp here so we don't get a C runtime dependency... */ + if (ct >= sizeof (rdp_ident) - 1) + { + int i; + for (i = 0; i < sizeof (rdp_ident) - 1; i++) + { + if (buf[i] != rdp_ident[i]) + break; + } /* for */ + + if (i == sizeof (rdp_ident) - 1) + return(0); /* this is an RDP thing. Skip this device. */ + } /* if */ + + return(1); /* we want this device. */ +} /* accept_device */ + + +/* !!! FIXME: this code sucks. */ +static void get_device_product_name(char *name, size_t namesize, + const RAWINPUTDEVICELIST *dev) +{ + const char regkeyroot[] = "System\\CurrentControlSet\\Enum\\"; + const char default_device_name[] = "Unidentified input device"; + DWORD outsize = namesize; + DWORD regtype = REG_SZ; + char *buf = NULL; + char *ptr = NULL; + char *keyname = NULL; + UINT i = 0; + UINT ct = 0; + LONG rc = 0; + HKEY hkey; + + *name = '\0'; /* really insane default. */ + if (sizeof (default_device_name) >= namesize) + return; + + /* in case we can't stumble upon something better... */ + CopyMemory(name, default_device_name, sizeof (default_device_name)); + + if (pGetRawInputDeviceInfoA(dev->hDevice, RIDI_DEVICENAME, NULL, &ct) < 0) + return; + + /* ct == is chars, not bytes, but we used the ASCII version. */ + buf = (char *) alloca(ct+1); + keyname = (char *) alloca(ct + sizeof (regkeyroot)); + if ((buf == NULL) || (keyname == NULL)) + return; + + if (pGetRawInputDeviceInfoA(dev->hDevice, RIDI_DEVICENAME, buf, &ct) < 0) + return; + + /* + * This string tap dancing gets us a registry keyname in this form: + * SYSTEM\CurrentControlSet\Enum\BUSTYPE\DEVICECLASS\DEVICEID + * (those are my best-guess for the actual elements, but the format + * appears to be sound.) + */ + ct -= 4; + buf += 4; /* skip the "\\??\\" on the front of the string. */ + for (i = 0, ptr = buf; i < ct; i++, ptr++) /* convert '#' to '\\' ... */ + { + if (*ptr == '#') + *ptr = '\\'; + else if (*ptr == '{') /* hit the GUID part of the string. */ + break; + } /* for */ + + *ptr = '\0'; + CopyMemory(keyname, regkeyroot, sizeof (regkeyroot) - 1); + CopyMemory(keyname + (sizeof (regkeyroot) - 1), buf, i + 1); + rc = pRegOpenKeyExA(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &hkey); + if (rc != ERROR_SUCCESS) + return; + + rc = pRegQueryValueExA(hkey, "DeviceDesc", NULL, ®type, name, &outsize); + pRegCloseKey(hkey); + if (rc != ERROR_SUCCESS) + { + /* msdn says failure may mangle the buffer, so default it again. */ + CopyMemory(name, default_device_name, sizeof (default_device_name)); + return; + } /* if */ + name[namesize-1] = '\0'; /* just in case. */ +} /* get_device_product_name */ + + +static void init_mouse(const RAWINPUTDEVICELIST *dev) +{ + MouseStruct *mouse = &mice[available_mice]; + + if (accept_device(dev)) + { + ZeroMemory(mouse, sizeof (MouseStruct)); + get_device_product_name(mouse->name, sizeof (mouse->name), dev); + mouse->handle = dev->hDevice; + available_mice++; /* we're good. */ + } /* if */ +} /* init_mouse */ + + +static int windows_wminput_init(void) +{ + RAWINPUTDEVICELIST *devlist = NULL; + UINT ct = 0; + UINT i; + + available_mice = 0; + + if (!find_api_symbols()) /* only supported on WinXP and later. */ + return(0); + + pGetRawInputDeviceList(NULL, &ct, sizeof (RAWINPUTDEVICELIST)); + if (ct == 0) /* no devices. */ + return(0); + + devlist = (PRAWINPUTDEVICELIST) alloca(sizeof (RAWINPUTDEVICELIST) * ct); + pGetRawInputDeviceList(devlist, &ct, sizeof (RAWINPUTDEVICELIST)); + for (i = 0; i < ct; i++) + init_mouse(&devlist[i]); + + if (!init_event_queue()) + { + cleanup_window(); + available_mice = 0; + } /* if */ + + return(available_mice); +} /* windows_wminput_init */ + + +static void windows_wminput_quit(void) +{ + /* unregister WM_INPUT devices... */ + RAWINPUTDEVICE rid; + ZeroMemory(&rid, sizeof (rid)); + rid.usUsagePage = 1; /* GenericDesktop page */ + rid.usUsage = 2; /* GeneralDestop Mouse usage. */ + rid.dwFlags |= RIDEV_REMOVE; + pRegisterRawInputDevices(&rid, 1, sizeof (rid)); + cleanup_window(); + available_mice = 0; + pDeleteCriticalSection(&mutex); +} /* windows_wminput_quit */ + + +static const char *windows_wminput_name(unsigned int index) +{ + if (index < available_mice) + return(mice[index].name); + return(NULL); +} /* windows_wminput_name */ + + +/* + * Windows doesn't send a WM_INPUT event when you unplug a mouse, + * so we try to do a basic query by device handle here; if the + * query fails, we assume the device has vanished and generate a + * disconnect. + */ +static int check_for_disconnects(ManyMouseEvent *ev) +{ + /* + * (i) is static so we iterate through all mice round-robin and check + * one mouse per call to ManyMouse_PollEvent(). This makes this test O(1). + */ + static unsigned int i = 0; + MouseStruct *mouse = NULL; + + if (++i >= available_mice) /* check first in case of redetect */ + i = 0; + + mouse = &mice[i]; + if (mouse->handle != NULL) /* not NULL == still plugged in. */ + { + UINT size = 0; + UINT rc = pGetRawInputDeviceInfoA(mouse->handle, RIDI_DEVICEINFO, + NULL, &size); + if (rc == (UINT) -1) /* failed...probably unplugged... */ + { + mouse->handle = NULL; + ev->type = MANYMOUSE_EVENT_DISCONNECT; + ev->device = i; + return(1); + } /* if */ + } /* if */ + + return(0); /* no disconnect event this time. */ +} /* check_for_disconnects */ + + +static int windows_wminput_poll(ManyMouseEvent *ev) +{ + MSG Msg; /* run the queue for WM_INPUT messages, etc ... */ + int found = 0; + + /* ...favor existing events in the queue... */ + pEnterCriticalSection(&mutex); + if (input_events_read != input_events_write) /* no events if equal. */ + { + CopyMemory(ev, &input_events[input_events_read], sizeof (*ev)); + input_events_read = ((input_events_read + 1) % MAX_EVENTS); + found = 1; + } /* if */ + pLeaveCriticalSection(&mutex); + + if (!found) + { + /* pump Windows for new hardware events... */ + while (pPeekMessageA(&Msg, raw_hwnd, 0, 0, PM_REMOVE)) + { + pTranslateMessage(&Msg); + pDispatchMessageA(&Msg); + } /* while */ + + /* In case something new came in, give it to the app... */ + pEnterCriticalSection(&mutex); + if (input_events_read != input_events_write) /* no events if equal. */ + { + CopyMemory(ev, &input_events[input_events_read], sizeof (*ev)); + input_events_read = ((input_events_read + 1) % MAX_EVENTS); + found = 1; + } /* if */ + pLeaveCriticalSection(&mutex); + } /* if */ + + /* + * Check for disconnects if queue is totally empty and Windows didn't + * report anything new at this time. This ensures that we don't send a + * disconnect event through ManyMouse and then later give a valid + * event to the app for a device that is now missing. + */ + if (!found) + found = check_for_disconnects(ev); + + return(found); +} /* windows_wminput_poll */ + + +ManyMouseDriver ManyMouseDriver_windows = +{ + windows_wminput_init, + windows_wminput_quit, + windows_wminput_name, + windows_wminput_poll +}; + +#endif /* ifdef WINDOWS blocker */ + +/* end of windows_wminput.c ... */ +