;Copyright (C) 1997-2001 ZSNES Team ( zsknight@zsnes.com / _demo_@zsnes.com ) ; ;This program is free software; you can redistribute it and/or ;modify it under the terms of the GNU General Public License ;as published by the Free Software Foundation; either ;version 2 of the License, or (at your option) any later ;version. ; ;This program is distributed in the hope that it will be useful, ;but WITHOUT ANY WARRANTY; without even the implied warranty of ;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;GNU General Public License for more details. ; ;You should have received a copy of the GNU General Public License ;along with this program; if not, write to the Free Software ;Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ; GUI Cheat Code Routines AddCSCheatCode: cmp byte[CSInputDisplay],'_' je .nodisplay jmp .okay .nodisplay ret .okay mov eax,[curentryval] mov [curaddrvalcs],eax mov eax,[CSCurValue] mov [curvaluecs],eax xor ecx,ecx mov cl,[CheatSrcByteSize] inc cl cmp byte[CheatUpperByteOnly],0 je .cspardisploop mov cl,1 .cspardispagain cmp dword[curvaluecs],0FFh jbe .cspardisploop shr dword[curvaluecs],8 inc dword[curaddrvalcs] jmp .cspardispagain .cspardisploop push ecx mov esi,GUICSrcTextQ mov ecx,3 mov eax,[curaddrvalcs] add eax,7E0000h mov bl,[curvaluecs] ; write bl at address eax call AddCheatCode shr dword[curvaluecs],8 mov byte[GUItextcolor],223 add dword[CheatSearchYPos],10 inc dword[curaddrvalcs] pop ecx dec ecx jnz near .cspardisploop mov byte[CheatWinMode],2 ret %macro SearchCMPByte 0 mov bl,[edi] cmp bl,[esi] %endmacro %macro SearchCMP2Bytes 0 mov bx,[edi] cmp bx,[esi] %endmacro %macro SearchCMP3Bytes 0 push ecx mov ebx,[edi] mov ecx,[esi] and ebx,0FFFFFFh and ecx,0FFFFFFh cmp ebx,ecx pop ecx %endmacro %macro SearchCMP4Bytes 0 mov ebx,[edi] cmp ebx,[esi] %endmacro %macro SearchMacro 2 mov dl,0FEh %%searchloop %2 %1 %%nofail and [eax],dl %%nofail inc edi inc esi cmp dl,7Fh jne %%noinceax inc eax %%noinceax rol dl,1 loop %%searchloop %endmacro %macro SearchMacroB 1 cmp byte[CheatCompareValue],0 je near %%greater cmp byte[CheatCompareValue],1 je near %%lessthan cmp byte[CheatCompareValue],3 je near %%notequalthan SearchMacro je, %1 jmp .end %%greater SearchMacro ja, %1 jmp .end %%lessthan SearchMacro jb, %1 jmp .end %%notequalthan SearchMacro jne, %1 jmp .end %endmacro CheatCodeSearchProcess: cmp byte[CheatSrcSearchType],1 je near .comparative cmp byte[CSInputDisplay],0 je near .nodisplay cmp byte[CSInputDisplay],'_' je near .nodisplay cmp byte[CSOverValue],1 je near .nodisplay mov byte[CSInputDisplay],'_' mov byte[CSInputDisplay+1],0 ; Process Cheat Search mov ecx,65536*2 xor ebx,ebx mov bl,byte[CheatSrcByteSize] sub ecx,ebx mov edx,[SrcMask+ebx*4] mov edi,dword[vidbuffer] add edi,129600+65536*2 mov esi,[wramdata] mov bl,0FEh mov bh,01h .exactloop mov eax,[esi] and eax,edx cmp eax,[CSCurValue] je .found inc eax and eax,edx cmp eax,[CSCurValue] je .foundb .failedfind and [edi],bl jmp .foundc .found test byte[edi+16384],bh jz .failedfind jmp .foundc .foundb cmp byte[FirstSearch],1 je .clear test byte[edi+16384],bh jnz .failedfind jmp .foundc .clear and byte[edi+16384],bl .foundc cmp bl,7Fh jne .noincedi inc edi .noincedi rol bl,1 rol bh,1 inc esi loop .exactloop ; CSCurValue dd 0 mov byte[CopyRamToggle],1 mov byte[CheatSearchStatus],1 .nodisplay ret .comparative mov byte[CSInputDisplay],'_' mov byte[CSInputDisplay+1],0 mov byte[CheatSearchStatus],1 mov eax,dword[vidbuffer] add eax,129600+65536*2 mov esi,dword[vidbuffer] add esi,129600 mov edi,[wramdata] mov ecx,65536*2 cmp byte[CheatSrcByteSize],1 je near .bytesize2 cmp byte[CheatSrcByteSize],2 je near .bytesize3 cmp byte[CheatSrcByteSize],3 je near .bytesize4 SearchMacroB SearchCMPByte .bytesize2 dec ecx SearchMacroB SearchCMP2Bytes .bytesize3 sub ecx,2 SearchMacroB SearchCMP3Bytes .bytesize4 sub ecx,3 SearchMacroB SearchCMP4Bytes .end mov byte[CopyRamToggle],1 ret CopyRamToggle db 0 FirstSearch db 0 CheatCodeSearchInit: mov byte[CSInputDisplay],'_' mov byte[CSInputDisplay+1],0 mov byte[CheatWinMode],1 mov byte[CheatSearchStatus],0 cmp byte[CopyRamToggle],0 mov byte[FirstSearch],1 mov eax,dword[vidbuffer] add eax,129600 ; copy 128k ram mov ebx,[wramdata] mov ecx,32768 .loop mov edx,[ebx] mov [eax],edx add ebx,4 add eax,4 loop .loop ; fill searched buffer with 0xFF mov eax,dword[vidbuffer] add eax,129600+65536*2 mov ecx,8192 .loop2 mov dword[eax],0FFFFFFFFh add eax,4 loop .loop2 cmp byte[CheatSrcSearchType],1 jne .nottype1 mov byte[CheatSearchStatus],1 .nottype1 mov dword[CheatCompareValue],0 mov eax,dword[vidbuffer] add eax,129600+65536*2 cmp byte[CheatSrcByteSize],1 je near .bytesize2 cmp byte[CheatSrcByteSize],2 je near .bytesize3 cmp byte[CheatSrcByteSize],3 je near .bytesize4 ret .bytesize2 and byte[eax+16383],07Fh ret .bytesize3 and byte[eax+16383],03Fh ret .bytesize4 and byte[eax+16383],01Fh ret CheatCodeSave: cmp byte[NumCheats],0 jne .okay mov byte[GUICBHold],0 ret .okay mov byte[cheatdata+6],254 mov byte[cheatdata+7],252 call SRAMDirc mov byte[GUICBHold],0 mov ebx,[statefileloc] sub ebx,2 mov eax,[fnamest+ebx] mov dword[fnamest+ebx],'CHT' push eax push ebx mov edx,fnamest+1 call Create_File jc .cheatsavefail mov bx,ax mov ecx,[NumCheats] mov edx,ecx shl ecx,4 shl edx,2 add ecx,edx add ecx,edx add ecx,edx mov edx,cheatdata call Write_File call Close_File .cheatsavefail pop ebx pop eax mov [fnamest+ebx],eax call LOADDir ret CheatCodeLoad: call SRAMDirc mov byte[GUICBHold],0 mov ebx,[statefileloc] sub ebx,2 mov eax,[fnamest+ebx] mov dword[fnamest+ebx],'CHT' push eax push ebx mov edx,fnamest+1 call Open_File jc near .fail mov bx,ax ; Disable all codes push ebx mov esi,cheatdata mov ecx,[NumCheats] cmp ecx,0 je .skip .loop2 test byte[esi],4 jnz .disabled2 push esi push ecx call DisableCheatCode pop ecx pop esi .disabled2 add esi,28 dec ecx jnz .loop2 .skip pop ebx mov ecx,255*28 mov edx,cheatdata call Read_File push eax call Close_File pop eax cmp byte[cheatdata+6],254 jne .notnewformat cmp byte[cheatdata+7],252 jne .notnewformat jmp .newformat .notnewformat ; Convert format mov esi,cheatdata mov ebx,18 push eax xor edx,edx div ebx push edx mov [NumCheats],eax mov ebx,28 mul ebx mov ecx,eax pop edx pop eax sub eax,edx .convloop sub ecx,28 sub eax,18 mov ebx,6 .convloopb mov dl,[cheatdata+eax+ebx-1] mov [cheatdata+ecx+ebx-1],dl dec ebx jnz .convloopb mov ebx,12 .convloopd mov dl,[cheatdata+eax+ebx+5] mov [cheatdata+ecx+ebx+7],dl dec ebx jnz .convloopd mov ebx,8 .convloopc mov byte[cheatdata+ecx+ebx+19],0 dec ebx jnz .convloopc or ecx,ecx jnz .convloop jmp .fin .newformat mov ebx,28 xor edx,edx div ebx mov [NumCheats],eax .fin pop ebx pop eax mov [fnamest+ebx],eax ; Enable all ON toggled cheat codes mov esi,cheatdata mov ecx,[NumCheats] cmp ecx,0 je .skip2 .loop test byte[esi],4 jnz .disabled push esi push ecx call EnableCheatCode pop ecx pop esi .disabled add esi,28 dec ecx jnz .loop .skip2 mov eax,[NumCheats] cmp eax,[GUIcurrentcheatcursloc] ja .noconf dec eax mov dword[GUIcurrentcheatcursloc],eax .noconf cmp dword[NumCheats],0 jne .nozero mov dword[GUIcurrentcheatcursloc],0 mov byte[CheatOn],0 call LOADDir ret .nozero mov byte[CheatOn],1 call LOADDir ret .fail pop ebx pop eax mov [fnamest+ebx],eax call LOADDir ret CheatCodeRemove: cmp dword[NumCheats],0 jne .nonone mov byte[GUICBHold],0 ret .nonone mov byte[GUICBHold],0 mov esi,[GUIcurrentcheatcursloc] shl esi,5 sub esi,[GUIcurrentcheatcursloc] sub esi,[GUIcurrentcheatcursloc] sub esi,[GUIcurrentcheatcursloc] sub esi,[GUIcurrentcheatcursloc] add esi,cheatdata push esi call DisableCheatCode pop esi mov eax,255 sub eax,[GUIcurrentcheatcursloc] mov ebx,eax shl eax,4 add eax,ebx add eax,ebx .loop mov bl,[esi+28] mov [esi],bl inc esi dec eax jnz .loop dec dword[NumCheats] mov eax,[GUIcurrentcheatcursloc] cmp dword[NumCheats],0 je .okay cmp eax,[NumCheats] jne .okay dec dword[GUIcurrentcheatcursloc] .okay cmp byte[NumCheats],0 jne .cheatexists mov byte[CheatOn],0 .cheatexists ret CheatCodeFix: cmp dword[NumCheats],0 jne .nonone mov byte[GUICBHold],0 ret .nonone mov byte[GUICBHold],0 call DisableCheatCode mov esi,[GUIcurrentcheatcursloc] shl esi,5 sub esi,[GUIcurrentcheatcursloc] sub esi,[GUIcurrentcheatcursloc] sub esi,[GUIcurrentcheatcursloc] sub esi,[GUIcurrentcheatcursloc] add esi,cheatdata xor byte[esi+3],80h call EnableCheatCodeNoPrevMod ret CheatCodeToggle: cmp dword[NumCheats],0 jne .nonone mov byte[GUICBHold],0 ret .nonone mov byte[GUICBHold],0 mov esi,[GUIcurrentcheatcursloc] shl esi,5 sub esi,[GUIcurrentcheatcursloc] sub esi,[GUIcurrentcheatcursloc] sub esi,[GUIcurrentcheatcursloc] sub esi,[GUIcurrentcheatcursloc] add esi,cheatdata test byte[esi],4 jz DisableCheatCode jmp EnableCheatCodeNoPrevMod DisableCheatCode: ; code is at esi xor ecx,ecx xor ebx,ebx or byte[esi],4 test byte[esi],1 jnz .gfrom mov al,[esi+5] mov cx,[esi+2] mov bl,[esi+4] mov byte[writeon],1 test byte[esi],80h jnz .nowrite test byte[esi-28],80h jnz .nowrite call dword near [memtablew8+ebx*4] .nowrite mov byte[writeon],0 ret .gfrom mov al,[esi+5] mov ecx,[esi+2] and ecx,0FFFFFFh mov esi,[romdata] mov [esi+ecx],al ret .gfram mov al,[esi+5] mov ecx,[esi+2] and ecx,0FFFFFFh mov esi,[sram] mov [esi+ecx],al ret EnableCheatCode: ; code is at esi xor ecx,ecx xor ebx,ebx and byte[esi],0FBh test byte[esi],1 jnz .gfrom mov al,[esi+1] mov cx,[esi+2] mov bl,[esi+4] push ecx push eax push ebx push edx call dword near [memtabler8+ebx*4] pop edx mov byte[esi+5],al pop ebx pop eax pop ecx mov byte[writeon],1 test byte[esi],80h jnz .nowrite test byte[esi-28],80h jnz .nowrite call dword near [memtablew8+ebx*4] .nowrite mov byte[writeon],0 ret .gfrom mov al,[esi+1] mov ecx,[esi+2] and ecx,0FFFFFFh mov esi,[romdata] mov bl,[esi+ecx] mov [esi+ecx],al mov [esi+5],bl ret .gfram mov al,[esi+1] mov ecx,[esi+2] and ecx,0FFFFFFh mov esi,[sram] mov bl,[esi+ecx] mov [esi+ecx],al mov [esi+5],bl ret EnableCheatCodeNoPrevMod: ; code is at esi xor ecx,ecx xor ebx,ebx and byte[esi],0FBh test byte[esi],1 jnz .gfrom mov al,[esi+1] mov cx,[esi+2] mov bl,[esi+4] mov byte[writeon],1 test byte[esi],80h jnz .nowrite test byte[esi-28],80h jnz .nowrite call dword near [memtablew8+ebx*4] .nowrite mov byte[writeon],0 ret .gfrom mov al,[esi+1] mov ecx,[esi+2] and ecx,0FFFFFFh mov esi,[romdata] mov bl,[esi+ecx] mov [esi+ecx],al mov [esi+5],bl ret .gfram mov al,[esi+1] mov ecx,[esi+2] and ecx,0FFFFFFh mov esi,[sram] mov bl,[esi+ecx] mov [esi+ecx],al mov [esi+5],bl ret AddCheatCode: mov byte[GUICBHold],0 cmp dword[NumCheats],255 jne .okay ret .okay push eax push ebx ; transfer description mov eax,[NumCheats] shl eax,5 sub eax,[NumCheats] sub eax,[NumCheats] sub eax,[NumCheats] sub eax,[NumCheats] add eax,cheatdata mov edx,eax push edx add eax,6 mov ebx,CSDescDisplay mov ecx,20 .dloop mov dl,[ebx] mov [eax+2],dl mov [eax+18+2],dl mov [eax+18*2+2],dl inc ebx inc eax loop .dloop pop edx pop ebx pop eax ; toggle, value, address, pvalue, name(12) mov byte[edx],0 mov [edx+1],bl push eax sub eax,7E0000h add eax,[wramdata] mov bh,[eax] mov [eax],bl pop eax mov [edx+2],eax mov [edx+5],bh inc dword[NumCheats] mov edx,7 mov al,[GUIpmenupos] push eax call CheckMenuItemHelp pop eax mov [GUIpmenupos],al mov byte[CheatOn],1 ret ProcessCheatCode: mov byte[GUICBHold],0 cmp dword[NumCheats],255 je .fail cmp byte[GUICheatPosA],0 je .fail jmp .okay .fail ret .okay ; make sure flashing cursor doesn't exist xor ebx,ebx mov bl,[GUICheatPosB] mov byte[GUICheatTextA+ebx],0 ; transfer description mov eax,[NumCheats] shl eax,5 sub eax,[NumCheats] sub eax,[NumCheats] sub eax,[NumCheats] sub eax,[NumCheats] add eax,cheatdata add eax,6 mov ebx,GUICheatTextA mov ecx,20 .dloop mov dl,[ebx] mov [eax+2],dl mov [eax+18+2],dl mov [eax+18*2+2],dl inc ebx inc eax loop .dloop ; determine whether it is gamegenie, par, or GF ; uppercase all codes if necessary mov eax,GUICheatText9 mov ecx,14 .loop mov bl,[eax] cmp bl,'a' jb .nolower cmp bl,'z' ja .nolower sub bl,'a'-'A' mov [eax],bl .nolower inc eax loop .loop mov byte[guicheatvalrep],0 xor eax,eax mov al,[GUICheatPosA] dec al cmp byte[GUICheatText9+eax],'R' jne .notrep mov byte[guicheatvalrep],80h dec byte[GUICheatPosA] .notrep cmp byte[GUICheatPosA],8 je near .par cmp byte[GUICheatPosA],9 je near .gg cmp byte[GUICheatPosA],14 je near .gf .invalidpar jmp guicheaterror .par ; check if code is valid mov eax,GUICheatText9 mov ecx,8 .looppar mov bl,[eax] cmp bl,'0' jb .invalidpar cmp bl,'9' jbe .okaypar cmp bl,'A' jb .invalidpar cmp bl,'F' ja .invalidpar .okaypar inc eax loop .looppar jmp decodepar .invalidgg jmp guicheaterror .gg ; check if code is valid mov eax,GUICheatText9 mov ecx,9 .loopgg cmp ecx,5 jne .nomid cmp byte[eax],'-' jne .invalidgg inc eax dec ecx .nomid mov bl,[eax] cmp bl,'0' jb .invalidgg cmp bl,'9' jbe .okaygg cmp bl,'A' jb .invalidgg cmp bl,'F' ja .invalidgg .okaygg inc eax loop .loopgg jmp decodegg ret .invalidgf jmp guicheaterror .gf ; check if code is valid mov eax,GUICheatText9 mov ecx,5 .loopgf mov bl,[eax] cmp bl,'0' jb .invalidgf cmp bl,'9' jbe .okaygf cmp bl,'A' jb .invalidgf cmp bl,'F' ja .invalidgf .okaygf inc eax loop .loopgf mov eax,GUICheatText9+5 mov ecx,6 .loopgf2 mov bl,[eax] cmp bl,'X' je .okaygf2 cmp bl,'0' jb .invalidgf cmp bl,'9' jbe .okaygf2 cmp bl,'A' jb near .invalidgf cmp bl,'F' ja near .invalidgf .okaygf2 inc eax loop .loopgf2 mov bl,[GUICheatText9+13] cmp bl,'0' je .okaygf3 cmp bl,'1' jne near .invalidgf .okaygf3 jmp decodegf decodegf: ; convert code to number format mov ecx,14 mov esi,GUICheatText9 .loopb2 mov al,[esi] cmp al,'X' je .let2 cmp al,'A' jb .num2 sub al,'A' add al,10 jmp .let2 .num2 sub al,'0' .let2 mov [esi],al inc esi dec ecx jnz .loopb2 ; get address xor ebx,ebx xor ecx,ecx mov cl,[GUICheatText9] shl ecx,4 add cl,[GUICheatText9+1] shl ecx,4 add cl,[GUICheatText9+2] shl ecx,4 add cl,[GUICheatText9+3] shl ecx,4 add cl,[GUICheatText9+4] mov edx,[NumCheats] shl edx,5 sub edx,[NumCheats] sub edx,[NumCheats] sub edx,[NumCheats] sub edx,[NumCheats] ; Write data to memory cmp byte[GUICheatText9+13],1 je near .modifysram ; get data cmp byte[GUICheatText9+5],'X' je near .nocode cmp byte[GUICheatText9+6],'X' je near .nocode mov bl,[GUICheatText9+5] shl bl,4 add bl,[GUICheatText9+6] mov esi,[romdata] mov al,[esi+ecx] mov [esi+ecx],bl mov byte[cheatdata+edx],1 mov [cheatdata+edx+2],ecx mov [cheatdata+edx+1],bl mov [cheatdata+edx+5],al push eax mov al,[guicheatvalrep] or [cheatdata+edx],al pop eax inc byte[NumCheats] add edx,28 .nocode inc ecx cmp byte[GUICheatText9+7],'X' je near .nocode1 cmp byte[GUICheatText9+8],'X' je near .nocode1 cmp byte[NumCheats],255 je near .nocode1 mov bl,[GUICheatText9+7] shl bl,4 add bl,[GUICheatText9+8] mov esi,[romdata] mov al,[esi+ecx] mov [esi+ecx],bl mov byte[cheatdata+edx],1 mov [cheatdata+edx+2],ecx mov [cheatdata+edx+1],bl mov [cheatdata+edx+5],al inc byte[NumCheats] add edx,28 .nocode1 inc ecx cmp byte[GUICheatText9+9],'X' je near .nocode2 cmp byte[GUICheatText9+10],'X' je near .nocode2 cmp byte[NumCheats],255 je near .nocode2 mov bl,[GUICheatText9+9] shl bl,4 add bl,[GUICheatText9+10] mov esi,[romdata] mov al,[esi+ecx] mov [esi+ecx],bl mov byte[cheatdata+edx],1 mov [cheatdata+edx+2],ecx mov [cheatdata+edx+1],bl mov [cheatdata+edx+5],al inc byte[NumCheats] .nocode2 jmp .quit .modifysram cmp ecx,65535 ja near .quit mov esi,[sram] ; get data cmp byte[GUICheatText9+5],'X' je .nocodeb cmp byte[GUICheatText9+6],'X' je .nocodeb mov bl,[GUICheatText9+5] shl bl,4 add bl,[GUICheatText9+6] mov al,[esi+ecx] mov [esi+ecx],bl mov byte[cheatdata+edx],2 mov [cheatdata+edx+2],ecx mov [cheatdata+edx+1],bl mov [cheatdata+edx+5],al inc byte[NumCheats] add edx,28 .nocodeb inc ecx cmp byte[GUICheatText9+7],'X' je .nocode1b cmp byte[GUICheatText9+8],'X' je .nocode1b cmp byte[NumCheats],255 je .nocode1b cmp ecx,65535 ja .nocode1b mov bl,[GUICheatText9+7] shl bl,4 add bl,[GUICheatText9+8] mov al,[esi+ecx+1] mov [esi+ecx+1],bl mov byte[cheatdata+edx],2 mov [cheatdata+edx+2],ecx mov [cheatdata+edx+1],bl mov [cheatdata+edx+5],al inc byte[NumCheats] add edx,28 .nocode1b inc ecx cmp byte[GUICheatText9+9],'X' je .nocode2c cmp byte[GUICheatText9+10],'X' je .nocode2c cmp byte[NumCheats],255 je .nocode2c cmp ecx,65535 ja .nocode2c mov bl,[GUICheatText9+9] shl bl,4 add bl,[GUICheatText9+10] mov al,[esi+ecx+2] mov [esi+ecx+2],bl mov byte[cheatdata+edx],2 mov [cheatdata+edx+2],ecx mov [cheatdata+edx+1],bl mov [cheatdata+edx+5],al inc byte[NumCheats] .nocode2c .quit cmp byte[NumCheats],0 je .nocheat mov byte[CheatOn],1 mov dword[GUIcurrentcheatwin],1 mov eax,[NumCheats] dec eax mov [GUIcurrentcheatcursloc],eax sub eax,11 mov [GUIcurrentcheatviewloc],eax test dword[GUIcurrentcheatviewloc],80000000h jz .noview mov dword[GUIcurrentcheatviewloc],0 .noview .nocheat mov dword[GUICheatText9],0 mov dword[GUICheatTextA],0 mov byte[GUICheatPosA],0 mov byte[GUICheatPosB],0 ret decodegg: ;Genie Hex: D F 4 7 0 9 1 5 6 B C 8 A 2 3 E ;Normal Hex: 0 1 2 3 4 5 6 7 8 9 A B C D E F ; 4 6 D E 2 7 8 3 B 5 C 9 A 0 F 1 ; Convert code mov esi,GUICheatText9 mov eax,[esi+5] mov [esi+4],eax ; convert code to number format mov ecx,8 xor eax,eax .loopb3 mov al,[esi] cmp al,'A' jb .num3 sub al,'A' add al,10 jmp .let3 .num3 sub al,'0' .let3 mov al,[.GG2Norm+eax] mov [esi],al inc esi dec ecx jnz .loopb3 mov esi,GUICheatText9 xor ecx,ecx mov cl,[esi+2] shl ecx,4 add cl,[esi+3] shl ecx,4 add cl,[esi+4] shl ecx,4 add cl,[esi+5] shl ecx,4 add cl,[esi+6] shl ecx,4 add cl,[esi+7] ; 0123456789ABCDEF01234567 ; 24bit encoded address: ijklqrstopabcduvwxefghmn ; abcdefghijklmnopqrstuvwx ; >8 >12 >6<10 >6 <14 <10 mov ebx,ecx and ebx,000000000011110000000000b ;abcd shl ebx,10 mov eax,ecx and eax,000000000000000000111100b ;efgh shl eax,14 add ebx,eax mov eax,ecx and eax,111100000000000000000000b ;ijkl shr eax,8 add ebx,eax mov eax,ecx and eax,000000000000000000000011b ;mn shl eax,10 add ebx,eax mov eax,ecx and eax,000000001100000000000000b ;op shr eax,6 add ebx,eax mov eax,ecx and eax,000011110000000000000000b ;qrst shr eax,12 add ebx,eax mov eax,ecx and eax,000000000000001111000000b ;uvwx shr eax,6 add ebx,eax xor ecx,ecx mov cx,bx shr ebx,16 test bl,40h jz .noover ; xor cx,8000h .noover mov al,[esi] shl al,4 add al,[esi+1] ; store into cheatdata mov edx,[NumCheats] shl edx,5 sub edx,[NumCheats] sub edx,[NumCheats] sub edx,[NumCheats] sub edx,[NumCheats] mov byte[cheatdata+edx],0 mov [cheatdata+edx+1],al mov [cheatdata+edx+2],cx mov [cheatdata+edx+4],bl push eax mov al,[guicheatvalrep] or [cheatdata+edx],al pop eax push ecx push eax push ebx push edx call dword near [memtabler8+ebx*4] pop edx mov byte[cheatdata+edx+5],al pop ebx pop eax pop ecx mov byte[writeon],1 test byte[cheatdata+edx],80h jnz .nowrite test byte[cheatdata+edx-28],80h jnz .nowrite call dword near [memtablew8+ebx*4] .nowrite mov byte[writeon],0 mov byte[CheatOn],1 inc byte[NumCheats] mov dword[GUICheatText9],0 mov dword[GUICheatTextA],0 mov byte[GUICheatPosA],0 mov byte[GUICheatPosB],0 mov dword[GUIcurrentcheatwin],1 mov eax,[NumCheats] dec eax mov [GUIcurrentcheatcursloc],eax sub eax,11 mov [GUIcurrentcheatviewloc],eax test dword[GUIcurrentcheatviewloc],80000000h jz .noview mov dword[GUIcurrentcheatviewloc],0 .noview ret .GG2Norm db 04h,06h,0Dh,0Eh,02h,07h,08h,03h,0Bh,05h,0Ch,09h,0Ah,00h,0Fh,01h decodepar: ; convert code to number format mov ecx,8 mov esi,GUICheatText9 .loopb mov al,[esi] cmp al,'A' jb .num sub al,'A' add al,10 jmp .let .num sub al,'0' .let mov [esi],al inc esi dec ecx jnz .loopb ; get address xor ebx,ebx xor ecx,ecx mov bl,[GUICheatText9] shl bl,4 add bl,[GUICheatText9+1] mov cl,[GUICheatText9+2] shl cx,4 add cl,[GUICheatText9+3] shl cx,4 add cl,[GUICheatText9+4] shl cx,4 add cl,[GUICheatText9+5] mov al,[GUICheatText9+6] shl al,4 add al,[GUICheatText9+7] ; store into cheatdata xor edx,edx mov dl,[NumCheats] push ebx mov ebx,edx shl edx,5 sub edx,ebx sub edx,ebx sub edx,ebx sub edx,ebx pop ebx mov byte[cheatdata+edx],0 mov [cheatdata+edx+1],al mov [cheatdata+edx+2],cx mov [cheatdata+edx+4],bl push eax mov al,[guicheatvalrep] or [cheatdata+edx],al pop eax push ecx push eax push ebx push edx call dword near [memtabler8+ebx*4] pop edx mov byte[cheatdata+edx+5],al pop ebx pop eax pop ecx mov byte[writeon],1 test byte[cheatdata+edx],80h jnz .nowrite test byte[cheatdata+edx-28],80h jnz .nowrite call dword near [memtablew8+ebx*4] .nowrite mov byte[writeon],0 mov byte[CheatOn],1 inc dword[NumCheats] mov dword[GUICheatText9],0 mov dword[GUICheatTextA],0 mov byte[GUICheatPosA],0 mov byte[GUICheatPosB],0 mov dword[GUIcurrentcheatwin],1 mov eax,[NumCheats] dec eax mov [GUIcurrentcheatcursloc],eax sub eax,11 mov [GUIcurrentcheatviewloc],eax test dword[GUIcurrentcheatviewloc],80000000h jz .noview mov dword[GUIcurrentcheatviewloc],0 .noview ret guicheaterror: xor ebx,ebx mov ecx,256+128+64 .a mov byte[pressed+ebx],0 inc ebx loop .a .again call GUIUnBuffer call DisplayBoxes call DisplayMenu GUIBox 75,95,192,143,160 GUIBox 75,95,192,95,162 GUIBox 75,95,75,143,161 GUIBox 192,95,192,143,159 GUIBox 75,143,192,143,158 GUIOuttext 81,101,guicheaterror1,220-15 GUIOuttext 80,100,guicheaterror1,220 GUIOuttext 81,109,guicheaterror2,220-15 GUIOuttext 80,108,guicheaterror2,220 GUIOuttext 81,117,guicheaterror3,220-15 GUIOuttext 80,116,guicheaterror3,220 GUIOuttext 81,125,guicheaterror4,220-15 GUIOuttext 80,124,guicheaterror4,220 GUIOuttext 81,135,guicheaterror5,220-15 GUIOuttext 80,134,guicheaterror5,220 call vidpastecopyscr call JoyRead xor ebx,ebx mov ecx,256+128+64 .b cmp byte[pressed+ebx],0 jne .pressedokay inc ebx loop .b cmp byte[MouseDis],1 je .mousedis call Get_MouseData test bx,01h jnz .pressedokay .mousedis jmp .again .pressedokay .again2 call Check_Key or al,al jz .nokey call Get_Key jmp .again2 .nokey cmp byte[MouseDis],1 je .mousedis2 push ebx ; mov eax,0Bh ; int 33h pop ebx .mousedis2 mov dword[GUIcurrentcheatwin],1 mov byte[GUIpclicked],1 ret guicheaterror1 db 'INVALID CODE! YOU',0 guicheaterror2 db 'MUST ENTER A VALID',0 guicheaterror3 db 'GAME GENIE,PAR, OR',0 guicheaterror4 db 'GOLD FINGER CODE.',0 guicheaterror5 db 'PRESS ANY KEY.',0 guicheatvalrep db 0