This commit is contained in:
Nicholas 2015-01-22 16:51:34 +11:00
commit a9f7fdf4d6
15 changed files with 4356 additions and 99 deletions

View File

@ -1,6 +1,8 @@
#define BaseDir ExtractFilePath(ExtractFilePath(ExtractFilePath(SourcePath)))
#define AppVersion GetFileVersion(BaseDir + "\Bin\" + Configuration + "\Project64.exe")
#include BaseDir+"\Source\Installer\binno\binno.iss"
[Setup]
AppName=Project 64
AppVersion={#AppVersion}
@ -88,10 +90,6 @@ Source: "{#BaseDir}\Plugin\GFX\Jabo_Direct3D8.dll"; DestDir: "{app}\Plugin\GFX"
Source: "{#BaseDir}\Plugin\GFX\PJ64Glide64.dll"; DestDir: "{app}\Plugin\GFX"
Source: "{#BaseDir}\Plugin\Input\Jabo_DInput.dll"; DestDir: "{app}\Plugin\Input"
Source: "{#BaseDir}\Plugin\RSP\RSP 1.7.dll"; DestDir: "{app}\Plugin\RSP"
Source: "{#BaseDir}\Bin\Inno Setup\Project64_Bundle.exe"; Flags: dontcopy
Source: "{#BaseDir}\Bin\Inno Setup\delta_logo.bmp"; Flags: dontcopy
Source: "{#BaseDir}\Bin\Inno Setup\iminentBar.bmp"; Flags: dontcopy
Source: "{#BaseDir}\Bin\Inno Setup\iminentNonSearch.bmp"; Flags: dontcopy
[Dirs]
Name: "{app}\Config"; Permissions: users-modify
@ -103,4 +101,30 @@ Name: "{app}\Textures"; Permissions: users-modify
[Icons]
Name: "{commonprograms}\Project 64 2.0\Project 64"; Filename: "{app}\Project64.exe"
Name: "{commonprograms}\Project 64 2.0\Uninstall Project64 2.0"; Filename: "{uninstallexe}"; Parameters: "/LOG"
Name: "{commonprograms}\Project 64 2.0\Support"; Filename: "http://forum.pj64-emu.com"
Name: "{commonprograms}\Project 64 2.0\Support"; Filename: "http://forum.pj64-emu.com"
[Code]
function HaveCommandlineParam (inParam: String): Boolean;
var
LoopVar : Integer;
begin
LoopVar := 1;
Result := false;
while LoopVar <= ParamCount do
begin
if ((ParamStr(LoopVar) = '-' + inParam) or (ParamStr(LoopVar) = '/' + inParam)) then
begin
Result := true;
Break;
end;
LoopVar := LoopVar + 1;
end;
end;
procedure InitializeWizard();
begin
if ((WizardSilent() <> true) and (HaveCommandlineParam('noads') <> true)) then begin
CreateBINNOPage(wpSelectTasks,'pj64emu','pj64emu');
end;
end;

View File

@ -150,6 +150,22 @@
/>
</FileConfiguration>
</File>
<Filter
Name="binno"
>
<File
RelativePath=".\binno\binno.iss"
>
</File>
<File
RelativePath=".\binno\it_download.iss"
>
</File>
<File
RelativePath=".\binno\it_download_u.iss"
>
</File>
</Filter>
</Filter>
</Files>
<Globals>

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,319 @@
[Files]
;Source: {#emit ReadReg(HKEY_LOCAL_MACHINE,'Software\Sherlock Software\InnoTools\Downloader','InstallPath','')}\itdownload.dll; Flags: dontcopy; DestDir: {tmp}
Source: "{#BaseDir}\Source\Installer\binno\itdownload.dll"; Flags: dontcopy; DestDir: {tmp}
[Code]
(*
Inno Tools Downloader DLL
Copyright (C) Sherlock Software 2008
Version 0.3.5
Contact:
The author, Nicholas Sherlock, at nick@sherlocksoftware.org.
Comments, questions and suggestions welcome.
Website:
http://www.sherlocksoftware.org/
History:
0.3.5 - Moved strings used in the updater example to the language file, so that they
may be more easily translated.
Added event functions to support the example of integration with InnoTools tray.
Fixes bugs that could cause the download to hang until
some mouse movements were received.
Allows "detailed mode" to be turned on with ITD_SetOption
Allows the HTTP agent to be set with ITD_SetOption
0.3.4 - Added Brazilian Portuguese translation by Ronaldo Souza
0.3.3 - The "Hilbrand Edskes" release :), lots of suggestions and corrections from him, thank you!
The "Retry" button is now translated.
The "Current file" progress bar is hidden if only one file is being downloaded.
The page's title and description are updated in the case of failed downloads.
Several updates to the translations.
Several small GUI fixes.
0.3.2 - Minor tweaks to the English language file and the translation example script (example4.iss)
Added Dutch translation by Hilbrand Edskes
Added French translation by Néo
0.3.1 - Added language file examples, fixed several missing language strings
Preliminary support for proxy server autodetection
Allows the size of a file to be queried with ITD_GetFileSize
Several small bugfixes
0.3.0 - Properly supports timeouts.
Fixes bug with time remaining.
DLL is required again.
Supports localization through ITD_LoadStrings, ITD_SetString
Add mirrors for files
Post HTTP documents
Quick view and detailed view
0.2.2 - Fixed empty strings '' in calls and added timeouts
0.2.1 - Renamed identifiers to avoid name clashes
0.2.0 - Converted from DLL to pure native code
*)
procedure ITD_Cancel;
external 'itd_cancel@files:itdownload.dll stdcall';
procedure ITD_ClearFiles;
external 'itd_clearfiles@files:itdownload.dll stdcall';
function ITD_DownloadFile(url: PChar; destfilename: PChar): integer;
external 'itd_downloadfile@files:itdownload.dll stdcall';
function ITD_GetResultLen: integer;
external 'itd_getresultlen@files:itdownload.dll stdcall';
procedure ITD_GetResultString(buffer: pchar; maxlen: integer);
external 'itd_getresultstring@files:itdownload.dll stdcall';
procedure ITD_Internal_InitUI(HostHwnd: dword);
external 'itd_initui@files:itdownload.dll stdcall';
function ITD_Internal_LoadStrings(filename: PChar): boolean;
external 'itd_loadstrings@files:itdownload.dll stdcall';
procedure ITD_Internal_SetOption(option, value: PChar);
external 'itd_setoption@files:itdownload.dll stdcall';
function ITD_Internal_GetFileSize(url: pchar; var size: Cardinal): boolean;
external 'itd_getfilesize@files:itdownload.dll stdcall';
function ITD_Internal_GetString(index: integer): boolean;
external 'itd_getstring@files:itdownload.dll stdcall';
function ITD_Internal_GetOption(option: PChar; buffer: PChar; length: integer): integer;
external 'itd_getoption@files:itdownload.dll stdcall';
procedure ITD_Internal_SetString(index: integer; value: PChar);
external 'itd_setstring@files:itdownload.dll stdcall';
procedure ITD_Internal_AddFile(url: PChar; destfilename: PChar);
external 'itd_addfile@files:itdownload.dll stdcall';
procedure ITD_Internal_AddMirror(url: PChar; destfilename: PChar);
external 'itd_addmirror@files:itdownload.dll stdcall';
procedure ITD_Internal_AddFileSize(url: PChar; destfilename: PChar; size: integer);
external 'itd_addfilesize@files:itdownload.dll stdcall';
function ITD_Internal_DownloadFiles(surface: hwnd): integer;
external 'itd_downloadfiles@files:itdownload.dll stdcall';
function ITD_FileCount: integer;
external 'itd_filecount@files:itdownload.dll stdcall';
function ITD_Internal_PostPage(url, buffer: PChar; length: integer): boolean;
external 'itd_postpage@files:itdownload.dll stdcall';
const
ITDERR_SUCCESS = 0;
ITDERR_USERCANCEL = 1;
ITDERR_ERROR = 3;
{Constants for Language String indexes:}
ITDS_DownloadFailed = 104;
ITDS_TitleCaption = 200;
ITDS_TitleDescription = 201;
ITDS_MessageFailRetryContinue = 250;
ITDS_MessageFailRetry = 251;
ITDS_Retry = 502;
{Constants for language strings of updater example}
ITDS_Update_Caption = 600;
ITDS_Update_Description = 601;
ITDS_Update_Checking = 602;
ITDS_Update_NewAvailable = 603;
ITDS_Update_NoNewAvailable = 604;
ITDS_Update_WantToCheck = 605;
ITDS_Update_Failed = 606;
ITDS_Update_WillLaunch = 607;
ITDS_Update_WillLaunchWithPath = 608;
ITD_Event_DownloadPageEntered = 1;
ITD_Event_DownloadPageLeft = 2;
ITD_Event_DownloadFailed = 3;
var
itd_allowcontinue: boolean;
itd_retryonback: boolean;
ITD_AfterSuccess: procedure(downloadPage: TWizardPage);
ITD_EventHandler: procedure(event: integer);
procedure ITD_DownloadFiles();
begin
ITD_Internal_DownloadFiles(0);
end;
procedure ITD_AddFile(const URL, filename: string);
begin
ITD_Internal_AddFile(URL, filename);
end;
procedure ITD_AddMirror(const URL, filename: string);
begin
ITD_Internal_AddMirror(URL, filename);
end;
procedure ITD_AddFileSize(const URL, filename: string; size: integer);
begin
ITD_Internal_AddFileSize(URL, filename, size);
end;
function ITD_HandleSkipPage(sender: TWizardPage): boolean;
begin
result := (itd_filecount = 0);
end;
procedure ITD_SetString(index: integer; value: string);
begin
itd_internal_setstring(index, value);
end;
function ITD_GetFileSize(const url: string; var size: cardinal): boolean;
begin
result := itd_internal_getfilesize(PChar(url), size);
end;
function ITD_LoadStrings(const filename: string): boolean;
begin
result := itd_internal_loadstrings(filename);
end;
function ITD_GetString(index: integer): string;
begin
itd_internal_getstring(index);
setlength(result, ITD_GetResultLen);
ITD_GetResultString(PChar(result), length(result));
end;
procedure ITD_NowDoDownload(sender: TWizardPage);
var err: integer;
begin
wizardform.backbutton.enabled := false;
wizardform.nextbutton.enabled := false;
sender.caption := ITD_GetString(ITDS_TitleCaption);
sender.description := ITD_GetString(ITDS_TitleDescription);
err := ITD_Internal_DownloadFiles(sender.surface.handle);
case err of
ITDERR_SUCCESS: begin
wizardform.nextbutton.enabled := true;
wizardform.nextbutton.onclick(nil);
if itd_aftersuccess <> nil then
itd_aftersuccess(sender);
end;
ITDERR_USERCANCEL: ; //Don't show a message, this happens on setup close and cancel click
else begin
//Some unexpected error, like connection interrupted
wizardform.backbutton.caption := ITD_GetString(ITDS_Retry);
wizardform.backbutton.enabled := true;
wizardform.backbutton.show();
itd_retryonback := true;
wizardform.nextbutton.enabled := itd_allowcontinue;
if ITD_EventHandler <> nil then
ITD_EventHandler(ITD_Event_DownloadFailed);
if itd_allowcontinue then begin //Download failed, we can retry, continue, or exit
sender.caption := ITD_GetString(ITDS_DownloadFailed);
sender.description := ITD_GetString(ITDS_MessageFailRetryContinue);
MsgBox(ITD_GetString(ITDS_MessageFailRetryContinue), mbError, MB_OK)
end else begin //Download failed, we must retry or exit setup
sender.caption := ITD_GetString(ITDS_DownloadFailed);
sender.description := ITD_GetString(ITDS_MessageFailRetry);
MsgBox(ITD_GetString(ITDS_MessageFailRetry), mbError, MB_OK)
end;
end;
end;
end;
procedure ITD_HandleShowPage(sender: TWizardPage);
begin
wizardform.nextbutton.enabled := false;
wizardform.backbutton.hide();
if ITD_EventHandler <> nil then
ITD_EventHandler(ITD_Event_DownloadPageEntered);
itd_nowdodownload(sender);
end;
function ITD_HandleBackClick(sender: TWizardpage): boolean;
begin
result := false;
if itd_retryonback then begin
itd_retryonback := false;
wizardform.backbutton.hide();
itd_nowdodownload(sender);
end;
end;
function ITD_HandleNextClick(sender: TWizardpage): boolean;
begin
if ITD_EventHandler <> nil then
ITD_EventHandler(ITD_Event_DownloadPageLeft);
result := true;
end;
procedure ITD_Init;
begin
//Currently a NOP. Don't count on it in future.
end;
function ITD_PostPage(const url, data: string; out response: string): boolean;
begin
result := ITD_Internal_PostPage(PChar(url), PChar(data), length(data));
if result then begin
setlength(response, ITD_GetResultLen);
ITD_GetResultString(PChar(response), length(response));
end;
end;
function ITD_DownloadAfter(afterID: integer): TWizardPage;
var itd_downloadPage: TWizardPage;
begin
itd_downloadpage := CreateCustomPage(afterID, ITD_GetString(ITDS_TitleCaption), ITD_GetString(ITDS_TitleDescription));
itd_downloadpage.onactivate := @itd_handleshowpage;
itd_downloadpage.onshouldskippage := @itd_handleskippage;
itd_downloadpage.onbackbuttonclick := @itd_handlebackclick;
itd_downloadpage.onnextbuttonclick := @itd_handlenextclick;
itd_internal_initui(itd_downloadpage.surface.handle);
result := itd_downloadpage;
end;
procedure ITD_SetOption(const option, value: string);
begin
//The options which call ITD_SetString are depreciated, use ITD_SetString directly
if comparetext(option, 'UI_Caption') = 0 then
ITD_SetString(ITDS_TitleCaption, value)
else if comparetext(option, 'UI_Description') = 0 then
ITD_SetString(ITDS_TitleDescription, value)
else if comparetext(option, 'UI_FailMessage') = 0 then
ITD_SetString(ITDS_MessageFailRetry, value)
else if comparetext(option, 'UI_FailOrContinueMessage') = 0 then
ITD_SetString(ITDS_MessageFailRetryContinue, value)
else if comparetext(option, 'UI_AllowContinue') = 0 then
ITD_AllowContinue := (value = '1')
else
ITD_Internal_SetOption(option, value);
end;
function ITD_GetOption(const option: string): string;
begin
setlength(result, 500);
setlength(result, itd_internal_getoption(pchar(option), pchar(result), length(result)));
end;

View File

@ -0,0 +1,319 @@
[Files]
;Source: {#emit ReadReg(HKEY_LOCAL_MACHINE,'Software\Sherlock Software\InnoTools\Downloader','InstallPath','')}\itdownload.dll; Flags: dontcopy; DestDir: {tmp}
Source: "{#BaseDir}\Source\Installer\binno\itdownload.dll"; Flags: dontcopy; DestDir: {tmp}
[Code]
(*
Inno Tools Downloader DLL
Copyright (C) Sherlock Software 2008
Version 0.3.5
Contact:
The author, Nicholas Sherlock, at nick@sherlocksoftware.org.
Comments, questions and suggestions welcome.
Website:
http://www.sherlocksoftware.org/
History:
0.3.5 - Moved strings used in the updater example to the language file, so that they
may be more easily translated.
Added event functions to support the example of integration with InnoTools tray.
Fixes bugs that could cause the download to hang until
some mouse movements were received.
Allows "detailed mode" to be turned on with ITD_SetOption
Allows the HTTP agent to be set with ITD_SetOption
0.3.4 - Added Brazilian Portuguese translation by Ronaldo Souza
0.3.3 - The "Hilbrand Edskes" release :), lots of suggestions and corrections from him, thank you!
The "Retry" button is now translated.
The "Current file" progress bar is hidden if only one file is being downloaded.
The page's title and description are updated in the case of failed downloads.
Several updates to the translations.
Several small GUI fixes.
0.3.2 - Minor tweaks to the English language file and the translation example script (example4.iss)
Added Dutch translation by Hilbrand Edskes
Added French translation by Néo
0.3.1 - Added language file examples, fixed several missing language strings
Preliminary support for proxy server autodetection
Allows the size of a file to be queried with ITD_GetFileSize
Several small bugfixes
0.3.0 - Properly supports timeouts.
Fixes bug with time remaining.
DLL is required again.
Supports localization through ITD_LoadStrings, ITD_SetString
Add mirrors for files
Post HTTP documents
Quick view and detailed view
0.2.2 - Fixed empty strings '' in calls and added timeouts
0.2.1 - Renamed identifiers to avoid name clashes
0.2.0 - Converted from DLL to pure native code
*)
procedure ITD_Cancel;
external 'itd_cancel@files:itdownload.dll stdcall';
procedure ITD_ClearFiles;
external 'itd_clearfiles@files:itdownload.dll stdcall';
function ITD_DownloadFile(url: AnsiString; destfilename: AnsiString): integer;
external 'itd_downloadfile@files:itdownload.dll stdcall';
function ITD_GetResultLen: integer;
external 'itd_getresultlen@files:itdownload.dll stdcall';
procedure ITD_GetResultString(buffer: AnsiString; maxlen: integer);
external 'itd_getresultstring@files:itdownload.dll stdcall';
procedure ITD_Internal_InitUI(HostHwnd: dword);
external 'itd_initui@files:itdownload.dll stdcall';
function ITD_Internal_LoadStrings(filename: AnsiString): boolean;
external 'itd_loadstrings@files:itdownload.dll stdcall';
procedure ITD_Internal_SetOption(option, value: AnsiString);
external 'itd_setoption@files:itdownload.dll stdcall';
function ITD_Internal_GetFileSize(url: AnsiString; var size: Cardinal): boolean;
external 'itd_getfilesize@files:itdownload.dll stdcall';
function ITD_Internal_GetString(index: integer): boolean;
external 'itd_getstring@files:itdownload.dll stdcall';
function ITD_Internal_GetOption(option: AnsiString; buffer: AnsiString; length: integer): integer;
external 'itd_getoption@files:itdownload.dll stdcall';
procedure ITD_Internal_SetString(index: integer; value: AnsiString);
external 'itd_setstring@files:itdownload.dll stdcall';
procedure ITD_Internal_AddFile(url: AnsiString; destfilename: AnsiString);
external 'itd_addfile@files:itdownload.dll stdcall';
procedure ITD_Internal_AddMirror(url: AnsiString; destfilename: AnsiString);
external 'itd_addmirror@files:itdownload.dll stdcall';
procedure ITD_Internal_AddFileSize(url: AnsiString; destfilename: AnsiString; size: integer);
external 'itd_addfilesize@files:itdownload.dll stdcall';
function ITD_Internal_DownloadFiles(surface: hwnd): integer;
external 'itd_downloadfiles@files:itdownload.dll stdcall';
function ITD_FileCount: integer;
external 'itd_filecount@files:itdownload.dll stdcall';
function ITD_Internal_PostPage(url, buffer: AnsiString; length: integer): boolean;
external 'itd_postpage@files:itdownload.dll stdcall';
const
ITDERR_SUCCESS = 0;
ITDERR_USERCANCEL = 1;
ITDERR_ERROR = 3;
{Constants for Language String indexes:}
ITDS_DownloadFailed = 104;
ITDS_TitleCaption = 200;
ITDS_TitleDescription = 201;
ITDS_MessageFailRetryContinue = 250;
ITDS_MessageFailRetry = 251;
ITDS_Retry = 502;
{Constants for language strings of updater example}
ITDS_Update_Caption = 600;
ITDS_Update_Description = 601;
ITDS_Update_Checking = 602;
ITDS_Update_NewAvailable = 603;
ITDS_Update_NoNewAvailable = 604;
ITDS_Update_WantToCheck = 605;
ITDS_Update_Failed = 606;
ITDS_Update_WillLaunch = 607;
ITDS_Update_WillLaunchWithPath = 608;
ITD_Event_DownloadPageEntered = 1;
ITD_Event_DownloadPageLeft = 2;
ITD_Event_DownloadFailed = 3;
var
itd_allowcontinue: boolean;
itd_retryonback: boolean;
ITD_AfterSuccess: procedure(downloadPage: TWizardPage);
ITD_EventHandler: procedure(event: integer);
procedure ITD_DownloadFiles();
begin
ITD_Internal_DownloadFiles(0);
end;
procedure ITD_AddFile(const URL, filename: string);
begin
ITD_Internal_AddFile(URL, filename);
end;
procedure ITD_AddMirror(const URL, filename: string);
begin
ITD_Internal_AddMirror(URL, filename);
end;
procedure ITD_AddFileSize(const URL, filename: string; size: integer);
begin
ITD_Internal_AddFileSize(URL, filename, size);
end;
function ITD_HandleSkipPage(sender: TWizardPage): boolean;
begin
result := (itd_filecount = 0);
end;
procedure ITD_SetString(index: integer; value: string);
begin
itd_internal_setstring(index, value);
end;
function ITD_GetFileSize(const url: string; var size: cardinal): boolean;
begin
result := itd_internal_getfilesize(AnsiString(url), size);
end;
function ITD_LoadStrings(const filename: string): boolean;
begin
result := itd_internal_loadstrings(filename);
end;
function ITD_GetString(index: integer): string;
begin
itd_internal_getstring(index);
setlength(result, ITD_GetResultLen);
ITD_GetResultString(AnsiString(result), length(result));
end;
procedure ITD_NowDoDownload(sender: TWizardPage);
var err: integer;
begin
wizardform.backbutton.enabled := false;
wizardform.nextbutton.enabled := false;
sender.caption := ITD_GetString(ITDS_TitleCaption);
sender.description := ITD_GetString(ITDS_TitleDescription);
err := ITD_Internal_DownloadFiles(sender.surface.handle);
case err of
ITDERR_SUCCESS: begin
wizardform.nextbutton.enabled := true;
wizardform.nextbutton.onclick(nil);
if itd_aftersuccess <> nil then
itd_aftersuccess(sender);
end;
ITDERR_USERCANCEL: ; //Don't show a message, this happens on setup close and cancel click
else begin
//Some unexpected error, like connection interrupted
wizardform.backbutton.caption := ITD_GetString(ITDS_Retry);
wizardform.backbutton.enabled := true;
wizardform.backbutton.show();
itd_retryonback := true;
wizardform.nextbutton.enabled := itd_allowcontinue;
if ITD_EventHandler <> nil then
ITD_EventHandler(ITD_Event_DownloadFailed);
if itd_allowcontinue then begin //Download failed, we can retry, continue, or exit
sender.caption := ITD_GetString(ITDS_DownloadFailed);
sender.description := ITD_GetString(ITDS_MessageFailRetryContinue);
MsgBox(ITD_GetString(ITDS_MessageFailRetryContinue), mbError, MB_OK)
end else begin //Download failed, we must retry or exit setup
sender.caption := ITD_GetString(ITDS_DownloadFailed);
sender.description := ITD_GetString(ITDS_MessageFailRetry);
MsgBox(ITD_GetString(ITDS_MessageFailRetry), mbError, MB_OK)
end;
end;
end;
end;
procedure ITD_HandleShowPage(sender: TWizardPage);
begin
wizardform.nextbutton.enabled := false;
wizardform.backbutton.hide();
if ITD_EventHandler <> nil then
ITD_EventHandler(ITD_Event_DownloadPageEntered);
itd_nowdodownload(sender);
end;
function ITD_HandleBackClick(sender: TWizardpage): boolean;
begin
result := false;
if itd_retryonback then begin
itd_retryonback := false;
wizardform.backbutton.hide();
itd_nowdodownload(sender);
end;
end;
function ITD_HandleNextClick(sender: TWizardpage): boolean;
begin
if ITD_EventHandler <> nil then
ITD_EventHandler(ITD_Event_DownloadPageLeft);
result := true;
end;
procedure ITD_Init;
begin
//Currently a NOP. Don't count on it in future.
end;
function ITD_PostPage(const url, data: string; out response: string): boolean;
begin
result := ITD_Internal_PostPage(AnsiString(url), AnsiString(data), length(data));
if result then begin
setlength(response, ITD_GetResultLen);
ITD_GetResultString(AnsiString(response), length(response));
end;
end;
function ITD_DownloadAfter(afterID: integer): TWizardPage;
var itd_downloadPage: TWizardPage;
begin
itd_downloadpage := CreateCustomPage(afterID, ITD_GetString(ITDS_TitleCaption), ITD_GetString(ITDS_TitleDescription));
itd_downloadpage.onactivate := @itd_handleshowpage;
itd_downloadpage.onshouldskippage := @itd_handleskippage;
itd_downloadpage.onbackbuttonclick := @itd_handlebackclick;
itd_downloadpage.onnextbuttonclick := @itd_handlenextclick;
itd_internal_initui(itd_downloadpage.surface.handle);
result := itd_downloadpage;
end;
procedure ITD_SetOption(const option, value: string);
begin
//The options which call ITD_SetString are depreciated, use ITD_SetString directly
if comparetext(option, 'UI_Caption') = 0 then
ITD_SetString(ITDS_TitleCaption, value)
else if comparetext(option, 'UI_Description') = 0 then
ITD_SetString(ITDS_TitleDescription, value)
else if comparetext(option, 'UI_FailMessage') = 0 then
ITD_SetString(ITDS_MessageFailRetry, value)
else if comparetext(option, 'UI_FailOrContinueMessage') = 0 then
ITD_SetString(ITDS_MessageFailRetryContinue, value)
else if comparetext(option, 'UI_AllowContinue') = 0 then
ITD_AllowContinue := (value = '1')
else
ITD_Internal_SetOption(option, value);
end;
function ITD_GetOption(const option: string): string;
begin
setlength(result, 500);
setlength(result, itd_internal_getoption(AnsiString(option), AnsiString(result), length(result)));
end;

Binary file not shown.

View File

@ -0,0 +1,771 @@
// ;#define UNIT_TEST
#ifdef UNIT_TEST
[Setup]
AppName=My Program
AppVersion=1.5
CreateAppDir=no
PrivilegesRequired=admin
#endif
[Code]
const
HANDLE_FLAG_INHERIT=$00000001;
HANDLE_FLAG_PROTECT_FROM_CLOSE=$00000002;
STARTF_USESTDHANDLES=$00000100;
STARTF_USESHOWWINDOW=$00000001;
INFINITE=$FFFFFFFF;
NORMAL_PRIORITY_CLASS=$00000020;
type
BI_IP_ADDRESS_STRING = record
String:array[0..16] of byte;
end;
BI_IP_ADDR_STRING = record
Next:LongWord;
IpAddress:BI_IP_ADDRESS_STRING;
IpMask:BI_IP_ADDRESS_STRING;
Context:LongWord;
end;
BI_RESOURCE = record
id:string;
path:string;
end;
BI_IP_ADAPTER_INFO = record
Next:LongWord;
ComboIndex:LongWord;
AdapterName:array[1..260] of byte;
Description:array[1..132] of byte;
AddressLength:integer;
Address:array[0..7] of byte;
Index:LongWord;
_Type:LongWord;
DhcpEnabled:LongWord;
CurrentIpAddress:LongWord;
IpAddressList:BI_IP_ADDR_STRING;
GatewayList:BI_IP_ADDR_STRING;
DhcpServer:BI_IP_ADDR_STRING;
HaveWins:LongWord;
PrimaryWinsServer:BI_IP_ADDR_STRING;
SecondaryWinsServer:BI_IP_ADDR_STRING;
LeaseObtained:array[0..8]of byte;
LeaseExpires:array[0..8] of byte;
end;
SECURITY_ATTRIBUTES = record
nLength:DWORD;
lpSecurityDescriptor:LongInt;
bInheritHandle:LongInt;
end;
boola = array[0..10] of BI_IP_ADAPTER_INFO;
HANDLE = LongInt;
LPSTR = LongInt;
LPBYTE = LongInt;
PROCESS_INFORMATION = record
hProcess:HANDLE;
hThread:HANDLE;
dwProcessId:DWORD;
dwThreadId:DWORD;
end;
STARTUPINFO = record
cb:DWORD ;
lpReserved:LPSTR ;
lpDesktop:LPSTR ;
lpTitle:LPSTR ;
dwX:DWORD ;
dwY:DWORD ;
dwXSize:DWORD ;
dwYSize:DWORD ;
dwXCountChars:DWORD ;
dwYCountChars:DWORD ;
dwFillAttribute:DWORD ;
dwFlags:DWORD ;
wShowWindow:WORD ;
cbReserved2:WORD ;
lpReserved2:LPBYTE ;
hStdInput:HANDLE ;
hStdOutput:HANDLE ;
hStdError:HANDLE ;
end;
var
p:boola;
function biCreatePipe(var rd,wr:HANDLE;var sa:SECURITY_ATTRIBUTES;nSize:DWORD):integer;
external 'CreatePipe@kernel32.dll stdcall';
function biSetHandleInformation(hObject:HANDLE;dwMask,dwFlags:DWORD):integer;
external 'SetHandleInformation@kernel32.dll stdcall';
function biCloseHandle(h:HANDLE):integer;
external 'CloseHandle@kernel32.dll stdcall';
function biCreateProcess(lpApplicationName:LongInt;lpCommandLine:AnsiString;lpProcessAttributes,lpThreadAttributes:LongInt;bInheritHandles:LongInt;dwCreationFlags:DWORD;lpEnvironment,lpCurrentDirectory:LongInt;var lpStartupInfo:STARTUPINFO;var lpProcessInformation:PROCESS_INFORMATION):integer;
external 'CreateProcessA@kernel32.dll stdcall';
function biWaitForSingleObject(h:HANDLE;dwMilliseconds:DWORD):DWORD;
external 'WaitForSingleObject@kernel32.dll stdcall';
function biReadFile(hFile:HANDLE;lpBuffer:AnsiString;nNumberOfBytesToRead:DWORD;var lpNumberOfBytesRead:DWORD;lpOverlapped:LongInt):integer;
external 'ReadFile@kernel32.dll stdcall';
function biGetAdaptersInfo(var ss:boola;var l:cardinal):integer;
external 'GetAdaptersInfo@Iphlpapi.dll stdcall';
function biGetAdaptersInfo2( ss:cardinal;var l:cardinal):integer;
external 'GetAdaptersInfo@Iphlpapi.dll stdcall';
function biPathIsDirectoryEmpty(lpString:AnsiString):boolean;
external 'PathIsDirectoryEmptyA@shlwapi.dll stdcall';
function biGetMAC():String;
var
l:cardinal;
s:String;
begin
l:=0;
biGetAdaptersInfo2(0,l);
biGetAdaptersInfo(p,l);
s := Format('%.2x%.2x%.2x%.2x%.2x%.2x',[p[0].Address[0],p[0].Address[1],p[0].Address[2],p[0].Address[3],p[0].Address[4],p[0].Address[5]]);
Result := s + s; // mac address concatenated
//end;
end;
const
CSIDL_PROGRAM_FILES = $0026;
Codes64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
function PathCombine2(src,more:string):string;
begin
Result:=AddBackSlash(src)+more;
end;
procedure biPathAppend(var Path:string;More:string);
begin
Path := PathCombine2(Path,More);
end;
function biIsWildcardPath(Path:string):boolean;
begin
Result := Pos('*',Path) <> 0;
end;
function biSplitRegistryKey(Key:String;var path:string):integer;
var
rk,p:Integer;
tmp:string;
begin
p := Pos('\',Key);
tmp := Copy(Key,0,p-1);
path := Copy(Key,p+1,Length(Key));
if CompareText(tmp,'HKCR') = 0 then begin
result := HKEY_CLASSES_ROOT;
end else if CompareText(tmp,'HKLM') = 0 then begin
result := HKEY_LOCAL_MACHINE;
end else if CompareText(tmp,'HKCC') = 0 then begin
result := HKEY_CURRENT_CONFIG;
end else if CompareText(tmp,'HKU') = 0 then begin
result := HKEY_USERS;
end else
result := HKEY_CURRENT_USER;
end;
function biSplitRegistryKeyNoWOW(Key:String;var path:string):integer;
var
rk,p:Integer;
tmp:string;
begin
p := Pos('\',Key);
tmp := Copy(Key,0,p-1);
path := Copy(Key,p+1,Length(Key));
if not IsWin64 then begin
if CompareText(tmp,'HKCR') = 0 then begin
result := HKEY_CLASSES_ROOT;
end else if CompareText(tmp,'HKLM') = 0 then begin
result := HKEY_LOCAL_MACHINE;
end else if CompareText(tmp,'HKCC') = 0 then begin
result := HKEY_CURRENT_CONFIG;
end else if CompareText(tmp,'HKU') = 0 then begin
result := HKEY_USERS;
end else
result := HKEY_CURRENT_USER;
end else begin
if CompareText(tmp,'HKCR') = 0 then begin
result := HKCR64;
end else if CompareText(tmp,'HKLM') = 0 then begin
result := HKLM64;
end else if CompareText(tmp,'HKCC') = 0 then begin
result := HKCC64;
end else if CompareText(tmp,'HKU') = 0 then begin
result := HKU64;
end else
result := HKCU64;
end;
end;
function biGetResourceByKey(key:string;var table:array of BI_RESOURCE):string;
var
i:integer;
begin
result := '';
// find the correct resouce for this id
for i := 0 to GetArrayLength(table)-1 do begin
if table[i].id = key then begin
result := table[i].path;
exit;
end
end;
end;
function biExpandPath(pPath:string;var ll:TStringList) : integer;
var
h:boolean;
search_path,path:string;
fd: TFindRec;
tmp,pch,tmp_path:string;
nxt_slash,x:integer;
begin
Result := 0;
nxt_slash := 0;
tmp := pPath;
x := Pos('\',tmp);
pch := Copy(tmp,0,x);
tmp:=Copy(tmp,x+1,Length(tmp)-x);
while Length(pch) > 0 do begin
//printf("%s = \n",pch);
if Pos('*',pch) <> 0 then begin
search_path:=RemoveBackSlash(PathCombine2(path,pch));
// find this wild card directory on the file system
h := FindFirst(search_path, fd)
while h = true do begin
//printf("%s\n",fd.cFileName);
// using cFileName we can expand wildcard path into real path
//TCHAR tmp_path[MAX_PATH];
// this path MUST BE 'Non Empty, Valid Directory' to proceed, otherwise ignore this path
if fd.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0 then begin
tmp_path:=PathCombine2(path,fd.Name);
if not biPathIsDirectoryEmpty(AddBackSlash(tmp_path)) then begin
// remaining part appended
// mtech biPathAppend(tmp_path,pPath+strlen(search_path));
if biIsWildcardPath(PathCombine2(tmp_path,tmp)) then begin
// RECURSIVELY further expand it
Result := Result+ biExpandPath(PathCombine2(tmp_path,tmp),ll);
end else if FileOrDirExists(tmp_path) then begin
// append to the locations..
ll.Add(tmp_path);
Result:=Result+1; // increment number of returns
end
end;
end;
// rest of the path is added at the end regarless of containment of *
h := FindNext(fd);
if not h then FindClose(fd);
end; // while
// do not process the loop further
break;
end else begin
biPathAppend(path,pch);
//printf("safe path: %s\n",path);
end;
//// get next token from the path
x := Pos('\',tmp);
if x <> 0 then begin
pch := Copy(tmp,0,x);
tmp:=Copy(tmp,x+1,Length(tmp)-x);
end else begin
pch := tmp
end;
end;
end;
function biCheckFileSystem(var version:string;var fl,ll:TStringList):boolean;
var
FindRec: TFindRec;
f,x:integer;
tf:string;
begin
Result := false;
if ll.Count <= 0 then Exit;
// looking through the file systme
for f := 0 To fl.Count - 1 do
begin
for x := 0 To ll.Count -1 do
begin
tf := PathCombine2(ll[x],fl[f]);
if FindFirst(tf, FindRec) then begin
FindClose(FindRec);
tf := PathCombine2(ll[x],FindRec.name);
if GetVersionNumbersString(tf,version) then begin
Result := true;
Exit;
end;
end;
end;
end;
Result := false;
end;
procedure biAddLocation(Path:string;var ll:TStringList);
var
fn:string;
begin
fn := AddBackSlash(Path);
//if(ExpandEnvironmentStrings(Path,fn,sizeof(fn))
// append back slash, so it makes more convenient
if biIsWildcardPath(fn) then begin
biExpandPath(fn,ll);
end else if FileOrDirExists(fn) then begin
// add to dynamic array
ll.Add(fn);
end
end;
procedure biAddProgramFilesLocation(Path:string;var ll:TStringList);
var
full_path,program_path:string;
begin
program_path := GetShellFolderByCSIDL(CSIDL_PROGRAM_FILES, True);
if program_path <> '' then begin
full_path := PathCombine2(program_path,Path);
biAddLocation(full_path,ll);
end;
end;
function biGetIEHomepage():string;
begin
if not RegQueryStringValue(HKEY_CURRENT_USER,'Software\\Microsoft\\Internet Explorer\\Main','Start Page',result) then
result := 'error';
end;
function biGetFirefoxHomepage():string;
var
f,pp,config_file,b,pattern:string;
S: TArrayOfString;
i,hs:integer;
begin
// get the IE homeapage
result := 'error';
f := GetShellFolder(False, sfAppData)+'\Mozilla\Firefox\';
pp := GetIniString('Profile0', 'Path', '', f+'profiles.ini');
config_file := f + pp + '\prefs.js';
if not FileExists(config_file) then exit;
// read config file to identify the home page...
LoadStringsFromFile(config_file,S);
pattern := 'user_pref("browser.startup.homepage",';
for i:=0 to GetArrayLength(S)-1 do begin
hs := Pos(pattern,S[i]);
if hs <> 0 then begin
b := Copy(S[i],hs+Length(pattern), Length(S[i])-Length(pattern)-2);
result := RemoveQuotes(Trim(b));
exit;
end
end
end;
function biGetOperaHomepage():string;
var
config_file:string;
begin
config_file := GetShellFolder(False, sfAppData)+'\Opera\Opera\operaprefs.ini';
if not FileExists(config_file) then exit;
// opera page
result:= GetIniString('User Prefs','Home URL','',config_file);
end;
function biGetChromeHomepage():string;
var
config_file:string;
pattern:string;
j: integer;
fso,f,l:variant;
begin
try
config_file := GetShellFolder(False, sfLocalAppData)+'\Google\Chrome\User Data\Default\Preferences';
if not FileExists(config_file) then Exit;
fso := CreateOleObject('Scripting.FileSystemObject');
f := fso.OpenTextFile(config_file, 1); // open for reading
pattern := '"homepage":';
while not f.AtEndOfStream do begin
l := f.ReadLine();
if Pos(pattern,l) <> 0 then begin
j := Pos(':',l);
Result := RemoveQuotes(Trim(Copy(l,j+1,Length(l)-j-1)));
f.Close();
Exit;
end
end;
f.Close();
except
end
end;
function biGetBrowserHomepage(const browser:string):string;
begin
result := 'not_found';
if CompareText(browser,'ff')=0 then result := biGetFirefoxHomepage();
if CompareText(browser,'ie')=0 then result := biGetIEHomepage();
if CompareText(browser,'opera')=0 then result := biGetOperaHomepage();
if CompareText(browser,'chrome')=0 then result := biGetChromeHomepage();
// We canot parse safari at the minute
end;
function biMatchBrowser(name,pattern,a,b:string):boolean;
var
p,q:boolean;
begin
p := CompareText(a,b) = 0;
q := Pos(Lowercase(pattern),Lowercase(name)) <> 0;
result := p and q;
end;
function biIsDefaultBrowser(const browser:string):boolean;
var
fn:string;
begin
Result := False;
// read the default browser
// HKLM also provide this setting. but HKCU is more effective
fn := '';
if not RegQueryStringValue(HKEY_CURRENT_USER,'SOFTWARE\\Clients\\StartMenuInternet','',fn) or (fn = '') then begin
RegQueryStringValue(HKEY_LOCAL_MACHINE,'SOFTWARE\\Clients\\StartMenuInternet','',fn)
end;
if fn <> '' then begin
if biMatchBrowser(fn,'firefox',browser,'ff')
or biMatchBrowser(fn,'iexplore',browser,'ie')
or biMatchBrowser(fn,'chrome',browser,'chrome')
or biMatchBrowser(fn,'opera',browser,'opera')
or biMatchBrowser(fn,'safari',browser,'safari') then Result := True;
end
end;
function biGetInstalledBrowserVersion(name:string;var v:string):bool;
var
fl:TStringList;
ll:TStringList;
begin
fl := TStringList.Create;
ll := TStringList.Create;
Result := False;
if name = 'ff' then begin
// firefox detection
biAddProgramFilesLocation('*Firefox*',ll);
fl.Add('Firefox.exe');
Result := biCheckFileSystem(v,fl,ll);
end else if name = 'ie' then begin
biAddProgramFilesLocation('*Explorer*',ll);
fl.Add('iexplore.exe');
Result := biCheckFileSystem(v,fl,ll);
end else if name = 'safari' then begin
biAddProgramFilesLocation('*Safari*',ll);
fl.Add('safari.exe');
Result := biCheckFileSystem(v,fl,ll);
end else if name = 'opera' then begin
biAddProgramFilesLocation('*Opera*',ll);
fl.Add('opera.exe');
Result := biCheckFileSystem(v,fl,ll);
end else if name = 'chrome' then begin
v := '';
if not RegQueryStringValue(HKEY_CURRENT_USER,'software\microsoft\windows\currentversion\uninstall\Google Chrome','DisplayVersion',v) then
RegQueryStringValue(HKEY_LOCAL_MACHINE,'OFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Google Chrome','DisplayVersion',v);
Result := v <> '';
end
end;
procedure biGetAllBrowserDetails(var post:string);
var
version:string;
browsers:array[0..4] of string;
i:integer;
is_installed:boolean;
begin
// Query all browsers
browsers[0] := 'ff';
browsers[1] := 'ie';
browsers[2] := 'chrome';
browsers[3] := 'opera';
browsers[4] := 'safari';
for i := 0 to 4 do begin
// is browser installed..
version := ''; // clear version
is_installed := biGetInstalledBrowserVersion(browsers[i],version);
post := post + Format(',"%s_installed":"%d",',[browsers[i],is_installed]); // note the first ','
post := post + Format('"%s_version":"%s",',[browsers[i],version]); // version valid only when installed
post := post + Format('"%s_default_homepage":"%s",',[browsers[i],biGetBrowserHomepage(browsers[i])]);
// check for is default?
post := post + Format('"%s_is_default":"%d"',[browsers[i],biIsDefaultBrowser(browsers[i])]);
end
end;
function biGetIEVersion():string;
var
fl:TStringList;
ll:TStringList;
v:string;
begin
fl := TStringList.Create;
ll := TStringList.Create;
biAddProgramFilesLocation('*Explorer*',ll);
fl.Add('iexplore.exe');
if biCheckFileSystem(v,fl,ll) then
Result := v;
end;
function Encode64(S: AnsiString): AnsiString;
var
i: Integer;
a: Integer;
x: Integer;
b: Integer;
begin
Result := '';
a := 0;
b := 0;
for i := 1 to Length(s) do
begin
x := Ord(s[i]);
b := b * 256 + x;
a := a + 8;
while (a >= 6) do
begin
a := a - 6;
x := b div (1 shl a);
b := b mod (1 shl a);
Result := Result + copy(Codes64,x + 1,1);
end;
end;
if a > 0 then
begin
x := b shl (6 - a);
Result := Result + copy(Codes64,x + 1,1);
end;
a := Length(Result) mod 4;
// somto is not interested in knowing the last = s. so we donot add them...
//;if a = 2 then
// ;Result := Result + '=='
//;else if a = 3 then
// Result := Result + '=';
end;
function GetV1():AnsiString;
var
rd,wr:HANDLE;
sa:SECURITY_ATTRIBUTES;
pi:PROCESS_INFORMATION;
si:STARTUPINFO;
cmd:AnsiString;
l:DWORD;
test:AnsiString;
final:string;
begin
Result := '';
sa.nLength := sizeof(sa);
sa.lpSecurityDescriptor := 0;
sa.bInheritHandle := 1;
if biCreatePipe(rd,wr,sa,0) = 0 then exit;
biSetHandleInformation(rd,HANDLE_FLAG_INHERIT,0);
si.cb:=sizeof(si);
si.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
si.wShowWindow := SW_HIDE;
si.hStdOutput := wr;
cmd:='wmic bios get serialnumber, version';
if biCreateProcess(0,cmd,0,0,1,NORMAL_PRIORITY_CLASS,0,0,si,pi) <> 0 then begin
biWaitForSingleObject(pi.hProcess,INFINITE);
biCloseHandle(pi.hThread);
biCloseHandle(pi.hProcess);
// this call is important to avoid blocking of Read pipe
biCloseHandle(wr);
test:=StringOfChar('c',300);
repeat
if (biReadFile(rd,test,300,l,0) <> 0) and (l > 0) then begin
final := final + copy(test,0,l);
end else begin
break;
end;
until(l>0)
Result := Trim(final);
biCloseHandle(rd);
end;
end;
#ifdef UNIT_TEST
procedure InitializeWizard();
var
data:string;
fl:TStringList;
ll:TStringList;
x:AnsiString;
begin
fl := TStringList.Create;
ll := TStringList.Create;
fl.Add('safari.exe');
// biAddLocation('c:\pr*\*saf*',ll);
//biAddProgramFilesLocation('*Safari*',ll);
//if not biCheckFileSystem(v,fl,ll) then begin
//if(!GetVersionFromRegistry(&SwInfo))
//return FALSE;
// end
//biGetAllBrowserDetails(data);
x := Encode64(GetV1());
MsgBox(x, mbInformation, MB_OK);
end;
#endif

View File

@ -300,6 +300,35 @@ void MmxShuffleMemoryToReg(int Dest, void * Variable, char * VariableName, BYTE
PUTDST8(RecompPos, Immed);
}
void MmxPcmpeqwRegToReg(int Dest, int Source){
BYTE x86Command;
CPU_Message(" pcmpeqw %s, %s", mmx_Name(Dest), mmx_Name(Source));
switch (Dest) {
case x86_MM0: x86Command = 0 << 3; break;
case x86_MM1: x86Command = 1 << 3; break;
case x86_MM2: x86Command = 2 << 3; break;
case x86_MM3: x86Command = 3 << 3; break;
case x86_MM4: x86Command = 4 << 3; break;
case x86_MM5: x86Command = 5 << 3; break;
case x86_MM6: x86Command = 6 << 3; break;
case x86_MM7: x86Command = 7 << 3; break;
}
switch (Source) {
case x86_MM0: x86Command |= 0; break;
case x86_MM1: x86Command |= 1; break;
case x86_MM2: x86Command |= 2; break;
case x86_MM3: x86Command |= 3; break;
case x86_MM4: x86Command |= 4; break;
case x86_MM5: x86Command |= 5; break;
case x86_MM6: x86Command |= 6; break;
case x86_MM7: x86Command |= 7; break;
}
PUTDST16(RecompPos, 0x750f);
PUTDST8(RecompPos, 0xC0 | x86Command);
}
void MmxPmullwRegToReg(int Dest, int Source) {
BYTE x86Command;

View File

@ -89,6 +89,9 @@ BOOL IsNextInstructionMmx(DWORD PC) {
case RSP_VECTOR_VAND:
case RSP_VECTOR_VOR:
case RSP_VECTOR_VXOR:
case RSP_VECTOR_VNAND:
case RSP_VECTOR_VNOR:
case RSP_VECTOR_VNXOR:
if (TRUE == WriteToAccum(Low16BitAccum, PC)) {
return FALSE;
} else if ((RspOp.rs & 0x0f) >= 2 && (RspOp.rs & 0x0f) <= 7 && IsMmx2Enabled == FALSE) {
@ -247,20 +250,25 @@ DWORD WriteToAccum2 (int Location, int PC, BOOL RecursiveCall) {
case RSP_VECTOR_VMADL:
case RSP_VECTOR_VMADM:
case RSP_VECTOR_VMADN:
case RSP_VECTOR_VMADH:
return TRUE;
case RSP_VECTOR_VMADH:
if (Location == Low16BitAccum) { break; }
return TRUE;
case RSP_VECTOR_VABS:
case RSP_VECTOR_VADD:
case RSP_VECTOR_VADDC:
case RSP_VECTOR_VSUB:
case RSP_VECTOR_VSUBC:
case RSP_VECTOR_VAND:
case RSP_VECTOR_VNAND:
case RSP_VECTOR_VOR:
case RSP_VECTOR_VNOR:
case RSP_VECTOR_VXOR:
case RSP_VECTOR_VNXOR:
/* since these modify the accumulator lower-16 bits we can */
/* safely assume these 'reset' the accumulator no matter what */
return FALSE;
// return FALSE;
case RSP_VECTOR_VCR:
case RSP_VECTOR_VCH:
case RSP_VECTOR_VCL:
@ -272,12 +280,11 @@ DWORD WriteToAccum2 (int Location, int PC, BOOL RecursiveCall) {
case RSP_VECTOR_VLT:
case RSP_VECTOR_VEQ:
case RSP_VECTOR_VGE:
case RSP_VECTOR_VMRG:
case RSP_VECTOR_VMOV:
if (Location == Low16BitAccum) { return FALSE; }
break;
case RSP_VECTOR_VMOV:
case RSP_VECTOR_VMRG:
break;
case RSP_VECTOR_VSAW:
return TRUE;
default:

View File

@ -878,7 +878,7 @@ void CompilerRSPBlock ( void ) {
CompilePC += 4;
break;
}
} while ( NextInstruction != FINISH_BLOCK && CompilePC < 0x1000);
} while (NextInstruction != FINISH_BLOCK && (CompilePC < 0x1000 || NextInstruction == DELAY_SLOT));
CPU_Message("==== end of recompiled code ====");
if (Compiler.bReOrdering == TRUE) {

View File

@ -84,6 +84,9 @@ DWORD BranchCompare = 0;
# define CompileVaddc
# define CompileVsubc
# define CompileVmrg
# define CompileVnxor
# define CompileVnor
# define CompileVnand
#endif
#ifdef RSP_VectorLoads
# define CompileSqv /* Verified 12/17/2000 - Jabo */
@ -623,6 +626,7 @@ void Compile_LH ( void ) {
MoveVariableToX86reg(&RSP_GPR[RSPOpC.base].UW, GPR_Name(RSPOpC.base), x86_EBX);
if (Offset != 0) AddConstToX86Reg(x86_EBX, Offset);
AndConstToX86Reg(x86_EBX, 0x0fff);
TestConstToX86Reg(1, x86_EBX);
JneLabel32("Unaligned", 0);
Jump[0] = RecompPos - 4;
@ -639,7 +643,6 @@ void Compile_LH ( void ) {
CompilerToggleBuffer();
XorConstToX86Reg(x86_EBX, 2);
AndConstToX86Reg(x86_EBX, 0x0fff);
MoveSxN64MemToX86regHalf(x86_EAX, x86_EBX);
MoveX86regToVariable(x86_EAX, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt));
@ -676,6 +679,7 @@ void Compile_LW ( void ) {
MoveVariableToX86reg(&RSP_GPR[RSPOpC.base].UW, GPR_Name(RSPOpC.base), x86_EBX);
if (Offset != 0) AddConstToX86Reg(x86_EBX, Offset);
AndConstToX86Reg(x86_EBX, 0x0fff);
TestConstToX86Reg(3, x86_EBX);
JneLabel32("UnAligned", 0);
Jump[0] = RecompPos - 4;
@ -707,7 +711,6 @@ void Compile_LW ( void ) {
Jump[1] = RecompPos - 4;
CompilerToggleBuffer();
AndConstToX86Reg(x86_EBX, 0x0fff);
MoveN64MemToX86reg(x86_EAX, x86_EBX);
MoveX86regToVariable(x86_EAX, &RSP_GPR[RSPOpC.rt].UW, GPR_Name(RSPOpC.rt));
@ -893,6 +896,7 @@ void Compile_SW ( void ) {
MoveVariableToX86reg(&RSP_GPR[RSPOpC.base].UW, GPR_Name(RSPOpC.base), x86_EBX);
if (Offset != 0) AddConstToX86Reg(x86_EBX, Offset);
AndConstToX86Reg(x86_EBX, 0x0fff);
TestConstToX86Reg(3, x86_EBX);
JneLabel32("Unaligned", 0);
Jump[0] = RecompPos - 4;
@ -931,7 +935,6 @@ void Compile_SW ( void ) {
CompilerToggleBuffer();
AndConstToX86Reg(x86_EBX, 0x0fff);
if (RSPOpC.rt == 0) {
XorX86RegToX86Reg(x86_EAX,x86_EAX);
} else {
@ -3134,10 +3137,11 @@ void Compile_Vector_VADD ( void ) {
AdcX86RegToX86Reg(x86_EAX, x86_EBX);
if (bWriteToAccum == TRUE) {
MoveX86regHalfToVariable(x86_EAX, &RSP_ACCUM[el].HW[1], "RSP_ACCUM[el].HW[1]");
if (bWriteToAccum != FALSE) {
sprintf(Reg, "RSP_ACCUM[%i].HW[1]", el);
MoveX86regHalfToVariable(x86_EAX, &RSP_ACCUM[el].HW[1], Reg);
}
if (bWriteToDest == TRUE) {
if (bWriteToDest != FALSE) {
CompX86RegToX86Reg(x86_EAX, x86_ESI);
CondMoveGreater(x86_EAX, x86_ESI);
CompX86RegToX86Reg(x86_EAX, x86_EDI);
@ -3248,10 +3252,12 @@ void Compile_Vector_VSUB ( void ) {
SbbX86RegToX86Reg(x86_EAX, x86_EBX);
if (bWriteToAccum == TRUE) {
MoveX86regHalfToVariable(x86_EAX, &RSP_ACCUM[el].HW[1], "RSP_ACCUM[el].HW[1]");
if (bWriteToAccum != FALSE) {
sprintf(Reg, "RSP_ACCUM[%i].HW[1]", el);
MoveX86regHalfToVariable(x86_EAX, &RSP_ACCUM[el].HW[1], Reg);
}
if (bWriteToDest == TRUE) {
if (bWriteToDest != FALSE) {
CompX86RegToX86Reg(x86_EAX, x86_ESI);
CondMoveGreater(x86_EAX, x86_ESI);
CompX86RegToX86Reg(x86_EAX, x86_EDI);
@ -3408,10 +3414,12 @@ void Compile_Vector_VADDC ( void ) {
}
OrX86RegToX86Reg(x86_ECX, x86_EDX);
if (bWriteToAccum == TRUE) {
MoveX86regHalfToVariable(x86_EAX, &RSP_ACCUM[el].HW[1], "RSP_ACCUM[el].HW[1]");
if (bWriteToAccum != FALSE) {
sprintf(Reg, "RSP_ACCUM[%i].HW[1]", el);
MoveX86regHalfToVariable(x86_EAX, &RSP_ACCUM[el].HW[1], Reg);
}
if (bWriteToDest == TRUE) {
if (bWriteToDest != FALSE) {
sprintf(Reg, "RSP_Vect[%i].HW[%i]", RSPOpC.sa, el);
MoveX86regHalfToVariable(x86_EAX, &RSP_Vect[RSPOpC.sa].HW[el], Reg);
}
@ -3470,10 +3478,11 @@ void Compile_Vector_VSUBC ( void ) {
ShiftLeftSignImmed(x86_EDX, 7 - el);
OrX86RegToX86Reg(x86_ECX, x86_EDX);
if (bWriteToAccum == TRUE) {
MoveX86regHalfToVariable(x86_EAX, &RSP_ACCUM[el].HW[1], "RSP_ACCUM[el].HW[1]");
if (bWriteToAccum != FALSE) {
sprintf(Reg, "RSP_ACCUM[%i].HW[1]", el);
MoveX86regHalfToVariable(x86_EAX, &RSP_ACCUM[el].HW[1], Reg);
}
if (bWriteToDest == TRUE) {
if (bWriteToDest != FALSE) {
sprintf(Reg, "RSP_Vect[%i].HW[%i]", RSPOpC.sa, el);
MoveX86regHalfToVariable(x86_EAX, &RSP_Vect[RSPOpC.sa].HW[el], Reg);
}
@ -3546,7 +3555,7 @@ void Compile_Vector_VNE ( void ) {
Cheat_r4300iOpcode(RSP_Vector_VNE,"RSP_Vector_VNE");
}
BOOL Compile_Vector_VGE_MMX(void) {
BOOL Compile_Vector_VGE_MMX ( void ) {
char Reg[256];
if ((RSPOpC.rs & 0xF) >= 2 && (RSPOpC.rs & 0xF) <= 7 && IsMmx2Enabled == FALSE)
@ -3615,6 +3624,7 @@ void Compile_Vector_VCR ( void ) {
void Compile_Vector_VMRG ( void ) {
char Reg[256];
int count, el, del;
BOOL bWriteToAccum = WriteToAccum(Low16BitAccum, CompilePC);
#ifndef CompileVmrg
Cheat_r4300iOpcode(RSP_Vector_VMRG,"RSP_Vector_VMRG"); return;
@ -3637,6 +3647,10 @@ void Compile_Vector_VMRG ( void ) {
CondMoveNotEqual(x86_ECX, x86_EAX);
CondMoveEqual(x86_ECX, x86_EBX);
if (bWriteToAccum == TRUE) {
sprintf(Reg, "RSP_ACCUM[%i].HW[1]", el);
MoveX86regHalfToVariable(x86_ECX, &RSP_ACCUM[el].HW[1], Reg);
}
sprintf(Reg, "RSP_Vect[%i].HW[%i]", RSPOpC.sa, el);
MoveX86regHalfToVariable(x86_ECX, &RSP_Vect[RSPOpC.sa].HW[el], Reg);
}
@ -3685,6 +3699,7 @@ BOOL Compile_Vector_VAND_MMX ( void ) {
void Compile_Vector_VAND ( void ) {
char Reg[256];
int el, del, count;
BOOL bWriteToDest = WriteToVectorDest(RSPOpC.sa, CompilePC);
BOOL bElement = ((RSPOpC.rs & 0x0f) >= 8) ? TRUE : FALSE;
BOOL bWriteToAccum = WriteToAccum(Low16BitAccum, CompilePC);
@ -3721,18 +3736,113 @@ void Compile_Vector_VAND ( void ) {
AndX86RegHalfToX86RegHalf(x86_EAX, x86_EBX);
}
sprintf(Reg, "RSP_Vect[%i].HW[%i]", RSPOpC.sa, el);
MoveX86regHalfToVariable(x86_EAX, &RSP_Vect[RSPOpC.sa].HW[el], Reg);
if (bWriteToDest != FALSE) {
sprintf(Reg, "RSP_Vect[%i].HW[%i]", RSPOpC.sa, el);
MoveX86regHalfToVariable(x86_EAX, &RSP_Vect[RSPOpC.sa].HW[el], Reg);
}
if (bWriteToAccum != FALSE) {
sprintf(Reg, "RSP_ACCUM[el].HW[1]", el);
sprintf(Reg, "RSP_ACCUM[%i].HW[1]", el);
MoveX86regHalfToVariable(x86_EAX, &RSP_ACCUM[el].HW[1], Reg);
}
}
}
BOOL Compile_Vector_VNAND_MMX ( void ) {
char Reg[256];
/* Do our MMX checks here */
if (IsMmxEnabled == FALSE)
return FALSE;
if ((RSPOpC.rs & 0x0f) >= 2 && (RSPOpC.rs & 0x0f) <= 7 && IsMmx2Enabled == FALSE)
return FALSE;
sprintf(Reg, "RSP_Vect[%i].UHW[0]", RSPOpC.rd);
MmxMoveQwordVariableToReg(x86_MM0, &RSP_Vect[RSPOpC.rd].UHW[0], Reg);
sprintf(Reg, "RSP_Vect[%i].UHW[4]", RSPOpC.rd);
MmxMoveQwordVariableToReg(x86_MM1, &RSP_Vect[RSPOpC.rd].UHW[4], Reg);
MmxPcmpeqwRegToReg(x86_MM7, x86_MM7);
if ((RSPOpC.rs & 0xF) >= 8) {
RSP_Element2Mmx(x86_MM2);
MmxPandRegToReg(x86_MM0, x86_MM2);
MmxPandRegToReg(x86_MM1, x86_MM2);
} else if ((RSPOpC.rs & 0xF) < 2) {
sprintf(Reg, "RSP_Vect[%i].HW[0]", RSPOpC.rt);
MmxPandVariableToReg(&RSP_Vect[RSPOpC.rt].HW[0], Reg, x86_MM0);
sprintf(Reg, "RSP_Vect[%i].HW[4]", RSPOpC.rt);
MmxPandVariableToReg(&RSP_Vect[RSPOpC.rt].HW[4], Reg, x86_MM1);
} else {
RSP_MultiElement2Mmx(x86_MM2, x86_MM3);
MmxPandRegToReg(x86_MM0, x86_MM2);
MmxPandRegToReg(x86_MM1, x86_MM3);
}
MmxXorRegToReg(x86_MM0, x86_MM7);
MmxXorRegToReg(x86_MM1, x86_MM7);
sprintf(Reg, "RSP_Vect[%i].UHW[0]", RSPOpC.sa);
MmxMoveQwordRegToVariable(x86_MM0, &RSP_Vect[RSPOpC.sa].UHW[0], Reg);
sprintf(Reg, "RSP_Vect[%i].UHW[4]", RSPOpC.sa);
MmxMoveQwordRegToVariable(x86_MM1, &RSP_Vect[RSPOpC.sa].UHW[4], Reg);
if (IsNextInstructionMmx(CompilePC) == FALSE)
MmxEmptyMultimediaState();
return TRUE;
}
void Compile_Vector_VNAND ( void ) {
Cheat_r4300iOpcode(RSP_Vector_VNAND,"RSP_Vector_VNAND");
char Reg[256];
int el, del, count;
BOOL bWriteToDest = WriteToVectorDest(RSPOpC.sa, CompilePC);
BOOL bElement = ((RSPOpC.rs & 0x0f) >= 8) ? TRUE : FALSE;
BOOL bWriteToAccum = WriteToAccum(Low16BitAccum, CompilePC);
#ifndef CompileVnand
Cheat_r4300iOpcode(RSP_Vector_VNAND, "RSP_Vector_VNAND"); return;
#endif
CPU_Message(" %X %s", CompilePC, RSPOpcodeName(RSPOpC.Hex, CompilePC));
if (bWriteToAccum == FALSE) {
if (TRUE == Compile_Vector_VNAND_MMX())
return;
}
if (bElement == TRUE) {
del = (RSPOpC.rs & 0x07) ^ 7;
sprintf(Reg, "RSP_Vect[%i].HW[%i]", RSPOpC.rt, del);
MoveVariableToX86regHalf(&RSP_Vect[RSPOpC.rt].HW[del], Reg, x86_EBX);
}
for (count = 0; count < 8; count++) {
el = Indx[RSPOpC.rs].B[count];
del = EleSpec[RSPOpC.rs].B[el];
CPU_Message(" Iteration: %i", count);
sprintf(Reg, "RSP_Vect[%i].HW[%i]", RSPOpC.rd, el);
MoveVariableToX86regHalf(&RSP_Vect[RSPOpC.rd].HW[el], Reg, x86_EAX);
if (bElement == FALSE) {
sprintf(Reg, "RSP_Vect[%i].HW[%i]", RSPOpC.rt, del);
AndVariableToX86regHalf(&RSP_Vect[RSPOpC.rt].HW[del], Reg, x86_EAX);
} else {
AndX86RegHalfToX86RegHalf(x86_EAX, x86_EBX);
}
NotX86reg(x86_EAX);
if (bWriteToDest != FALSE) {
sprintf(Reg, "RSP_Vect[%i].HW[%i]", RSPOpC.sa, el);
MoveX86regHalfToVariable(x86_EAX, &RSP_Vect[RSPOpC.sa].HW[el], Reg);
}
if (bWriteToAccum != FALSE) {
sprintf(Reg, "RSP_ACCUM[%i].HW[1]", el);
MoveX86regHalfToVariable(x86_EAX, &RSP_ACCUM[el].HW[1], Reg);
}
}
}
BOOL Compile_Vector_VOR_MMX ( void ) {
@ -3749,7 +3859,9 @@ BOOL Compile_Vector_VOR_MMX ( void ) {
sprintf(Reg, "RSP_Vect[%i].UHW[4]", RSPOpC.rd);
MmxMoveQwordVariableToReg(x86_MM1, &RSP_Vect[RSPOpC.rd].UHW[4], Reg);
if ((RSPOpC.rs & 0xF) >= 8) {
if ((RSPOpC.rs & 0xF) < 2 && (RSPOpC.rd == RSPOpC.rt)) {
} else if ((RSPOpC.rs & 0xF) >= 8) {
RSP_Element2Mmx(x86_MM2);
MmxPorRegToReg(x86_MM0, x86_MM2);
MmxPorRegToReg(x86_MM1, x86_MM2);
@ -3781,11 +3893,11 @@ void Compile_Vector_VOR ( void ) {
BOOL bElement = ((RSPOpC.rs & 0x0f) >= 8) ? TRUE : FALSE;
BOOL bWriteToAccum = WriteToAccum(Low16BitAccum, CompilePC);
#ifndef CompileVor
Cheat_r4300iOpcode(RSP_Vector_VOR,"RSP_Vector_VOR"); return;
#endif
#ifndef CompileVor
Cheat_r4300iOpcode(RSP_Vector_VOR, "RSP_Vector_VOR"); return;
#endif
CPU_Message(" %X %s",CompilePC,RSPOpcodeName(RSPOpC.Hex,CompilePC));
CPU_Message(" %X %s", CompilePC, RSPOpcodeName(RSPOpC.Hex, CompilePC));
if (bWriteToAccum == FALSE) {
if (TRUE == Compile_Vector_VOR_MMX())
@ -3806,7 +3918,7 @@ void Compile_Vector_VOR ( void ) {
sprintf(Reg, "RSP_Vect[%i].HW[%i]", RSPOpC.rd, el);
MoveVariableToX86regHalf(&RSP_Vect[RSPOpC.rd].HW[el], Reg, x86_EAX);
if (bElement == FALSE) {
sprintf(Reg, "RSP_Vect[%i].HW[%i]", RSPOpC.rt, del);
OrVariableToX86regHalf(&RSP_Vect[RSPOpC.rt].HW[del], Reg, x86_EAX);
@ -3814,8 +3926,8 @@ void Compile_Vector_VOR ( void ) {
OrX86RegToX86Reg(x86_EAX, x86_EBX);
}
if (bWriteToAccum == TRUE) {
sprintf(Reg, "RSP_ACCUM[el].HW[1]", el);
if (bWriteToAccum != FALSE) {
sprintf(Reg, "RSP_ACCUM[%i].HW[1]", el);
MoveX86regHalfToVariable(x86_EAX, &RSP_ACCUM[el].HW[1], Reg);
}
sprintf(Reg, "RSP_Vect[%i].HW[%i]", RSPOpC.sa, el);
@ -3823,8 +3935,97 @@ void Compile_Vector_VOR ( void ) {
}
}
BOOL Compile_Vector_VNOR_MMX ( void ) {
char Reg[256];
/* Do our MMX checks here */
if (IsMmxEnabled == FALSE)
return FALSE;
if ((RSPOpC.rs & 0x0f) >= 2 && (RSPOpC.rs & 0x0f) <= 7 && IsMmx2Enabled == FALSE)
return FALSE;
sprintf(Reg, "RSP_Vect[%i].UHW[0]", RSPOpC.rd);
MmxMoveQwordVariableToReg(x86_MM0, &RSP_Vect[RSPOpC.rd].UHW[0], Reg);
sprintf(Reg, "RSP_Vect[%i].UHW[4]", RSPOpC.rd);
MmxMoveQwordVariableToReg(x86_MM1, &RSP_Vect[RSPOpC.rd].UHW[4], Reg);
MmxPcmpeqwRegToReg(x86_MM7, x86_MM7);
if ((RSPOpC.rs & 0xF) >= 8) {
RSP_Element2Mmx(x86_MM2);
MmxPorRegToReg(x86_MM0, x86_MM2);
MmxPorRegToReg(x86_MM1, x86_MM2);
} else if ((RSPOpC.rs & 0xF) < 2) {
sprintf(Reg, "RSP_Vect[%i].HW[0]", RSPOpC.rt);
MmxPorVariableToReg(&RSP_Vect[RSPOpC.rt].HW[0], Reg, x86_MM0);
sprintf(Reg, "RSP_Vect[%i].HW[4]", RSPOpC.rt);
MmxPorVariableToReg(&RSP_Vect[RSPOpC.rt].HW[4], Reg, x86_MM1);
} else {
RSP_MultiElement2Mmx(x86_MM2, x86_MM3);
MmxPorRegToReg(x86_MM0, x86_MM2);
MmxPorRegToReg(x86_MM1, x86_MM3);
}
MmxXorRegToReg(x86_MM0, x86_MM7);
MmxXorRegToReg(x86_MM1, x86_MM7);
sprintf(Reg, "RSP_Vect[%i].UHW[0]", RSPOpC.sa);
MmxMoveQwordRegToVariable(x86_MM0, &RSP_Vect[RSPOpC.sa].UHW[0], Reg);
sprintf(Reg, "RSP_Vect[%i].UHW[4]", RSPOpC.sa);
MmxMoveQwordRegToVariable(x86_MM1, &RSP_Vect[RSPOpC.sa].UHW[4], Reg);
if (IsNextInstructionMmx(CompilePC) == FALSE)
MmxEmptyMultimediaState();
return TRUE;
}
void Compile_Vector_VNOR ( void ) {
Cheat_r4300iOpcode(RSP_Vector_VNOR,"RSP_Vector_VNOR");
char Reg[256];
int el, del, count;
BOOL bElement = ((RSPOpC.rs & 0x0f) >= 8) ? TRUE : FALSE;
BOOL bWriteToAccum = WriteToAccum(Low16BitAccum, CompilePC);
#ifndef CompileVnor
Cheat_r4300iOpcode(RSP_Vector_VNOR, "RSP_Vector_VNOR"); return;
#endif
CPU_Message(" %X %s", CompilePC, RSPOpcodeName(RSPOpC.Hex, CompilePC));
if (bWriteToAccum == FALSE) {
if (TRUE == Compile_Vector_VNOR_MMX())
return;
}
if (bElement == TRUE) {
del = (RSPOpC.rs & 0x07) ^ 7;
sprintf(Reg, "RSP_Vect[%i].HW[%i]", RSPOpC.rt, del);
MoveVariableToX86regHalf(&RSP_Vect[RSPOpC.rt].HW[del], Reg, x86_EBX);
}
for (count = 0; count < 8; count++) {
el = Indx[RSPOpC.rs].B[count];
del = EleSpec[RSPOpC.rs].B[el];
CPU_Message(" Iteration: %i", count);
sprintf(Reg, "RSP_Vect[%i].HW[%i]", RSPOpC.rd, el);
MoveVariableToX86regHalf(&RSP_Vect[RSPOpC.rd].HW[el], Reg, x86_EAX);
if (bElement == FALSE) {
sprintf(Reg, "RSP_Vect[%i].HW[%i]", RSPOpC.rt, del);
OrVariableToX86regHalf(&RSP_Vect[RSPOpC.rt].HW[del], Reg, x86_EAX);
} else {
OrX86RegToX86Reg(x86_EAX, x86_EBX);
}
NotX86reg(x86_EAX);
if (bWriteToAccum != FALSE) {
sprintf(Reg, "RSP_ACCUM[%i].HW[1]", el);
MoveX86regHalfToVariable(x86_EAX, &RSP_ACCUM[el].HW[1], Reg);
}
sprintf(Reg, "RSP_Vect[%i].HW[%i]", RSPOpC.sa, el);
MoveX86regHalfToVariable(x86_EAX, &RSP_Vect[RSPOpC.sa].HW[el], Reg);
}
}
BOOL Compile_Vector_VXOR_MMX ( void ) {
@ -3845,7 +4046,7 @@ BOOL Compile_Vector_VXOR_MMX ( void ) {
sprintf(Reg, "RSP_Vect[%i].UHW[4]", RSPOpC.sa);
MmxMoveQwordRegToVariable(VXOR_DynaRegCount, &RSP_Vect[RSPOpC.sa].UHW[4], Reg);
VXOR_DynaRegCount = (VXOR_DynaRegCount + 1) & 7;
} else {
} else {
sprintf(Reg, "RSP_Vect[%i].UHW[0]", RSPOpC.rd);
MmxMoveQwordVariableToReg(x86_MM0, &RSP_Vect[RSPOpC.rd].UHW[0], Reg);
sprintf(Reg, "RSP_Vect[%i].UHW[4]", RSPOpC.rd);
@ -3881,33 +4082,111 @@ BOOL Compile_Vector_VXOR_MMX ( void ) {
return TRUE;
}
void Compile_Vector_VXOR ( void ) {
void Compile_Vector_VXOR ( void ) {
#ifdef CompileVxor
char Reg[256];
DWORD count;
BOOL bWriteToAccum = WriteToAccum(Low16BitAccum, CompilePC);
char Reg[256];
DWORD count;
BOOL bWriteToAccum = WriteToAccum(Low16BitAccum, CompilePC);
CPU_Message(" %X %s",CompilePC,RSPOpcodeName(RSPOpC.Hex,CompilePC));
if (!bWriteToAccum || ((RSPOpC.rs & 0xF) < 2 && RSPOpC.rd == RSPOpC.rt)) {
if (TRUE == Compile_Vector_VXOR_MMX()) {
if (bWriteToAccum == TRUE) {
XorX86RegToX86Reg(x86_EAX, x86_EAX);
for (count = 0; count < 8; count++) {
sprintf(Reg, "RSP_ACCUM[%i].HW[1]", count);
MoveX86regHalfToVariable(x86_EAX, &RSP_ACCUM[count].HW[1], Reg);
CPU_Message(" %X %s", CompilePC, RSPOpcodeName(RSPOpC.Hex, CompilePC));
if (!bWriteToAccum || ((RSPOpC.rs & 0xF) < 2 && RSPOpC.rd == RSPOpC.rt)) {
if (TRUE == Compile_Vector_VXOR_MMX()) {
if (bWriteToAccum == TRUE) {
XorX86RegToX86Reg(x86_EAX, x86_EAX);
for (count = 0; count < 8; count++) {
sprintf(Reg, "RSP_ACCUM[%i].HW[1]", count);
MoveX86regHalfToVariable(x86_EAX, &RSP_ACCUM[count].HW[1], Reg);
}
}
return;
}
return;
}
}
#endif
Cheat_r4300iOpcodeNoMessage(RSP_Vector_VXOR,"RSP_Vector_VXOR");
Cheat_r4300iOpcodeNoMessage(RSP_Vector_VXOR, "RSP_Vector_VXOR");
}
BOOL Compile_Vector_VNXOR_MMX ( void ) {
char Reg[256];
/* Do our MMX checks here */
if (IsMmxEnabled == FALSE)
return FALSE;
if ((RSPOpC.rs & 0x0f) >= 2 && (RSPOpC.rs & 0x0f) <= 7 && IsMmx2Enabled == FALSE)
return FALSE;
if ((RSPOpC.rs & 0xF) < 2 && (RSPOpC.rd == RSPOpC.rt)) {
static DWORD VNXOR_DynaRegCount = 0;
MmxPcmpeqwRegToReg(VNXOR_DynaRegCount, VNXOR_DynaRegCount);
sprintf(Reg, "RSP_Vect[%i].UHW[0]", RSPOpC.sa);
MmxMoveQwordRegToVariable(VNXOR_DynaRegCount, &RSP_Vect[RSPOpC.sa].UHW[0], Reg);
sprintf(Reg, "RSP_Vect[%i].UHW[4]", RSPOpC.sa);
MmxMoveQwordRegToVariable(VNXOR_DynaRegCount, &RSP_Vect[RSPOpC.sa].UHW[4], Reg);
VNXOR_DynaRegCount = (VNXOR_DynaRegCount + 1) & 7;
} else {
sprintf(Reg, "RSP_Vect[%i].UHW[0]", RSPOpC.rd);
MmxMoveQwordVariableToReg(x86_MM0, &RSP_Vect[RSPOpC.rd].UHW[0], Reg);
sprintf(Reg, "RSP_Vect[%i].UHW[4]", RSPOpC.rd);
MmxMoveQwordVariableToReg(x86_MM1, &RSP_Vect[RSPOpC.rd].UHW[4], Reg);
MmxPcmpeqwRegToReg(x86_MM7, x86_MM7);
if ((RSPOpC.rs & 0xF) >= 8) {
RSP_Element2Mmx(x86_MM2);
MmxXorRegToReg(x86_MM0, x86_MM2);
MmxXorRegToReg(x86_MM1, x86_MM2);
} else if ((RSPOpC.rs & 0xF) < 2) {
sprintf(Reg, "RSP_Vect[%i].HW[0]", RSPOpC.rt);
MmxMoveQwordVariableToReg(x86_MM2, &RSP_Vect[RSPOpC.rt].HW[0], Reg);
sprintf(Reg, "RSP_Vect[%i].HW[4]", RSPOpC.rt);
MmxMoveQwordVariableToReg(x86_MM3, &RSP_Vect[RSPOpC.rt].HW[4], Reg);
MmxXorRegToReg(x86_MM0, x86_MM2);
MmxXorRegToReg(x86_MM1, x86_MM3);
} else {
RSP_MultiElement2Mmx(x86_MM2, x86_MM3);
MmxXorRegToReg(x86_MM0, x86_MM2);
MmxXorRegToReg(x86_MM1, x86_MM3);
}
MmxXorRegToReg(x86_MM0, x86_MM7);
MmxXorRegToReg(x86_MM1, x86_MM7);
sprintf(Reg, "RSP_Vect[%i].UHW[0]", RSPOpC.sa);
MmxMoveQwordRegToVariable(x86_MM0, &RSP_Vect[RSPOpC.sa].UHW[0], Reg);
sprintf(Reg, "RSP_Vect[%i].UHW[4]", RSPOpC.sa);
MmxMoveQwordRegToVariable(x86_MM1, &RSP_Vect[RSPOpC.sa].UHW[4], Reg);
}
if (IsNextInstructionMmx(CompilePC) == FALSE)
MmxEmptyMultimediaState();
return TRUE;
}
void Compile_Vector_VNXOR ( void ) {
Cheat_r4300iOpcode(RSP_Vector_VNXOR,"RSP_Vector_VNXOR");
#ifdef CompileVnxor
char Reg[256];
DWORD count;
BOOL bWriteToAccum = WriteToAccum(Low16BitAccum, CompilePC);
CPU_Message(" %X %s", CompilePC, RSPOpcodeName(RSPOpC.Hex, CompilePC));
if (!bWriteToAccum || ((RSPOpC.rs & 0xF) < 2 && RSPOpC.rd == RSPOpC.rt)) {
if (TRUE == Compile_Vector_VNXOR_MMX()) {
if (bWriteToAccum == TRUE) {
OrConstToX86Reg(0xFFFFFFFF, x86_EAX);
for (count = 0; count < 8; count++) {
sprintf(Reg, "RSP_ACCUM[%i].HW[1]", count);
MoveX86regHalfToVariable(x86_EAX, &RSP_ACCUM[count].HW[1], Reg);
}
}
return;
}
}
#endif
Cheat_r4300iOpcode(RSP_Vector_VNXOR, "RSP_Vector_VNXOR");
}
void Compile_Vector_VRCP ( void ) {
@ -3959,13 +4238,22 @@ void Compile_Vector_VRCPH ( void ) {
void Compile_Vector_VMOV ( void ) {
char Reg[256];
int el;
int el, count;
BOOL bWriteToAccum = WriteToAccum(Low16BitAccum, CompilePC);
#ifndef CompileVmov
Cheat_r4300iOpcode(RSP_Vector_VMOV, "RSP_Vector_VMOV"); return;
#endif
#ifndef CompileVmov
Cheat_r4300iOpcode(RSP_Vector_VMOV,"RSP_Vector_VMOV"); return;
#endif
CPU_Message(" %X %s", CompilePC, RSPOpcodeName(RSPOpC.Hex, CompilePC));
CPU_Message(" %X %s",CompilePC,RSPOpcodeName(RSPOpC.Hex,CompilePC));
if (bWriteToAccum){
for (count = 0; count < 8; count++) {
sprintf(Reg, "RSP_Vect[%i].UHW[%i]", RSPOpC.rt, EleSpec[RSPOpC.rs].B[count]);
MoveVariableToX86regHalf(&RSP_Vect[RSPOpC.rt].UHW[EleSpec[RSPOpC.rs].B[count]], Reg, x86_EAX);
sprintf(Reg, "RSP_ACCUM[%i].HW[1]", count);
MoveX86regHalfToVariable(x86_EAX, &RSP_ACCUM[count].HW[1], Reg);
}
}
el = EleSpec[RSPOpC.rs].B[(RSPOpC.rd & 0x7)];
sprintf(Reg, "RSP_Vect[%i].UHW[%i]", RSPOpC.rt, el);
@ -4186,10 +4474,10 @@ void Compile_Opcode_LDV ( void ) {
sprintf(Reg, "Dmem + %Xh", Addr + 4);
MoveVariableToX86reg(RSPInfo.DMEM + Addr + 4, Reg, x86_ECX);
sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, 16 - RSPOpC.del - 4);
MoveX86regToVariable(x86_EAX, &RSP_Vect[RSPOpC.rt].B[16 - RSPOpC.del - 4], Reg);
sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, 16 - RSPOpC.del - 8);
MoveX86regToVariable(x86_ECX, &RSP_Vect[RSPOpC.rt].B[16 - RSPOpC.del - 8], Reg);
sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, (16 - RSPOpC.del - 4) & 0xF);
MoveX86regToVariable(x86_EAX, &RSP_Vect[RSPOpC.rt].B[(16 - RSPOpC.del - 4) & 0xF], Reg);
sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, (16 - RSPOpC.del - 8) & 0xF);
MoveX86regToVariable(x86_ECX, &RSP_Vect[RSPOpC.rt].B[(16 - RSPOpC.del - 8) & 0xF], Reg);
return;
}
@ -4238,10 +4526,10 @@ void Compile_Opcode_LDV ( void ) {
MoveN64MemDispToX86reg(x86_ECX, x86_EBX, 4);
/* Because of byte swapping this swizzle works nicely */
sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, 16 - RSPOpC.del - 4);
MoveX86regToVariable(x86_EAX, &RSP_Vect[RSPOpC.rt].B[16 - RSPOpC.del - 4], Reg);
sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, 16 - RSPOpC.del - 8);
MoveX86regToVariable(x86_ECX, &RSP_Vect[RSPOpC.rt].B[16 - RSPOpC.del - 8], Reg);
sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, (16 - RSPOpC.del - 4) & 0xF);
MoveX86regToVariable(x86_EAX, &RSP_Vect[RSPOpC.rt].B[(16 - RSPOpC.del - 4) & 0xF], Reg);
sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, (16 - RSPOpC.del - 8) & 0xF);
MoveX86regToVariable(x86_ECX, &RSP_Vect[RSPOpC.rt].B[(16 - RSPOpC.del - 8) & 0xF], Reg);
CPU_Message(" Done:");
x86_SetBranch32b(Jump[1], RecompPos);
@ -4587,25 +4875,25 @@ void Compile_Opcode_SDV ( void ) {
// return;
//}
#ifndef CompileSdv
Cheat_r4300iOpcode(RSP_Opcode_SDV,"RSP_Opcode_SDV"); return;
#endif
CPU_Message(" %X %s",CompilePC,RSPOpcodeName(RSPOpC.Hex,CompilePC));
#ifndef CompileSdv
Cheat_r4300iOpcode(RSP_Opcode_SDV, "RSP_Opcode_SDV"); return;
#endif
CPU_Message(" %X %s", CompilePC, RSPOpcodeName(RSPOpC.Hex, CompilePC));
if (IsRegConst(RSPOpC.base) == TRUE) {
DWORD Addr = (MipsRegConst(RSPOpC.base) + offset) & 0xfff;
if ((Addr & 3) != 0) {
CompilerWarning("Unaligned SDV at constant address PC = %04X", CompilePC);
Cheat_r4300iOpcodeNoMessage(RSP_Opcode_SDV,"RSP_Opcode_SDV");
Cheat_r4300iOpcodeNoMessage(RSP_Opcode_SDV, "RSP_Opcode_SDV");
return;
}
sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, 16 - RSPOpC.del - 4);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[16 - RSPOpC.del - 4], Reg, x86_EAX);
sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, 16 - RSPOpC.del - 8);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[16 - RSPOpC.del - 8], Reg, x86_EBX);
sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, (16 - RSPOpC.del - 4) & 0xF);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[(16 - RSPOpC.del - 4) & 0xF], Reg, x86_EAX);
sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, (16 - RSPOpC.del - 8) & 0xF);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[(16 - RSPOpC.del - 8) & 0xF], Reg, x86_EBX);
sprintf(Reg, "Dmem + %Xh", Addr);
MoveX86regToVariable(x86_EAX, RSPInfo.DMEM + Addr, Reg);
@ -4613,7 +4901,7 @@ void Compile_Opcode_SDV ( void ) {
MoveX86regToVariable(x86_EBX, RSPInfo.DMEM + Addr + 4, Reg);
return;
}
MoveVariableToX86reg(&RSP_GPR[RSPOpC.base].UW, GPR_Name(RSPOpC.base), x86_EBX);
if (offset != 0) {
AddConstToX86Reg(x86_EBX, offset);
@ -4622,11 +4910,11 @@ void Compile_Opcode_SDV ( void ) {
TestConstToX86Reg(3, x86_EBX);
JneLabel32("Unaligned", 0);
Jump[0] = RecompPos - 4;
CompilerToggleBuffer();
CPU_Message(" Unaligned:");
x86_SetBranch32b((DWORD*)Jump[0], (DWORD*)RecompPos);
sprintf(Reg, "RSP_Vect[%i].UB[%i]", RSPOpC.rt, 15 - RSPOpC.del);
MoveOffsetToX86reg((DWORD)&RSP_Vect[RSPOpC.rt].UB[15 - RSPOpC.del], Reg, x86_EDI);
MoveConstToX86reg(8, x86_ECX);
@ -4647,10 +4935,10 @@ void Compile_Opcode_SDV ( void ) {
Jump[1] = RecompPos - 4;
CompilerToggleBuffer();
sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, 16 - RSPOpC.del - 4);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[16 - RSPOpC.del - 4], Reg, x86_EAX);
sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, 16 - RSPOpC.del - 8);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[16 - RSPOpC.del - 8], Reg, x86_ECX);
sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, (16 - RSPOpC.del - 4) & 0xF);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[(16 - RSPOpC.del - 4) & 0xF], Reg, x86_EAX);
sprintf(Reg, "RSP_Vect[%i].B[%i]", RSPOpC.rt, (16 - RSPOpC.del - 8) & 0xF);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[(16 - RSPOpC.del - 8) & 0xF], Reg, x86_ECX);
MoveX86regToN64Mem(x86_EAX, x86_EBX);
MoveX86regToN64MemDisp(x86_ECX, x86_EBX, 4);
@ -4669,7 +4957,7 @@ void Compile_Opcode_SQV ( void ) {
CPU_Message(" %X %s",CompilePC,RSPOpcodeName(RSPOpC.Hex,CompilePC));
if (RSPOpC.del != 0) {
if (RSPOpC.del != 0 && RSPOpC.del != 12) {
rsp_UnknownOpcode();
return;
}
@ -4688,14 +4976,25 @@ void Compile_Opcode_SQV ( void ) {
*/
if (IsSseEnabled == FALSE) {
sprintf(Reg, "RSP_Vect[%i].B[12]", RSPOpC.rt);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[12], Reg, x86_EAX);
sprintf(Reg, "RSP_Vect[%i].B[8]", RSPOpC.rt);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[8], Reg, x86_EBX);
sprintf(Reg, "RSP_Vect[%i].B[4]", RSPOpC.rt);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[4], Reg, x86_ECX);
sprintf(Reg, "RSP_Vect[%i].B[0]", RSPOpC.rt);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[0], Reg, x86_EDX);
if (RSPOpC.del == 12) {
sprintf(Reg, "RSP_Vect[%i].B[0]", RSPOpC.rt);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[0], Reg, x86_EDX);
sprintf(Reg, "RSP_Vect[%i].B[12]", RSPOpC.rt);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[12], Reg, x86_EAX);
sprintf(Reg, "RSP_Vect[%i].B[8]", RSPOpC.rt);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[8], Reg, x86_EBX);
sprintf(Reg, "RSP_Vect[%i].B[4]", RSPOpC.rt);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[4], Reg, x86_ECX);
} else {
sprintf(Reg, "RSP_Vect[%i].B[12]", RSPOpC.rt);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[12], Reg, x86_EAX);
sprintf(Reg, "RSP_Vect[%i].B[8]", RSPOpC.rt);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[8], Reg, x86_EBX);
sprintf(Reg, "RSP_Vect[%i].B[4]", RSPOpC.rt);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[4], Reg, x86_ECX);
sprintf(Reg, "RSP_Vect[%i].B[0]", RSPOpC.rt);
MoveVariableToX86reg(&RSP_Vect[RSPOpC.rt].B[0], Reg, x86_EDX);
}
sprintf(Reg, "Dmem+%Xh+0", Addr);
MoveX86regToVariable(x86_EAX, RSPInfo.DMEM + Addr + 0, Reg);
@ -4708,7 +5007,11 @@ void Compile_Opcode_SQV ( void ) {
} else {
sprintf(Reg, "RSP_Vect[%i].B[0]", RSPOpC.rt);
SseMoveAlignedVariableToReg(&RSP_Vect[RSPOpC.rt].B[0], Reg, x86_XMM0);
SseShuffleReg(x86_XMM0, x86_MM0, 0x1b);
if (RSPOpC.del == 12) {
SseShuffleReg(x86_XMM0, x86_MM0, 0x6c);
} else {
SseShuffleReg(x86_XMM0, x86_MM0, 0x1b);
}
sprintf(Reg, "Dmem+%Xh", Addr);
SseMoveUnalignedRegToVariable(x86_XMM0, RSPInfo.DMEM + Addr, Reg);
}

View File

@ -294,7 +294,7 @@ void SseXorRegToReg(int Dest, int Source) {
case x86_XMM4: x86Command = 0x20; break;
case x86_XMM5: x86Command = 0x28; break;
case x86_XMM6: x86Command = 0x30; break;
case x86_XMM7: x86Command = 0x28; break;
case x86_XMM7: x86Command = 0x38; break;
}
switch (Source) {
case x86_XMM0: x86Command += 0x00; break;

View File

@ -2071,6 +2071,22 @@ void NegateX86reg(int x86reg) {
}
}
void NotX86reg(int x86reg) {
CPU_Message(" not %s", x86_Name(x86reg));
switch (x86reg) {
case x86_EAX: PUTDST16(RecompPos, 0xd0f7); break;
case x86_EBX: PUTDST16(RecompPos, 0xd3f7); break;
case x86_ECX: PUTDST16(RecompPos, 0xd1f7); break;
case x86_EDX: PUTDST16(RecompPos, 0xd2f7); break;
case x86_ESI: PUTDST16(RecompPos, 0xd6f7); break;
case x86_EDI: PUTDST16(RecompPos, 0xd7f7); break;
case x86_ESP: PUTDST16(RecompPos, 0xd4f7); break;
case x86_EBP: PUTDST16(RecompPos, 0xd5f7); break;
default:
DisplayError("NotX86reg\nUnknown x86 Register");
}
}
void OrConstToVariable(DWORD Const, void * Variable, char * VariableName) {
CPU_Message(" or dword ptr [%s], 0x%X",VariableName, Const);
PUTDST16(RecompPos,0x0D81);

View File

@ -149,6 +149,7 @@ void MoveZxN64MemToX86regHalf ( int x86reg, int AddrReg );
void MoveZxVariableToX86regHalf ( void *Variable, char *VariableName, int x86reg );
void MulX86reg ( int x86reg );
void NegateX86reg ( int x86reg );
void NotX86reg ( int x86reg );
void OrConstToVariable ( DWORD Const, void * Variable, char * VariableName );
void OrConstToX86Reg ( DWORD Const, int x86Reg );
void OrVariableToX86Reg ( void * Variable, char * VariableName, int x86Reg );
@ -214,6 +215,7 @@ void MmxPorRegToReg ( int Dest, int Source );
void MmxPorVariableToReg ( void * Variable, char * VariableName, int Dest );
void MmxXorRegToReg ( int Dest, int Source );
void MmxShuffleMemoryToReg ( int Dest, void * Variable, char * VariableName, BYTE Immed );
void MmxPcmpeqwRegToReg ( int Dest, int Source );
void MmxPmullwRegToReg ( int Dest, int Source );
void MmxPmullwVariableToReg ( int Dest, void * Variable, char * VariableName );
void MmxPmulhuwRegToReg ( int Dest, int Source );