diff options
author | pixel <pixel> | 2004-11-27 21:44:15 +0000 |
---|---|---|
committer | pixel <pixel> | 2004-11-27 21:44:15 +0000 |
commit | 50f0dd331f8168fb5b2cd60c70178fad627b7fb6 (patch) | |
tree | 65fcec7bd507791f0db8a3af1b60ad9ac631f4a7 /lib | |
parent | f1df76865d1751469deff19e62255d50a814f183 (diff) |
Large dos2unix commit...
Diffstat (limited to 'lib')
-rw-r--r-- | lib/cdabstract.cpp | 384 | ||||
-rw-r--r-- | lib/cdreader.cpp | 668 | ||||
-rw-r--r-- | lib/dteutils.cpp | 638 | ||||
-rw-r--r-- | lib/luapsx.cpp | 614 | ||||
-rw-r--r-- | lib/lzss.cpp | 928 | ||||
-rw-r--r-- | lib/mips.cpp | 2136 | ||||
-rw-r--r-- | lib/mipsdis.cpp | 360 | ||||
-rw-r--r-- | lib/mipsdump.cpp | 414 | ||||
-rw-r--r-- | lib/mipsmem.cpp | 698 | ||||
-rw-r--r-- | lib/mipsobj.cpp | 538 | ||||
-rw-r--r-- | lib/yazedc.cpp | 546 |
11 files changed, 3962 insertions, 3962 deletions
diff --git a/lib/cdabstract.cpp b/lib/cdabstract.cpp index ff438c4..ceb5f70 100644 --- a/lib/cdabstract.cpp +++ b/lib/cdabstract.cpp @@ -1,192 +1,192 @@ -/* - * PSX-Tools Bundle Pack - * Copyright (C) 2002-2003 Nicolas "Pixel" Noble - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* $Id: cdabstract.cpp,v 1.7 2003-12-11 16:53:43 pixel Exp $ */ - -#include "cdabstract.h" -#include "Input.h" -#include "cdreader.h" - -#ifdef __linux__ -#include <unistd.h> -#include <sys/ioctl.h> -#include <fcntl.h> -#include <linux/cdrom.h> -#endif - -#if defined (_MSC_VER) || defined (__MINGW32__) -#include <windowsx.h> -#endif - -Handle * cdabstract::open_cd(const String & nom) { - if (nom.extract(0, 2).toupper() == "CD:") { - return new cdreader(nom.extract(3)); - } else { - return new Input(nom); - } -} - -bool cdabstract::canprobe() { -#ifdef __linux__ - return true; -#endif -#ifdef _WIN32 - OSVERSIONINFO ov; - memset(&ov, 0, sizeof(OSVERSIONINFO)); - ov.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - - GetVersionEx(&ov); - - return ((ov.dwPlatformId == VER_PLATFORM_WIN32_NT) && (ov.dwMajorVersion > 4)); -#endif - return false; -} - -std::vector<String> cdabstract::probe() throw (GeneralException) { - int i; - std::vector<String> r; - String probed; - - if (!canprobe()) - throw GeneralException("Can't probe CD devices on this platform."); - -#ifdef __linux__ - if (subprobe(probed = "/dev/cdrom")) - r.push_back(probed); - - for (i = 0; i < 63; i++) { - probed.set("/dev/cdroms/cdrom%i", i); - if (subprobe(probed)) - r.push_back(probed); - } - for (i = 'a'; i <= 'z'; i++) { - probed.set("/dev/hd%c", i); - if (subprobe(probed)) - r.push_back(probed); - } -#endif - -#ifdef _WIN32 - for (i = 'A'; i <= 'Z'; i++) { - probed.set("%c:\\", i); - if (subprobe(probed)) - r.push_back(probed); - } -#endif - - return r; -} - -#ifdef _WIN32 -HANDLE cdabstract::OpenIOCTLFile(char cLetter) { - HANDLE hF; - char szFName[16]; - OSVERSIONINFO ov; - DWORD dwFlags; - DWORD dwIOCTLAttr = 0; - - memset(&ov, 0, sizeof(OSVERSIONINFO)); - ov.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&ov); - - if((ov.dwPlatformId == VER_PLATFORM_WIN32_NT) && (ov.dwMajorVersion > 4)) - dwFlags = GENERIC_READ | GENERIC_WRITE; // add gen write on W2k/XP - else dwFlags = GENERIC_READ; - - sprintf(szFName, "\\\\.\\%c:", cLetter); - - hF = CreateFile(szFName, dwFlags, FILE_SHARE_READ, // open drive - NULL, OPEN_EXISTING, dwIOCTLAttr, NULL); - - if (hF == INVALID_HANDLE_VALUE) { // mmm... no success? - dwFlags ^= GENERIC_WRITE; // -> try write toggle - hF = CreateFile(szFName, dwFlags, FILE_SHARE_READ, // -> open drive again - NULL, OPEN_EXISTING, dwIOCTLAttr, NULL); - if (hF == INVALID_HANDLE_VALUE) - return NULL; - } - return hF; -} - -typedef struct { - ULONG Length; - UCHAR PortNumber; - UCHAR PathId; - UCHAR TargetId; - UCHAR Lun; -} SCSI_ADDRESS, *PSCSI_ADDRESS; - -void cdabstract::GetIOCTLAdapter(HANDLE hF, int * iDA, int * iDT, int * iDL) { - char szBuf[1024]; - PSCSI_ADDRESS pSA; - DWORD dwRet; - - *iDA = *iDT = *iDL = -1; - - if (hF == NULL) - return; - - memset(szBuf,0,1024); - - pSA = (PSCSI_ADDRESS)szBuf; - pSA->Length = sizeof(SCSI_ADDRESS); - - if (!DeviceIoControl(hF, IOCTL_SCSI_GET_ADDRESS, NULL, 0, pSA, - sizeof(SCSI_ADDRESS), &dwRet, NULL)) - return; - - *iDA = pSA->PortNumber; - *iDT = pSA->TargetId; - *iDL = pSA->Lun; -} -#endif - -bool cdabstract::subprobe(String & probed) { -#ifdef __linux__ - int h, caps; - - h = open(probed.to_charp(), O_RDONLY | O_NONBLOCK); - - if (ioctl(h, CDROM_GET_CAPABILITY, &caps) < 0) { - close(h); - return false; - } else { - close(h); - return true; - } -#endif - -#ifdef _WIN32 - int iDA, iDT, iDL; - char letter[4]; - HANDLE h; - - if (GetDriveType(probed.to_charp()) == DRIVE_CDROM) { - h = OpenIOCTLFile(probed[0]); - GetIOCTLAdapter(h, &iDA, &iDT, &iDL); - CloseHandle(h); - if ((iDA != -1) && (iDT != -1) && (iDL != -1)) { - probed += String().set(" [%i:%i:%i]", iDA, iDT, iDL); - return true; - } - } -#endif - - return false; -} +/*
+ * PSX-Tools Bundle Pack
+ * Copyright (C) 2002-2003 Nicolas "Pixel" Noble
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: cdabstract.cpp,v 1.8 2004-11-27 21:44:48 pixel Exp $ */
+
+#include "cdabstract.h"
+#include "Input.h"
+#include "cdreader.h"
+
+#ifdef __linux__
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <linux/cdrom.h>
+#endif
+
+#if defined (_MSC_VER) || defined (__MINGW32__)
+#include <windowsx.h>
+#endif
+
+Handle * cdabstract::open_cd(const String & nom) {
+ if (nom.extract(0, 2).toupper() == "CD:") {
+ return new cdreader(nom.extract(3));
+ } else {
+ return new Input(nom);
+ }
+}
+
+bool cdabstract::canprobe() {
+#ifdef __linux__
+ return true;
+#endif
+#ifdef _WIN32
+ OSVERSIONINFO ov;
+ memset(&ov, 0, sizeof(OSVERSIONINFO));
+ ov.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+
+ GetVersionEx(&ov);
+
+ return ((ov.dwPlatformId == VER_PLATFORM_WIN32_NT) && (ov.dwMajorVersion > 4));
+#endif
+ return false;
+}
+
+std::vector<String> cdabstract::probe() throw (GeneralException) {
+ int i;
+ std::vector<String> r;
+ String probed;
+
+ if (!canprobe())
+ throw GeneralException("Can't probe CD devices on this platform.");
+
+#ifdef __linux__
+ if (subprobe(probed = "/dev/cdrom"))
+ r.push_back(probed);
+
+ for (i = 0; i < 63; i++) {
+ probed.set("/dev/cdroms/cdrom%i", i);
+ if (subprobe(probed))
+ r.push_back(probed);
+ }
+ for (i = 'a'; i <= 'z'; i++) {
+ probed.set("/dev/hd%c", i);
+ if (subprobe(probed))
+ r.push_back(probed);
+ }
+#endif
+
+#ifdef _WIN32
+ for (i = 'A'; i <= 'Z'; i++) {
+ probed.set("%c:\\", i);
+ if (subprobe(probed))
+ r.push_back(probed);
+ }
+#endif
+
+ return r;
+}
+
+#ifdef _WIN32
+HANDLE cdabstract::OpenIOCTLFile(char cLetter) {
+ HANDLE hF;
+ char szFName[16];
+ OSVERSIONINFO ov;
+ DWORD dwFlags;
+ DWORD dwIOCTLAttr = 0;
+
+ memset(&ov, 0, sizeof(OSVERSIONINFO));
+ ov.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&ov);
+
+ if((ov.dwPlatformId == VER_PLATFORM_WIN32_NT) && (ov.dwMajorVersion > 4))
+ dwFlags = GENERIC_READ | GENERIC_WRITE; // add gen write on W2k/XP
+ else dwFlags = GENERIC_READ;
+
+ sprintf(szFName, "\\\\.\\%c:", cLetter);
+
+ hF = CreateFile(szFName, dwFlags, FILE_SHARE_READ, // open drive
+ NULL, OPEN_EXISTING, dwIOCTLAttr, NULL);
+
+ if (hF == INVALID_HANDLE_VALUE) { // mmm... no success?
+ dwFlags ^= GENERIC_WRITE; // -> try write toggle
+ hF = CreateFile(szFName, dwFlags, FILE_SHARE_READ, // -> open drive again
+ NULL, OPEN_EXISTING, dwIOCTLAttr, NULL);
+ if (hF == INVALID_HANDLE_VALUE)
+ return NULL;
+ }
+ return hF;
+}
+
+typedef struct {
+ ULONG Length;
+ UCHAR PortNumber;
+ UCHAR PathId;
+ UCHAR TargetId;
+ UCHAR Lun;
+} SCSI_ADDRESS, *PSCSI_ADDRESS;
+
+void cdabstract::GetIOCTLAdapter(HANDLE hF, int * iDA, int * iDT, int * iDL) {
+ char szBuf[1024];
+ PSCSI_ADDRESS pSA;
+ DWORD dwRet;
+
+ *iDA = *iDT = *iDL = -1;
+
+ if (hF == NULL)
+ return;
+
+ memset(szBuf,0,1024);
+
+ pSA = (PSCSI_ADDRESS)szBuf;
+ pSA->Length = sizeof(SCSI_ADDRESS);
+
+ if (!DeviceIoControl(hF, IOCTL_SCSI_GET_ADDRESS, NULL, 0, pSA,
+ sizeof(SCSI_ADDRESS), &dwRet, NULL))
+ return;
+
+ *iDA = pSA->PortNumber;
+ *iDT = pSA->TargetId;
+ *iDL = pSA->Lun;
+}
+#endif
+
+bool cdabstract::subprobe(String & probed) {
+#ifdef __linux__
+ int h, caps;
+
+ h = open(probed.to_charp(), O_RDONLY | O_NONBLOCK);
+
+ if (ioctl(h, CDROM_GET_CAPABILITY, &caps) < 0) {
+ close(h);
+ return false;
+ } else {
+ close(h);
+ return true;
+ }
+#endif
+
+#ifdef _WIN32
+ int iDA, iDT, iDL;
+ char letter[4];
+ HANDLE h;
+
+ if (GetDriveType(probed.to_charp()) == DRIVE_CDROM) {
+ h = OpenIOCTLFile(probed[0]);
+ GetIOCTLAdapter(h, &iDA, &iDT, &iDL);
+ CloseHandle(h);
+ if ((iDA != -1) && (iDT != -1) && (iDL != -1)) {
+ probed += String().set(" [%i:%i:%i]", iDA, iDT, iDL);
+ return true;
+ }
+ }
+#endif
+
+ return false;
+}
diff --git a/lib/cdreader.cpp b/lib/cdreader.cpp index 83bd1b3..7777c4d 100644 --- a/lib/cdreader.cpp +++ b/lib/cdreader.cpp @@ -1,334 +1,334 @@ -/* - * PSX-Tools Bundle Pack - * Copyright (C) 2002-2003 Nicolas "Pixel" Noble - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* $Id: cdreader.cpp,v 1.19 2003-12-26 19:05:31 pixel Exp $ */ - -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include "cdreader.h" -#include "Exceptions.h" -#include "generic.h" -#ifdef HAVE_CONFIG_H -#include "config.h" -#else -#define _(x) x -#endif -#include "cdabstract.h" - -#define nsectorsarow 1 -#define cachesize 2048 - -bool cdreader::CanWrite() const { - return 0; -} - -bool cdreader::CanRead() const { - return 1; -} - -bool cdreader::CanSeek() const { - return 1; -} - -String cdreader::GetName() const { - return n + " raw reading"; -} - -ssize_t cdreader::GetSize() const { - return -1; -} - -off_t cdreader::seek(off_t offset, int whence) throw (GeneralException) { - switch (whence) { - case SEEK_SET: - itell = offset; - break; - case SEEK_CUR: - itell += offset; - break; - case SEEK_END: - throw GeneralException("Can not yet seek from the end of a CD."); - } - return itell; -} - -ssize_t cdreader::read(void *buf, size_t count) throw (GeneralException) { - char sector[2352]; - size_t r = count; - - size_t remain = itell % 2352; - sectorseek(itell / 2352); - - while (count > 0) { - size_t n = MIN(2352 - remain, count); - fetchsector(sector); - bcopy(sector + remain, buf, n); - buf = ((char *) buf) + n; - itell += n; - count -= n; - remain = 0; - } - - return r; -} - -void cdreader::sectorseek(int sec) { - sector = sec; -} - -void cdreader::fetchsector(void * buf, int sec) { - if (sec >= 0) - sector = sec; - - if (sectors[sector]) { - actualize(sectors[sector]); - memcpy(buf, sectors[sector]->sector, 2352); - return; - } - - Byte buffers[2352 * nsectorsarow]; - - getsector(buffers, sec = sector, nsectorsarow); - - for (int i = nsectorsarow - 1; i >= 0; i--) { - introduce(buffers + i * 2352, sec + i); - } - - memcpy(buf, buffers, 2352); - - while (nsectors > cachesize) { - removetail(); - } -} - -cdreader::~cdreader() { - while (nsectors) { - removetail(); - } -} - -void cdreader::removetail() { - if (!tail) - return; - - sectors[tail->n] = 0; - - if (head == tail) { - free(tail); - head = tail = 0; - nsectors = 0; - } else { - cachedsector * p; - (p = tail->prev)->next = 0; - free(tail); - tail = p; - nsectors--; - } -} - -void cdreader::actualize(cachedsector * s) { - if (s == head) - return; - - if (s != tail) { - s->next->prev = s->prev; - } else { - tail = s->prev; - } - s->prev->next = s->next; - - head->prev = s; - s->prev = 0; - s->next = head; - head = s; -} - -void cdreader::introduce(Byte * datas, int n) { - cachedsector * s; - - s = (cachedsector *) malloc(sizeof(cachedsector)); - memcpy(s->sector, datas, 2352); - s->n = n; - - if (head) { - s->next = head; - head->prev = s; - head = s; - } else { - head = tail = s; - s->prev = s->next = 0; - } - sectors[n] = s; - - nsectors++; -} - -#ifdef __linux__ -#include <unistd.h> -#include <sys/ioctl.h> -#include <linux/cdrom.h> - -cdreader::cdreader(const String & no) throw (GeneralException) : - Handle(open(no.to_charp(), O_RDONLY)), n(no), sector(0) { - int i; - -#ifdef DEBUG - printm(M_INFO, "Opening cdrom device " + no + "\n"); -#endif - - if (GetHandle() < 0) { - throw IOGeneral(String(_("Error opening file ")) + no + _(" for reading: ") + strerror(errno)); - } - - struct stat s; - fstat(GetHandle(), &s); - - if (!S_ISBLK(s.st_mode)) { - throw GeneralException(no + " is not a block device."); - } - - for (i = 0; i < 400000; i++) { - sectors[i] = 0; - } - head = tail = 0; - nsectors = 0; -} - -cdreader::cdreader(const cdreader & inp) : Handle(inp), n(inp.n) { - int i; - - for (i = 0; i < 400000; i++) { - sectors[i] = 0; - } - head = tail = 0; - nsectors = 0; -} - -void cdreader::getsector(void *buf, int sec, int nb) throw (GeneralException) { - struct cdrom_msf * msf = (struct cdrom_msf *) buf; - if (sec >= 0) - sector = sec; - - sector += 150; - - msf->cdmsf_min0 = sector /CD_SECS /CD_FRAMES; - msf->cdmsf_sec0 = (sector /CD_FRAMES)%CD_SECS; - msf->cdmsf_frame0= sector %CD_FRAMES; - msf->cdmsf_min1 = (sector + nb)/CD_SECS /CD_FRAMES; - msf->cdmsf_sec1 = ((sector + nb)/CD_FRAMES)%CD_SECS; - msf->cdmsf_frame1= (sector + nb)%CD_FRAMES; - - sector -= 150; - - if (ioctl(GetHandle(), CDROMREADRAW, buf) < 0) { - throw GeneralException(String("unable to read cd sector ") + sector + ": " + strerror(errno)); - } - - sector += nb; -} -#endif - -#if defined (_MSC_VER) || defined (__MINGW32__) -cdreader::cdreader(const String & no) throw (GeneralException) : - Handle(-1), n(no), sector(0) { - if (!(hFile = cdabstract::OpenIOCTLFile(no[0]))) - throw GeneralException("Error opening device " + no); - for (int i = 0; i < 400000; i++) { - sectors[i] = 0; - } - head = tail = 0; - nsectors = 0; -} - -cdreader::cdreader(const cdreader & i) : Handle(i), n(i.n) { - hFile = i.hFile; - for (int x = 0; x < 400000; x++) { - sectors[x] = 0; - } - head = tail = 0; - nsectors = 0; -} - -void cdreader::close() throw (GeneralException) { - CloseHandle(hFile); -} - -typedef enum _TRACK_MODE_TYPE { - YellowMode2, - XAForm2, - CDDA -} TRACK_MODE_TYPE, *PTRACK_MODE_TYPE; - -typedef struct _RAW_READ_INFO { - LARGE_INTEGER DiskOffset; - ULONG SectorCount; - TRACK_MODE_TYPE TrackMode; -} RAW_READ_INFO, *PRAW_READ_INFO; - -void cdreader::getsector(void *buf, int sec, int nb) throw (GeneralException) { - RAW_READ_INFO rawIOCTL; - DWORD dwRet; - BOOL bStat; - bool done = false; - if (sec >= 0) - sector = sec; - - rawIOCTL.DiskOffset.QuadPart = sector * 2048; - rawIOCTL.SectorCount = nb; - rawIOCTL.TrackMode = YellowMode2; - - while (!done) { - SetLastError(0); - bStat = DeviceIoControl(hFile, IOCTL_CDROM_RAW_READ, - &rawIOCTL, sizeof(RAW_READ_INFO), - buf, 2352 * nb, &dwRet, NULL); - if (!bStat) { - DWORD dwErrCode = GetLastError(); - if (dwErrCode == ERROR_INVALID_FUNCTION) { - if (rawIOCTL.TrackMode == YellowMode2) { - rawIOCTL.TrackMode = XAForm2; - continue; - } - } - if (dwErrCode != ERROR_IO_PENDING) { - LPVOID lpMsgBuf; - if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPTSTR) &lpMsgBuf, 0, NULL )) - throw GeneralException("Gave up on reading CD: unknown error"); - String errmsg = (LPCTSTR) lpMsgBuf; - LocalFree(lpMsgBuf); - throw GeneralException("Gave up on reading CD: " + errmsg); - } - } else { - done = true; - } - } - - sector += nb; -} - -#endif +/*
+ * PSX-Tools Bundle Pack
+ * Copyright (C) 2002-2003 Nicolas "Pixel" Noble
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: cdreader.cpp,v 1.20 2004-11-27 21:44:48 pixel Exp $ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "cdreader.h"
+#include "Exceptions.h"
+#include "generic.h"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#else
+#define _(x) x
+#endif
+#include "cdabstract.h"
+
+#define nsectorsarow 1
+#define cachesize 2048
+
+bool cdreader::CanWrite() const {
+ return 0;
+}
+
+bool cdreader::CanRead() const {
+ return 1;
+}
+
+bool cdreader::CanSeek() const {
+ return 1;
+}
+
+String cdreader::GetName() const {
+ return n + " raw reading";
+}
+
+ssize_t cdreader::GetSize() const {
+ return -1;
+}
+
+off_t cdreader::seek(off_t offset, int whence) throw (GeneralException) {
+ switch (whence) {
+ case SEEK_SET:
+ itell = offset;
+ break;
+ case SEEK_CUR:
+ itell += offset;
+ break;
+ case SEEK_END:
+ throw GeneralException("Can not yet seek from the end of a CD.");
+ }
+ return itell;
+}
+
+ssize_t cdreader::read(void *buf, size_t count) throw (GeneralException) {
+ char sector[2352];
+ size_t r = count;
+
+ size_t remain = itell % 2352;
+ sectorseek(itell / 2352);
+
+ while (count > 0) {
+ size_t n = MIN(2352 - remain, count);
+ fetchsector(sector);
+ bcopy(sector + remain, buf, n);
+ buf = ((char *) buf) + n;
+ itell += n;
+ count -= n;
+ remain = 0;
+ }
+
+ return r;
+}
+
+void cdreader::sectorseek(int sec) {
+ sector = sec;
+}
+
+void cdreader::fetchsector(void * buf, int sec) {
+ if (sec >= 0)
+ sector = sec;
+
+ if (sectors[sector]) {
+ actualize(sectors[sector]);
+ memcpy(buf, sectors[sector]->sector, 2352);
+ return;
+ }
+
+ Byte buffers[2352 * nsectorsarow];
+
+ getsector(buffers, sec = sector, nsectorsarow);
+
+ for (int i = nsectorsarow - 1; i >= 0; i--) {
+ introduce(buffers + i * 2352, sec + i);
+ }
+
+ memcpy(buf, buffers, 2352);
+
+ while (nsectors > cachesize) {
+ removetail();
+ }
+}
+
+cdreader::~cdreader() {
+ while (nsectors) {
+ removetail();
+ }
+}
+
+void cdreader::removetail() {
+ if (!tail)
+ return;
+
+ sectors[tail->n] = 0;
+
+ if (head == tail) {
+ free(tail);
+ head = tail = 0;
+ nsectors = 0;
+ } else {
+ cachedsector * p;
+ (p = tail->prev)->next = 0;
+ free(tail);
+ tail = p;
+ nsectors--;
+ }
+}
+
+void cdreader::actualize(cachedsector * s) {
+ if (s == head)
+ return;
+
+ if (s != tail) {
+ s->next->prev = s->prev;
+ } else {
+ tail = s->prev;
+ }
+ s->prev->next = s->next;
+
+ head->prev = s;
+ s->prev = 0;
+ s->next = head;
+ head = s;
+}
+
+void cdreader::introduce(Byte * datas, int n) {
+ cachedsector * s;
+
+ s = (cachedsector *) malloc(sizeof(cachedsector));
+ memcpy(s->sector, datas, 2352);
+ s->n = n;
+
+ if (head) {
+ s->next = head;
+ head->prev = s;
+ head = s;
+ } else {
+ head = tail = s;
+ s->prev = s->next = 0;
+ }
+ sectors[n] = s;
+
+ nsectors++;
+}
+
+#ifdef __linux__
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <linux/cdrom.h>
+
+cdreader::cdreader(const String & no) throw (GeneralException) :
+ Handle(open(no.to_charp(), O_RDONLY)), n(no), sector(0) {
+ int i;
+
+#ifdef DEBUG
+ printm(M_INFO, "Opening cdrom device " + no + "\n");
+#endif
+
+ if (GetHandle() < 0) {
+ throw IOGeneral(String(_("Error opening file ")) + no + _(" for reading: ") + strerror(errno));
+ }
+
+ struct stat s;
+ fstat(GetHandle(), &s);
+
+ if (!S_ISBLK(s.st_mode)) {
+ throw GeneralException(no + " is not a block device.");
+ }
+
+ for (i = 0; i < 400000; i++) {
+ sectors[i] = 0;
+ }
+ head = tail = 0;
+ nsectors = 0;
+}
+
+cdreader::cdreader(const cdreader & inp) : Handle(inp), n(inp.n) {
+ int i;
+
+ for (i = 0; i < 400000; i++) {
+ sectors[i] = 0;
+ }
+ head = tail = 0;
+ nsectors = 0;
+}
+
+void cdreader::getsector(void *buf, int sec, int nb) throw (GeneralException) {
+ struct cdrom_msf * msf = (struct cdrom_msf *) buf;
+ if (sec >= 0)
+ sector = sec;
+
+ sector += 150;
+
+ msf->cdmsf_min0 = sector /CD_SECS /CD_FRAMES;
+ msf->cdmsf_sec0 = (sector /CD_FRAMES)%CD_SECS;
+ msf->cdmsf_frame0= sector %CD_FRAMES;
+ msf->cdmsf_min1 = (sector + nb)/CD_SECS /CD_FRAMES;
+ msf->cdmsf_sec1 = ((sector + nb)/CD_FRAMES)%CD_SECS;
+ msf->cdmsf_frame1= (sector + nb)%CD_FRAMES;
+
+ sector -= 150;
+
+ if (ioctl(GetHandle(), CDROMREADRAW, buf) < 0) {
+ throw GeneralException(String("unable to read cd sector ") + sector + ": " + strerror(errno));
+ }
+
+ sector += nb;
+}
+#endif
+
+#if defined (_MSC_VER) || defined (__MINGW32__)
+cdreader::cdreader(const String & no) throw (GeneralException) :
+ Handle(-1), n(no), sector(0) {
+ if (!(hFile = cdabstract::OpenIOCTLFile(no[0])))
+ throw GeneralException("Error opening device " + no);
+ for (int i = 0; i < 400000; i++) {
+ sectors[i] = 0;
+ }
+ head = tail = 0;
+ nsectors = 0;
+}
+
+cdreader::cdreader(const cdreader & i) : Handle(i), n(i.n) {
+ hFile = i.hFile;
+ for (int x = 0; x < 400000; x++) {
+ sectors[x] = 0;
+ }
+ head = tail = 0;
+ nsectors = 0;
+}
+
+void cdreader::close() throw (GeneralException) {
+ CloseHandle(hFile);
+}
+
+typedef enum _TRACK_MODE_TYPE {
+ YellowMode2,
+ XAForm2,
+ CDDA
+} TRACK_MODE_TYPE, *PTRACK_MODE_TYPE;
+
+typedef struct _RAW_READ_INFO {
+ LARGE_INTEGER DiskOffset;
+ ULONG SectorCount;
+ TRACK_MODE_TYPE TrackMode;
+} RAW_READ_INFO, *PRAW_READ_INFO;
+
+void cdreader::getsector(void *buf, int sec, int nb) throw (GeneralException) {
+ RAW_READ_INFO rawIOCTL;
+ DWORD dwRet;
+ BOOL bStat;
+ bool done = false;
+ if (sec >= 0)
+ sector = sec;
+
+ rawIOCTL.DiskOffset.QuadPart = sector * 2048;
+ rawIOCTL.SectorCount = nb;
+ rawIOCTL.TrackMode = YellowMode2;
+
+ while (!done) {
+ SetLastError(0);
+ bStat = DeviceIoControl(hFile, IOCTL_CDROM_RAW_READ,
+ &rawIOCTL, sizeof(RAW_READ_INFO),
+ buf, 2352 * nb, &dwRet, NULL);
+ if (!bStat) {
+ DWORD dwErrCode = GetLastError();
+ if (dwErrCode == ERROR_INVALID_FUNCTION) {
+ if (rawIOCTL.TrackMode == YellowMode2) {
+ rawIOCTL.TrackMode = XAForm2;
+ continue;
+ }
+ }
+ if (dwErrCode != ERROR_IO_PENDING) {
+ LPVOID lpMsgBuf;
+ if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR) &lpMsgBuf, 0, NULL ))
+ throw GeneralException("Gave up on reading CD: unknown error");
+ String errmsg = (LPCTSTR) lpMsgBuf;
+ LocalFree(lpMsgBuf);
+ throw GeneralException("Gave up on reading CD: " + errmsg);
+ }
+ } else {
+ done = true;
+ }
+ }
+
+ sector += nb;
+}
+
+#endif
diff --git a/lib/dteutils.cpp b/lib/dteutils.cpp index 85a7df2..42f36bf 100644 --- a/lib/dteutils.cpp +++ b/lib/dteutils.cpp @@ -1,319 +1,319 @@ -/* - * PSX-Tools Bundle Pack - * Copyright (C) 2002 Nicolas "Pixel" Noble - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include "generic.h" -#include "Handle.h" - -class thingtree : public Base { - public: - static void addstring(const String, long); - static long look(const String); - static void destroy(); - private: - thingtree(); - thingtree(char, bool, thingtree *, long); - ~thingtree(); - char thischar; - bool terminal; - thingtree * father, * child, * brother; - long thingentry; - static thingtree * root; -}; - -thingtree * thingtree::root = 0; - -thingtree::thingtree(char gchar, bool gterm, thingtree * gfather, long gthingentry) : thischar(gchar), terminal(gterm), thingentry(gthingentry) { - if (!gfather) { - if (!root) { - root = new thingtree(); - } - father = root; - } else { - father = gfather; - } - brother = father->child; - father->child = this; -} - -thingtree::thingtree() : thischar(0), terminal(false), father(0), child(0), brother(0) { } - -long thingtree::look(const String s) { - long currentthing = -1; - thingtree * ptr = root; - int i; - - if (!ptr) { - printm(M_ERROR, "Error: thingtree not initialised\n"); - exit(-1); - } - - for (i = 0; s[i]; i++) { -// printm(M_INFO, "Looking for '%c'\n", *p); - for (ptr = ptr->child; ptr; ptr = ptr->brother) { -// printm(M_INFO, "Looking in %p: %c\n", ptr, ptr->thischar); - if (ptr->thischar == s[i]) { - if (ptr->terminal) { - currentthing = ptr->thingentry; - } - break; - } - } - if (!ptr) { -// printm(M_INFO, "Not found.\n"); - break; - } - } - - if (currentthing == -1) { - printm(M_ERROR, "Error, can't find any entry for string '" + s + "'\n"); - } - - return currentthing; -} - -void thingtree::addstring(const String s, long thingentry) { - thingtree * ptr, * fptr; - int i; - - if (!root) { - root = new thingtree(); - } - -// printm(M_INFO, "Creating new thingtree entry: %li='%s'\n", thingentry, s); - - ptr = root; - for (i = 0; s[i]; i++) { - fptr = ptr; -// printm(M_INFO, "Finding entry for '%c'\n", *p); - for (ptr = ptr->child; ptr; ptr = ptr->brother) { -// printm(M_INFO, "Browsing childs: %p = %c\n", ptr, ptr->thischar); - if (ptr->thischar == s[i]) - break; - } - - if (!ptr) { -// printm(M_INFO, "Creating new branch for %c\n", *p); - ptr = new thingtree(s[i], s[i + 1] == 0, fptr, thingentry); -// printm(M_INFO, "Created branch %p\n", ptr); - } else { - if (s[i + 1] == 0) { - ptr->terminal = true; - ptr->thingentry = thingentry; - } - } - } -} - -void thingtree::destroy() { - delete root; - root = 0; -} - -thingtree::~thingtree() { - if (father->child == this) - father->child = brother; - - while (child) - delete child; -} - -String things[256]; - -char * dte_text; -char dte_flags[256 * 256]; -long dte_counters[256 * 256]; -long dte_entries[256]; -char alloweds[256]; -long dte_usage[256]; - -long dte_most; -long dte_counter; -long dte_text_size; -int dte_size; -long gain; -long nb_dte = 0; -long tnb_dte = 0; - -void dte_reset(void) { - memset(dte_counters, 0, 0x40000); - dte_most = 0; - dte_counter = 0; -} - -void build_dte(void) { - int i; - Uint16 t, t2; - unsigned short p = 0; - - for (i = 0; i < dte_text_size; i++) { - t = *((Uint16 *) (dte_text + i)); - t2 = *((Uint16 *) (dte_text + i + 1)); - if (t == p) { - p = 0; - continue; - } - p = t; - if (!dte_flags[t]) { -// if ((!dte_flags[t]) && (dte_flags[t2] != 3)) { - if ((dte_counters[t]++) == 0) { - nb_dte++; - } - if (dte_counters[t] > dte_counter) { - dte_most = t; - dte_counter = dte_counters[t]; - } -// } else if (dte_flags[t] == 3) { -// i++; - } - } -} - -void push_entry(long entry) { - int i; - char t[3], c1, c2; - t[2] = 0; - - c1 = dte_most & 0xff; - c2 = dte_most >> 8; - t[0] = things[c1][0]; - t[1] = things[c2][0]; - - for (i = 0; i < 256; i++) { - if (!dte_entries[i]) { - dte_entries[i] = entry; - things[i] = strdup(t); - thingtree::addstring(t, i); - break; - } - } -} - -void dte_compress() { - int i, j; - char c1, c2; - - for (i = 0; i < 256; i++) { - for (j = 0; j < 256; j++) { - dte_flags[i * 256 + j] = alloweds[i] ? alloweds[j] ? 0 : 1 : 1; - } - } - - gain = 0; - - printm(M_STATUS, "Going for it: dte_size = %i\n", dte_size); - for (i = 0; i < dte_size; i++) { - dte_reset(); - build_dte(); - if (!tnb_dte) - tnb_dte = nb_dte; - c1 = dte_most & 0xff; - c2 = dte_most >> 8; - c1 = things[c1][0]; - c2 = things[c2][0]; - printm(M_INFO, "Entry #%i, most count: %li, couple = 0x%04x = (%c %c)\n", i, dte_counter, (int) dte_most, c1, c2); - dte_flags[dte_most] = 3; - gain += dte_counter; - push_entry(dte_most); - } - - printm(M_STATUS, "Estimated gain: %li bytes, new file size = %li\n", gain, dte_text_size - gain); -} - -void read_thingy(Handle * f) { - String line, st, thing; - long code; - int i; - - dte_size = 0; - - for (i = 0; i < 256; i++) { - dte_entries[i] = -1; - } - - while (1) { - line = "0x"; - *f >> st; - if (st.strlen()) { - line += st.extract(0, 1); - code = line.to_int(); - thing = st.extract(3); - switch (thing.strlen()) { - case 0: - dte_size++; - dte_entries[code] = 0; - break; - case 1: - alloweds[code] = 1; - default: - things[code] = thing; - thingtree::addstring(thing, code); - } - } - } -} - -void read_thingy_file(Handle * f) { - String line, trans; - long code; - int ptr = 0, i, c; - - for (i = 0; i < 256; i++) { - dte_usage[i] = 0; - } - - while (1) { - *f >> line; - if (!line.strlen()) - continue; - i = 0; - while (line[i]) { - if (line[i] == '<') { - if ((c = line.strchr('>', i)) < 0) { - printm(M_ERROR, "Error in file: '<' not closed.\n"); - exit(-1); - } - i++; - if (c == 2) { - trans = "0x" + line.extract(i, 2); - code = line.to_int(); - dte_text[ptr++] = code; - printm(M_BARE, "0x%02x-", code); - } else { - printm(M_BARE, "Unknow " + trans.extract(2) + "-"); - } - i += c; - } else { - if ((code = thingtree::look(line.extract(i))) == -1) - exit(-1); - dte_text[ptr++] = code; - i += things[code].strlen(); - printm(M_BARE, things[code] + "-"); - dte_usage[code]++; - } - } - printm(M_BARE, "\n"); - } - - dte_text[ptr] = dte_text[ptr + 1] = dte_text[ptr + 2] = dte_text[ptr + 3] = 0; - dte_text_size = ptr; -} +/*
+ * PSX-Tools Bundle Pack
+ * Copyright (C) 2002 Nicolas "Pixel" Noble
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include "generic.h"
+#include "Handle.h"
+
+class thingtree : public Base {
+ public:
+ static void addstring(const String, long);
+ static long look(const String);
+ static void destroy();
+ private:
+ thingtree();
+ thingtree(char, bool, thingtree *, long);
+ ~thingtree();
+ char thischar;
+ bool terminal;
+ thingtree * father, * child, * brother;
+ long thingentry;
+ static thingtree * root;
+};
+
+thingtree * thingtree::root = 0;
+
+thingtree::thingtree(char gchar, bool gterm, thingtree * gfather, long gthingentry) : thischar(gchar), terminal(gterm), thingentry(gthingentry) {
+ if (!gfather) {
+ if (!root) {
+ root = new thingtree();
+ }
+ father = root;
+ } else {
+ father = gfather;
+ }
+ brother = father->child;
+ father->child = this;
+}
+
+thingtree::thingtree() : thischar(0), terminal(false), father(0), child(0), brother(0) { }
+
+long thingtree::look(const String s) {
+ long currentthing = -1;
+ thingtree * ptr = root;
+ int i;
+
+ if (!ptr) {
+ printm(M_ERROR, "Error: thingtree not initialised\n");
+ exit(-1);
+ }
+
+ for (i = 0; s[i]; i++) {
+// printm(M_INFO, "Looking for '%c'\n", *p);
+ for (ptr = ptr->child; ptr; ptr = ptr->brother) {
+// printm(M_INFO, "Looking in %p: %c\n", ptr, ptr->thischar);
+ if (ptr->thischar == s[i]) {
+ if (ptr->terminal) {
+ currentthing = ptr->thingentry;
+ }
+ break;
+ }
+ }
+ if (!ptr) {
+// printm(M_INFO, "Not found.\n");
+ break;
+ }
+ }
+
+ if (currentthing == -1) {
+ printm(M_ERROR, "Error, can't find any entry for string '" + s + "'\n");
+ }
+
+ return currentthing;
+}
+
+void thingtree::addstring(const String s, long thingentry) {
+ thingtree * ptr, * fptr;
+ int i;
+
+ if (!root) {
+ root = new thingtree();
+ }
+
+// printm(M_INFO, "Creating new thingtree entry: %li='%s'\n", thingentry, s);
+
+ ptr = root;
+ for (i = 0; s[i]; i++) {
+ fptr = ptr;
+// printm(M_INFO, "Finding entry for '%c'\n", *p);
+ for (ptr = ptr->child; ptr; ptr = ptr->brother) {
+// printm(M_INFO, "Browsing childs: %p = %c\n", ptr, ptr->thischar);
+ if (ptr->thischar == s[i])
+ break;
+ }
+
+ if (!ptr) {
+// printm(M_INFO, "Creating new branch for %c\n", *p);
+ ptr = new thingtree(s[i], s[i + 1] == 0, fptr, thingentry);
+// printm(M_INFO, "Created branch %p\n", ptr);
+ } else {
+ if (s[i + 1] == 0) {
+ ptr->terminal = true;
+ ptr->thingentry = thingentry;
+ }
+ }
+ }
+}
+
+void thingtree::destroy() {
+ delete root;
+ root = 0;
+}
+
+thingtree::~thingtree() {
+ if (father->child == this)
+ father->child = brother;
+
+ while (child)
+ delete child;
+}
+
+String things[256];
+
+char * dte_text;
+char dte_flags[256 * 256];
+long dte_counters[256 * 256];
+long dte_entries[256];
+char alloweds[256];
+long dte_usage[256];
+
+long dte_most;
+long dte_counter;
+long dte_text_size;
+int dte_size;
+long gain;
+long nb_dte = 0;
+long tnb_dte = 0;
+
+void dte_reset(void) {
+ memset(dte_counters, 0, 0x40000);
+ dte_most = 0;
+ dte_counter = 0;
+}
+
+void build_dte(void) {
+ int i;
+ Uint16 t, t2;
+ unsigned short p = 0;
+
+ for (i = 0; i < dte_text_size; i++) {
+ t = *((Uint16 *) (dte_text + i));
+ t2 = *((Uint16 *) (dte_text + i + 1));
+ if (t == p) {
+ p = 0;
+ continue;
+ }
+ p = t;
+ if (!dte_flags[t]) {
+// if ((!dte_flags[t]) && (dte_flags[t2] != 3)) {
+ if ((dte_counters[t]++) == 0) {
+ nb_dte++;
+ }
+ if (dte_counters[t] > dte_counter) {
+ dte_most = t;
+ dte_counter = dte_counters[t];
+ }
+// } else if (dte_flags[t] == 3) {
+// i++;
+ }
+ }
+}
+
+void push_entry(long entry) {
+ int i;
+ char t[3], c1, c2;
+ t[2] = 0;
+
+ c1 = dte_most & 0xff;
+ c2 = dte_most >> 8;
+ t[0] = things[c1][0];
+ t[1] = things[c2][0];
+
+ for (i = 0; i < 256; i++) {
+ if (!dte_entries[i]) {
+ dte_entries[i] = entry;
+ things[i] = strdup(t);
+ thingtree::addstring(t, i);
+ break;
+ }
+ }
+}
+
+void dte_compress() {
+ int i, j;
+ char c1, c2;
+
+ for (i = 0; i < 256; i++) {
+ for (j = 0; j < 256; j++) {
+ dte_flags[i * 256 + j] = alloweds[i] ? alloweds[j] ? 0 : 1 : 1;
+ }
+ }
+
+ gain = 0;
+
+ printm(M_STATUS, "Going for it: dte_size = %i\n", dte_size);
+ for (i = 0; i < dte_size; i++) {
+ dte_reset();
+ build_dte();
+ if (!tnb_dte)
+ tnb_dte = nb_dte;
+ c1 = dte_most & 0xff;
+ c2 = dte_most >> 8;
+ c1 = things[c1][0];
+ c2 = things[c2][0];
+ printm(M_INFO, "Entry #%i, most count: %li, couple = 0x%04x = (%c %c)\n", i, dte_counter, (int) dte_most, c1, c2);
+ dte_flags[dte_most] = 3;
+ gain += dte_counter;
+ push_entry(dte_most);
+ }
+
+ printm(M_STATUS, "Estimated gain: %li bytes, new file size = %li\n", gain, dte_text_size - gain);
+}
+
+void read_thingy(Handle * f) {
+ String line, st, thing;
+ long code;
+ int i;
+
+ dte_size = 0;
+
+ for (i = 0; i < 256; i++) {
+ dte_entries[i] = -1;
+ }
+
+ while (1) {
+ line = "0x";
+ *f >> st;
+ if (st.strlen()) {
+ line += st.extract(0, 1);
+ code = line.to_int();
+ thing = st.extract(3);
+ switch (thing.strlen()) {
+ case 0:
+ dte_size++;
+ dte_entries[code] = 0;
+ break;
+ case 1:
+ alloweds[code] = 1;
+ default:
+ things[code] = thing;
+ thingtree::addstring(thing, code);
+ }
+ }
+ }
+}
+
+void read_thingy_file(Handle * f) {
+ String line, trans;
+ long code;
+ int ptr = 0, i, c;
+
+ for (i = 0; i < 256; i++) {
+ dte_usage[i] = 0;
+ }
+
+ while (1) {
+ *f >> line;
+ if (!line.strlen())
+ continue;
+ i = 0;
+ while (line[i]) {
+ if (line[i] == '<') {
+ if ((c = line.strchr('>', i)) < 0) {
+ printm(M_ERROR, "Error in file: '<' not closed.\n");
+ exit(-1);
+ }
+ i++;
+ if (c == 2) {
+ trans = "0x" + line.extract(i, 2);
+ code = line.to_int();
+ dte_text[ptr++] = code;
+ printm(M_BARE, "0x%02x-", code);
+ } else {
+ printm(M_BARE, "Unknow " + trans.extract(2) + "-");
+ }
+ i += c;
+ } else {
+ if ((code = thingtree::look(line.extract(i))) == -1)
+ exit(-1);
+ dte_text[ptr++] = code;
+ i += things[code].strlen();
+ printm(M_BARE, things[code] + "-");
+ dte_usage[code]++;
+ }
+ }
+ printm(M_BARE, "\n");
+ }
+
+ dte_text[ptr] = dte_text[ptr + 1] = dte_text[ptr + 2] = dte_text[ptr + 3] = 0;
+ dte_text_size = ptr;
+}
diff --git a/lib/luapsx.cpp b/lib/luapsx.cpp index b68d3ab..eb1473b 100644 --- a/lib/luapsx.cpp +++ b/lib/luapsx.cpp @@ -1,307 +1,307 @@ -/* - * PSX-Tools Bundle Pack - * Copyright (C) 2002-2003 Nicolas "Pixel" Noble - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* $Id: luapsx.cpp,v 1.5 2004-07-16 15:04:52 pixel Exp $ */ - -#include <LuaHandle.h> -#include "luapsx.h" -#include "generic.h" - -void over(Byte * d, Byte R, Byte G, Byte B, Byte A) { - d[0] = R; - d[1] = G; - d[2] = B; -} - -void alpha(Byte * d, Byte R, Byte G, Byte B, Byte A) { - A = MIN(A, (Byte) 128); - d[0] = ((int)d[0] * (128 - A) + R * A) >> 7; - d[1] = ((int)d[1] * (128 - A) + G * A) >> 7; - d[2] = ((int)d[2] * (128 - A) + B * A) >> 7; -} - -void lighten(Byte * d, Byte R, Byte G, Byte B, Byte A) { - A = MIN(A, (Byte) 128); - R = ((int)d[0] * (128 - A) + R * A) >> 7; - G = ((int)d[1] * (128 - A) + G * A) >> 7; - B = ((int)d[2] * (128 - A) + B * A) >> 7; - d[0] = MAX(R, d[0]); - d[1] = MAX(G, d[1]); - d[2] = MAX(B, d[2]); -} - -void darken(Byte * d, Byte R, Byte G, Byte B, Byte A) { - A = MIN(A, (Byte) 128); - R = ((int)d[0] * (128 - A) + R * A) >> 7; - G = ((int)d[1] * (128 - A) + G * A) >> 7; - B = ((int)d[2] * (128 - A) + B * A) >> 7; - d[0] = MIN(R, d[0]); - d[1] = MIN(G, d[1]); - d[2] = MIN(B, d[2]); -} - -enum { - BLIT_OVER = 0, - BLIT_OVER32, - BLIT_ALPHA, - BLIT_LIGHTEN, - BLIT_LIGHTEN32, - BLIT_DARKEN, - BLIT_DARKEN32, -}; - -typedef void psx; - -enum psx_functions_t { - PSX_BSDECODE = 0, - PSX_BSENCODE, - PSX_BLIT, -}; - -struct lua_functypes_t psx_functions[] = { - { PSX_BSDECODE, "bsdecode", 3, 3, { LUA_OBJECT, LUA_NUMBER, LUA_NUMBER } }, - { PSX_BSENCODE, "bsencode", 3, 5, { LUA_OBJECT, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER } }, - { PSX_BLIT, "blit", 9, 9, { LUA_OBJECT, LUA_OBJECT, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER } }, - { -1, 0, 0, 0, 0 } -}; - -class sLua_psx : public Base { - public: - DECLARE_FUNCTION(psx, PSX_BSDECODE); - DECLARE_FUNCTION(psx, PSX_BSENCODE); - DECLARE_FUNCTION(psx, PSX_BLIT); - private: - static int psx_proceed_statics(Lua * L, int n, int caller); -}; - -void Luapsx::pushstatics(Lua * L) throw (GeneralException ) { - CHECK_FUNCTIONS(psx); - - PUSH_FUNCTION(psx, PSX_BSDECODE); - PUSH_FUNCTION(psx, PSX_BSENCODE); - PUSH_FUNCTION(psx, PSX_BLIT); - - L->push("BLIT_OVER"); - L->push((lua_Number) BLIT_OVER); - L->settable(LUA_GLOBALSINDEX); - - L->push("BLIT_OVER32"); - L->push((lua_Number) BLIT_OVER32); - L->settable(LUA_GLOBALSINDEX); - - L->push("BLIT_ALPHA"); - L->push((lua_Number) BLIT_ALPHA); - L->settable(LUA_GLOBALSINDEX); - - L->push("BLIT_LIGHTEN"); - L->push((lua_Number) BLIT_LIGHTEN); - L->settable(LUA_GLOBALSINDEX); - - L->push("BLIT_LIGHTEN32"); - L->push((lua_Number) BLIT_LIGHTEN32); - L->settable(LUA_GLOBALSINDEX); - - L->push("BLIT_DARKEN"); - L->push((lua_Number) BLIT_DARKEN); - L->settable(LUA_GLOBALSINDEX); - - L->push("BLIT_DARKEN32"); - L->push((lua_Number) BLIT_DARKEN32); - L->settable(LUA_GLOBALSINDEX); -} - -int sLua_psx::psx_proceed_statics(Lua * L, int n, int caller) { - int r = 0; - - switch (caller) { - case PSX_BSDECODE: - r = 1; - { - Buffer * b = new Buffer(true); - Handle * f = (Handle *) LuaObject::getme(L, 1); - int width = L->tonumber(2); - int height = L->tonumber(3); - Byte * in = (Byte *) malloc(f->GetSize() + 10); - Byte * out = (Byte *) malloc(width * height * 3); - LuaBuffer lb(b); - lb.pushdestruct(L); - f->read(in, f->GetSize()); - bs_decode_rgb24(out, (bs_header_t *) in, width, height, 0); - for (int i = 0; i < width * height * 3; i++) { - b[i] = out[i]; - } - free(out); - free(in); - } - case PSX_BSENCODE: - r = 3; - { - unsigned short out[0x80000]; - Buffer * b = new Buffer(true); - LuaBuffer lb(b); - lb.pushdestruct(L); - Handle * f = (Handle *) LuaObject::getme(L, 1); - bs_input_image_t img; - img.width = L->tonumber(2); - img.height = L->tonumber(3); - int max_size = 14112, cur_size; - int q_scale = 1; - if (n >= 4) - max_size = L->tonumber(4); - if (n >= 5) - q_scale = L->tonumber(5); - img.lpbits = (Byte *) malloc(f->GetSize()); - img.top = img.lpbits; - img.nextline = img.width * 3; - img.bit = 24; - - f->read(img.lpbits, f->GetSize()); - - bs_init(); - - cur_size = max_size + 1; - - for (cur_size = max_size + 1; max_size < cur_size; q_scale++) { - cur_size = bs_encode((bs_header_t *) out, &img, 2, q_scale, 0); - } - - for (int i = 0; i < cur_size; i++) { - b[i] = out[i]; - } - - L->push((lua_Number) cur_size); - L->push((lua_Number) q_scale); - } - case PSX_BLIT: - r = 0; - { - Handle * d = (Handle *) LuaObject::getme(L, 1); - Handle * s = (Handle *) LuaObject::getme(L, 2); - int dw = L->tonumber(3), - dh = L->tonumber(4), - sw = L->tonumber(5), - sh = L->tonumber(6), - sx = L->tonumber(7), - sy = L->tonumber(8), - bl = L->tonumber(9); - int bytes, dstart = 0, dskip = 0, sstart = 0, sskip = 0, i, j; - Byte RGB[3], R, G, B, A = 128; - void (*op_func)(Byte *, Byte, Byte, Byte, Byte); - - switch(bl) { - case BLIT_OVER: - bytes = 3; - op_func = over; - break; - case BLIT_OVER32: - bytes = 4; - op_func = over; - break; - case BLIT_ALPHA: - bytes = 4; - op_func = alpha; - break; - case BLIT_LIGHTEN: - bytes = 3; - op_func = lighten; - break; - case BLIT_LIGHTEN32: - bytes = 4; - op_func = lighten; - break; - case BLIT_DARKEN: - bytes = 3; - op_func = darken; - break; - case BLIT_DARKEN32: - bytes = 4; - op_func = darken; - break; - default: - L->error("Blitting operation unknown."); - return 0; - } - -#if 0 - if ((sx + sw) < 0) - return; - - if (sx >= dw) - return; - - if ((sy + sh) < 0) - return; - - if (sy >= dh) - return; -#endif - - if (sy < 0) { - sstart -= sw * bytes * sy; - sh += sy; - sy = 0; - } else { - dstart += dw * 3 * sy; - } - - if ((sy + sh) > dh) { - sh -= (sy + sh) - dh; - } - - if (sx < 0) { - sstart -= sx * bytes; - sskip -= sx * bytes; - sw += sx; - sx = 0; - } else { - dstart += sx * 3; - } - - if ((sx + sw) > dw) { - sskip += (sx + sw) - dw; - sw -= (sx + sw) - dw; - } - - dskip = (dw - sw) * 3; - - d->seek(dstart); - s->seek(sstart); - - for (i = 0; i < sh; i++, s->seek(sskip, SEEK_CUR), d->seek(dskip, SEEK_CUR)) { - for (j = 0; j < sw; j++) { - RGB[0] = d->readU8(); - RGB[1] = d->readU8(); - RGB[2] = d->readU8(); - d->seek(-3, SEEK_CUR); - R = s->readU8(); - G = s->readU8(); - B = s->readU8(); - if (bytes == 4) - A = s->readU8(); - op_func(RGB, R, G, B, A); - d->writeU8(R); - d->writeU8(G); - d->writeU8(B); - } - } - - } - } - return r; -} +/*
+ * PSX-Tools Bundle Pack
+ * Copyright (C) 2002-2003 Nicolas "Pixel" Noble
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: luapsx.cpp,v 1.6 2004-11-27 21:44:48 pixel Exp $ */
+
+#include <LuaHandle.h>
+#include "luapsx.h"
+#include "generic.h"
+
+void over(Byte * d, Byte R, Byte G, Byte B, Byte A) {
+ d[0] = R;
+ d[1] = G;
+ d[2] = B;
+}
+
+void alpha(Byte * d, Byte R, Byte G, Byte B, Byte A) {
+ A = MIN(A, (Byte) 128);
+ d[0] = ((int)d[0] * (128 - A) + R * A) >> 7;
+ d[1] = ((int)d[1] * (128 - A) + G * A) >> 7;
+ d[2] = ((int)d[2] * (128 - A) + B * A) >> 7;
+}
+
+void lighten(Byte * d, Byte R, Byte G, Byte B, Byte A) {
+ A = MIN(A, (Byte) 128);
+ R = ((int)d[0] * (128 - A) + R * A) >> 7;
+ G = ((int)d[1] * (128 - A) + G * A) >> 7;
+ B = ((int)d[2] * (128 - A) + B * A) >> 7;
+ d[0] = MAX(R, d[0]);
+ d[1] = MAX(G, d[1]);
+ d[2] = MAX(B, d[2]);
+}
+
+void darken(Byte * d, Byte R, Byte G, Byte B, Byte A) {
+ A = MIN(A, (Byte) 128);
+ R = ((int)d[0] * (128 - A) + R * A) >> 7;
+ G = ((int)d[1] * (128 - A) + G * A) >> 7;
+ B = ((int)d[2] * (128 - A) + B * A) >> 7;
+ d[0] = MIN(R, d[0]);
+ d[1] = MIN(G, d[1]);
+ d[2] = MIN(B, d[2]);
+}
+
+enum {
+ BLIT_OVER = 0,
+ BLIT_OVER32,
+ BLIT_ALPHA,
+ BLIT_LIGHTEN,
+ BLIT_LIGHTEN32,
+ BLIT_DARKEN,
+ BLIT_DARKEN32,
+};
+
+typedef void psx;
+
+enum psx_functions_t {
+ PSX_BSDECODE = 0,
+ PSX_BSENCODE,
+ PSX_BLIT,
+};
+
+struct lua_functypes_t psx_functions[] = {
+ { PSX_BSDECODE, "bsdecode", 3, 3, { LUA_OBJECT, LUA_NUMBER, LUA_NUMBER } },
+ { PSX_BSENCODE, "bsencode", 3, 5, { LUA_OBJECT, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER } },
+ { PSX_BLIT, "blit", 9, 9, { LUA_OBJECT, LUA_OBJECT, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER } },
+ { -1, 0, 0, 0, 0 }
+};
+
+class sLua_psx : public Base {
+ public:
+ DECLARE_FUNCTION(psx, PSX_BSDECODE);
+ DECLARE_FUNCTION(psx, PSX_BSENCODE);
+ DECLARE_FUNCTION(psx, PSX_BLIT);
+ private:
+ static int psx_proceed_statics(Lua * L, int n, int caller);
+};
+
+void Luapsx::pushstatics(Lua * L) throw (GeneralException ) {
+ CHECK_FUNCTIONS(psx);
+
+ PUSH_FUNCTION(psx, PSX_BSDECODE);
+ PUSH_FUNCTION(psx, PSX_BSENCODE);
+ PUSH_FUNCTION(psx, PSX_BLIT);
+
+ L->push("BLIT_OVER");
+ L->push((lua_Number) BLIT_OVER);
+ L->settable(LUA_GLOBALSINDEX);
+
+ L->push("BLIT_OVER32");
+ L->push((lua_Number) BLIT_OVER32);
+ L->settable(LUA_GLOBALSINDEX);
+
+ L->push("BLIT_ALPHA");
+ L->push((lua_Number) BLIT_ALPHA);
+ L->settable(LUA_GLOBALSINDEX);
+
+ L->push("BLIT_LIGHTEN");
+ L->push((lua_Number) BLIT_LIGHTEN);
+ L->settable(LUA_GLOBALSINDEX);
+
+ L->push("BLIT_LIGHTEN32");
+ L->push((lua_Number) BLIT_LIGHTEN32);
+ L->settable(LUA_GLOBALSINDEX);
+
+ L->push("BLIT_DARKEN");
+ L->push((lua_Number) BLIT_DARKEN);
+ L->settable(LUA_GLOBALSINDEX);
+
+ L->push("BLIT_DARKEN32");
+ L->push((lua_Number) BLIT_DARKEN32);
+ L->settable(LUA_GLOBALSINDEX);
+}
+
+int sLua_psx::psx_proceed_statics(Lua * L, int n, int caller) {
+ int r = 0;
+
+ switch (caller) {
+ case PSX_BSDECODE:
+ r = 1;
+ {
+ Buffer * b = new Buffer(true);
+ Handle * f = (Handle *) LuaObject::getme(L, 1);
+ int width = L->tonumber(2);
+ int height = L->tonumber(3);
+ Byte * in = (Byte *) malloc(f->GetSize() + 10);
+ Byte * out = (Byte *) malloc(width * height * 3);
+ LuaBuffer lb(b);
+ lb.pushdestruct(L);
+ f->read(in, f->GetSize());
+ bs_decode_rgb24(out, (bs_header_t *) in, width, height, 0);
+ for (int i = 0; i < width * height * 3; i++) {
+ b[i] = out[i];
+ }
+ free(out);
+ free(in);
+ }
+ case PSX_BSENCODE:
+ r = 3;
+ {
+ unsigned short out[0x80000];
+ Buffer * b = new Buffer(true);
+ LuaBuffer lb(b);
+ lb.pushdestruct(L);
+ Handle * f = (Handle *) LuaObject::getme(L, 1);
+ bs_input_image_t img;
+ img.width = L->tonumber(2);
+ img.height = L->tonumber(3);
+ int max_size = 14112, cur_size;
+ int q_scale = 1;
+ if (n >= 4)
+ max_size = L->tonumber(4);
+ if (n >= 5)
+ q_scale = L->tonumber(5);
+ img.lpbits = (Byte *) malloc(f->GetSize());
+ img.top = img.lpbits;
+ img.nextline = img.width * 3;
+ img.bit = 24;
+
+ f->read(img.lpbits, f->GetSize());
+
+ bs_init();
+
+ cur_size = max_size + 1;
+
+ for (cur_size = max_size + 1; max_size < cur_size; q_scale++) {
+ cur_size = bs_encode((bs_header_t *) out, &img, 2, q_scale, 0);
+ }
+
+ for (int i = 0; i < cur_size; i++) {
+ b[i] = out[i];
+ }
+
+ L->push((lua_Number) cur_size);
+ L->push((lua_Number) q_scale);
+ }
+ case PSX_BLIT:
+ r = 0;
+ {
+ Handle * d = (Handle *) LuaObject::getme(L, 1);
+ Handle * s = (Handle *) LuaObject::getme(L, 2);
+ int dw = L->tonumber(3),
+ dh = L->tonumber(4),
+ sw = L->tonumber(5),
+ sh = L->tonumber(6),
+ sx = L->tonumber(7),
+ sy = L->tonumber(8),
+ bl = L->tonumber(9);
+ int bytes, dstart = 0, dskip = 0, sstart = 0, sskip = 0, i, j;
+ Byte RGB[3], R, G, B, A = 128;
+ void (*op_func)(Byte *, Byte, Byte, Byte, Byte);
+
+ switch(bl) {
+ case BLIT_OVER:
+ bytes = 3;
+ op_func = over;
+ break;
+ case BLIT_OVER32:
+ bytes = 4;
+ op_func = over;
+ break;
+ case BLIT_ALPHA:
+ bytes = 4;
+ op_func = alpha;
+ break;
+ case BLIT_LIGHTEN:
+ bytes = 3;
+ op_func = lighten;
+ break;
+ case BLIT_LIGHTEN32:
+ bytes = 4;
+ op_func = lighten;
+ break;
+ case BLIT_DARKEN:
+ bytes = 3;
+ op_func = darken;
+ break;
+ case BLIT_DARKEN32:
+ bytes = 4;
+ op_func = darken;
+ break;
+ default:
+ L->error("Blitting operation unknown.");
+ return 0;
+ }
+
+#if 0
+ if ((sx + sw) < 0)
+ return;
+
+ if (sx >= dw)
+ return;
+
+ if ((sy + sh) < 0)
+ return;
+
+ if (sy >= dh)
+ return;
+#endif
+
+ if (sy < 0) {
+ sstart -= sw * bytes * sy;
+ sh += sy;
+ sy = 0;
+ } else {
+ dstart += dw * 3 * sy;
+ }
+
+ if ((sy + sh) > dh) {
+ sh -= (sy + sh) - dh;
+ }
+
+ if (sx < 0) {
+ sstart -= sx * bytes;
+ sskip -= sx * bytes;
+ sw += sx;
+ sx = 0;
+ } else {
+ dstart += sx * 3;
+ }
+
+ if ((sx + sw) > dw) {
+ sskip += (sx + sw) - dw;
+ sw -= (sx + sw) - dw;
+ }
+
+ dskip = (dw - sw) * 3;
+
+ d->seek(dstart);
+ s->seek(sstart);
+
+ for (i = 0; i < sh; i++, s->seek(sskip, SEEK_CUR), d->seek(dskip, SEEK_CUR)) {
+ for (j = 0; j < sw; j++) {
+ RGB[0] = d->readU8();
+ RGB[1] = d->readU8();
+ RGB[2] = d->readU8();
+ d->seek(-3, SEEK_CUR);
+ R = s->readU8();
+ G = s->readU8();
+ B = s->readU8();
+ if (bytes == 4)
+ A = s->readU8();
+ op_func(RGB, R, G, B, A);
+ d->writeU8(R);
+ d->writeU8(G);
+ d->writeU8(B);
+ }
+ }
+
+ }
+ }
+ return r;
+}
diff --git a/lib/lzss.cpp b/lib/lzss.cpp index 1d7ecfb..7b134aa 100644 --- a/lib/lzss.cpp +++ b/lib/lzss.cpp @@ -1,464 +1,464 @@ -/* - * PSX-Tools Bundle Pack - * Copyright (C) 2002 Nicolas "Pixel" Noble - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <iostream> -#include "generic.h" -#include "lzss.h" -#include "Handle.h" - -lzss::lzss() : tolerate(1), blockb(0), scheme(schemes[0]), lzss_maxsize(18), lzss_maxptr(0x0fff) { - compute_limits(); -} - -/* - -Valkyrie Profile V2: - -JJJJJJJJ LLLLJJJJ -VVVVVVVV 1111RRRR -RRRRRRRR 11110000 VVVVVVVV - -*/ - -const lzss::scheme_t lzss::schemes[] = { -/* Nom 1 I J O N 16 P F W Lm1 Ls1 Lm2 Ls2 Jm1 Js1 Jm2 Js2 Fm1 Fs1 Fm2 Fs2 Vm1 Vs1 Vm2 Vs2 Flags*/ -#if 0 /* Zelda GC */ - {"Yaz0", 0, 1, 1, 0, 0, 0, 0, 0, 0, 0xf0, -4, 0x00, 0, 0x0f, 8, 0xff, 0, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, -#endif - {"Xenogears", 1, 0, 0, 1, 0, 0, 0, 0, 0, 0x00, 0, 0xf0, -4, 0xff, 0, 0x0f, 8, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, - {"DBZ RPG", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0f, 0, 0x00, 0, 0xf0, -4, 0xff, 4, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, - {"FF7", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0, 0x0f, 0, 0xff, 0, 0xf0, 4, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, - {"Leen Mean", 1, 1, 1, 1, 0, 0, 0, 0, 0, 0x0f, 0, 0x00, 0, 0xf0, 4, 0xff, 0, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, - {"Metal Max", 0, 0, 0, 1, 0, 0, 2, 0, 0x12, 0x00, 0, 0x0f, 0, 0xff, 0, 0xf0, 4, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, - {"Ogre Battle", 0, 0, 0, 1, 0, 0, 1, 0, 0, 0xf8, -3, 0x00, 0, 0x07, 8, 0xff, 0, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, - {"Lodoss Wars", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0, 0x7f, 0, 0xff, 0, 0x80, 1, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, - {"FF6 PSX", 0, 0, 0, 1, 1, 1, 0, 0, 0, 0x1f, 1, 0x00, 0, 0xe0, -4, 0xff, 4, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, - {"Valkyrie-1", 0, 0, 0, 1, 1, 0, 0, 0, 0, 0x00, 0, 0xf0, -4, 0xff, 0, 0x0f, 8, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, - {"Valkyrie-2", 0, 0, 0, 1, 1, 0, 0, 2, 0, 0x00, 0, 0xf0, -4, 0xff, 0, 0x0f, 8, 0x00, 0, 0x0f, 0, 0xff, 0, 0x00, 0}, - {"ToD", 0, 0, 0,-1, 1, 0, 1, 1, 3, 0x00, 0, 0x0f, 0, 0xff, 0, 0xf0, 4, 0x00, 0, 0xf0, -4, 0xff, 0, 0x00, 0}, - {0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0} -}; - -Byte lzss::swap_bits(Byte i) { - i = ((i >> 1) & 0x55) | ((i << 1) & 0xaa); - i = ((i >> 2) & 0x33) | ((i << 2) & 0xcc); - i = ((i >> 4) & 0x0f) | ((i << 4) & 0xf0); - return i; -} - -unsigned int lzss::shift(unsigned int c, int s) { - return s > 0 ? (c << s) : c >> (-s); -} - -void lzss::compute_limits(void) { - unsigned char val1, val2; - - val1 = val2 = 0xff; - - lzss_maxsize = shift(val1 & scheme.l_mask_1, scheme.l_shft_1) | - shift(val2 & scheme.l_mask_2, scheme.l_shft_2); - lzss_maxptr = shift(val1 & scheme.j_mask_1, scheme.j_shft_1) | - shift(val2 & scheme.j_mask_2, scheme.j_shft_2); - - lzss_maxsize = lzss_maxsize + 3 + scheme.sixteen_bits; - lzss_maxptr += scheme.one_jump; - - if (scheme.l_mask_1 & scheme.j_mask_1) { - printm(M_ERROR, "Masks are overlapping for value 1\n"); - exit(-1); - } - - if (scheme.l_mask_2 & scheme.j_mask_2) { - printm(M_ERROR, "Masks are overlapping for value 2\n"); - exit(-1); - } - - if (shift(scheme.l_mask_1, scheme.l_shft_1) & shift(scheme.l_mask_2, scheme.l_shft_2)) { - printm(M_ERROR, "Shifts build an overlap for lenght\n"); - exit(-1); - } - - if (shift(scheme.j_mask_1, scheme.j_shft_1) & shift(scheme.j_mask_2, scheme.j_shft_2)) { - printm(M_ERROR, "Shifts build an overlap for jump\n"); - exit(-1); - } - - printm(M_INFO, "Computed values: maxsize = %i, maxptr = 0x%06x\n", lzss_maxsize, lzss_maxptr); -} - -unsigned int lzss::lzss_decomp(Handle * f_source, Handle * f_cible, int true_length) -{ - unsigned char bitmap, fbitmap; - unsigned char valeur; - unsigned char * text_buf; - unsigned char val1, val2, val3; - int negative_error = scheme.negative_trick, overlap_error = scheme.overlap_trick == 1; - int r = 0; - int decomp_count; - int decomp_length; - int decomp_fill; - int decomp_jump; - int decomp_offset = 0; - int loop_length; - int whole_count; - int i, j; - int length, reads; - - compute_limits(); - - f_source->read(&length, 4); - if (true_length >= 0) { - length = true_length; - } - whole_count = 0; - - printm(M_INFO, "Decompressing %i bytes\n", length); - - text_buf = (unsigned char *) malloc(length + 8); - - do { - f_source->read(&bitmap, 1); - if (scheme.sixteen_bits) { - f_source->read(&fbitmap, 1); - printm(M_INFO, "16bits behavior, false bitmap = %02x\n", fbitmap); - } - printm(M_INFO, "Begin of block, bitmap = %02x\n", bitmap); - if (scheme.bitmap_inversed) { - bitmap = swap_bits(bitmap); - } - for (i = 0; i < 8; i++) { - printm(M_INFO, " - Chunk %i (offset cible = %li = 0x%04x, offset source = %li = 0x%04x)\n", i, f_cible->tell(), f_cible->tell(), f_source->tell(), f_source->tell()); - if (whole_count >= length) - break; - if ((bitmap & 1) ^ scheme.one_is_compressed) { - for (j = 0; j < (scheme.sixteen_bits ? 2 : 1); j++) { - reads = f_source->read(&valeur, 1); - if (!reads) { - printm(M_WARNING, " WARNING! PADDING!\n"); - free(text_buf); - return length; - } - printm(M_INFO, " Copying 0x%02x\n", valeur); - f_cible->write(&valeur, 1); - text_buf[r++] = valeur; - whole_count++; - } - } else { - f_source->read(&val1, 1); - f_source->read(&val2, 1); - decomp_length = shift(val1 & scheme.l_mask_1, scheme.l_shft_1) | - shift(val2 & scheme.l_mask_2, scheme.l_shft_2); - decomp_fill = shift(val1 & scheme.f_mask_1, scheme.f_shft_1) | - shift(val2 & scheme.f_mask_2, scheme.f_shft_2); - decomp_jump = shift(val1 & scheme.j_mask_1, scheme.j_shft_1) | - shift(val2 & scheme.j_mask_2, scheme.j_shft_2); - valeur = shift(val1 & scheme.v_mask_1, scheme.v_shft_1) | - shift(val2 & scheme.v_mask_2, scheme.v_shft_2); -// decomp_jump &= lzss_maxptr; bad, ugly, non working - decomp_jump += scheme.one_jump; - decomp_length = decomp_length + 3 + scheme.sixteen_bits; - decomp_fill = decomp_fill + 3 + scheme.sixteen_bits; -#if 0 /* Zelda GC */ - decomp_length--; - if (decomp_length == 2) { - printm(M_INFO, "Big jump\n"); - decomp_length = f_source->readU8() + 18; - } -#endif - if ((decomp_length == lzss_maxsize) && (scheme.filling)) { - if ((decomp_fill == 3) && (scheme.filling == 2)) { - f_source->read(&val3, 1); - printm(M_INFO, " Found an extended needle (val1 = 0x%02x, val2 = 0x%02x, val3 = 0x%02x)\n", val1, val2, val3); - decomp_fill = val1 + 19; - valeur = val3; - } else { - printm(M_INFO, " Found a 0x%02x-filling needle of %li bytes (val1 = 0x%02x, val2 = 0x%02x)\n", valeur, decomp_fill, val1, val2); - } - for (decomp_count = 0; decomp_count < decomp_fill; decomp_count++) { - f_cible->write(&valeur, 1); - text_buf[r++] = valeur; - if (!blockb) - whole_count++; - } - if (blockb) - whole_count++; - } else { - switch (scheme.ptrb) { - case 0: - decomp_offset = r - decomp_jump; - break; - case 1: - decomp_offset = r - lzss_maxptr - 1 + decomp_jump - scheme.window_start; - break; - case 2: - decomp_offset = decomp_jump - scheme.window_start; - break; - } - decomp_offset += scheme.overlap_trick == -1 ? decomp_length : 0; - loop_length = decomp_offset + decomp_length; - if ((loop_length >= r) && (!overlap_error)) { - if (!tolerate) { - free(text_buf); - return 0; - } - printm(M_ERROR, "Overlap trick used without it beeing enabled in the scheme.\n"); - overlap_error = 1; - } - printm(M_INFO, " Found a needle of %li bytes at %li = 0x%04x, jump of %li = 0x%04x (val1 = 0x%02x, val2 = 0x%02x)\n", decomp_length, decomp_offset, decomp_offset, decomp_jump, decomp_jump, val1, val2); - for (decomp_count = decomp_offset; decomp_count < loop_length; decomp_count++) { - if (!blockb) - whole_count++; - if (decomp_count < 0) { - valeur = 0; - f_cible->write(&valeur, 1); - text_buf[r++] = 0; - if (!negative_error) { - if (!tolerate) { - free(text_buf); - return 0; - } - printm(M_ERROR, "Negative trick used without it beeing enabled in the scheme.\n"); - negative_error = 1; - } - printm(M_INFO, "Filling with 0\n"); - } else { - f_cible->write(&text_buf[decomp_count], 1); - printm(M_INFO, "@0x%04x: 0x%02x\n", decomp_count, text_buf[decomp_count]); - text_buf[r++] = text_buf[decomp_count]; - } - if (whole_count >= length) - break; - } - if (blockb) - whole_count++; - } - } - bitmap >>= 1; - } - } while (whole_count < length); - free(text_buf); - - return length; -} - -unsigned char lzss::lzss_rd(unsigned char * t, int p) { - return ((p < 0) ? 0 : (t[p])); -} - -int lzss::lzss_comp_strstr(unsigned char * needle, unsigned char * r, int * l, int sp) { - char redo[256]; - int length, i, p, ptr, maxlength; - - i = 1; - redo[0] = p = 0; - while (i < lzss_maxsize) { - if (needle[i] == needle[p]) { - redo[i++] = ++p; - } else if (p > 0) { - p = redo[p - 1]; - } else { - redo[i++] = 0; - } - } - - length = maxlength = 0; - i = sp; - p = 0; - ptr = 0; - - while ((i - sp - (scheme.overlap_trick ? p : 0)) < *l) { - if (needle[p] == lzss_rd(r, i)) { - if (p == (lzss_maxsize - 1)) { - *l = lzss_maxsize; - return i - lzss_maxsize + 1; - } - i++; - p++; - } else if (p > 0) { - if (p > maxlength) { - if (!((i - p) & scheme.sixteen_bits)) { - ptr = i - (maxlength = p); - } - } - p = redo[p - 1]; - } else { - i++; - } - } - - *l = maxlength; - return ptr; -} - -unsigned char * lzss::lzss_memcomp(unsigned char * r, int * l, int * delta) { - unsigned char bitmap, * comp; - int ptr, needle, needle_length, comp_ptr, bitmap_ptr, val1, val2; - int jump, farest, remaining; - int j; - - comp = (unsigned char *) malloc(3 * *l); - - compute_limits(); - - ptr = 0; - blk = 0; - bitmap_count = 0; - comp_ptr = 1 + scheme.sixteen_bits; - bitmap = 0; - bitmap_ptr = 0; - printm(M_INFO, "Begin of block 0.\n"); - while ((remaining = *l - ptr) > 0) { - printm(M_INFO, " Remaining bytes: %li\n", remaining); - lzss_maxsize = MIN(lzss_maxsize, remaining); - bitmap_count++; - bitmap >>= 1; - farest = ptr - lzss_maxptr; - farest = farest > ((-lzss_maxsize) * scheme.negative_trick) ? farest : -lzss_maxsize * scheme.negative_trick; - needle_length = ptr - farest; - if (scheme.ptrb == 2) { - farest = 0; - needle_length = MIN(lzss_maxptr - scheme.window_start, ptr); - } - needle = lzss_comp_strstr(&r[ptr], r, &needle_length, farest); - if ((needle < 0) && ((-needle) > needle_length)) { - needle = -needle_length; - } - printm(M_INFO, " - Chunk %i (offset source = %li = 0x%04x, offset cible = %li = 0x%04x)\n", bitmap_count - 1, ptr, ptr, comp_ptr, comp_ptr); - jump = ptr - needle; - needle_length = needle_length > remaining ? remaining : needle_length; - - if (needle_length & scheme.sixteen_bits) { - needle_length--; - } - - if ((needle < 0) || (!jump)) { - printm(M_INFO, " Nothing found.\n"); - } else { - printm(M_INFO, " Found a needle of %i bytes at offset %i (jump = %i = 0x%04x)\n", needle_length, needle, jump, jump); - } - - if ((needle_length <= (2 + scheme.sixteen_bits)) || (!jump)) { - if (needle_length > 2) { - printm(M_ERROR, " ** REJECTED **\n"); - } - for (j = 0; j < (scheme.sixteen_bits ? 2 : 1); j++) { - printm(M_INFO, " Repeating 0x%02x\n", r[ptr]); - comp[comp_ptr] = r[ptr]; - ptr++; - comp_ptr++; - } - bitmap |= 0x80; - } else { - int j; - printm(M_INFO, " Found a needle of %li bytes at %li = 0x%04x\n", needle_length, needle, needle); - for (j = 0; j < needle_length; j++) { - printm(M_INFO, "@0x%04x: 0x%02x - @0x%04x: 0x%02x\n", needle + j, lzss_rd(r, needle + j - scheme.window_start), ptr + j, lzss_rd(r, ptr + j)); - if (lzss_rd(r, needle + j) != lzss_rd(r, ptr + j)) { - printm(M_ERROR, "ERROR!!\n"); - } - } - jump -= scheme.one_jump; - printm(M_INFO, "ptr = %li, needle = %li, jump = %li = 0x%03x\n", ptr, needle, jump, jump); - ptr += needle_length; - needle_length -= 3; - switch (scheme.ptrb) { - case 0: - break; - case 1: - jump = lzss_maxptr + 1 - jump; - break; - case 2: - jump = needle + scheme.window_start; - break; - } - val1 = comp[comp_ptr++] = (shift(jump, -scheme.j_shft_1) & scheme.j_mask_1) | - (shift(needle_length, -scheme.l_shft_1) & scheme.l_mask_1); - val2 = comp[comp_ptr++] = (shift(jump, -scheme.j_shft_2) & scheme.j_mask_2) | - (shift(needle_length, -scheme.l_shft_2) & scheme.l_mask_2); - printm(M_INFO, " writing info1 = 0x%02x, info2 = 0x%02x\n", val1, val2); - } - - bitmap ^= scheme.one_is_compressed << 7; - - if (bitmap_count == 8) { - blk++; - printm(M_INFO, "End of block, writing bitmap = 0x%02x\n", bitmap); - printm(M_INFO, "Begin of block %li.\n", blk); - bitmap_count = 0; - if (scheme.bitmap_inversed) - bitmap = swap_bits(bitmap); - comp[bitmap_ptr] = bitmap; - if (scheme.sixteen_bits) { - comp[bitmap_ptr + 1] = 0; - } - bitmap_ptr = comp_ptr; - comp_ptr += (scheme.sixteen_bits ? 2 : 1); - } - } - - if (bitmap_count) { - bitmap >>= (8 - bitmap_count); - if (scheme.bitmap_inversed) - bitmap = swap_bits(bitmap); - comp[bitmap_ptr] = bitmap; - if (scheme.sixteen_bits) { - comp[bitmap_ptr + 1] = 0; - } - } else { - comp_ptr--; - } - - if (delta) { - *delta = (bitmap_count ? 8 - bitmap_count : 0); - } - - *l = comp_ptr; - return comp; -} - -void lzss::lzss_comp(Handle * f_source, Handle * f_cible, int * delta) { - int length = f_source->GetSize(), l; - unsigned char * r = (unsigned char *) malloc(length), * c; - - f_source->read(r, length); - l = length; - c = lzss_memcomp(r, &l, delta); - if (delta) { - length += *delta; - } - f_cible->write(&length, 4); - if (delta) { - length -= *delta; - } - f_cible->write(c, l); - free(c); - free(r); -} - -void lzss::change_scheme(scheme_t new_scheme) { - scheme = new_scheme; - compute_limits(); -} - -lzss::scheme_t lzss::get_scheme() { - return scheme; -} +/*
+ * PSX-Tools Bundle Pack
+ * Copyright (C) 2002 Nicolas "Pixel" Noble
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <iostream>
+#include "generic.h"
+#include "lzss.h"
+#include "Handle.h"
+
+lzss::lzss() : tolerate(1), blockb(0), scheme(schemes[0]), lzss_maxsize(18), lzss_maxptr(0x0fff) {
+ compute_limits();
+}
+
+/*
+
+Valkyrie Profile V2:
+
+JJJJJJJJ LLLLJJJJ
+VVVVVVVV 1111RRRR
+RRRRRRRR 11110000 VVVVVVVV
+
+*/
+
+const lzss::scheme_t lzss::schemes[] = {
+/* Nom 1 I J O N 16 P F W Lm1 Ls1 Lm2 Ls2 Jm1 Js1 Jm2 Js2 Fm1 Fs1 Fm2 Fs2 Vm1 Vs1 Vm2 Vs2 Flags*/
+#if 0 /* Zelda GC */
+ {"Yaz0", 0, 1, 1, 0, 0, 0, 0, 0, 0, 0xf0, -4, 0x00, 0, 0x0f, 8, 0xff, 0, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
+#endif
+ {"Xenogears", 1, 0, 0, 1, 0, 0, 0, 0, 0, 0x00, 0, 0xf0, -4, 0xff, 0, 0x0f, 8, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
+ {"DBZ RPG", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0f, 0, 0x00, 0, 0xf0, -4, 0xff, 4, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
+ {"FF7", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0, 0x0f, 0, 0xff, 0, 0xf0, 4, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
+ {"Leen Mean", 1, 1, 1, 1, 0, 0, 0, 0, 0, 0x0f, 0, 0x00, 0, 0xf0, 4, 0xff, 0, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
+ {"Metal Max", 0, 0, 0, 1, 0, 0, 2, 0, 0x12, 0x00, 0, 0x0f, 0, 0xff, 0, 0xf0, 4, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
+ {"Ogre Battle", 0, 0, 0, 1, 0, 0, 1, 0, 0, 0xf8, -3, 0x00, 0, 0x07, 8, 0xff, 0, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
+ {"Lodoss Wars", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0, 0x7f, 0, 0xff, 0, 0x80, 1, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
+ {"FF6 PSX", 0, 0, 0, 1, 1, 1, 0, 0, 0, 0x1f, 1, 0x00, 0, 0xe0, -4, 0xff, 4, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
+ {"Valkyrie-1", 0, 0, 0, 1, 1, 0, 0, 0, 0, 0x00, 0, 0xf0, -4, 0xff, 0, 0x0f, 8, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0},
+ {"Valkyrie-2", 0, 0, 0, 1, 1, 0, 0, 2, 0, 0x00, 0, 0xf0, -4, 0xff, 0, 0x0f, 8, 0x00, 0, 0x0f, 0, 0xff, 0, 0x00, 0},
+ {"ToD", 0, 0, 0,-1, 1, 0, 1, 1, 3, 0x00, 0, 0x0f, 0, 0xff, 0, 0xf0, 4, 0x00, 0, 0xf0, -4, 0xff, 0, 0x00, 0},
+ {0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}
+};
+
+Byte lzss::swap_bits(Byte i) {
+ i = ((i >> 1) & 0x55) | ((i << 1) & 0xaa);
+ i = ((i >> 2) & 0x33) | ((i << 2) & 0xcc);
+ i = ((i >> 4) & 0x0f) | ((i << 4) & 0xf0);
+ return i;
+}
+
+unsigned int lzss::shift(unsigned int c, int s) {
+ return s > 0 ? (c << s) : c >> (-s);
+}
+
+void lzss::compute_limits(void) {
+ unsigned char val1, val2;
+
+ val1 = val2 = 0xff;
+
+ lzss_maxsize = shift(val1 & scheme.l_mask_1, scheme.l_shft_1) |
+ shift(val2 & scheme.l_mask_2, scheme.l_shft_2);
+ lzss_maxptr = shift(val1 & scheme.j_mask_1, scheme.j_shft_1) |
+ shift(val2 & scheme.j_mask_2, scheme.j_shft_2);
+
+ lzss_maxsize = lzss_maxsize + 3 + scheme.sixteen_bits;
+ lzss_maxptr += scheme.one_jump;
+
+ if (scheme.l_mask_1 & scheme.j_mask_1) {
+ printm(M_ERROR, "Masks are overlapping for value 1\n");
+ exit(-1);
+ }
+
+ if (scheme.l_mask_2 & scheme.j_mask_2) {
+ printm(M_ERROR, "Masks are overlapping for value 2\n");
+ exit(-1);
+ }
+
+ if (shift(scheme.l_mask_1, scheme.l_shft_1) & shift(scheme.l_mask_2, scheme.l_shft_2)) {
+ printm(M_ERROR, "Shifts build an overlap for lenght\n");
+ exit(-1);
+ }
+
+ if (shift(scheme.j_mask_1, scheme.j_shft_1) & shift(scheme.j_mask_2, scheme.j_shft_2)) {
+ printm(M_ERROR, "Shifts build an overlap for jump\n");
+ exit(-1);
+ }
+
+ printm(M_INFO, "Computed values: maxsize = %i, maxptr = 0x%06x\n", lzss_maxsize, lzss_maxptr);
+}
+
+unsigned int lzss::lzss_decomp(Handle * f_source, Handle * f_cible, int true_length)
+{
+ unsigned char bitmap, fbitmap;
+ unsigned char valeur;
+ unsigned char * text_buf;
+ unsigned char val1, val2, val3;
+ int negative_error = scheme.negative_trick, overlap_error = scheme.overlap_trick == 1;
+ int r = 0;
+ int decomp_count;
+ int decomp_length;
+ int decomp_fill;
+ int decomp_jump;
+ int decomp_offset = 0;
+ int loop_length;
+ int whole_count;
+ int i, j;
+ int length, reads;
+
+ compute_limits();
+
+ f_source->read(&length, 4);
+ if (true_length >= 0) {
+ length = true_length;
+ }
+ whole_count = 0;
+
+ printm(M_INFO, "Decompressing %i bytes\n", length);
+
+ text_buf = (unsigned char *) malloc(length + 8);
+
+ do {
+ f_source->read(&bitmap, 1);
+ if (scheme.sixteen_bits) {
+ f_source->read(&fbitmap, 1);
+ printm(M_INFO, "16bits behavior, false bitmap = %02x\n", fbitmap);
+ }
+ printm(M_INFO, "Begin of block, bitmap = %02x\n", bitmap);
+ if (scheme.bitmap_inversed) {
+ bitmap = swap_bits(bitmap);
+ }
+ for (i = 0; i < 8; i++) {
+ printm(M_INFO, " - Chunk %i (offset cible = %li = 0x%04x, offset source = %li = 0x%04x)\n", i, f_cible->tell(), f_cible->tell(), f_source->tell(), f_source->tell());
+ if (whole_count >= length)
+ break;
+ if ((bitmap & 1) ^ scheme.one_is_compressed) {
+ for (j = 0; j < (scheme.sixteen_bits ? 2 : 1); j++) {
+ reads = f_source->read(&valeur, 1);
+ if (!reads) {
+ printm(M_WARNING, " WARNING! PADDING!\n");
+ free(text_buf);
+ return length;
+ }
+ printm(M_INFO, " Copying 0x%02x\n", valeur);
+ f_cible->write(&valeur, 1);
+ text_buf[r++] = valeur;
+ whole_count++;
+ }
+ } else {
+ f_source->read(&val1, 1);
+ f_source->read(&val2, 1);
+ decomp_length = shift(val1 & scheme.l_mask_1, scheme.l_shft_1) |
+ shift(val2 & scheme.l_mask_2, scheme.l_shft_2);
+ decomp_fill = shift(val1 & scheme.f_mask_1, scheme.f_shft_1) |
+ shift(val2 & scheme.f_mask_2, scheme.f_shft_2);
+ decomp_jump = shift(val1 & scheme.j_mask_1, scheme.j_shft_1) |
+ shift(val2 & scheme.j_mask_2, scheme.j_shft_2);
+ valeur = shift(val1 & scheme.v_mask_1, scheme.v_shft_1) |
+ shift(val2 & scheme.v_mask_2, scheme.v_shft_2);
+// decomp_jump &= lzss_maxptr; bad, ugly, non working
+ decomp_jump += scheme.one_jump;
+ decomp_length = decomp_length + 3 + scheme.sixteen_bits;
+ decomp_fill = decomp_fill + 3 + scheme.sixteen_bits;
+#if 0 /* Zelda GC */
+ decomp_length--;
+ if (decomp_length == 2) {
+ printm(M_INFO, "Big jump\n");
+ decomp_length = f_source->readU8() + 18;
+ }
+#endif
+ if ((decomp_length == lzss_maxsize) && (scheme.filling)) {
+ if ((decomp_fill == 3) && (scheme.filling == 2)) {
+ f_source->read(&val3, 1);
+ printm(M_INFO, " Found an extended needle (val1 = 0x%02x, val2 = 0x%02x, val3 = 0x%02x)\n", val1, val2, val3);
+ decomp_fill = val1 + 19;
+ valeur = val3;
+ } else {
+ printm(M_INFO, " Found a 0x%02x-filling needle of %li bytes (val1 = 0x%02x, val2 = 0x%02x)\n", valeur, decomp_fill, val1, val2);
+ }
+ for (decomp_count = 0; decomp_count < decomp_fill; decomp_count++) {
+ f_cible->write(&valeur, 1);
+ text_buf[r++] = valeur;
+ if (!blockb)
+ whole_count++;
+ }
+ if (blockb)
+ whole_count++;
+ } else {
+ switch (scheme.ptrb) {
+ case 0:
+ decomp_offset = r - decomp_jump;
+ break;
+ case 1:
+ decomp_offset = r - lzss_maxptr - 1 + decomp_jump - scheme.window_start;
+ break;
+ case 2:
+ decomp_offset = decomp_jump - scheme.window_start;
+ break;
+ }
+ decomp_offset += scheme.overlap_trick == -1 ? decomp_length : 0;
+ loop_length = decomp_offset + decomp_length;
+ if ((loop_length >= r) && (!overlap_error)) {
+ if (!tolerate) {
+ free(text_buf);
+ return 0;
+ }
+ printm(M_ERROR, "Overlap trick used without it beeing enabled in the scheme.\n");
+ overlap_error = 1;
+ }
+ printm(M_INFO, " Found a needle of %li bytes at %li = 0x%04x, jump of %li = 0x%04x (val1 = 0x%02x, val2 = 0x%02x)\n", decomp_length, decomp_offset, decomp_offset, decomp_jump, decomp_jump, val1, val2);
+ for (decomp_count = decomp_offset; decomp_count < loop_length; decomp_count++) {
+ if (!blockb)
+ whole_count++;
+ if (decomp_count < 0) {
+ valeur = 0;
+ f_cible->write(&valeur, 1);
+ text_buf[r++] = 0;
+ if (!negative_error) {
+ if (!tolerate) {
+ free(text_buf);
+ return 0;
+ }
+ printm(M_ERROR, "Negative trick used without it beeing enabled in the scheme.\n");
+ negative_error = 1;
+ }
+ printm(M_INFO, "Filling with 0\n");
+ } else {
+ f_cible->write(&text_buf[decomp_count], 1);
+ printm(M_INFO, "@0x%04x: 0x%02x\n", decomp_count, text_buf[decomp_count]);
+ text_buf[r++] = text_buf[decomp_count];
+ }
+ if (whole_count >= length)
+ break;
+ }
+ if (blockb)
+ whole_count++;
+ }
+ }
+ bitmap >>= 1;
+ }
+ } while (whole_count < length);
+ free(text_buf);
+
+ return length;
+}
+
+unsigned char lzss::lzss_rd(unsigned char * t, int p) {
+ return ((p < 0) ? 0 : (t[p]));
+}
+
+int lzss::lzss_comp_strstr(unsigned char * needle, unsigned char * r, int * l, int sp) {
+ char redo[256];
+ int length, i, p, ptr, maxlength;
+
+ i = 1;
+ redo[0] = p = 0;
+ while (i < lzss_maxsize) {
+ if (needle[i] == needle[p]) {
+ redo[i++] = ++p;
+ } else if (p > 0) {
+ p = redo[p - 1];
+ } else {
+ redo[i++] = 0;
+ }
+ }
+
+ length = maxlength = 0;
+ i = sp;
+ p = 0;
+ ptr = 0;
+
+ while ((i - sp - (scheme.overlap_trick ? p : 0)) < *l) {
+ if (needle[p] == lzss_rd(r, i)) {
+ if (p == (lzss_maxsize - 1)) {
+ *l = lzss_maxsize;
+ return i - lzss_maxsize + 1;
+ }
+ i++;
+ p++;
+ } else if (p > 0) {
+ if (p > maxlength) {
+ if (!((i - p) & scheme.sixteen_bits)) {
+ ptr = i - (maxlength = p);
+ }
+ }
+ p = redo[p - 1];
+ } else {
+ i++;
+ }
+ }
+
+ *l = maxlength;
+ return ptr;
+}
+
+unsigned char * lzss::lzss_memcomp(unsigned char * r, int * l, int * delta) {
+ unsigned char bitmap, * comp;
+ int ptr, needle, needle_length, comp_ptr, bitmap_ptr, val1, val2;
+ int jump, farest, remaining;
+ int j;
+
+ comp = (unsigned char *) malloc(3 * *l);
+
+ compute_limits();
+
+ ptr = 0;
+ blk = 0;
+ bitmap_count = 0;
+ comp_ptr = 1 + scheme.sixteen_bits;
+ bitmap = 0;
+ bitmap_ptr = 0;
+ printm(M_INFO, "Begin of block 0.\n");
+ while ((remaining = *l - ptr) > 0) {
+ printm(M_INFO, " Remaining bytes: %li\n", remaining);
+ lzss_maxsize = MIN(lzss_maxsize, remaining);
+ bitmap_count++;
+ bitmap >>= 1;
+ farest = ptr - lzss_maxptr;
+ farest = farest > ((-lzss_maxsize) * scheme.negative_trick) ? farest : -lzss_maxsize * scheme.negative_trick;
+ needle_length = ptr - farest;
+ if (scheme.ptrb == 2) {
+ farest = 0;
+ needle_length = MIN(lzss_maxptr - scheme.window_start, ptr);
+ }
+ needle = lzss_comp_strstr(&r[ptr], r, &needle_length, farest);
+ if ((needle < 0) && ((-needle) > needle_length)) {
+ needle = -needle_length;
+ }
+ printm(M_INFO, " - Chunk %i (offset source = %li = 0x%04x, offset cible = %li = 0x%04x)\n", bitmap_count - 1, ptr, ptr, comp_ptr, comp_ptr);
+ jump = ptr - needle;
+ needle_length = needle_length > remaining ? remaining : needle_length;
+
+ if (needle_length & scheme.sixteen_bits) {
+ needle_length--;
+ }
+
+ if ((needle < 0) || (!jump)) {
+ printm(M_INFO, " Nothing found.\n");
+ } else {
+ printm(M_INFO, " Found a needle of %i bytes at offset %i (jump = %i = 0x%04x)\n", needle_length, needle, jump, jump);
+ }
+
+ if ((needle_length <= (2 + scheme.sixteen_bits)) || (!jump)) {
+ if (needle_length > 2) {
+ printm(M_ERROR, " ** REJECTED **\n");
+ }
+ for (j = 0; j < (scheme.sixteen_bits ? 2 : 1); j++) {
+ printm(M_INFO, " Repeating 0x%02x\n", r[ptr]);
+ comp[comp_ptr] = r[ptr];
+ ptr++;
+ comp_ptr++;
+ }
+ bitmap |= 0x80;
+ } else {
+ int j;
+ printm(M_INFO, " Found a needle of %li bytes at %li = 0x%04x\n", needle_length, needle, needle);
+ for (j = 0; j < needle_length; j++) {
+ printm(M_INFO, "@0x%04x: 0x%02x - @0x%04x: 0x%02x\n", needle + j, lzss_rd(r, needle + j - scheme.window_start), ptr + j, lzss_rd(r, ptr + j));
+ if (lzss_rd(r, needle + j) != lzss_rd(r, ptr + j)) {
+ printm(M_ERROR, "ERROR!!\n");
+ }
+ }
+ jump -= scheme.one_jump;
+ printm(M_INFO, "ptr = %li, needle = %li, jump = %li = 0x%03x\n", ptr, needle, jump, jump);
+ ptr += needle_length;
+ needle_length -= 3;
+ switch (scheme.ptrb) {
+ case 0:
+ break;
+ case 1:
+ jump = lzss_maxptr + 1 - jump;
+ break;
+ case 2:
+ jump = needle + scheme.window_start;
+ break;
+ }
+ val1 = comp[comp_ptr++] = (shift(jump, -scheme.j_shft_1) & scheme.j_mask_1) |
+ (shift(needle_length, -scheme.l_shft_1) & scheme.l_mask_1);
+ val2 = comp[comp_ptr++] = (shift(jump, -scheme.j_shft_2) & scheme.j_mask_2) |
+ (shift(needle_length, -scheme.l_shft_2) & scheme.l_mask_2);
+ printm(M_INFO, " writing info1 = 0x%02x, info2 = 0x%02x\n", val1, val2);
+ }
+
+ bitmap ^= scheme.one_is_compressed << 7;
+
+ if (bitmap_count == 8) {
+ blk++;
+ printm(M_INFO, "End of block, writing bitmap = 0x%02x\n", bitmap);
+ printm(M_INFO, "Begin of block %li.\n", blk);
+ bitmap_count = 0;
+ if (scheme.bitmap_inversed)
+ bitmap = swap_bits(bitmap);
+ comp[bitmap_ptr] = bitmap;
+ if (scheme.sixteen_bits) {
+ comp[bitmap_ptr + 1] = 0;
+ }
+ bitmap_ptr = comp_ptr;
+ comp_ptr += (scheme.sixteen_bits ? 2 : 1);
+ }
+ }
+
+ if (bitmap_count) {
+ bitmap >>= (8 - bitmap_count);
+ if (scheme.bitmap_inversed)
+ bitmap = swap_bits(bitmap);
+ comp[bitmap_ptr] = bitmap;
+ if (scheme.sixteen_bits) {
+ comp[bitmap_ptr + 1] = 0;
+ }
+ } else {
+ comp_ptr--;
+ }
+
+ if (delta) {
+ *delta = (bitmap_count ? 8 - bitmap_count : 0);
+ }
+
+ *l = comp_ptr;
+ return comp;
+}
+
+void lzss::lzss_comp(Handle * f_source, Handle * f_cible, int * delta) {
+ int length = f_source->GetSize(), l;
+ unsigned char * r = (unsigned char *) malloc(length), * c;
+
+ f_source->read(r, length);
+ l = length;
+ c = lzss_memcomp(r, &l, delta);
+ if (delta) {
+ length += *delta;
+ }
+ f_cible->write(&length, 4);
+ if (delta) {
+ length -= *delta;
+ }
+ f_cible->write(c, l);
+ free(c);
+ free(r);
+}
+
+void lzss::change_scheme(scheme_t new_scheme) {
+ scheme = new_scheme;
+ compute_limits();
+}
+
+lzss::scheme_t lzss::get_scheme() {
+ return scheme;
+}
diff --git a/lib/mips.cpp b/lib/mips.cpp index 1378227..05a1201 100644 --- a/lib/mips.cpp +++ b/lib/mips.cpp @@ -1,1068 +1,1068 @@ -/* - * PSX-Tools Bundle Pack - * Copyright (C) 2002-2003 Nicolas "Pixel" Noble - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* $Id: mips.cpp,v 1.3 2004-01-03 15:04:47 pixel Exp $ */ - -#include "mips.h" - -/* Code HIGHLY ripped off^W^W inspired from PCSX. */ - -#if 1 -char * registers[] = { - "0", "at", "v0", "v1", "a0", "a1", "a2", "a3", - "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", - "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", - "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra", -}; -#else -char * registers[] = { - "00", "01", "02", "03", "04", "05", "06", "07", - "08", "09", "0a", "0b", "0c", "0d", "0e", "0f", - "10", "11", "12", "13", "14", "15", "16", "17", - "18", "19", "1a", "1b", "1c", "1d", "1e", "1f", -}; -#endif - -char * CP0registers[] = { - "Index" , "Random" , "EntryLo0", "EntryLo1", "Context" , "PageMask" , "Wired" , "*Check me*", - "BadVAddr" , "Count" , "EntryHi" , "Compare" , "Status" , "Cause" , "ExceptPC" , "PRevID" , - "Config" , "LLAddr" , "WatchLo" , "WatchHi" , "XContext", "*RES*" , "*RES*" , "*RES*" , - "*RES*" , "*RES* " , "PErr" , "CacheErr", "TagLo" , "TagHi" , "ErrorEPC" , "*RES*" }; - -typedef void (*TdisR3000AF)(TDis *, Uint32 code, Uint32 pc); - -// These macros are used to assemble the disassembler functions -#define MakeDisF(fn, b) \ - static void fn(TDis * d, Uint32 code, Uint32 pc) { \ - d->pc = pc; \ - b; \ - } - -#define _Funct_ ((code ) & 0x3F) // The funct part of the instruction register -#define _Rd_ ((code >> 11) & 0x1F) // The rd part of the instruction register -#define _Rt_ ((code >> 16) & 0x1F) // The rt part of the instruction register -#define _Rs_ ((code >> 21) & 0x1F) // The rs part of the instruction register -#define _Sa_ ((code >> 6) & 0x1F) // The sa part of the instruction register -#define _Im_ ( code & 0xFFFF) // The immediate part of the instruction register - // The signed immediate part of the instruction register -#define _sIm_ (code & 0x8000 ? - (((~code) & 0x7FFF) + 1) : ( code & 0x7FFF)) - -#define _Target_ (0x80000000 + ((code & 0x03ffffff) * 4)) -#define _Branch_ (pc + 4 + ((short)_Im_ * 4)) -#define _OfB_ _Im_, _nRs_ - -#define dName(n) { d->Name(n); } -#define dGPR(i) { d->PushGPReg(i); } -#define dCP0(i) { d->PushCPReg(i); } -#define dImm() { d->PushImm(_Im_); } -#define dTarget() { d->PushTarget(_Target_); } -#define dSa() { d->PushSa(_Sa_); } -#if 0 -#define dOfB() { \ - Uint32 pcode = d->getmem()->Read32(pc - 4); \ - if ((((pcode >> 16) & 0x1F) == _Rs_) && ((pcode >> 26) == 0xf)) { \ - Uint32 full; \ - Uint16 lower; \ - int16 slower; \ - lower = _Im_; \ - slower = *((int16 *) &lower); \ - \ - full = ((pcode & 0xffff) << 16) + slower; \ - \ - d->PushOfB(_Rs_, full, width); \ - \ - dMemRefer(full, width); \ - } else { \ - d->PushOfB(_Rs_, _Im_, width); \ - } \ -} -#else -#define dOfB() { \ - d->PushOfB(_Rs_, _Im_, width); \ -} -#endif -#define dOffset() { \ - d->PushOffset(_Branch_); \ -} -// printf(" ; Maybe RefTo %8.8lX", offset); -#define dFull(full) { \ - d->PushFull(full); \ - d->Comment("MaybeRefTo..."); \ -} - -#define sep - -#define dInvalid() { \ - d->SetTag(pc, CODE, false); \ - d->SetTag(pc, STOP, true); \ - d->Invalid(); \ -} - -#define dSuspect() { \ - d->Suspect(); \ - d->Comment("Suspect!"); \ -} -#if 0 // with OfB... -// printf(" ; RefTo %8.8lX - %i bits", offset, width); -#define dMemRefer(offset, width) { \ - d->PushMemref(offset, width); \ - d->Comment("RefTo..."); \ -} -#endif - -#define Invalidate(reg) { \ - if (!reg) \ - dSuspect(); \ -} - -#define SetReg(reg, val) { \ - if (!reg) \ - dSuspect(); \ -} - -#define MarkFunction(target) { \ - d->add_function(target); \ -} - -#define Branch(branch) { \ - d->add_branch(branch); \ -} - -#define Jump(target) { \ - d->add_jump(target); \ -} - -#define Stop(target) { \ - d->SetTag(target, STOP, true); \ -} - -/********************************************************* -* Arithmetic with immediate operand * -* Format: OP rt, rs, immediate * -*********************************************************/ - -MakeDisF(disADDI, - dName("addi"); - - dGPR(_Rt_); sep; - if (_Rt_ != _Rs_) { - dGPR(_Rs_); sep; - } - dImm(); - - Invalidate(_Rt_); - - d->Comment("Add immediate"); -) - -MakeDisF(disADDIU, - if (!_Rs_) { - dName("li"); - - dGPR(_Rt_); sep; - dImm(); - - Uint32 full; - int32 sfull; - Uint16 lower; - int16 slower; - lower = _Im_; - slower = *((int16 *) &lower); - - sfull = slower; - full = *((Uint32 *) &sfull); - - SetReg(_Rt_, full); - - d->Comment("Load immediate"); - } else { - Uint32 pcode = d->getmem()->Read32(pc - 4); - if ((((pcode >> 16) & 0x1F) == _Rt_) && (_Rt_ == _Rs_) && ((pcode >> 26) == 0xf)) { - Uint32 full; - Uint16 lower; - int16 slower; - lower = _Im_; - slower = *((int16 *) &lower); - - full = ((pcode & 0xffff) << 16) + slower; - - dName("li"); - dGPR(_Rt_); sep; - dFull(full); - SetReg(_Rt_, full); - d->Comment("Load immediate (aggregate)"); - } else { - dName("addiu"); - - dGPR(_Rt_); sep; - if (_Rt_ != _Rs_) { - dGPR(_Rs_); sep; - } - dImm(); - - Invalidate(_Rt_); - - d->Comment("Add immediate"); - } - } -) - -MakeDisF(disANDI, - dName("andi"); - - dGPR(_Rt_); sep; - if (_Rt_ != _Rs_) { - dGPR(_Rs_); sep; - } - dImm(); - - Invalidate(_Rt_); - - d->Comment("And immediate"); -) - -MakeDisF(disORI, - if (!_Rs_) { - dName("liu"); - - dGPR(_Rt_); sep; - dImm(); - SetReg(_Rt_, _Im_); - - d->Comment("Load immediate without sign extension"); - } else { - dName("ori"); - - dGPR(_Rt_); sep; - if (_Rt_ != _Rs_) { - dGPR(_Rs_); sep; - } - dImm(); - Invalidate(_Rt_); - d->Comment("Or immediate"); - } -) - -MakeDisF(disSLTI, - dName("slti"); - - dGPR(_Rt_); sep; - if (_Rt_ != _Rs_) { - dGPR(_Rs_); sep; - } - dImm(); - - Invalidate(_Rt_); - - d->Comment(registers[_Rt_] + String(" = ") + registers[_Rs_] + " < immediate ? 1 : 0 (signed)"); -) - -MakeDisF(disSLTIU, - dName("sltiu"); - - dGPR(_Rt_); sep; - if (_Rt_ != _Rs_) { - dGPR(_Rs_); sep; - } - dImm(); - - Invalidate(_Rt_); - - d->Comment(registers[_Rt_] + String(" = ") + registers[_Rs_] + " < immediate ? 1 : 0 (unsigned)"); -) - -MakeDisF(disXORI, - dName("xori"); - - dGPR(_Rt_); sep; - if (_Rt_ != _Rs_) { - dGPR(_Rs_); sep; - } - dImm(); - - Invalidate(_Rt_); - - d->Comment("XOr immediate"); -) - -/********************************************************* -* Register arithmetic * -* Format: OP rd, rs, rt * -*********************************************************/ -MakeDisF(disADD, - dName("add"); - - dGPR(_Rd_); sep; - if (_Rd_ != _Rs_) { - dGPR(_Rs_); sep; - } - dGPR(_Rt_); - - Invalidate(_Rt_); - - d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " + " + registers[_Rt_]); -) - -MakeDisF(disADDU, - if (!_Rt_) { - dName("move"); - - dGPR(_Rd_); sep; - dGPR(_Rs_); - if (_Rs_) { - Invalidate(_Rd_); - } else { - SetReg(_Rd_, 0); - } - d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_]); - } else { - dName("addu"); - - dGPR(_Rd_); sep; - if (_Rd_ != _Rs_) { - dGPR(_Rs_); sep; - } - dGPR(_Rt_); - Invalidate(_Rd_); - d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " + " + registers[_Rt_]); - } -) - -MakeDisF(disAND, - dName("and"); - - dGPR(_Rd_); sep; - if (_Rd_ != _Rs_) { - dGPR(_Rs_); sep; - } - dGPR(_Rt_); - Invalidate(_Rd_); - d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " & " + registers[_Rt_]); -) - -MakeDisF(disNOR, - dName("nor"); - - dGPR(_Rd_); sep; - if (_Rd_ != _Rs_) { - dGPR(_Rs_); sep; - } - dGPR(_Rt_); - Invalidate(_Rd_); - d->Comment(String(registers[_Rd_]) + " = ~(" + registers[_Rs_] + " & " + registers[_Rt_] + ")"); -) - -MakeDisF(disOR, - dName("or"); - - dGPR(_Rd_); sep; - if (_Rd_ != _Rs_) { - dGPR(_Rs_); sep; - } - dGPR(_Rt_); - Invalidate(_Rd_); - d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " | " + registers[_Rt_]); -) - -MakeDisF(disSLT, - dName("slt"); - - dGPR(_Rd_); sep; - if (_Rd_ != _Rs_) { - dGPR(_Rs_); sep; - } - dGPR(_Rt_); - Invalidate(_Rd_); - d->Comment(registers[_Rd_] + String(" = ") + registers[_Rs_] + " < " + registers[_Rt_] + " ? 1 : 0 (signed)"); -) - -MakeDisF(disSLTU, - dName("sltu"); - - dGPR(_Rd_); sep; - if (_Rd_ != _Rs_) { - dGPR(_Rs_); sep; - } - dGPR(_Rt_); - Invalidate(_Rd_); - d->Comment(registers[_Rd_] + String(" = ") + registers[_Rs_] + " < " + registers[_Rt_] + " ? 1 : 0 (unsigned)"); -) - -MakeDisF(disSUB, - dName("sub"); - - dGPR(_Rd_); sep; - if (_Rd_ != _Rs_) { - dGPR(_Rs_); sep; - } - dGPR(_Rt_); - Invalidate(_Rd_); - d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " - " + registers[_Rt_]); -) - -MakeDisF(disSUBU, - dName("subu"); - - dGPR(_Rd_); sep; - if (_Rd_ != _Rs_) { - dGPR(_Rs_); sep; - } - dGPR(_Rt_); - Invalidate(_Rd_); - d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " - " + registers[_Rt_]); -) - -MakeDisF(disXOR, - dName("xor"); - - dGPR(_Rd_); sep; - if (_Rd_ != _Rs_) { - dGPR(_Rs_); sep; - } - dGPR(_Rt_); - Invalidate(_Rd_); - d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " ^ " + registers[_Rt_]); -) - -/********************************************************* -* Register arithmetic & Register trap logic * -* Format: OP rs, rt * -*********************************************************/ -MakeDisF(disDIV, - dName("div"); - - dGPR(_Rs_); sep; - dGPR(_Rt_); - - String c1 = String(registers[_Rs_]) + " / " + registers[_Rt_]; - String c2 = String(registers[_Rs_]) + " %% " + registers[_Rt_]; - - d->Comment("lo = " + c1 + "; hi = " + c2); -) - -MakeDisF(disDIVU, - dName("divu"); - - dGPR(_Rs_); sep; - dGPR(_Rt_); - - d->Comment(String("lo = " ) + registers[_Rs_] + " / " + registers[_Rt_] + "; hi = " + registers[_Rs_] + " % " + registers[_Rt_]); -) - -MakeDisF(disMULT, - dName("mult"); - - dGPR(_Rs_); sep; - dGPR(_Rt_); - - d->Comment(String("hilo = ") + registers[_Rs_] + " * " + registers[_Rt_]); -) - -MakeDisF(disMULTU, - dName("multu"); - - dGPR(_Rs_); sep; - dGPR(_Rt_); - - d->Comment(String("hilo = ") + registers[_Rs_] + " * " + registers[_Rt_]); -) - -/********************************************************* -* Register branch logic * -* Format: OP rs, offset * -*********************************************************/ -MakeDisF(disBGEZ, - dName("bgez"); - - dGPR(_Rs_); sep; - dOffset(); - Branch(_Branch_); - d->Comment("Branch if " + String(registers[_Rs_]) + " >= 0"); -) - -MakeDisF(disBGEZAL, - dName("bgezal"); - - dGPR(_Rs_); sep; - dOffset(); - Branch(_Branch_); - d->Comment("Branch and link if " + String(registers[_Rs_]) + " >= 0"); -) - -MakeDisF(disBGTZ, - dName("bgtz"); - - dGPR(_Rs_); sep; - dOffset(); - Branch(_Branch_); - d->Comment("Branch if " + String(registers[_Rs_]) + " > 0"); -) - -MakeDisF(disBLEZ, - dName("blez"); - - dGPR(_Rs_); sep; - dOffset(); - Branch(_Branch_); - d->Comment("Branch if " + String(registers[_Rs_]) + " <= 0"); -) - -MakeDisF(disBLTZ, - dName("bltz"); - - dGPR(_Rs_); sep; - dOffset(); - Branch(_Branch_); - d->Comment("Branch if " + String(registers[_Rs_]) + " < 0"); -) - -MakeDisF(disBLTZAL, - dName("bltzal"); - - dGPR(_Rs_); sep; - dOffset(); - Branch(_Branch_); - d->Comment("Branch and link if " + String(registers[_Rs_]) + " <= 0"); -) - -/********************************************************* -* Shift arithmetic with constant shift * -* Format: OP rd, rt, sa * -*********************************************************/ -MakeDisF(disSLL, - if ((!_Rd_) && (!_Rt_)) { - dName("nop"); - if (code) { - dSuspect(); - } - } else { - dName("sll"); - - dGPR(_Rd_); sep; - if (_Rd_ != _Rt_) { - dGPR(_Rt_); sep; - } - dSa(); - Invalidate(_Rd_); - d->Comment(String(registers[_Rd_]) + " = " + registers[_Rt_] + " << immediate"); - } -) - -MakeDisF(disSRA, - dName("sra"); - - dGPR(_Rd_); sep; - if (_Rd_ != _Rt_) { - dGPR(_Rt_); sep; - } - dSa(); - Invalidate(_Rd_); - d->Comment(String(registers[_Rd_]) + " = " + registers[_Rt_] + " >> immediate (arithmetic)"); -) - -MakeDisF(disSRL, - dName("srl"); - - dGPR(_Rd_); sep; - if (_Rd_ != _Rt_) { - dGPR(_Rt_); sep; - } - dSa(); - Invalidate(_Rd_); - d->Comment(String(registers[_Rd_]) + " = " + registers[_Rt_] + " >> immediate (logical)"); -) - -/********************************************************* -* Shift arithmetic with variant register shift * -* Format: OP rd, rt, rs * -*********************************************************/ -MakeDisF(disSLLV, - dName("sllv"); - - dGPR(_Rd_); sep; - if (_Rd_ != _Rt_) { - dGPR(_Rt_); sep; - } - dGPR(_Rs_); - Invalidate(_Rd_); - d->Comment(String(registers[_Rd_]) + " = " + registers[_Rt_] + " << " + registers[_Rs_]); -) - -MakeDisF(disSRAV, - dName("srav"); - - dGPR(_Rd_); sep; - if (_Rd_ != _Rt_) { - dGPR(_Rt_); sep; - } - dGPR(_Rs_); - Invalidate(_Rd_); - d->Comment(String(registers[_Rd_]) + " = " + registers[_Rt_] + " >> " + registers[_Rs_] + " (arithmetic)"); -) - -MakeDisF(disSRLV, - dName("srlv"); - - dGPR(_Rd_); sep; - if (_Rd_ != _Rt_) { - dGPR(_Rt_); sep; - } - dGPR(_Rs_); - Invalidate(_Rd_); - d->Comment(String(registers[_Rd_]) + " = " + registers[_Rt_] + " >> " + registers[_Rs_] + " (logical)"); -) - -/********************************************************* -* Load higher 16 bits of the first word in GPR with imm * -* Format: OP rt, immediate * -*********************************************************/ -MakeDisF(disLUI, - dName("lui"); - - dGPR(_Rt_); sep; - dImm(); - - Invalidate(_Rt_); - - d->Comment("Load upper immediate"); -) - -/********************************************************* -* Move from HI/LO to GPR * -* Format: OP rd * -*********************************************************/ -MakeDisF(disMFHI, - dName("mfhi"); - - dGPR(_Rd_); - Invalidate(_Rd_); - - d->Comment(String(registers[_Rd_]) + " = hi"); -) - -MakeDisF(disMFLO, - dName("mflo"); - - dGPR(_Rd_); - Invalidate(_Rd_); - - d->Comment(String(registers[_Rd_]) + " = lo"); -) - -/********************************************************* -* Move from GPR to HI/LO * -* Format: OP rd * -*********************************************************/ -MakeDisF(disMTHI, - dName("mthi"); - - dGPR(_Rd_); - - d->Comment("hi = " + String(registers[_Rd_])); -) - -MakeDisF(disMTLO, - dName("mtlo"); - - dGPR(_Rd_); - - d->Comment("lo = " + String(registers[_Rd_])); -) - -/********************************************************* -* Special purpose instructions * -* Format: OP * -*********************************************************/ -MakeDisF(disBREAK, - dName("break"); - - Stop(pc + 4); - - d->Comment("Stops the machine"); -) -MakeDisF(disRFE, dName("rfe")) - -MakeDisF(disSYSCALL, - int syscall; - dName("syscall"); - syscall = code & 0xfffff; - - d->Comment(String("Syscall number ") + syscall); -) - -MakeDisF(disHLE, dName("hle")) - -MakeDisF(disRTPS, dName("rtps")) -MakeDisF(disOP , dName("op")) -MakeDisF(disNCLIP, dName("nclip")) -MakeDisF(disDPCS, dName("dpcs")) -MakeDisF(disINTPL, dName("intpl")) -MakeDisF(disMVMVA, dName("mvmva")) -MakeDisF(disNCDS , dName("ncds")) -MakeDisF(disCDP , dName("cdp")) -MakeDisF(disNCDT , dName("ncdt")) -MakeDisF(disNCCS , dName("nccs")) -MakeDisF(disCC , dName("cc")) -MakeDisF(disNCS , dName("ncs")) -MakeDisF(disNCT , dName("nct")) -MakeDisF(disSQR , dName("sqr")) -MakeDisF(disDCPL , dName("dcpl")) -MakeDisF(disDPCT , dName("dpct")) -MakeDisF(disAVSZ3, dName("avsz3")) -MakeDisF(disAVSZ4, dName("avsz4")) -MakeDisF(disRTPT , dName("rtpt")) -MakeDisF(disGPF , dName("gpf")) -MakeDisF(disGPL , dName("gpl")) -MakeDisF(disNCCT , dName("ncct")) - -MakeDisF(disMFC2, dName("mfc2"); dGPR(_Rt_); Invalidate(_Rt_); ) -MakeDisF(disCFC2, dName("cfc2"); dGPR(_Rt_); Invalidate(_Rt_); ) -MakeDisF(disMTC2, dName("mtc2"); dGPR(_Rt_);) -MakeDisF(disCTC2, dName("ctc2"); dGPR(_Rt_);) - -/********************************************************* -* Register branch logic * -* Format: OP rs, rt, offset * -*********************************************************/ -MakeDisF(disBEQ, - if ((!_Rt_) && (!_Rs_)) { - dName("b"); - - dOffset(); - Branch(_Branch_); - Stop(pc + 8); - - d->Comment("Branch always"); - } - if (!_Rt_) { - dName("bez"); - - dGPR(_Rs_); sep; - dOffset(); - Branch(_Branch_); - - d->Comment(String("Branch if ") + registers[_Rs_] + " == 0"); - } else { - dName("beq"); - - dGPR(_Rs_); sep; - dGPR(_Rt_); sep; - dOffset(); - Branch(_Branch_); - - d->Comment(String("Branch if ") + registers[_Rs_] + " == " + registers[_Rt_]); - } -) - -MakeDisF(disBNE, - if (!_Rt_) { - dName("bnz"); - - dGPR(_Rs_); sep; - dOffset(); - Branch(_Branch_); - - d->Comment(String("Branch if ") + registers[_Rs_] + " != 0"); - } else { - dName("bne"); - - dGPR(_Rs_); sep; - dGPR(_Rt_); sep; - dOffset(); - Branch(_Branch_); - - d->Comment(String("Branch if ") + registers[_Rs_] + " != " + registers[_Rt_]); - } -) - -/********************************************************* -* Jump to target * -* Format: OP target * -*********************************************************/ -MakeDisF(disJ, - dName("j"); - - dTarget(); - Jump(_Target_); - Stop(pc + 8); - - d->Comment("Jump always"); -) - -MakeDisF(disJAL, - dName("jal"); - - dTarget(); - Invalidate(Rra); - MarkFunction(_Target_); - - d->Comment("Jump and link (function call)"); -) - -/********************************************************* -* Register jump * -* Format: OP rs, rd * -*********************************************************/ -MakeDisF(disJR, - dName("jr"); - dGPR(_Rs_); - Stop(pc + 8); - - d->Comment("Jump register"); -) - -MakeDisF(disJALR, - dName("jalr"); - - dGPR(_Rs_); - - if ((_Rd_) != Rra) { - sep; dGPR(_Rd_); - } - - Invalidate(_Rd_); - - d->Comment("Jump and link register (function call)"); -) - -/********************************************************* -* Load and store for GPR * -* Format: OP rt, offset(base) * -*********************************************************/ -MakeDisF(disLB, - int width = 8; - dName("lb"); - - dGPR(_Rt_); sep; - dOfB(); - - Invalidate(_Rt_); - d->Comment("Load signed byte"); -) - -MakeDisF(disLBU, - int width = 8; - dName("lbu"); - - dGPR(_Rt_); sep; - dOfB(); - - Invalidate(_Rt_); - d->Comment("Load unsigned byte"); -) - -MakeDisF(disLH, - int width = 16; - dName("lh"); - - dGPR(_Rt_); sep; - dOfB(); - - Invalidate(_Rt_); - d->Comment("Load signed half"); -) - -MakeDisF(disLHU, - int width = 16; - dName("lhu"); - - dGPR(_Rt_); sep; - dOfB(); - - Invalidate(_Rt_); - d->Comment("Load unsigned half"); -) - -MakeDisF(disLW, - int width = 32; - dName("lw"); - - dGPR(_Rt_); sep; - dOfB(); - - Invalidate(_Rt_); - d->Comment("Load word"); -) - -MakeDisF(disLWL, - int width = 32; - dName("lwl"); - - dGPR(_Rt_); sep; - dOfB(); - - Invalidate(_Rt_); - d->Comment("Load word left"); -) - -MakeDisF(disLWR, - int width = 32; - dName("lwr"); - - dGPR(_Rt_); sep; - dOfB(); - - Invalidate(_Rt_); - d->Comment("Load word right"); -) - -MakeDisF(disLWC2, - int width = 32; - dName("lwc2"); - - dCP0(_Rt_); sep; - dOfB(); -) - -MakeDisF(disSB, - int width = 8; - dName("sb"); - - dGPR(_Rt_); sep; - dOfB(); - d->Comment("Store byte"); -) - -MakeDisF(disSH, - int width = 16; - dName("sh"); - - dGPR(_Rt_); sep; - dOfB(); - d->Comment("Store half"); -) - -MakeDisF(disSW, - int width = 32; - dName("sw"); - - dGPR(_Rt_); sep; - dOfB(); - d->Comment("Store word"); -) - -MakeDisF(disSWL, - int width = 32; - dName("swl"); - - dGPR(_Rt_); sep; - dOfB(); - d->Comment("Store word left"); -) - -MakeDisF(disSWR, - int width = 32; - dName("swr"); - - dGPR(_Rt_); sep; - dOfB(); - d->Comment("Store word right"); -) - -MakeDisF(disSWC2, - int width = 32; - dName("swc2"); - - dGPR(_Rt_); sep; - dOfB(); -) - -/********************************************************* -* Moves between GPR and COPx * -* Format: OP rt, fs * -*********************************************************/ -MakeDisF(disMFC0, dName("mfc0"); dGPR(_Rt_); sep; dCP0(_Rd_); Invalidate(_Rt_);) -MakeDisF(disMTC0, dName("mtc0"); dCP0(_Rd_); sep; dGPR(_Rt_);) -MakeDisF(disCFC0, dName("cfc0"); dGPR(_Rt_); sep; dCP0(_Rd_); Invalidate(_Rt_);) -MakeDisF(disCTC0, dName("ctc0"); dCP0(_Rd_); sep; dGPR(_Rt_);) - -/********************************************************* -* Unknow instruction (would generate an exception) * -* Format: ? * -*********************************************************/ -MakeDisF(disNULL, - dName("*** Bad OP ***"); - dInvalid(); -) - - -TdisR3000AF disR3000A_SPECIAL[] = { // Subset of disSPECIAL - disSLL , disNULL , disSRL , disSRA , disSLLV , disNULL , disSRLV , disSRAV , - disJR , disJALR , disNULL, disNULL, disSYSCALL, disBREAK , disNULL , disNULL , - disMFHI, disMTHI , disMFLO, disMTLO, disNULL , disNULL , disNULL , disNULL , - disMULT, disMULTU, disDIV , disDIVU, disNULL , disNULL , disNULL , disNULL , - disADD , disADDU , disSUB , disSUBU, disAND , disOR , disXOR , disNOR , - disNULL, disNULL , disSLT , disSLTU, disNULL , disNULL , disNULL , disNULL , - disNULL, disNULL , disNULL, disNULL, disNULL , disNULL , disNULL , disNULL , - disNULL, disNULL , disNULL, disNULL, disNULL , disNULL , disNULL , disNULL}; - -MakeDisF(disSPECIAL, disR3000A_SPECIAL[_Funct_](d, code, pc)) - -TdisR3000AF disR3000A_BCOND[] = { // Subset of disBCOND - disBLTZ , disBGEZ , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, - disNULL , disNULL , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, - disBLTZAL, disBGEZAL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, - disNULL , disNULL , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL}; - -MakeDisF(disBCOND, disR3000A_BCOND[_Rt_](d, code, pc)) - -TdisR3000AF disR3000A_COP0[] = { // Subset of disCOP0 - disMFC0, disNULL, disCFC0, disNULL, disMTC0, disNULL, disCTC0, disNULL, - disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, - disRFE , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, - disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL}; - -MakeDisF(disCOP0, disR3000A_COP0[_Rs_](d, code, pc)) - -TdisR3000AF disR3000A_BASIC[] = { // Subset of disBASIC (based on rs) - disMFC2, disNULL, disCFC2, disNULL, disMTC2, disNULL, disCTC2, disNULL, - disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, - disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, - disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL}; - -MakeDisF(disBASIC, disR3000A_BASIC[_Rs_](d, code, pc)) - -TdisR3000AF disR3000A_COP2[] = { // Subset of disR3000F_COP2 (based on funct) - disBASIC, disRTPS , disNULL , disNULL , disNULL, disNULL , disNCLIP, disNULL, - disNULL , disNULL , disNULL , disNULL , disOP , disNULL , disNULL , disNULL, - disDPCS , disINTPL, disMVMVA, disNCDS , disCDP , disNULL , disNCDT , disNULL, - disNULL , disNULL , disNULL , disNCCS , disCC , disNULL , disNCS , disNULL, - disNCT , disNULL , disNULL , disNULL , disNULL, disNULL , disNULL , disNULL, - disSQR , disDCPL , disDPCT , disNULL , disNULL, disAVSZ3, disAVSZ4, disNULL, - disRTPT , disNULL , disNULL , disNULL , disNULL, disNULL , disNULL , disNULL, - disNULL , disNULL , disNULL , disNULL , disNULL, disGPF , disGPL , disNCCT }; - -MakeDisF(disCOP2, disR3000A_COP2[_Funct_](d, code, pc)) - -TdisR3000AF disR3000A[] = { - disSPECIAL , disBCOND , disJ , disJAL , disBEQ , disBNE , disBLEZ , disBGTZ , - disADDI , disADDIU , disSLTI , disSLTIU, disANDI, disORI , disXORI , disLUI , - disCOP0 , disNULL , disCOP2 , disNULL , disNULL, disNULL, disNULL , disNULL , - disNULL , disNULL , disNULL , disNULL , disNULL, disNULL, disNULL , disNULL , - disLB , disLH , disLWL , disLW , disLBU , disLHU , disLWR , disNULL , - disSB , disSH , disSWL , disSW , disNULL, disNULL, disSWR , disNULL , - disNULL , disNULL , disLWC2 , disNULL , disNULL, disNULL, disNULL , disNULL , - disNULL , disNULL , disSWC2 , disHLE , disNULL, disNULL, disNULL , disNULL }; - -//MakeDisFg(disR3000AF, disR3000A[code >> 26](code, pc)) - -void decode(TDis * d, Uint32 pc) { - Uint32 code = d->getmem()->Read32(pc); - disR3000A[code >> 26](d, code, pc); -} +/*
+ * PSX-Tools Bundle Pack
+ * Copyright (C) 2002-2003 Nicolas "Pixel" Noble
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: mips.cpp,v 1.4 2004-11-27 21:44:48 pixel Exp $ */
+
+#include "mips.h"
+
+/* Code HIGHLY ripped off^W^W inspired from PCSX. */
+
+#if 1
+char * registers[] = {
+ "0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
+ "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
+ "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
+ "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra",
+};
+#else
+char * registers[] = {
+ "00", "01", "02", "03", "04", "05", "06", "07",
+ "08", "09", "0a", "0b", "0c", "0d", "0e", "0f",
+ "10", "11", "12", "13", "14", "15", "16", "17",
+ "18", "19", "1a", "1b", "1c", "1d", "1e", "1f",
+};
+#endif
+
+char * CP0registers[] = {
+ "Index" , "Random" , "EntryLo0", "EntryLo1", "Context" , "PageMask" , "Wired" , "*Check me*",
+ "BadVAddr" , "Count" , "EntryHi" , "Compare" , "Status" , "Cause" , "ExceptPC" , "PRevID" ,
+ "Config" , "LLAddr" , "WatchLo" , "WatchHi" , "XContext", "*RES*" , "*RES*" , "*RES*" ,
+ "*RES*" , "*RES* " , "PErr" , "CacheErr", "TagLo" , "TagHi" , "ErrorEPC" , "*RES*" };
+
+typedef void (*TdisR3000AF)(TDis *, Uint32 code, Uint32 pc);
+
+// These macros are used to assemble the disassembler functions
+#define MakeDisF(fn, b) \
+ static void fn(TDis * d, Uint32 code, Uint32 pc) { \
+ d->pc = pc; \
+ b; \
+ }
+
+#define _Funct_ ((code ) & 0x3F) // The funct part of the instruction register
+#define _Rd_ ((code >> 11) & 0x1F) // The rd part of the instruction register
+#define _Rt_ ((code >> 16) & 0x1F) // The rt part of the instruction register
+#define _Rs_ ((code >> 21) & 0x1F) // The rs part of the instruction register
+#define _Sa_ ((code >> 6) & 0x1F) // The sa part of the instruction register
+#define _Im_ ( code & 0xFFFF) // The immediate part of the instruction register
+ // The signed immediate part of the instruction register
+#define _sIm_ (code & 0x8000 ? - (((~code) & 0x7FFF) + 1) : ( code & 0x7FFF))
+
+#define _Target_ (0x80000000 + ((code & 0x03ffffff) * 4))
+#define _Branch_ (pc + 4 + ((short)_Im_ * 4))
+#define _OfB_ _Im_, _nRs_
+
+#define dName(n) { d->Name(n); }
+#define dGPR(i) { d->PushGPReg(i); }
+#define dCP0(i) { d->PushCPReg(i); }
+#define dImm() { d->PushImm(_Im_); }
+#define dTarget() { d->PushTarget(_Target_); }
+#define dSa() { d->PushSa(_Sa_); }
+#if 0
+#define dOfB() { \
+ Uint32 pcode = d->getmem()->Read32(pc - 4); \
+ if ((((pcode >> 16) & 0x1F) == _Rs_) && ((pcode >> 26) == 0xf)) { \
+ Uint32 full; \
+ Uint16 lower; \
+ int16 slower; \
+ lower = _Im_; \
+ slower = *((int16 *) &lower); \
+ \
+ full = ((pcode & 0xffff) << 16) + slower; \
+ \
+ d->PushOfB(_Rs_, full, width); \
+ \
+ dMemRefer(full, width); \
+ } else { \
+ d->PushOfB(_Rs_, _Im_, width); \
+ } \
+}
+#else
+#define dOfB() { \
+ d->PushOfB(_Rs_, _Im_, width); \
+}
+#endif
+#define dOffset() { \
+ d->PushOffset(_Branch_); \
+}
+// printf(" ; Maybe RefTo %8.8lX", offset);
+#define dFull(full) { \
+ d->PushFull(full); \
+ d->Comment("MaybeRefTo..."); \
+}
+
+#define sep
+
+#define dInvalid() { \
+ d->SetTag(pc, CODE, false); \
+ d->SetTag(pc, STOP, true); \
+ d->Invalid(); \
+}
+
+#define dSuspect() { \
+ d->Suspect(); \
+ d->Comment("Suspect!"); \
+}
+#if 0 // with OfB...
+// printf(" ; RefTo %8.8lX - %i bits", offset, width);
+#define dMemRefer(offset, width) { \
+ d->PushMemref(offset, width); \
+ d->Comment("RefTo..."); \
+}
+#endif
+
+#define Invalidate(reg) { \
+ if (!reg) \
+ dSuspect(); \
+}
+
+#define SetReg(reg, val) { \
+ if (!reg) \
+ dSuspect(); \
+}
+
+#define MarkFunction(target) { \
+ d->add_function(target); \
+}
+
+#define Branch(branch) { \
+ d->add_branch(branch); \
+}
+
+#define Jump(target) { \
+ d->add_jump(target); \
+}
+
+#define Stop(target) { \
+ d->SetTag(target, STOP, true); \
+}
+
+/*********************************************************
+* Arithmetic with immediate operand *
+* Format: OP rt, rs, immediate *
+*********************************************************/
+
+MakeDisF(disADDI,
+ dName("addi");
+
+ dGPR(_Rt_); sep;
+ if (_Rt_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dImm();
+
+ Invalidate(_Rt_);
+
+ d->Comment("Add immediate");
+)
+
+MakeDisF(disADDIU,
+ if (!_Rs_) {
+ dName("li");
+
+ dGPR(_Rt_); sep;
+ dImm();
+
+ Uint32 full;
+ int32 sfull;
+ Uint16 lower;
+ int16 slower;
+ lower = _Im_;
+ slower = *((int16 *) &lower);
+
+ sfull = slower;
+ full = *((Uint32 *) &sfull);
+
+ SetReg(_Rt_, full);
+
+ d->Comment("Load immediate");
+ } else {
+ Uint32 pcode = d->getmem()->Read32(pc - 4);
+ if ((((pcode >> 16) & 0x1F) == _Rt_) && (_Rt_ == _Rs_) && ((pcode >> 26) == 0xf)) {
+ Uint32 full;
+ Uint16 lower;
+ int16 slower;
+ lower = _Im_;
+ slower = *((int16 *) &lower);
+
+ full = ((pcode & 0xffff) << 16) + slower;
+
+ dName("li");
+ dGPR(_Rt_); sep;
+ dFull(full);
+ SetReg(_Rt_, full);
+ d->Comment("Load immediate (aggregate)");
+ } else {
+ dName("addiu");
+
+ dGPR(_Rt_); sep;
+ if (_Rt_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dImm();
+
+ Invalidate(_Rt_);
+
+ d->Comment("Add immediate");
+ }
+ }
+)
+
+MakeDisF(disANDI,
+ dName("andi");
+
+ dGPR(_Rt_); sep;
+ if (_Rt_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dImm();
+
+ Invalidate(_Rt_);
+
+ d->Comment("And immediate");
+)
+
+MakeDisF(disORI,
+ if (!_Rs_) {
+ dName("liu");
+
+ dGPR(_Rt_); sep;
+ dImm();
+ SetReg(_Rt_, _Im_);
+
+ d->Comment("Load immediate without sign extension");
+ } else {
+ dName("ori");
+
+ dGPR(_Rt_); sep;
+ if (_Rt_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dImm();
+ Invalidate(_Rt_);
+ d->Comment("Or immediate");
+ }
+)
+
+MakeDisF(disSLTI,
+ dName("slti");
+
+ dGPR(_Rt_); sep;
+ if (_Rt_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dImm();
+
+ Invalidate(_Rt_);
+
+ d->Comment(registers[_Rt_] + String(" = ") + registers[_Rs_] + " < immediate ? 1 : 0 (signed)");
+)
+
+MakeDisF(disSLTIU,
+ dName("sltiu");
+
+ dGPR(_Rt_); sep;
+ if (_Rt_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dImm();
+
+ Invalidate(_Rt_);
+
+ d->Comment(registers[_Rt_] + String(" = ") + registers[_Rs_] + " < immediate ? 1 : 0 (unsigned)");
+)
+
+MakeDisF(disXORI,
+ dName("xori");
+
+ dGPR(_Rt_); sep;
+ if (_Rt_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dImm();
+
+ Invalidate(_Rt_);
+
+ d->Comment("XOr immediate");
+)
+
+/*********************************************************
+* Register arithmetic *
+* Format: OP rd, rs, rt *
+*********************************************************/
+MakeDisF(disADD,
+ dName("add");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dGPR(_Rt_);
+
+ Invalidate(_Rt_);
+
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " + " + registers[_Rt_]);
+)
+
+MakeDisF(disADDU,
+ if (!_Rt_) {
+ dName("move");
+
+ dGPR(_Rd_); sep;
+ dGPR(_Rs_);
+ if (_Rs_) {
+ Invalidate(_Rd_);
+ } else {
+ SetReg(_Rd_, 0);
+ }
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_]);
+ } else {
+ dName("addu");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dGPR(_Rt_);
+ Invalidate(_Rd_);
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " + " + registers[_Rt_]);
+ }
+)
+
+MakeDisF(disAND,
+ dName("and");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dGPR(_Rt_);
+ Invalidate(_Rd_);
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " & " + registers[_Rt_]);
+)
+
+MakeDisF(disNOR,
+ dName("nor");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dGPR(_Rt_);
+ Invalidate(_Rd_);
+ d->Comment(String(registers[_Rd_]) + " = ~(" + registers[_Rs_] + " & " + registers[_Rt_] + ")");
+)
+
+MakeDisF(disOR,
+ dName("or");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dGPR(_Rt_);
+ Invalidate(_Rd_);
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " | " + registers[_Rt_]);
+)
+
+MakeDisF(disSLT,
+ dName("slt");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dGPR(_Rt_);
+ Invalidate(_Rd_);
+ d->Comment(registers[_Rd_] + String(" = ") + registers[_Rs_] + " < " + registers[_Rt_] + " ? 1 : 0 (signed)");
+)
+
+MakeDisF(disSLTU,
+ dName("sltu");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dGPR(_Rt_);
+ Invalidate(_Rd_);
+ d->Comment(registers[_Rd_] + String(" = ") + registers[_Rs_] + " < " + registers[_Rt_] + " ? 1 : 0 (unsigned)");
+)
+
+MakeDisF(disSUB,
+ dName("sub");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dGPR(_Rt_);
+ Invalidate(_Rd_);
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " - " + registers[_Rt_]);
+)
+
+MakeDisF(disSUBU,
+ dName("subu");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dGPR(_Rt_);
+ Invalidate(_Rd_);
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " - " + registers[_Rt_]);
+)
+
+MakeDisF(disXOR,
+ dName("xor");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rs_) {
+ dGPR(_Rs_); sep;
+ }
+ dGPR(_Rt_);
+ Invalidate(_Rd_);
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rs_] + " ^ " + registers[_Rt_]);
+)
+
+/*********************************************************
+* Register arithmetic & Register trap logic *
+* Format: OP rs, rt *
+*********************************************************/
+MakeDisF(disDIV,
+ dName("div");
+
+ dGPR(_Rs_); sep;
+ dGPR(_Rt_);
+
+ String c1 = String(registers[_Rs_]) + " / " + registers[_Rt_];
+ String c2 = String(registers[_Rs_]) + " %% " + registers[_Rt_];
+
+ d->Comment("lo = " + c1 + "; hi = " + c2);
+)
+
+MakeDisF(disDIVU,
+ dName("divu");
+
+ dGPR(_Rs_); sep;
+ dGPR(_Rt_);
+
+ d->Comment(String("lo = " ) + registers[_Rs_] + " / " + registers[_Rt_] + "; hi = " + registers[_Rs_] + " % " + registers[_Rt_]);
+)
+
+MakeDisF(disMULT,
+ dName("mult");
+
+ dGPR(_Rs_); sep;
+ dGPR(_Rt_);
+
+ d->Comment(String("hilo = ") + registers[_Rs_] + " * " + registers[_Rt_]);
+)
+
+MakeDisF(disMULTU,
+ dName("multu");
+
+ dGPR(_Rs_); sep;
+ dGPR(_Rt_);
+
+ d->Comment(String("hilo = ") + registers[_Rs_] + " * " + registers[_Rt_]);
+)
+
+/*********************************************************
+* Register branch logic *
+* Format: OP rs, offset *
+*********************************************************/
+MakeDisF(disBGEZ,
+ dName("bgez");
+
+ dGPR(_Rs_); sep;
+ dOffset();
+ Branch(_Branch_);
+ d->Comment("Branch if " + String(registers[_Rs_]) + " >= 0");
+)
+
+MakeDisF(disBGEZAL,
+ dName("bgezal");
+
+ dGPR(_Rs_); sep;
+ dOffset();
+ Branch(_Branch_);
+ d->Comment("Branch and link if " + String(registers[_Rs_]) + " >= 0");
+)
+
+MakeDisF(disBGTZ,
+ dName("bgtz");
+
+ dGPR(_Rs_); sep;
+ dOffset();
+ Branch(_Branch_);
+ d->Comment("Branch if " + String(registers[_Rs_]) + " > 0");
+)
+
+MakeDisF(disBLEZ,
+ dName("blez");
+
+ dGPR(_Rs_); sep;
+ dOffset();
+ Branch(_Branch_);
+ d->Comment("Branch if " + String(registers[_Rs_]) + " <= 0");
+)
+
+MakeDisF(disBLTZ,
+ dName("bltz");
+
+ dGPR(_Rs_); sep;
+ dOffset();
+ Branch(_Branch_);
+ d->Comment("Branch if " + String(registers[_Rs_]) + " < 0");
+)
+
+MakeDisF(disBLTZAL,
+ dName("bltzal");
+
+ dGPR(_Rs_); sep;
+ dOffset();
+ Branch(_Branch_);
+ d->Comment("Branch and link if " + String(registers[_Rs_]) + " <= 0");
+)
+
+/*********************************************************
+* Shift arithmetic with constant shift *
+* Format: OP rd, rt, sa *
+*********************************************************/
+MakeDisF(disSLL,
+ if ((!_Rd_) && (!_Rt_)) {
+ dName("nop");
+ if (code) {
+ dSuspect();
+ }
+ } else {
+ dName("sll");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rt_) {
+ dGPR(_Rt_); sep;
+ }
+ dSa();
+ Invalidate(_Rd_);
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rt_] + " << immediate");
+ }
+)
+
+MakeDisF(disSRA,
+ dName("sra");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rt_) {
+ dGPR(_Rt_); sep;
+ }
+ dSa();
+ Invalidate(_Rd_);
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rt_] + " >> immediate (arithmetic)");
+)
+
+MakeDisF(disSRL,
+ dName("srl");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rt_) {
+ dGPR(_Rt_); sep;
+ }
+ dSa();
+ Invalidate(_Rd_);
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rt_] + " >> immediate (logical)");
+)
+
+/*********************************************************
+* Shift arithmetic with variant register shift *
+* Format: OP rd, rt, rs *
+*********************************************************/
+MakeDisF(disSLLV,
+ dName("sllv");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rt_) {
+ dGPR(_Rt_); sep;
+ }
+ dGPR(_Rs_);
+ Invalidate(_Rd_);
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rt_] + " << " + registers[_Rs_]);
+)
+
+MakeDisF(disSRAV,
+ dName("srav");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rt_) {
+ dGPR(_Rt_); sep;
+ }
+ dGPR(_Rs_);
+ Invalidate(_Rd_);
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rt_] + " >> " + registers[_Rs_] + " (arithmetic)");
+)
+
+MakeDisF(disSRLV,
+ dName("srlv");
+
+ dGPR(_Rd_); sep;
+ if (_Rd_ != _Rt_) {
+ dGPR(_Rt_); sep;
+ }
+ dGPR(_Rs_);
+ Invalidate(_Rd_);
+ d->Comment(String(registers[_Rd_]) + " = " + registers[_Rt_] + " >> " + registers[_Rs_] + " (logical)");
+)
+
+/*********************************************************
+* Load higher 16 bits of the first word in GPR with imm *
+* Format: OP rt, immediate *
+*********************************************************/
+MakeDisF(disLUI,
+ dName("lui");
+
+ dGPR(_Rt_); sep;
+ dImm();
+
+ Invalidate(_Rt_);
+
+ d->Comment("Load upper immediate");
+)
+
+/*********************************************************
+* Move from HI/LO to GPR *
+* Format: OP rd *
+*********************************************************/
+MakeDisF(disMFHI,
+ dName("mfhi");
+
+ dGPR(_Rd_);
+ Invalidate(_Rd_);
+
+ d->Comment(String(registers[_Rd_]) + " = hi");
+)
+
+MakeDisF(disMFLO,
+ dName("mflo");
+
+ dGPR(_Rd_);
+ Invalidate(_Rd_);
+
+ d->Comment(String(registers[_Rd_]) + " = lo");
+)
+
+/*********************************************************
+* Move from GPR to HI/LO *
+* Format: OP rd *
+*********************************************************/
+MakeDisF(disMTHI,
+ dName("mthi");
+
+ dGPR(_Rd_);
+
+ d->Comment("hi = " + String(registers[_Rd_]));
+)
+
+MakeDisF(disMTLO,
+ dName("mtlo");
+
+ dGPR(_Rd_);
+
+ d->Comment("lo = " + String(registers[_Rd_]));
+)
+
+/*********************************************************
+* Special purpose instructions *
+* Format: OP *
+*********************************************************/
+MakeDisF(disBREAK,
+ dName("break");
+
+ Stop(pc + 4);
+
+ d->Comment("Stops the machine");
+)
+MakeDisF(disRFE, dName("rfe"))
+
+MakeDisF(disSYSCALL,
+ int syscall;
+ dName("syscall");
+ syscall = code & 0xfffff;
+
+ d->Comment(String("Syscall number ") + syscall);
+)
+
+MakeDisF(disHLE, dName("hle"))
+
+MakeDisF(disRTPS, dName("rtps"))
+MakeDisF(disOP , dName("op"))
+MakeDisF(disNCLIP, dName("nclip"))
+MakeDisF(disDPCS, dName("dpcs"))
+MakeDisF(disINTPL, dName("intpl"))
+MakeDisF(disMVMVA, dName("mvmva"))
+MakeDisF(disNCDS , dName("ncds"))
+MakeDisF(disCDP , dName("cdp"))
+MakeDisF(disNCDT , dName("ncdt"))
+MakeDisF(disNCCS , dName("nccs"))
+MakeDisF(disCC , dName("cc"))
+MakeDisF(disNCS , dName("ncs"))
+MakeDisF(disNCT , dName("nct"))
+MakeDisF(disSQR , dName("sqr"))
+MakeDisF(disDCPL , dName("dcpl"))
+MakeDisF(disDPCT , dName("dpct"))
+MakeDisF(disAVSZ3, dName("avsz3"))
+MakeDisF(disAVSZ4, dName("avsz4"))
+MakeDisF(disRTPT , dName("rtpt"))
+MakeDisF(disGPF , dName("gpf"))
+MakeDisF(disGPL , dName("gpl"))
+MakeDisF(disNCCT , dName("ncct"))
+
+MakeDisF(disMFC2, dName("mfc2"); dGPR(_Rt_); Invalidate(_Rt_); )
+MakeDisF(disCFC2, dName("cfc2"); dGPR(_Rt_); Invalidate(_Rt_); )
+MakeDisF(disMTC2, dName("mtc2"); dGPR(_Rt_);)
+MakeDisF(disCTC2, dName("ctc2"); dGPR(_Rt_);)
+
+/*********************************************************
+* Register branch logic *
+* Format: OP rs, rt, offset *
+*********************************************************/
+MakeDisF(disBEQ,
+ if ((!_Rt_) && (!_Rs_)) {
+ dName("b");
+
+ dOffset();
+ Branch(_Branch_);
+ Stop(pc + 8);
+
+ d->Comment("Branch always");
+ }
+ if (!_Rt_) {
+ dName("bez");
+
+ dGPR(_Rs_); sep;
+ dOffset();
+ Branch(_Branch_);
+
+ d->Comment(String("Branch if ") + registers[_Rs_] + " == 0");
+ } else {
+ dName("beq");
+
+ dGPR(_Rs_); sep;
+ dGPR(_Rt_); sep;
+ dOffset();
+ Branch(_Branch_);
+
+ d->Comment(String("Branch if ") + registers[_Rs_] + " == " + registers[_Rt_]);
+ }
+)
+
+MakeDisF(disBNE,
+ if (!_Rt_) {
+ dName("bnz");
+
+ dGPR(_Rs_); sep;
+ dOffset();
+ Branch(_Branch_);
+
+ d->Comment(String("Branch if ") + registers[_Rs_] + " != 0");
+ } else {
+ dName("bne");
+
+ dGPR(_Rs_); sep;
+ dGPR(_Rt_); sep;
+ dOffset();
+ Branch(_Branch_);
+
+ d->Comment(String("Branch if ") + registers[_Rs_] + " != " + registers[_Rt_]);
+ }
+)
+
+/*********************************************************
+* Jump to target *
+* Format: OP target *
+*********************************************************/
+MakeDisF(disJ,
+ dName("j");
+
+ dTarget();
+ Jump(_Target_);
+ Stop(pc + 8);
+
+ d->Comment("Jump always");
+)
+
+MakeDisF(disJAL,
+ dName("jal");
+
+ dTarget();
+ Invalidate(Rra);
+ MarkFunction(_Target_);
+
+ d->Comment("Jump and link (function call)");
+)
+
+/*********************************************************
+* Register jump *
+* Format: OP rs, rd *
+*********************************************************/
+MakeDisF(disJR,
+ dName("jr");
+ dGPR(_Rs_);
+ Stop(pc + 8);
+
+ d->Comment("Jump register");
+)
+
+MakeDisF(disJALR,
+ dName("jalr");
+
+ dGPR(_Rs_);
+
+ if ((_Rd_) != Rra) {
+ sep; dGPR(_Rd_);
+ }
+
+ Invalidate(_Rd_);
+
+ d->Comment("Jump and link register (function call)");
+)
+
+/*********************************************************
+* Load and store for GPR *
+* Format: OP rt, offset(base) *
+*********************************************************/
+MakeDisF(disLB,
+ int width = 8;
+ dName("lb");
+
+ dGPR(_Rt_); sep;
+ dOfB();
+
+ Invalidate(_Rt_);
+ d->Comment("Load signed byte");
+)
+
+MakeDisF(disLBU,
+ int width = 8;
+ dName("lbu");
+
+ dGPR(_Rt_); sep;
+ dOfB();
+
+ Invalidate(_Rt_);
+ d->Comment("Load unsigned byte");
+)
+
+MakeDisF(disLH,
+ int width = 16;
+ dName("lh");
+
+ dGPR(_Rt_); sep;
+ dOfB();
+
+ Invalidate(_Rt_);
+ d->Comment("Load signed half");
+)
+
+MakeDisF(disLHU,
+ int width = 16;
+ dName("lhu");
+
+ dGPR(_Rt_); sep;
+ dOfB();
+
+ Invalidate(_Rt_);
+ d->Comment("Load unsigned half");
+)
+
+MakeDisF(disLW,
+ int width = 32;
+ dName("lw");
+
+ dGPR(_Rt_); sep;
+ dOfB();
+
+ Invalidate(_Rt_);
+ d->Comment("Load word");
+)
+
+MakeDisF(disLWL,
+ int width = 32;
+ dName("lwl");
+
+ dGPR(_Rt_); sep;
+ dOfB();
+
+ Invalidate(_Rt_);
+ d->Comment("Load word left");
+)
+
+MakeDisF(disLWR,
+ int width = 32;
+ dName("lwr");
+
+ dGPR(_Rt_); sep;
+ dOfB();
+
+ Invalidate(_Rt_);
+ d->Comment("Load word right");
+)
+
+MakeDisF(disLWC2,
+ int width = 32;
+ dName("lwc2");
+
+ dCP0(_Rt_); sep;
+ dOfB();
+)
+
+MakeDisF(disSB,
+ int width = 8;
+ dName("sb");
+
+ dGPR(_Rt_); sep;
+ dOfB();
+ d->Comment("Store byte");
+)
+
+MakeDisF(disSH,
+ int width = 16;
+ dName("sh");
+
+ dGPR(_Rt_); sep;
+ dOfB();
+ d->Comment("Store half");
+)
+
+MakeDisF(disSW,
+ int width = 32;
+ dName("sw");
+
+ dGPR(_Rt_); sep;
+ dOfB();
+ d->Comment("Store word");
+)
+
+MakeDisF(disSWL,
+ int width = 32;
+ dName("swl");
+
+ dGPR(_Rt_); sep;
+ dOfB();
+ d->Comment("Store word left");
+)
+
+MakeDisF(disSWR,
+ int width = 32;
+ dName("swr");
+
+ dGPR(_Rt_); sep;
+ dOfB();
+ d->Comment("Store word right");
+)
+
+MakeDisF(disSWC2,
+ int width = 32;
+ dName("swc2");
+
+ dGPR(_Rt_); sep;
+ dOfB();
+)
+
+/*********************************************************
+* Moves between GPR and COPx *
+* Format: OP rt, fs *
+*********************************************************/
+MakeDisF(disMFC0, dName("mfc0"); dGPR(_Rt_); sep; dCP0(_Rd_); Invalidate(_Rt_);)
+MakeDisF(disMTC0, dName("mtc0"); dCP0(_Rd_); sep; dGPR(_Rt_);)
+MakeDisF(disCFC0, dName("cfc0"); dGPR(_Rt_); sep; dCP0(_Rd_); Invalidate(_Rt_);)
+MakeDisF(disCTC0, dName("ctc0"); dCP0(_Rd_); sep; dGPR(_Rt_);)
+
+/*********************************************************
+* Unknow instruction (would generate an exception) *
+* Format: ? *
+*********************************************************/
+MakeDisF(disNULL,
+ dName("*** Bad OP ***");
+ dInvalid();
+)
+
+
+TdisR3000AF disR3000A_SPECIAL[] = { // Subset of disSPECIAL
+ disSLL , disNULL , disSRL , disSRA , disSLLV , disNULL , disSRLV , disSRAV ,
+ disJR , disJALR , disNULL, disNULL, disSYSCALL, disBREAK , disNULL , disNULL ,
+ disMFHI, disMTHI , disMFLO, disMTLO, disNULL , disNULL , disNULL , disNULL ,
+ disMULT, disMULTU, disDIV , disDIVU, disNULL , disNULL , disNULL , disNULL ,
+ disADD , disADDU , disSUB , disSUBU, disAND , disOR , disXOR , disNOR ,
+ disNULL, disNULL , disSLT , disSLTU, disNULL , disNULL , disNULL , disNULL ,
+ disNULL, disNULL , disNULL, disNULL, disNULL , disNULL , disNULL , disNULL ,
+ disNULL, disNULL , disNULL, disNULL, disNULL , disNULL , disNULL , disNULL};
+
+MakeDisF(disSPECIAL, disR3000A_SPECIAL[_Funct_](d, code, pc))
+
+TdisR3000AF disR3000A_BCOND[] = { // Subset of disBCOND
+ disBLTZ , disBGEZ , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
+ disNULL , disNULL , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
+ disBLTZAL, disBGEZAL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
+ disNULL , disNULL , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL};
+
+MakeDisF(disBCOND, disR3000A_BCOND[_Rt_](d, code, pc))
+
+TdisR3000AF disR3000A_COP0[] = { // Subset of disCOP0
+ disMFC0, disNULL, disCFC0, disNULL, disMTC0, disNULL, disCTC0, disNULL,
+ disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
+ disRFE , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
+ disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL};
+
+MakeDisF(disCOP0, disR3000A_COP0[_Rs_](d, code, pc))
+
+TdisR3000AF disR3000A_BASIC[] = { // Subset of disBASIC (based on rs)
+ disMFC2, disNULL, disCFC2, disNULL, disMTC2, disNULL, disCTC2, disNULL,
+ disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
+ disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL,
+ disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL};
+
+MakeDisF(disBASIC, disR3000A_BASIC[_Rs_](d, code, pc))
+
+TdisR3000AF disR3000A_COP2[] = { // Subset of disR3000F_COP2 (based on funct)
+ disBASIC, disRTPS , disNULL , disNULL , disNULL, disNULL , disNCLIP, disNULL,
+ disNULL , disNULL , disNULL , disNULL , disOP , disNULL , disNULL , disNULL,
+ disDPCS , disINTPL, disMVMVA, disNCDS , disCDP , disNULL , disNCDT , disNULL,
+ disNULL , disNULL , disNULL , disNCCS , disCC , disNULL , disNCS , disNULL,
+ disNCT , disNULL , disNULL , disNULL , disNULL, disNULL , disNULL , disNULL,
+ disSQR , disDCPL , disDPCT , disNULL , disNULL, disAVSZ3, disAVSZ4, disNULL,
+ disRTPT , disNULL , disNULL , disNULL , disNULL, disNULL , disNULL , disNULL,
+ disNULL , disNULL , disNULL , disNULL , disNULL, disGPF , disGPL , disNCCT };
+
+MakeDisF(disCOP2, disR3000A_COP2[_Funct_](d, code, pc))
+
+TdisR3000AF disR3000A[] = {
+ disSPECIAL , disBCOND , disJ , disJAL , disBEQ , disBNE , disBLEZ , disBGTZ ,
+ disADDI , disADDIU , disSLTI , disSLTIU, disANDI, disORI , disXORI , disLUI ,
+ disCOP0 , disNULL , disCOP2 , disNULL , disNULL, disNULL, disNULL , disNULL ,
+ disNULL , disNULL , disNULL , disNULL , disNULL, disNULL, disNULL , disNULL ,
+ disLB , disLH , disLWL , disLW , disLBU , disLHU , disLWR , disNULL ,
+ disSB , disSH , disSWL , disSW , disNULL, disNULL, disSWR , disNULL ,
+ disNULL , disNULL , disLWC2 , disNULL , disNULL, disNULL, disNULL , disNULL ,
+ disNULL , disNULL , disSWC2 , disHLE , disNULL, disNULL, disNULL , disNULL };
+
+//MakeDisFg(disR3000AF, disR3000A[code >> 26](code, pc))
+
+void decode(TDis * d, Uint32 pc) {
+ Uint32 code = d->getmem()->Read32(pc);
+ disR3000A[code >> 26](d, code, pc);
+}
diff --git a/lib/mipsdis.cpp b/lib/mipsdis.cpp index cbaf9e3..bb6364c 100644 --- a/lib/mipsdis.cpp +++ b/lib/mipsdis.cpp @@ -1,180 +1,180 @@ -/* - * PSX-Tools Bundle Pack - * Copyright (C) 2002-2003 Nicolas "Pixel" Noble - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* $Id: mipsdis.cpp,v 1.2 2004-01-26 15:31:55 pixel Exp $ */ - -#include "mipsdis.h" -#include "mips.h" - -TDis::TDis(mipsmem * _m) : mm(_m) { - reset(); -} - -void TDis::reset() { - invalid = false; -} - -mipsmem * TDis::getmem() { - return mm; -} - -void TDis::add_branch(Uint32 target) { - bheap.push(target); -} - -void TDis::add_jump(Uint32 target) { - jheap.push(target); -} - -void TDis::add_function(Uint32 target) { - fheap.push(target); -} - -void TDis::SetTag(Uint32 target, int tag, bool v) { - mm->SetTag(target, tag, v); -} - -void TDis::Name(const String & name) { -} - -void TDis::PushGPReg(int reg) { -} - -void TDis::PushCPReg(int reg) { -} - -void TDis::PushImm(Uint32 imm) { -} - -void TDis::PushTarget(Uint32 target) { - new refto_t(target, memdata::getmem(pc, getmem())); -} - -void TDis::PushSa(Uint32 sa) { -} - -void TDis::PushOfB(int reg, Uint32 offset, int width) { -} - -void TDis::PushOffset(Uint32 offset) { - new refto_t(offset, memdata::getmem(pc, getmem())); -} - -void TDis::PushFull(Uint32 full) { - if ((full >= 0x80000000) && (full < (0x80000000 + PSXMEM))) - new refto_t(full, memdata::getmem(pc, getmem())); -} - -void TDis::Invalid() { - invalid = true; -} - -void TDis::Suspect() { -} - -void TDis::Comment(const String & c) { -} - -Disassembler::Disassembler(mipsmem * _mm) : mm(_mm), dis(new TDis(mm)), started(false), infunction(false) { -} - -Disassembler::~Disassembler() { - delete dis; -} - -void Disassembler::crawl_code(Uint32 pc) { - Uint32 branched, ipc; - - if (pc == 0xffffffff) { - pc = mm->GetPC(); - } - - dis->bheap.push(pc); - - while (dis->bheap.size()) { - branched = pc = dis->bheap.top(); - dis->bheap.pop(); - printm(M_STATUS, "Crawling to branch %8.8lX\n", pc); - do { - if (pc >= (0x80000000 + PSXMEM)) { - dis->invalid = true; - break; - } - if (mm->GetTag(pc, CODE) || mm->GetTag(pc, INVALID)) { - pc += 4; - continue; - } - mm->SetTag(pc, CODE, true); - - printm(M_STATUS, "Working at %8.8lX\n", pc); - decode(dis, pc); - - pc += 4; - dis->reset(); - } while (!mm->GetTag(pc, STOP) && !dis->invalid); - - if (dis->invalid) { - for (ipc = branched; ipc <= pc; ipc += 4) { - mm->SetTag(ipc, CODE, false); - mm->SetTag(ipc, INVALID, true); - } - } - - if (dis->invalid && infunction) { - } - } -} - -void Disassembler::mainloop(void) { - Uint32 pc; - - infunction = false; - - // Crawl the start part. - printm(M_STATUS, "Starting crawl at %8.8lX\n", mm->GetPC()); - if (!started) - crawl_code(); - - started = true; - - // Work out all the functions. - printm(M_STATUS, "Crawling all detected functions\n"); - infunction = true; - while (dis->fheap.size()) { - pc = dis->fheap.top(); - dis->fheap.pop(); - printm(M_STATUS, "Crawling function %8.8lX\n", pc); - if (mm->GetTag(pc, CODE)) - continue; - crawl_code(pc); - } - - // Complete functions and all the detected jumps. - printm(M_STATUS, "Fixing all the remaining jumps\n"); -#if 0 - infunction = false; - while (dis->jheap.size()) { - pc = dis->jheap.top(); - dis->jheap.pop(); - if (mm->GetTag(pc, CODE)) - continue; - crawl_code(pc); - } -#endif -} +/*
+ * PSX-Tools Bundle Pack
+ * Copyright (C) 2002-2003 Nicolas "Pixel" Noble
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: mipsdis.cpp,v 1.3 2004-11-27 21:44:48 pixel Exp $ */
+
+#include "mipsdis.h"
+#include "mips.h"
+
+TDis::TDis(mipsmem * _m) : mm(_m) {
+ reset();
+}
+
+void TDis::reset() {
+ invalid = false;
+}
+
+mipsmem * TDis::getmem() {
+ return mm;
+}
+
+void TDis::add_branch(Uint32 target) {
+ bheap.push(target);
+}
+
+void TDis::add_jump(Uint32 target) {
+ jheap.push(target);
+}
+
+void TDis::add_function(Uint32 target) {
+ fheap.push(target);
+}
+
+void TDis::SetTag(Uint32 target, int tag, bool v) {
+ mm->SetTag(target, tag, v);
+}
+
+void TDis::Name(const String & name) {
+}
+
+void TDis::PushGPReg(int reg) {
+}
+
+void TDis::PushCPReg(int reg) {
+}
+
+void TDis::PushImm(Uint32 imm) {
+}
+
+void TDis::PushTarget(Uint32 target) {
+ new refto_t(target, memdata::getmem(pc, getmem()));
+}
+
+void TDis::PushSa(Uint32 sa) {
+}
+
+void TDis::PushOfB(int reg, Uint32 offset, int width) {
+}
+
+void TDis::PushOffset(Uint32 offset) {
+ new refto_t(offset, memdata::getmem(pc, getmem()));
+}
+
+void TDis::PushFull(Uint32 full) {
+ if ((full >= 0x80000000) && (full < (0x80000000 + PSXMEM)))
+ new refto_t(full, memdata::getmem(pc, getmem()));
+}
+
+void TDis::Invalid() {
+ invalid = true;
+}
+
+void TDis::Suspect() {
+}
+
+void TDis::Comment(const String & c) {
+}
+
+Disassembler::Disassembler(mipsmem * _mm) : mm(_mm), dis(new TDis(mm)), started(false), infunction(false) {
+}
+
+Disassembler::~Disassembler() {
+ delete dis;
+}
+
+void Disassembler::crawl_code(Uint32 pc) {
+ Uint32 branched, ipc;
+
+ if (pc == 0xffffffff) {
+ pc = mm->GetPC();
+ }
+
+ dis->bheap.push(pc);
+
+ while (dis->bheap.size()) {
+ branched = pc = dis->bheap.top();
+ dis->bheap.pop();
+ printm(M_STATUS, "Crawling to branch %8.8lX\n", pc);
+ do {
+ if (pc >= (0x80000000 + PSXMEM)) {
+ dis->invalid = true;
+ break;
+ }
+ if (mm->GetTag(pc, CODE) || mm->GetTag(pc, INVALID)) {
+ pc += 4;
+ continue;
+ }
+ mm->SetTag(pc, CODE, true);
+
+ printm(M_STATUS, "Working at %8.8lX\n", pc);
+ decode(dis, pc);
+
+ pc += 4;
+ dis->reset();
+ } while (!mm->GetTag(pc, STOP) && !dis->invalid);
+
+ if (dis->invalid) {
+ for (ipc = branched; ipc <= pc; ipc += 4) {
+ mm->SetTag(ipc, CODE, false);
+ mm->SetTag(ipc, INVALID, true);
+ }
+ }
+
+ if (dis->invalid && infunction) {
+ }
+ }
+}
+
+void Disassembler::mainloop(void) {
+ Uint32 pc;
+
+ infunction = false;
+
+ // Crawl the start part.
+ printm(M_STATUS, "Starting crawl at %8.8lX\n", mm->GetPC());
+ if (!started)
+ crawl_code();
+
+ started = true;
+
+ // Work out all the functions.
+ printm(M_STATUS, "Crawling all detected functions\n");
+ infunction = true;
+ while (dis->fheap.size()) {
+ pc = dis->fheap.top();
+ dis->fheap.pop();
+ printm(M_STATUS, "Crawling function %8.8lX\n", pc);
+ if (mm->GetTag(pc, CODE))
+ continue;
+ crawl_code(pc);
+ }
+
+ // Complete functions and all the detected jumps.
+ printm(M_STATUS, "Fixing all the remaining jumps\n");
+#if 0
+ infunction = false;
+ while (dis->jheap.size()) {
+ pc = dis->jheap.top();
+ dis->jheap.pop();
+ if (mm->GetTag(pc, CODE))
+ continue;
+ crawl_code(pc);
+ }
+#endif
+}
diff --git a/lib/mipsdump.cpp b/lib/mipsdump.cpp index ac77b33..1eb59f7 100644 --- a/lib/mipsdump.cpp +++ b/lib/mipsdump.cpp @@ -1,207 +1,207 @@ -/* - * PSX-Tools Bundle Pack - * Copyright (C) 2002-2003 Nicolas "Pixel" Noble - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* $Id: mipsdump.cpp,v 1.1 2004-01-03 15:04:47 pixel Exp $ */ - -#include "mipsdump.h" -#include "mips.h" - -TDump::TDump(mipsmem * mm) : TDis(mm) { - reset(); -} - -void TDump::reset() { - invalid = false; - hasbr = false; - hastg = false; - hasfc = false; - name = ""; - comments = ""; - args.clear(); -} - -void TDump::add_branch(Uint32 _tg) { - tg = _tg; - hasbr = true; -} - -void TDump::add_jump(Uint32 _tg) { - tg = _tg; - hastg = true; -} - -void TDump::add_function(Uint32 _tg) { - tg = _tg; - hasfc = true; -} - -void TDump::SetTag(Uint32 a, int t, bool v) { -} - -void TDump::Name(const String & _name) { - name = _name; -} - -void TDump::PushGPReg(int r) { - pairarg p; - - p.left = T_GPREGISTER; - p.right.v = r; - - args.push_back(p); -} - -void TDump::PushCPReg(int r) { - pairarg p; - - p.left = T_CPREGISTER; - p.right.v = r; - - args.push_back(p); -} - -void TDump::PushImm(Uint32 imm) { - pairarg p; - - p.left = T_IMM16; - p.right.v = imm; - - args.push_back(p); -} - -void TDump::PushTarget(Uint32 target) { - pairarg p; - - p.left = T_IMM32; - p.right.v = target; - - args.push_back(p); -} - -void TDump::PushSa(Uint32 sa) { - pairarg p; - - p.left = T_IMM8; - p.right.v = sa; - - args.push_back(p); -} - -void TDump::PushOfB(int reg, Uint32 offset, int width) { - pairarg p; - - p.left = T_OFB; - p.right.OfB.o = offset; - p.right.OfB.r = reg; - p.right.OfB.w = width; - - args.push_back(p); -} - -void TDump::PushOffset(Uint32 offset) { - pairarg p; - - p.left = T_IMM32; - p.right.v = offset; - - args.push_back(p); -} - -void TDump::PushFull(Uint32 full) { - pairarg p; - - p.left = T_IMM32; - p.right.v = full; - - args.push_back(p); -} - -void TDump::Invalid() { - invalid = true; -} - -void TDump::Suspect() { -} - -void TDump::Comment(const String & c) { - comments = c; -} - -Dumper::Dumper(mipsmem * _mm) : dump(new TDump(_mm)), mm(_mm) { -} - -void Dumper::process() { - Uint32 pc, code; - memdata * mem; - - for (pc = 0x80000000; pc < (0x80000000 + PSXMEM); pc++) { - if (mm->GetTag(pc, CODE)) { - decode(dump, pc); - code = mm->Read32(pc); - printm(M_STATUS, "%8.8lX %8.8lX: " + dump->name + "\t", pc, code); - for (std::vector<pairarg>::iterator i = dump->args.begin(); i != dump->args.end(); i++) { - switch(i->left) { - case T_GPREGISTER: - printm(M_BARE, "$%s", registers[i->right.v]); - break; - case T_CPREGISTER: - printm(M_BARE, "$%s", CP0registers[i->right.v]); - break; - case T_IMM8: - printm(M_BARE, "0x%2.2lX", i->right.v); - break; - case T_IMM16: - printm(M_BARE, "0x%4.4lX", i->right.v); - break; - case T_IMM32: - printm(M_BARE, "0x%8.8lX", i->right.v); - break; - case T_OFB: - printm(M_BARE, "0x%4.4lX($%s)", i->right.OfB.o, registers[i->right.OfB.r]); - break; - } - if ((i + 1) != dump->args.end()) { - printm(M_BARE, ", "); - } - } - if (dump->comments != "") { - printm(M_BARE, "\t; " + dump->comments); - } - printm(M_BARE, "\n"); - mem = mm->GetDatas(pc); - if (mem) { - reffrom_t * from; - refto_t * to; - - from = mem->getreffrom(); - to = mem->getrefto(); - - for (from = mem->getreffrom(); from; from = from->getnext()) { - printm(M_STATUS, " Reference from 0x%8.8lX\n", from->getref()->getaddress()); - } - - if (to) { - printm(M_STATUS, " Reference to 0x%8.8lX\n", to->getref()->getaddress()); - } - } - pc += 3; - dump->reset(); - } - } -} +/*
+ * PSX-Tools Bundle Pack
+ * Copyright (C) 2002-2003 Nicolas "Pixel" Noble
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: mipsdump.cpp,v 1.2 2004-11-27 21:44:48 pixel Exp $ */
+
+#include "mipsdump.h"
+#include "mips.h"
+
+TDump::TDump(mipsmem * mm) : TDis(mm) {
+ reset();
+}
+
+void TDump::reset() {
+ invalid = false;
+ hasbr = false;
+ hastg = false;
+ hasfc = false;
+ name = "";
+ comments = "";
+ args.clear();
+}
+
+void TDump::add_branch(Uint32 _tg) {
+ tg = _tg;
+ hasbr = true;
+}
+
+void TDump::add_jump(Uint32 _tg) {
+ tg = _tg;
+ hastg = true;
+}
+
+void TDump::add_function(Uint32 _tg) {
+ tg = _tg;
+ hasfc = true;
+}
+
+void TDump::SetTag(Uint32 a, int t, bool v) {
+}
+
+void TDump::Name(const String & _name) {
+ name = _name;
+}
+
+void TDump::PushGPReg(int r) {
+ pairarg p;
+
+ p.left = T_GPREGISTER;
+ p.right.v = r;
+
+ args.push_back(p);
+}
+
+void TDump::PushCPReg(int r) {
+ pairarg p;
+
+ p.left = T_CPREGISTER;
+ p.right.v = r;
+
+ args.push_back(p);
+}
+
+void TDump::PushImm(Uint32 imm) {
+ pairarg p;
+
+ p.left = T_IMM16;
+ p.right.v = imm;
+
+ args.push_back(p);
+}
+
+void TDump::PushTarget(Uint32 target) {
+ pairarg p;
+
+ p.left = T_IMM32;
+ p.right.v = target;
+
+ args.push_back(p);
+}
+
+void TDump::PushSa(Uint32 sa) {
+ pairarg p;
+
+ p.left = T_IMM8;
+ p.right.v = sa;
+
+ args.push_back(p);
+}
+
+void TDump::PushOfB(int reg, Uint32 offset, int width) {
+ pairarg p;
+
+ p.left = T_OFB;
+ p.right.OfB.o = offset;
+ p.right.OfB.r = reg;
+ p.right.OfB.w = width;
+
+ args.push_back(p);
+}
+
+void TDump::PushOffset(Uint32 offset) {
+ pairarg p;
+
+ p.left = T_IMM32;
+ p.right.v = offset;
+
+ args.push_back(p);
+}
+
+void TDump::PushFull(Uint32 full) {
+ pairarg p;
+
+ p.left = T_IMM32;
+ p.right.v = full;
+
+ args.push_back(p);
+}
+
+void TDump::Invalid() {
+ invalid = true;
+}
+
+void TDump::Suspect() {
+}
+
+void TDump::Comment(const String & c) {
+ comments = c;
+}
+
+Dumper::Dumper(mipsmem * _mm) : dump(new TDump(_mm)), mm(_mm) {
+}
+
+void Dumper::process() {
+ Uint32 pc, code;
+ memdata * mem;
+
+ for (pc = 0x80000000; pc < (0x80000000 + PSXMEM); pc++) {
+ if (mm->GetTag(pc, CODE)) {
+ decode(dump, pc);
+ code = mm->Read32(pc);
+ printm(M_STATUS, "%8.8lX %8.8lX: " + dump->name + "\t", pc, code);
+ for (std::vector<pairarg>::iterator i = dump->args.begin(); i != dump->args.end(); i++) {
+ switch(i->left) {
+ case T_GPREGISTER:
+ printm(M_BARE, "$%s", registers[i->right.v]);
+ break;
+ case T_CPREGISTER:
+ printm(M_BARE, "$%s", CP0registers[i->right.v]);
+ break;
+ case T_IMM8:
+ printm(M_BARE, "0x%2.2lX", i->right.v);
+ break;
+ case T_IMM16:
+ printm(M_BARE, "0x%4.4lX", i->right.v);
+ break;
+ case T_IMM32:
+ printm(M_BARE, "0x%8.8lX", i->right.v);
+ break;
+ case T_OFB:
+ printm(M_BARE, "0x%4.4lX($%s)", i->right.OfB.o, registers[i->right.OfB.r]);
+ break;
+ }
+ if ((i + 1) != dump->args.end()) {
+ printm(M_BARE, ", ");
+ }
+ }
+ if (dump->comments != "") {
+ printm(M_BARE, "\t; " + dump->comments);
+ }
+ printm(M_BARE, "\n");
+ mem = mm->GetDatas(pc);
+ if (mem) {
+ reffrom_t * from;
+ refto_t * to;
+
+ from = mem->getreffrom();
+ to = mem->getrefto();
+
+ for (from = mem->getreffrom(); from; from = from->getnext()) {
+ printm(M_STATUS, " Reference from 0x%8.8lX\n", from->getref()->getaddress());
+ }
+
+ if (to) {
+ printm(M_STATUS, " Reference to 0x%8.8lX\n", to->getref()->getaddress());
+ }
+ }
+ pc += 3;
+ dump->reset();
+ }
+ }
+}
diff --git a/lib/mipsmem.cpp b/lib/mipsmem.cpp index 761df13..660c3fc 100644 --- a/lib/mipsmem.cpp +++ b/lib/mipsmem.cpp @@ -1,349 +1,349 @@ -/* - * PSX-Tools Bundle Pack - * Copyright (C) 2002-2003 Nicolas "Pixel" Noble - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* $Id: mipsmem.cpp,v 1.1 2004-01-03 15:04:47 pixel Exp $ */ - -#include "mipsmem.h" - -refto_t::refto_t(Uint32 to, memdata * _m) : reffrom(new reffrom_t(this, _m->getmem(to))), mem(_m) { - refto_t * t = mem->getrefto(); - if (t) - delete t; - mem->setrefto(this); -} - -refto_t::~refto_t() { - mem->setrefto(0); - delete reffrom; -} - -memdata * refto_t::getmem() { - return mem; -} - -memdata * refto_t::getref() { - return reffrom->getmem(); -} - -reffrom_t::reffrom_t(refto_t * _refto, memdata * _m) : refto(_refto), header(_m) { - next = header->getreffrom(); - prev = 0; - header->setreffrom(this); - if (next) - next->prev = this; -} - -reffrom_t::~reffrom_t() { - if (next) - next->prev = prev; - if (prev) - prev->next = next; - else - header->setreffrom(next); -} - -memdata * reffrom_t::getmem() { - return header; -} - -memdata * reffrom_t::getref() { - return refto->getmem(); -} - -reffrom_t * reffrom_t::getnext() { - return next; -} - -memdata::memdata(Uint32 _address, mipsmem * _mm) : address(_address), mm(_mm), func(0), refto(0), reffrom(0) { - mm->SetDatas(address, this); -} - -memdata::~memdata() { - mm->SetDatas(address, 0); -} - -Uint32 memdata::getaddress() { - return address; -} - -memdata * memdata::getmem(Uint32 addr) { - return getmem(addr, mm); -} - -memdata * memdata::getmem(Uint32 addr, mipsmem * mm) { - memdata * t = mm->GetDatas(addr); - - if (!t) { - t = new memdata(addr, mm); - } - return t; -} - -func_t * memdata::getfunc() { - return func; -} - -refto_t * memdata::getrefto() { - return refto; -} - -reffrom_t * memdata::getreffrom() { - return reffrom; -} - -void memdata::setfunc(func_t * f) { - func = f; - checkdestroy(); -} - -void memdata::setrefto(refto_t * r) { - refto = r; - checkdestroy(); -} - -void memdata::setreffrom(reffrom_t * r) { - reffrom = r; - checkdestroy(); -} - -void memdata::checkdestroy() { - if (!func && !refto && !reffrom) { - delete this; - } -} - - -mipsmem::mipsmem() { - memset(psyqhead, 0, 0x800); - memset(plainmemory, 0, PSXMEM); - memset(patches, 0, PSXMEM); - memset(patchesmap, 0, PSXMEM / 8); - memset(tags, 0, PSXMEM); - memset(datas, 0, PSXMEM * sizeof(memdata *)); -} - -Uint8 mipsmem::Read8(Uint32 mem) { - if ((mem < 0x80000000) || (mem >= (0x80000000 + PSXMEM))) { - printm(M_WARNING, "Reading at out of bound of memory: 0x%08x\n", mem); - return 0xff; - } - - mem -= 0x80000000; - - if (IsPatched(mem)) { - return patches[mem]; - } else { - return plainmemory[mem]; - } -} - -Uint16 mipsmem::Read16(Uint32 mem) { - Uint8 a, b; - - if (mem & 1) { - printm(M_WARNING, "Read16 at a non 16-bits boundary: 0x%08x\n", mem); - } - - a = Read8(mem); - b = Read8(mem + 1); - - return a | (b << 8); -} - -Uint32 mipsmem::Read32(Uint32 mem) { - Uint8 a, b, c, d; - - if (mem & 3) { - printm(M_WARNING, "Read32 at a non 32-bits boundary: 0x%08x\n", mem); - } - - a = Read8(mem); - b = Read8(mem + 1); - c = Read8(mem + 2); - d = Read8(mem + 3); - - return a | (b << 8) | (c << 16) | (d << 24); -} - -void mipsmem::Write8(Uint32 mem, Uint8 value) { - if ((mem < 0x80000000) || (mem > (0x80000000 + PSXMEM - 1))) { - printm(M_WARNING, "Writing at out of bound of memory: 0x%08x\n", mem); - return; - } - - mem -= 0x80000000; - - patch(mem, 1); - patches[mem] = value; -} - -void mipsmem::Write16(Uint32 mem, Uint16 value) { - if ((mem < 0x80000000) || (mem > (0x80000000 + PSXMEM - 2))) { - printm(M_WARNING, "Writing at out of bound of memory: 0x%08x\n", mem); - return; - } - - mem -= 0x80000000; - - patch(mem, 2); - patches[mem] = value & 0xff; - patches[mem + 1] = (value >> 8) & 0xff; -} - -void mipsmem::Write32(Uint32 mem, Uint32 value) { - if ((mem < 0x80000000) || (mem > (0x80000000 + PSXMEM - 4))) { - printm(M_WARNING, "Writing at out of bound of memory: 0x%08x\n", mem); - return; - } - - mem -= 0x80000000; - - patch(mem, 4); - patches[mem] = value & 0xff; - patches[mem + 1] = (value >> 8) & 0xff; - patches[mem + 2] = (value >> 16) & 0xff; - patches[mem + 3] = (value >> 24) & 0xff; -} - -void mipsmem::unpatch8(Uint32 mem) { - unpatch(mem, 1); -} - -void mipsmem::unpatch16(Uint32 mem) { - unpatch(mem, 2); -} - -void mipsmem::unpatch32(Uint32 mem) { - unpatch(mem, 4); -} - -bool mipsmem::IsPatched(Uint32 mem) { - int mask, pos; - - pos = mem / 8; - mask = 1 << (mem % 8); - - return patchesmap[pos] & mask; -} - -void mipsmem::LoadPSYQ(Handle * h) { - h->read(psyqhead, 0x800); - memset(plainmemory, 0, PSXMEM); - paddr = ((psyq*)psyqhead)->t_addr; - psize = ((psyq*)psyqhead)->t_size; - startpc = ((psyq*)psyqhead)->pc0; - - printm(M_INFO, "Loading %i (%08x) bytes of data at %i (%08x).\n", psize, psize, paddr - 0x80000000, paddr); - - h->read(plainmemory + paddr - 0x80000000, psize); -} - -void mipsmem::SavePSYQ(Handle * h) {\ - Uint32 i; - - if (!*((Uint32 *)psyqhead)) - return; - h->write(psyqhead, 0x800); - paddr = ((psyq*)psyqhead)->t_addr; - psize = ((psyq*)psyqhead)->t_size; - - printm(M_INFO, "Writing %i (%08x) bytes of data from %i (%08x).\n", psize, psize, paddr - 0x80000000, paddr); - - for (i = paddr - 0x80000000; i < psize; i++) { - h->writeU8(Read8(i)); - } -} - -bool mipsmem::GetTag(Uint32 addr, char tag) { - int mask; - - if ((addr < 0x80000000) || (addr >= (0x80000000 + PSXMEM))) { - printm(M_WARNING, "Reading tag at out of bound of memory: 0x%08x\n", addr); - return false; - } - - mask = 1 << tag; - addr -= 0x80000000; - - return tags[addr] & mask; -} - -void mipsmem::SetTag(Uint32 addr, char tag, bool t) { - int mask; - - if ((addr < 0x80000000) || (addr >= (0x80000000 + PSXMEM))) { - printm(M_WARNING, "Setting tag at out of bound of memory: 0x%08x\n", addr); - return; - } - - mask = 1 << tag; - addr -= 0x80000000; - - if (t) { - tags[addr] |= mask; - } else { - tags[addr] &= ~mask; - } -} - -memdata * mipsmem::GetDatas(Uint32 addr) { - return datas[addr]; -} - -void mipsmem::SetDatas(Uint32 addr, memdata * p) { - datas[addr] = p; -} - -Uint32 mipsmem::GetPC() { - return startpc; -} - -Uint32 mipsmem::GetLower() { - return paddr; -} - -Uint32 mipsmem::GetUpper() { - return paddr + psize; -} - -void mipsmem::patch(Uint32 mem, int size) { - int mask, pos; - - pos = mem / 8; - mask = 1 << (mem % 8); - - patchesmap[pos] |= mask; - - if (size != 1) { - patch(mem + 1, size - 1); - } -} - -void mipsmem::unpatch(Uint32 mem, int size) { - int mask, pos; - - pos = mem / 8; - mask = ~(1 << (mem % 8)); - - patchesmap[pos] &= mask; - - if (size != 1) { - unpatch(mem + 1, size - 1); - } -} +/*
+ * PSX-Tools Bundle Pack
+ * Copyright (C) 2002-2003 Nicolas "Pixel" Noble
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: mipsmem.cpp,v 1.2 2004-11-27 21:44:48 pixel Exp $ */
+
+#include "mipsmem.h"
+
+refto_t::refto_t(Uint32 to, memdata * _m) : reffrom(new reffrom_t(this, _m->getmem(to))), mem(_m) {
+ refto_t * t = mem->getrefto();
+ if (t)
+ delete t;
+ mem->setrefto(this);
+}
+
+refto_t::~refto_t() {
+ mem->setrefto(0);
+ delete reffrom;
+}
+
+memdata * refto_t::getmem() {
+ return mem;
+}
+
+memdata * refto_t::getref() {
+ return reffrom->getmem();
+}
+
+reffrom_t::reffrom_t(refto_t * _refto, memdata * _m) : refto(_refto), header(_m) {
+ next = header->getreffrom();
+ prev = 0;
+ header->setreffrom(this);
+ if (next)
+ next->prev = this;
+}
+
+reffrom_t::~reffrom_t() {
+ if (next)
+ next->prev = prev;
+ if (prev)
+ prev->next = next;
+ else
+ header->setreffrom(next);
+}
+
+memdata * reffrom_t::getmem() {
+ return header;
+}
+
+memdata * reffrom_t::getref() {
+ return refto->getmem();
+}
+
+reffrom_t * reffrom_t::getnext() {
+ return next;
+}
+
+memdata::memdata(Uint32 _address, mipsmem * _mm) : address(_address), mm(_mm), func(0), refto(0), reffrom(0) {
+ mm->SetDatas(address, this);
+}
+
+memdata::~memdata() {
+ mm->SetDatas(address, 0);
+}
+
+Uint32 memdata::getaddress() {
+ return address;
+}
+
+memdata * memdata::getmem(Uint32 addr) {
+ return getmem(addr, mm);
+}
+
+memdata * memdata::getmem(Uint32 addr, mipsmem * mm) {
+ memdata * t = mm->GetDatas(addr);
+
+ if (!t) {
+ t = new memdata(addr, mm);
+ }
+ return t;
+}
+
+func_t * memdata::getfunc() {
+ return func;
+}
+
+refto_t * memdata::getrefto() {
+ return refto;
+}
+
+reffrom_t * memdata::getreffrom() {
+ return reffrom;
+}
+
+void memdata::setfunc(func_t * f) {
+ func = f;
+ checkdestroy();
+}
+
+void memdata::setrefto(refto_t * r) {
+ refto = r;
+ checkdestroy();
+}
+
+void memdata::setreffrom(reffrom_t * r) {
+ reffrom = r;
+ checkdestroy();
+}
+
+void memdata::checkdestroy() {
+ if (!func && !refto && !reffrom) {
+ delete this;
+ }
+}
+
+
+mipsmem::mipsmem() {
+ memset(psyqhead, 0, 0x800);
+ memset(plainmemory, 0, PSXMEM);
+ memset(patches, 0, PSXMEM);
+ memset(patchesmap, 0, PSXMEM / 8);
+ memset(tags, 0, PSXMEM);
+ memset(datas, 0, PSXMEM * sizeof(memdata *));
+}
+
+Uint8 mipsmem::Read8(Uint32 mem) {
+ if ((mem < 0x80000000) || (mem >= (0x80000000 + PSXMEM))) {
+ printm(M_WARNING, "Reading at out of bound of memory: 0x%08x\n", mem);
+ return 0xff;
+ }
+
+ mem -= 0x80000000;
+
+ if (IsPatched(mem)) {
+ return patches[mem];
+ } else {
+ return plainmemory[mem];
+ }
+}
+
+Uint16 mipsmem::Read16(Uint32 mem) {
+ Uint8 a, b;
+
+ if (mem & 1) {
+ printm(M_WARNING, "Read16 at a non 16-bits boundary: 0x%08x\n", mem);
+ }
+
+ a = Read8(mem);
+ b = Read8(mem + 1);
+
+ return a | (b << 8);
+}
+
+Uint32 mipsmem::Read32(Uint32 mem) {
+ Uint8 a, b, c, d;
+
+ if (mem & 3) {
+ printm(M_WARNING, "Read32 at a non 32-bits boundary: 0x%08x\n", mem);
+ }
+
+ a = Read8(mem);
+ b = Read8(mem + 1);
+ c = Read8(mem + 2);
+ d = Read8(mem + 3);
+
+ return a | (b << 8) | (c << 16) | (d << 24);
+}
+
+void mipsmem::Write8(Uint32 mem, Uint8 value) {
+ if ((mem < 0x80000000) || (mem > (0x80000000 + PSXMEM - 1))) {
+ printm(M_WARNING, "Writing at out of bound of memory: 0x%08x\n", mem);
+ return;
+ }
+
+ mem -= 0x80000000;
+
+ patch(mem, 1);
+ patches[mem] = value;
+}
+
+void mipsmem::Write16(Uint32 mem, Uint16 value) {
+ if ((mem < 0x80000000) || (mem > (0x80000000 + PSXMEM - 2))) {
+ printm(M_WARNING, "Writing at out of bound of memory: 0x%08x\n", mem);
+ return;
+ }
+
+ mem -= 0x80000000;
+
+ patch(mem, 2);
+ patches[mem] = value & 0xff;
+ patches[mem + 1] = (value >> 8) & 0xff;
+}
+
+void mipsmem::Write32(Uint32 mem, Uint32 value) {
+ if ((mem < 0x80000000) || (mem > (0x80000000 + PSXMEM - 4))) {
+ printm(M_WARNING, "Writing at out of bound of memory: 0x%08x\n", mem);
+ return;
+ }
+
+ mem -= 0x80000000;
+
+ patch(mem, 4);
+ patches[mem] = value & 0xff;
+ patches[mem + 1] = (value >> 8) & 0xff;
+ patches[mem + 2] = (value >> 16) & 0xff;
+ patches[mem + 3] = (value >> 24) & 0xff;
+}
+
+void mipsmem::unpatch8(Uint32 mem) {
+ unpatch(mem, 1);
+}
+
+void mipsmem::unpatch16(Uint32 mem) {
+ unpatch(mem, 2);
+}
+
+void mipsmem::unpatch32(Uint32 mem) {
+ unpatch(mem, 4);
+}
+
+bool mipsmem::IsPatched(Uint32 mem) {
+ int mask, pos;
+
+ pos = mem / 8;
+ mask = 1 << (mem % 8);
+
+ return patchesmap[pos] & mask;
+}
+
+void mipsmem::LoadPSYQ(Handle * h) {
+ h->read(psyqhead, 0x800);
+ memset(plainmemory, 0, PSXMEM);
+ paddr = ((psyq*)psyqhead)->t_addr;
+ psize = ((psyq*)psyqhead)->t_size;
+ startpc = ((psyq*)psyqhead)->pc0;
+
+ printm(M_INFO, "Loading %i (%08x) bytes of data at %i (%08x).\n", psize, psize, paddr - 0x80000000, paddr);
+
+ h->read(plainmemory + paddr - 0x80000000, psize);
+}
+
+void mipsmem::SavePSYQ(Handle * h) {\
+ Uint32 i;
+
+ if (!*((Uint32 *)psyqhead))
+ return;
+ h->write(psyqhead, 0x800);
+ paddr = ((psyq*)psyqhead)->t_addr;
+ psize = ((psyq*)psyqhead)->t_size;
+
+ printm(M_INFO, "Writing %i (%08x) bytes of data from %i (%08x).\n", psize, psize, paddr - 0x80000000, paddr);
+
+ for (i = paddr - 0x80000000; i < psize; i++) {
+ h->writeU8(Read8(i));
+ }
+}
+
+bool mipsmem::GetTag(Uint32 addr, char tag) {
+ int mask;
+
+ if ((addr < 0x80000000) || (addr >= (0x80000000 + PSXMEM))) {
+ printm(M_WARNING, "Reading tag at out of bound of memory: 0x%08x\n", addr);
+ return false;
+ }
+
+ mask = 1 << tag;
+ addr -= 0x80000000;
+
+ return tags[addr] & mask;
+}
+
+void mipsmem::SetTag(Uint32 addr, char tag, bool t) {
+ int mask;
+
+ if ((addr < 0x80000000) || (addr >= (0x80000000 + PSXMEM))) {
+ printm(M_WARNING, "Setting tag at out of bound of memory: 0x%08x\n", addr);
+ return;
+ }
+
+ mask = 1 << tag;
+ addr -= 0x80000000;
+
+ if (t) {
+ tags[addr] |= mask;
+ } else {
+ tags[addr] &= ~mask;
+ }
+}
+
+memdata * mipsmem::GetDatas(Uint32 addr) {
+ return datas[addr];
+}
+
+void mipsmem::SetDatas(Uint32 addr, memdata * p) {
+ datas[addr] = p;
+}
+
+Uint32 mipsmem::GetPC() {
+ return startpc;
+}
+
+Uint32 mipsmem::GetLower() {
+ return paddr;
+}
+
+Uint32 mipsmem::GetUpper() {
+ return paddr + psize;
+}
+
+void mipsmem::patch(Uint32 mem, int size) {
+ int mask, pos;
+
+ pos = mem / 8;
+ mask = 1 << (mem % 8);
+
+ patchesmap[pos] |= mask;
+
+ if (size != 1) {
+ patch(mem + 1, size - 1);
+ }
+}
+
+void mipsmem::unpatch(Uint32 mem, int size) {
+ int mask, pos;
+
+ pos = mem / 8;
+ mask = ~(1 << (mem % 8));
+
+ patchesmap[pos] &= mask;
+
+ if (size != 1) {
+ unpatch(mem + 1, size - 1);
+ }
+}
diff --git a/lib/mipsobj.cpp b/lib/mipsobj.cpp index 97663e6..233c5c5 100644 --- a/lib/mipsobj.cpp +++ b/lib/mipsobj.cpp @@ -1,269 +1,269 @@ -#include "mipsobj.h" - -section::section(const String & _name, int _type) : name(_name), type(_type), datas(0), length(0) { } -section::section() : name(""), type(-1), datas(0), length(0) { } - -section::~section() { - if (datas) - free(datas); -} - -void section::setname(const String & _name) { - name = _name; -} - -void section::settype(int _type) { - type = _type; -} - -void section::putdatas(const Uint8 * _datas, int _length) { - if (type != BSS) { - datas = (Uint8 *) realloc(datas, length + _length); - memcpy(datas + length, _datas, _length); - } - length += _length; -} - -int section::gettype() { - return type; -} - -int section::getsize() { - return length; -} - -const Uint8 * section::getdatas() { - return datas; -} - -void section::putreloc(const String & _symbol, int _type, Uint32 _offset) { - struct reloc_t r; - - r.symbol = _symbol; - r.type = _type; - r.offset = _offset; - - putreloc(r); -} - -void section::putreloc(const struct reloc_t & r) { - relocs.push_back(r); -} - -mipsobj::mipsobj() : loaded(false) { } - -mipsobj::~mipsobj() { } - -void loadELF(Handle * elf) throw (GeneralException) { -} - -#define OBJSIG 0x024b4e4c - -#define READNAME(_str, _file) { \ - char _name[256]; \ - int _len; \ - \ - _len = _file->readU8(); \ - _file->read(_name, _len); \ - _name[_len] = 0; \ - _str = _name; \ -} - -void mipsobj::loadOBJ(Handle * obj) throw (GeneralException) { - int cursec, len, reloctype, relocexpr, id; - bool eof = false; - std::map<int, String> secnames; - std::map<int, String> symbolnames; - Uint8 * datas; - struct reloc_t reloc; - struct symbol_t symbol; - String name; - - while (!eof) { - int entryid = obj->readU8(); - - switch (entryid) { - case 0x00: - eof = true; - break; - - case 0x02: - len = obj->readU16(); - datas = (Uint8 *) malloc(len); - - obj->read(datas, len); - sections[secnames[cursec]].putdatas(datas, len); - - free(datas); - break; - - case 0x06: - cursec = obj->readU16(); - break; - - case 0x08: - len = obj->readU32(); - - sections[secnames[cursec]].putdatas(0, len); - break; - - case 0x0a: - reloctype = obj->readU8(); - reloc.offset = obj->readU16(); - - switch (reloctype) { - case 0x10: - reloc.type = R_MIPS_32; - break; - case 0x4a: - reloc.type = R_MIPS_26; - break; - case 0x52: - reloc.type = R_MIPS_HI16; - break; - case 0x54: - reloc.type = R_MIPS_LO16; - break; - case 0x0a: - case 0x26: - case 0x28: - case 0x64: - printm(M_ERROR, "Relocation type %02x not supported.\n", reloctype); - exit(-1); - break; - default: - printm(M_ERROR, "Relocation type %02x UNKNOWN! Please send the object to the author.\n", reloctype); - exit(-1); - } - - relocexpr = obj->readU8(); - - switch (relocexpr) { - case 0x02: - reloc.symbol = symbolnames[obj->readU16()]; - break; - case 0x04: - reloc.symbol = secnames[obj->readU16()]; - break; - case 0x00: - case 0x0c: - case 0x16: - case 0x2c: - case 0x2e: - case 0x30: - case 0x32: - case 0x36: - printm(M_ERROR, "Relocation expression %02x not supported.\n", relocexpr); - exit(-1); - break; - default: - printm(M_ERROR, "Relocation expression %02x UNKNOWN! Please mail the author.\n", relocexpr); - exit(-1); - break; - } - - sections[secnames[cursec]].relocs.push_back(reloc); - - break; - - case 0x0c: - id = obj->readU16(); - symbol.section = obj->readU16(); - symbol.offset = obj->readU32(); - READNAME(symbol.name, obj); - symbol.type = GLOBAL; - - symbolnames[id] = symbol.name; - - break; - - case 0x0e: - id = obj->readU16(); - READNAME(symbol.name, obj); - symbol.type = EXTERN; - - symbolnames[id] = symbol.name; - - break; - - case 0x10: - id = obj->readU16(); - obj->readU8(); - obj->readU16(); - READNAME(name, obj); - - secnames[id] = name; - - break; - - case 0x12: - printm(M_WARNING, "Local symbol not supported.\n"); - obj->readU16(); - obj->readU32(); - READNAME(name, obj); - break; - - case 0x1c: - printm(M_WARNING, "File number and name not supported.\n"); - obj->readU16(); - READNAME(name, obj); - break; - - case 0x2e: - if ((id = obj->readU8()) != 7) { - printm(M_ERROR, "CPU type %i not supported.\n", id); - exit(-1); - } - break; - - case 0x30: - printm(M_ERROR, "Constant not supported.\n"); - exit(-1); - break; - - default: - printm(M_ERROR, "Object entry type %i UNKNOWN! Please send the object to the author.\n", entryid); - exit(-1); - break; - } - } -} - -#define LIBSIG 0x0142494c - -void mipsobj::loadLIB(Handle * lib, const String & objname) throw (GeneralException) { - char _name[9]; - String name; - int hsize, size, ptr; - bool found = false; - - lib->seek(0); - - if (lib->readU32() != LIBSIG) { - throw GeneralException("Not a Psy-Q lib file"); - } - - while (lib->tell() != lib->GetSize()) { - ptr = lib->tell(); - - lib->read(_name, 8); - name = _name; - lib->seek(4, SEEK_CUR); - hsize = lib->readU32(); - size = lib->readU32(); - - if (objname == name.trim()) { - lib->seek(ptr + hsize); - found = true; - break; - } - - lib->seek(ptr + size); - } - - if (!found) { - throw GeneralException("Object `" + objname + "' not found in archive " + lib->GetName()); - } - - loadOBJ(lib); -} +#include "mipsobj.h"
+
+section::section(const String & _name, int _type) : name(_name), type(_type), datas(0), length(0) { }
+section::section() : name(""), type(-1), datas(0), length(0) { }
+
+section::~section() {
+ if (datas)
+ free(datas);
+}
+
+void section::setname(const String & _name) {
+ name = _name;
+}
+
+void section::settype(int _type) {
+ type = _type;
+}
+
+void section::putdatas(const Uint8 * _datas, int _length) {
+ if (type != BSS) {
+ datas = (Uint8 *) realloc(datas, length + _length);
+ memcpy(datas + length, _datas, _length);
+ }
+ length += _length;
+}
+
+int section::gettype() {
+ return type;
+}
+
+int section::getsize() {
+ return length;
+}
+
+const Uint8 * section::getdatas() {
+ return datas;
+}
+
+void section::putreloc(const String & _symbol, int _type, Uint32 _offset) {
+ struct reloc_t r;
+
+ r.symbol = _symbol;
+ r.type = _type;
+ r.offset = _offset;
+
+ putreloc(r);
+}
+
+void section::putreloc(const struct reloc_t & r) {
+ relocs.push_back(r);
+}
+
+mipsobj::mipsobj() : loaded(false) { }
+
+mipsobj::~mipsobj() { }
+
+void loadELF(Handle * elf) throw (GeneralException) {
+}
+
+#define OBJSIG 0x024b4e4c
+
+#define READNAME(_str, _file) { \
+ char _name[256]; \
+ int _len; \
+ \
+ _len = _file->readU8(); \
+ _file->read(_name, _len); \
+ _name[_len] = 0; \
+ _str = _name; \
+}
+
+void mipsobj::loadOBJ(Handle * obj) throw (GeneralException) {
+ int cursec, len, reloctype, relocexpr, id;
+ bool eof = false;
+ std::map<int, String> secnames;
+ std::map<int, String> symbolnames;
+ Uint8 * datas;
+ struct reloc_t reloc;
+ struct symbol_t symbol;
+ String name;
+
+ while (!eof) {
+ int entryid = obj->readU8();
+
+ switch (entryid) {
+ case 0x00:
+ eof = true;
+ break;
+
+ case 0x02:
+ len = obj->readU16();
+ datas = (Uint8 *) malloc(len);
+
+ obj->read(datas, len);
+ sections[secnames[cursec]].putdatas(datas, len);
+
+ free(datas);
+ break;
+
+ case 0x06:
+ cursec = obj->readU16();
+ break;
+
+ case 0x08:
+ len = obj->readU32();
+
+ sections[secnames[cursec]].putdatas(0, len);
+ break;
+
+ case 0x0a:
+ reloctype = obj->readU8();
+ reloc.offset = obj->readU16();
+
+ switch (reloctype) {
+ case 0x10:
+ reloc.type = R_MIPS_32;
+ break;
+ case 0x4a:
+ reloc.type = R_MIPS_26;
+ break;
+ case 0x52:
+ reloc.type = R_MIPS_HI16;
+ break;
+ case 0x54:
+ reloc.type = R_MIPS_LO16;
+ break;
+ case 0x0a:
+ case 0x26:
+ case 0x28:
+ case 0x64:
+ printm(M_ERROR, "Relocation type %02x not supported.\n", reloctype);
+ exit(-1);
+ break;
+ default:
+ printm(M_ERROR, "Relocation type %02x UNKNOWN! Please send the object to the author.\n", reloctype);
+ exit(-1);
+ }
+
+ relocexpr = obj->readU8();
+
+ switch (relocexpr) {
+ case 0x02:
+ reloc.symbol = symbolnames[obj->readU16()];
+ break;
+ case 0x04:
+ reloc.symbol = secnames[obj->readU16()];
+ break;
+ case 0x00:
+ case 0x0c:
+ case 0x16:
+ case 0x2c:
+ case 0x2e:
+ case 0x30:
+ case 0x32:
+ case 0x36:
+ printm(M_ERROR, "Relocation expression %02x not supported.\n", relocexpr);
+ exit(-1);
+ break;
+ default:
+ printm(M_ERROR, "Relocation expression %02x UNKNOWN! Please mail the author.\n", relocexpr);
+ exit(-1);
+ break;
+ }
+
+ sections[secnames[cursec]].relocs.push_back(reloc);
+
+ break;
+
+ case 0x0c:
+ id = obj->readU16();
+ symbol.section = obj->readU16();
+ symbol.offset = obj->readU32();
+ READNAME(symbol.name, obj);
+ symbol.type = GLOBAL;
+
+ symbolnames[id] = symbol.name;
+
+ break;
+
+ case 0x0e:
+ id = obj->readU16();
+ READNAME(symbol.name, obj);
+ symbol.type = EXTERN;
+
+ symbolnames[id] = symbol.name;
+
+ break;
+
+ case 0x10:
+ id = obj->readU16();
+ obj->readU8();
+ obj->readU16();
+ READNAME(name, obj);
+
+ secnames[id] = name;
+
+ break;
+
+ case 0x12:
+ printm(M_WARNING, "Local symbol not supported.\n");
+ obj->readU16();
+ obj->readU32();
+ READNAME(name, obj);
+ break;
+
+ case 0x1c:
+ printm(M_WARNING, "File number and name not supported.\n");
+ obj->readU16();
+ READNAME(name, obj);
+ break;
+
+ case 0x2e:
+ if ((id = obj->readU8()) != 7) {
+ printm(M_ERROR, "CPU type %i not supported.\n", id);
+ exit(-1);
+ }
+ break;
+
+ case 0x30:
+ printm(M_ERROR, "Constant not supported.\n");
+ exit(-1);
+ break;
+
+ default:
+ printm(M_ERROR, "Object entry type %i UNKNOWN! Please send the object to the author.\n", entryid);
+ exit(-1);
+ break;
+ }
+ }
+}
+
+#define LIBSIG 0x0142494c
+
+void mipsobj::loadLIB(Handle * lib, const String & objname) throw (GeneralException) {
+ char _name[9];
+ String name;
+ int hsize, size, ptr;
+ bool found = false;
+
+ lib->seek(0);
+
+ if (lib->readU32() != LIBSIG) {
+ throw GeneralException("Not a Psy-Q lib file");
+ }
+
+ while (lib->tell() != lib->GetSize()) {
+ ptr = lib->tell();
+
+ lib->read(_name, 8);
+ name = _name;
+ lib->seek(4, SEEK_CUR);
+ hsize = lib->readU32();
+ size = lib->readU32();
+
+ if (objname == name.trim()) {
+ lib->seek(ptr + hsize);
+ found = true;
+ break;
+ }
+
+ lib->seek(ptr + size);
+ }
+
+ if (!found) {
+ throw GeneralException("Object `" + objname + "' not found in archive " + lib->GetName());
+ }
+
+ loadOBJ(lib);
+}
diff --git a/lib/yazedc.cpp b/lib/yazedc.cpp index 6350ef7..100cd38 100644 --- a/lib/yazedc.cpp +++ b/lib/yazedc.cpp @@ -1,273 +1,273 @@ -/* - * PSX-Tools Bundle Pack - * Copyright (C) 1998 Heiko Eissfeldt - * portions used& Chris Smith - * Modified by Yazoo, then by - * Nicolas "Pixel" Noble - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* $Id: yazedc.cpp,v 1.3 2003-12-04 01:47:37 pixel Exp $ */ - -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "yazedc.h" - -yazedc::yazedc() : minute(0), second(2), frame(0), sectortype(0) {} - -/* ------------- tables generated by gen_encodes --------------*/ - -#include "crctables" - -static int encode_L2_Q(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P + L2_Q]) -{ - unsigned char *Q; - int i,j; - - Q = inout + 4 + L2_RAW + 4 + 8 + L2_P; - memset(Q, 0, L2_Q); - for (j = 0; j < 26; j++) { - for (i = 0; i < 43; i++) { - unsigned char data; - - /* LSB */ - data = inout[(j*43*2+i*2*44) % (4 + L2_RAW + 4 + 8 + L2_P)]; - if (data != 0) { - unsigned int base = rs_l12_log[data]; - - unsigned int sum = base + DQ[0][i]; - if (sum >= ((1 << RS_L12_BITS)-1)) - sum -= (1 << RS_L12_BITS)-1; - - Q[0] ^= rs_l12_alog[sum]; - - sum = base + DQ[1][i]; - if (sum >= ((1 << RS_L12_BITS)-1)) - sum -= (1 << RS_L12_BITS)-1; - - Q[26*2] ^= rs_l12_alog[sum]; - } - /* MSB */ - data = inout[(j*43*2+i*2*44+1) % (4 + L2_RAW + 4 + 8 + L2_P)]; - if (data != 0) { - unsigned int base = rs_l12_log[data]; - - unsigned int sum = base+DQ[0][i]; - if (sum >= ((1 << RS_L12_BITS)-1)) - sum -= (1 << RS_L12_BITS)-1; - - Q[1] ^= rs_l12_alog[sum]; - - sum = base + DQ[1][i]; - if (sum >= ((1 << RS_L12_BITS)-1)) - sum -= (1 << RS_L12_BITS)-1; - - Q[26*2+1] ^= rs_l12_alog[sum]; - } - } - Q += 2; - } - return 0; -} - -static int encode_L2_P(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P]) -{ - unsigned char *P; - int i,j; - - P = inout + 4 + L2_RAW + 4 + 8; - memset(P, 0, L2_P); - for (j = 0; j < 43; j++) { - for (i = 0; i < 24; i++) { - unsigned char data; - - /* LSB */ - data = inout[i*2*43]; - if (data != 0) { - unsigned int base = rs_l12_log[data]; - - unsigned int sum = base + DP[0][i]; - if (sum >= ((1 << RS_L12_BITS)-1)) - sum -= (1 << RS_L12_BITS)-1; - - P[0] ^= rs_l12_alog[sum]; - - sum = base + DP[1][i]; - if (sum >= ((1 << RS_L12_BITS)-1)) - sum -= (1 << RS_L12_BITS)-1; - - P[43*2] ^= rs_l12_alog[sum]; - } - /* MSB */ - data = inout[i*2*43+1]; - if (data != 0) { - unsigned int base = rs_l12_log[data]; - - unsigned int sum = base + DP[0][i]; - if (sum >= ((1 << RS_L12_BITS)-1)) - sum -= (1 << RS_L12_BITS)-1; - - P[1] ^= rs_l12_alog[sum]; - - sum = base + DP[1][i]; - if (sum >= ((1 << RS_L12_BITS)-1)) - sum -= (1 << RS_L12_BITS)-1; - - P[43*2+1] ^= rs_l12_alog[sum]; - } - } - P += 2; - inout += 2; - } - return 0; -} - -int yazedc::scramble_L2(unsigned char *inout) -{ - unsigned char *r = inout + 12; - const unsigned char *s = yellowbook_scrambler; - unsigned int i; - unsigned int *f = (unsigned int *)inout; - - for (i = (L2_RAW + L2_Q + L2_P +16)/sizeof(unsigned char); i; i--) { - *r++ ^= *s++; - } - - /* generate F1 frames */ - for (i = (2352/sizeof(unsigned int)); i; i--) { - *f++ = ((*f & 0xff00ff00UL) >> 8) | ((*f & 0x00ff00ffUL) << 8); - } - - return 0; -} - -int yazedc::build_address(unsigned char inout[], int sectortype, unsigned address) -{ - inout[12] = minute; - inout[13] = second; - inout[14] = frame; - if (sectortype == MODE_0) - inout[15] = 0; - else if (sectortype == MODE_1) - inout[15] = 1; - else if (sectortype == MODE_2) - inout[15] = 2; - else if (sectortype == MODE_2_FORM_1) - inout[15] = 2; - else if (sectortype == MODE_2_FORM_2) - inout[15] = 2; - else - return -1; - return 0; -} - -#include "crctable.out" -unsigned long int build_edc(unsigned char inout[], int from, int upto) -{ - unsigned char *p = inout+from; - unsigned long result = 0; - - for (; from <= upto; from++) - result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8); - - return result; -} - -/* Layer 2 Product code en/decoder */ -int yazedc::do_encode_L2(unsigned char inout[(12 + 4 + L2_RAW+4+8+L2_Q+L2_P)], int sectortype, unsigned address) -{ - unsigned long int result; - -#define SYNCPATTERN "\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" - - /* supply initial sync pattern */ - memcpy(inout, SYNCPATTERN, sizeof(SYNCPATTERN)); - - if (sectortype == MODE_0) { - memset(inout + sizeof(SYNCPATTERN), 0, 4 + L2_RAW + 12 + L2_P + L2_Q); - build_address(inout, sectortype, address); - return 0; - } - - switch (sectortype) { - case MODE_1: - build_address(inout, sectortype, address); - result = build_edc(inout, 0, 16+2048-1); - inout[2064+0] = result >> 0L; - inout[2064+1] = result >> 8L; - inout[2064+2] = result >> 16L; - inout[2064+3] = result >> 24L; - memset(inout+2064+4, 0, 8); - encode_L2_P(inout+12); - encode_L2_Q(inout+12); - break; - case MODE_2: - build_address(inout, sectortype, address); - break; - case MODE_2_FORM_1: - result = build_edc(inout, 16, 16+8+2048-1); - inout[2072+0] = result >> 0L; - inout[2072+1] = result >> 8L; - inout[2072+2] = result >> 16L; - inout[2072+3] = result >> 24L; - - /* clear header for P/Q parity calculation */ - inout[12] = 0; - inout[12+1] = 0; - inout[12+2] = 0; - inout[12+3] = 0; - encode_L2_P(inout+12); - encode_L2_Q(inout+12); - build_address(inout, sectortype, address); - break; - case MODE_2_FORM_2: - build_address(inout, sectortype, address); - result = build_edc(inout, 16, 16+8+2324-1); - inout[2348+0] = result >> 0L; - inout[2348+1] = result >> 8L; - inout[2348+2] = result >> 16L; - inout[2348+3] = result >> 24L; - break; - default: - return -1; - } - - return 0; -} - -int yazedc::get_sector_type(void) -{ - return sectortype; -} - -int yazedc::set_sector_type(int st) -{ - switch(st) { - case MODE_0: - case MODE_1: - case MODE_2: - case MODE_2_FORM_1: - case MODE_2_FORM_2: - sectortype = st; - default: - return -1; - } - return 0; -} +/*
+ * PSX-Tools Bundle Pack
+ * Copyright (C) 1998 Heiko Eissfeldt
+ * portions used& Chris Smith
+ * Modified by Yazoo, then by
+ * Nicolas "Pixel" Noble
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: yazedc.cpp,v 1.4 2004-11-27 21:44:48 pixel Exp $ */
+
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "yazedc.h"
+
+yazedc::yazedc() : minute(0), second(2), frame(0), sectortype(0) {}
+
+/* ------------- tables generated by gen_encodes --------------*/
+
+#include "crctables"
+
+static int encode_L2_Q(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P + L2_Q])
+{
+ unsigned char *Q;
+ int i,j;
+
+ Q = inout + 4 + L2_RAW + 4 + 8 + L2_P;
+ memset(Q, 0, L2_Q);
+ for (j = 0; j < 26; j++) {
+ for (i = 0; i < 43; i++) {
+ unsigned char data;
+
+ /* LSB */
+ data = inout[(j*43*2+i*2*44) % (4 + L2_RAW + 4 + 8 + L2_P)];
+ if (data != 0) {
+ unsigned int base = rs_l12_log[data];
+
+ unsigned int sum = base + DQ[0][i];
+ if (sum >= ((1 << RS_L12_BITS)-1))
+ sum -= (1 << RS_L12_BITS)-1;
+
+ Q[0] ^= rs_l12_alog[sum];
+
+ sum = base + DQ[1][i];
+ if (sum >= ((1 << RS_L12_BITS)-1))
+ sum -= (1 << RS_L12_BITS)-1;
+
+ Q[26*2] ^= rs_l12_alog[sum];
+ }
+ /* MSB */
+ data = inout[(j*43*2+i*2*44+1) % (4 + L2_RAW + 4 + 8 + L2_P)];
+ if (data != 0) {
+ unsigned int base = rs_l12_log[data];
+
+ unsigned int sum = base+DQ[0][i];
+ if (sum >= ((1 << RS_L12_BITS)-1))
+ sum -= (1 << RS_L12_BITS)-1;
+
+ Q[1] ^= rs_l12_alog[sum];
+
+ sum = base + DQ[1][i];
+ if (sum >= ((1 << RS_L12_BITS)-1))
+ sum -= (1 << RS_L12_BITS)-1;
+
+ Q[26*2+1] ^= rs_l12_alog[sum];
+ }
+ }
+ Q += 2;
+ }
+ return 0;
+}
+
+static int encode_L2_P(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P])
+{
+ unsigned char *P;
+ int i,j;
+
+ P = inout + 4 + L2_RAW + 4 + 8;
+ memset(P, 0, L2_P);
+ for (j = 0; j < 43; j++) {
+ for (i = 0; i < 24; i++) {
+ unsigned char data;
+
+ /* LSB */
+ data = inout[i*2*43];
+ if (data != 0) {
+ unsigned int base = rs_l12_log[data];
+
+ unsigned int sum = base + DP[0][i];
+ if (sum >= ((1 << RS_L12_BITS)-1))
+ sum -= (1 << RS_L12_BITS)-1;
+
+ P[0] ^= rs_l12_alog[sum];
+
+ sum = base + DP[1][i];
+ if (sum >= ((1 << RS_L12_BITS)-1))
+ sum -= (1 << RS_L12_BITS)-1;
+
+ P[43*2] ^= rs_l12_alog[sum];
+ }
+ /* MSB */
+ data = inout[i*2*43+1];
+ if (data != 0) {
+ unsigned int base = rs_l12_log[data];
+
+ unsigned int sum = base + DP[0][i];
+ if (sum >= ((1 << RS_L12_BITS)-1))
+ sum -= (1 << RS_L12_BITS)-1;
+
+ P[1] ^= rs_l12_alog[sum];
+
+ sum = base + DP[1][i];
+ if (sum >= ((1 << RS_L12_BITS)-1))
+ sum -= (1 << RS_L12_BITS)-1;
+
+ P[43*2+1] ^= rs_l12_alog[sum];
+ }
+ }
+ P += 2;
+ inout += 2;
+ }
+ return 0;
+}
+
+int yazedc::scramble_L2(unsigned char *inout)
+{
+ unsigned char *r = inout + 12;
+ const unsigned char *s = yellowbook_scrambler;
+ unsigned int i;
+ unsigned int *f = (unsigned int *)inout;
+
+ for (i = (L2_RAW + L2_Q + L2_P +16)/sizeof(unsigned char); i; i--) {
+ *r++ ^= *s++;
+ }
+
+ /* generate F1 frames */
+ for (i = (2352/sizeof(unsigned int)); i; i--) {
+ *f++ = ((*f & 0xff00ff00UL) >> 8) | ((*f & 0x00ff00ffUL) << 8);
+ }
+
+ return 0;
+}
+
+int yazedc::build_address(unsigned char inout[], int sectortype, unsigned address)
+{
+ inout[12] = minute;
+ inout[13] = second;
+ inout[14] = frame;
+ if (sectortype == MODE_0)
+ inout[15] = 0;
+ else if (sectortype == MODE_1)
+ inout[15] = 1;
+ else if (sectortype == MODE_2)
+ inout[15] = 2;
+ else if (sectortype == MODE_2_FORM_1)
+ inout[15] = 2;
+ else if (sectortype == MODE_2_FORM_2)
+ inout[15] = 2;
+ else
+ return -1;
+ return 0;
+}
+
+#include "crctable.out"
+unsigned long int build_edc(unsigned char inout[], int from, int upto)
+{
+ unsigned char *p = inout+from;
+ unsigned long result = 0;
+
+ for (; from <= upto; from++)
+ result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8);
+
+ return result;
+}
+
+/* Layer 2 Product code en/decoder */
+int yazedc::do_encode_L2(unsigned char inout[(12 + 4 + L2_RAW+4+8+L2_Q+L2_P)], int sectortype, unsigned address)
+{
+ unsigned long int result;
+
+#define SYNCPATTERN "\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
+
+ /* supply initial sync pattern */
+ memcpy(inout, SYNCPATTERN, sizeof(SYNCPATTERN));
+
+ if (sectortype == MODE_0) {
+ memset(inout + sizeof(SYNCPATTERN), 0, 4 + L2_RAW + 12 + L2_P + L2_Q);
+ build_address(inout, sectortype, address);
+ return 0;
+ }
+
+ switch (sectortype) {
+ case MODE_1:
+ build_address(inout, sectortype, address);
+ result = build_edc(inout, 0, 16+2048-1);
+ inout[2064+0] = result >> 0L;
+ inout[2064+1] = result >> 8L;
+ inout[2064+2] = result >> 16L;
+ inout[2064+3] = result >> 24L;
+ memset(inout+2064+4, 0, 8);
+ encode_L2_P(inout+12);
+ encode_L2_Q(inout+12);
+ break;
+ case MODE_2:
+ build_address(inout, sectortype, address);
+ break;
+ case MODE_2_FORM_1:
+ result = build_edc(inout, 16, 16+8+2048-1);
+ inout[2072+0] = result >> 0L;
+ inout[2072+1] = result >> 8L;
+ inout[2072+2] = result >> 16L;
+ inout[2072+3] = result >> 24L;
+
+ /* clear header for P/Q parity calculation */
+ inout[12] = 0;
+ inout[12+1] = 0;
+ inout[12+2] = 0;
+ inout[12+3] = 0;
+ encode_L2_P(inout+12);
+ encode_L2_Q(inout+12);
+ build_address(inout, sectortype, address);
+ break;
+ case MODE_2_FORM_2:
+ build_address(inout, sectortype, address);
+ result = build_edc(inout, 16, 16+8+2324-1);
+ inout[2348+0] = result >> 0L;
+ inout[2348+1] = result >> 8L;
+ inout[2348+2] = result >> 16L;
+ inout[2348+3] = result >> 24L;
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+int yazedc::get_sector_type(void)
+{
+ return sectortype;
+}
+
+int yazedc::set_sector_type(int st)
+{
+ switch(st) {
+ case MODE_0:
+ case MODE_1:
+ case MODE_2:
+ case MODE_2_FORM_1:
+ case MODE_2_FORM_2:
+ sectortype = st;
+ default:
+ return -1;
+ }
+ return 0;
+}
|