Initial GS code engine implementation
- Replaced the cheat file format with YAML - Replaced the simulate_boot function with a small bit of C, and a loader in assembly - The loader is fairly well-documented, and points out which register states are required for CICs - Also includes a giant patcher function (relocatable assembly) which can patch the exception handler and run the code engine - The code engine is GS Pro 3.30-compatible, and supports all code types
This commit is contained in:
parent
3ba0910535
commit
90fb4e39a5
4
Makefile
4
Makefile
@ -7,9 +7,9 @@ N64TOOL = $(ROOTDIR)/bin/n64tool
|
|||||||
HEADERNAME = header
|
HEADERNAME = header
|
||||||
|
|
||||||
|
|
||||||
LINK_FLAGS = -G4 -L$(ROOTDIR)/lib -L$(ROOTDIR)/mips64-elf/lib -ldragon -lmikmod -lmad -lc -lm -ldragonsys -lnosys $(LIBS) -Tn64ld.x
|
LINK_FLAGS = -O1 -L$(ROOTDIR)/lib -L$(ROOTDIR)/mips64-elf/lib -ldragon -lmikmod -lmad -lyaml -lc -lm -ldragonsys -lnosys $(LIBS) -Tn64ld.x
|
||||||
PROG_NAME = menu
|
PROG_NAME = menu
|
||||||
CFLAGS = -std=gnu99 -march=vr4300 -mtune=vr4300 -G4 -I$(ROOTDIR)/include -I$(ROOTDIR)/mips64-elf/include -lpthread -lrt -D_REENTRANT -DUSE_TRUETYPE
|
CFLAGS = -std=gnu99 -march=vr4300 -mtune=vr4300 -O1 -I$(ROOTDIR)/include -I$(ROOTDIR)/mips64-elf/include -lpthread -lrt -D_REENTRANT -DUSE_TRUETYPE
|
||||||
ASFLAGS = -mtune=vr4300 -march=vr4300
|
ASFLAGS = -mtune=vr4300 -march=vr4300
|
||||||
CC = $(GCCN64PREFIX)gcc
|
CC = $(GCCN64PREFIX)gcc
|
||||||
AS = $(GCCN64PREFIX)as
|
AS = $(GCCN64PREFIX)as
|
||||||
|
26
README.md
26
README.md
@ -33,6 +33,7 @@ toolchain recommended by libdragon, with some updated versions.
|
|||||||
* [libdragon](https://github.com/parasyte/libdragon)
|
* [libdragon](https://github.com/parasyte/libdragon)
|
||||||
* [libmikmod-n64](https://github.com/parasyte/libmikmod-n64)
|
* [libmikmod-n64](https://github.com/parasyte/libmikmod-n64)
|
||||||
* [libmad-n64](https://github.com/parasyte/libmad-n64)
|
* [libmad-n64](https://github.com/parasyte/libmad-n64)
|
||||||
|
* [libyaml](http://pyyaml.org/wiki/LibYAML)
|
||||||
|
|
||||||
### Build the Toolchain
|
### Build the Toolchain
|
||||||
|
|
||||||
@ -98,11 +99,30 @@ toolchain installation path:
|
|||||||
```bash
|
```bash
|
||||||
$ git clone https://github.com/parasyte/libmad-n64.git
|
$ git clone https://github.com/parasyte/libmad-n64.git
|
||||||
$ cd libmad-n64
|
$ cd libmad-n64
|
||||||
$ export PATH=$PATH:/usr/local/mips64-elf/bin
|
$ export PATH=$PATH:$(N64_INST)/bin
|
||||||
$ CFLAGS="-march=vr4300 -mtune=vr4300 -mno-extern-sdata" \
|
$ CFLAGS="-march=vr4300 -mtune=vr4300 -mno-extern-sdata" \
|
||||||
LDFLAGS="-L/usr/local/mips64-elf/lib" LIBS="-lc -lnosys" \
|
LDFLAGS="-L$(N64_INST)/lib" LIBS="-lc -lnosys" \
|
||||||
./configure --host=mips64-elf --disable-shared \
|
./configure --host=mips64-elf --disable-shared \
|
||||||
--prefix=/usr/local/mips64-elf --enable-speed --enable-fpm=mips
|
--prefix=$(N64_INST) --enable-speed --enable-fpm=mips
|
||||||
|
$ make
|
||||||
|
$ make install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Build `libyaml`
|
||||||
|
|
||||||
|
Download libyaml 0.1.6 and build, be sure to set the path according to your
|
||||||
|
toolchain installation path:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ hg clone https://bitbucket.org/xi/libyaml
|
||||||
|
$ cd libyaml
|
||||||
|
$ hg update 0.1.6
|
||||||
|
$ ./bootstrap
|
||||||
|
$ export PATH=$PATH:$(N64_INST)/bin
|
||||||
|
$ CFLAGS="-std=gnu99 -march=vr4300 -mtune=vr4300" \
|
||||||
|
LDFLAGS="-L$(N64_INST)/lib -Tn64ld.x" \
|
||||||
|
LIBS="-ldragon -lc -ldragonsys -lnosys" \
|
||||||
|
./configure --host=mips64-elf --prefix=$(N64_INST)
|
||||||
$ make
|
$ make
|
||||||
$ make install
|
$ make install
|
||||||
```
|
```
|
||||||
|
612
menu.c
612
menu.c
@ -39,18 +39,8 @@
|
|||||||
#include <mikmod.h>
|
#include <mikmod.h>
|
||||||
#include "mp3.h"
|
#include "mp3.h"
|
||||||
|
|
||||||
//cheats
|
// YAML parser
|
||||||
struct gscEntry {
|
#include <yaml.h>
|
||||||
char *description;
|
|
||||||
char *gscodes;
|
|
||||||
u16 count;
|
|
||||||
u16 state;
|
|
||||||
u16 mask;
|
|
||||||
u16 value;
|
|
||||||
};
|
|
||||||
typedef struct gscEntry gscEntry_t;
|
|
||||||
|
|
||||||
gscEntry_t gGSCodes[256];
|
|
||||||
|
|
||||||
#ifdef USE_TRUETYPE
|
#ifdef USE_TRUETYPE
|
||||||
#define STB_TRUETYPE_IMPLEMENTATION
|
#define STB_TRUETYPE_IMPLEMENTATION
|
||||||
@ -649,7 +639,7 @@ void drawBoxNumber(display_context_t disp, int box){
|
|||||||
|
|
||||||
switch(box){
|
switch(box){
|
||||||
case 1: drawBox(20, 24, 277, 193, disp); break; //filebrowser
|
case 1: drawBox(20, 24, 277, 193, disp); break; //filebrowser
|
||||||
case 2: drawBox(60, 64, 197, 114, disp); break; //info screen
|
case 2: drawBox(60, 56, 200, 128, disp); break; //info screen
|
||||||
case 3:
|
case 3:
|
||||||
box_color= graphics_make_color(0x00, 0x00, 0x60, 0xC9);
|
box_color= graphics_make_color(0x00, 0x00, 0x60, 0xC9);
|
||||||
drawBox(79, 29, 161, 180, disp);
|
drawBox(79, 29, 161, 180, disp);
|
||||||
@ -1246,12 +1236,11 @@ void loadrom(display_context_t disp, u8 *buff, int fast){
|
|||||||
|
|
||||||
if (get_cic_save(cartID_short, &cic, &save)) {
|
if (get_cic_save(cartID_short, &cic, &save)) {
|
||||||
if(!fast)
|
if(!fast)
|
||||||
printText("found in db", 3, -1, disp);
|
printText("found in db", 3, -1, disp);
|
||||||
//thanks for the db :>
|
//thanks for the db :>
|
||||||
// cart was found, use CIC and SaveRAM type
|
// cart was found, use CIC and SaveRAM type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
sprintf(tmp, "Info: cic=%i save=%i",cic,save);
|
sprintf(tmp, "Info: cic=%i save=%i",cic,save);
|
||||||
printText(tmp, 3, -1, disp);
|
printText(tmp, 3, -1, disp);
|
||||||
@ -1317,7 +1306,6 @@ void loadrom(display_context_t disp, u8 *buff, int fast){
|
|||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
resp = diskRead(begin_sector, (void *)0xb0000000, lower_half);
|
resp = diskRead(begin_sector, (void *)0xb0000000, lower_half);
|
||||||
sleep(10);
|
|
||||||
resp = diskRead(begin_sector+lower_half, (void *)0xb2000000, file_sectors-lower_half);
|
resp = diskRead(begin_sector+lower_half, (void *)0xb2000000, file_sectors-lower_half);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2149,376 +2137,185 @@ void readSDcard(display_context_t disp, char *directory){
|
|||||||
display_dir(list, cursor, page, MAX_LIST, count, disp);
|
display_dir(list, cursor, page, MAX_LIST, count, disp);
|
||||||
}
|
}
|
||||||
|
|
||||||
//void readCheatFile(char *filename, display_context_t disp){
|
/*
|
||||||
int readCheatFile(char *filename){
|
* Returns two cheat lists:
|
||||||
//var file readin
|
* - One for the "at boot" cheats
|
||||||
u8 tmp[32];
|
* - Another for the "in-game" cheats
|
||||||
u8 ok=0;
|
*/
|
||||||
u8 firstr=1;
|
int readCheatFile(char *filename, u32 *cheat_lists[2]) {
|
||||||
|
// YAML parser
|
||||||
|
yaml_parser_t parser;
|
||||||
|
yaml_event_t event;
|
||||||
|
|
||||||
char *cp, *vp, *dp;
|
// State for YAML parser
|
||||||
char buffer[512];
|
int is_code = 0;
|
||||||
char temp[42];
|
int code_on = 1;
|
||||||
char buff[512];
|
int done = 0;
|
||||||
|
u32 *list1;
|
||||||
|
u32 *list2;
|
||||||
|
char *next;
|
||||||
|
|
||||||
int i = 0, j, type, offset = 0;
|
int repeater = 0;
|
||||||
|
u32 address;
|
||||||
|
u32 value;
|
||||||
|
|
||||||
int curr_cheat = -1;
|
yaml_parser_initialize(&parser);
|
||||||
|
|
||||||
FatRecord rec_tmpf;
|
FatRecord rec_tmpf;
|
||||||
ok = fatFindRecord(filename, &rec_tmpf, 0);
|
int ok = fatFindRecord(filename, &rec_tmpf, 0);
|
||||||
|
if (ok != 0) {
|
||||||
if(ok!=0){
|
|
||||||
return -1; //err file not found
|
return -1; //err file not found
|
||||||
}
|
}
|
||||||
else{
|
|
||||||
u8 resp = 0;
|
|
||||||
resp = fatOpenFileByeName(filename, 0);
|
|
||||||
|
|
||||||
//filesize of the opend file -> is the readfile / 512
|
u8 resp = 0;
|
||||||
int fsize= file.sec_available*512;
|
resp = fatOpenFileByeName(filename, 0);
|
||||||
char cheatfile_rawdata[fsize];
|
|
||||||
|
|
||||||
resp = fatReadFile(&cheatfile_rawdata, fsize / 512); //1 cluster
|
//filesize of the opend file -> is the readfile / 512
|
||||||
|
int fsize = file.sec_available * 512;
|
||||||
int line_chr=0;
|
char *cheatfile = malloc(fsize);
|
||||||
long c=0;
|
if (!cheatfile) {
|
||||||
|
return -2; // Out of memory
|
||||||
for(c=0;c<fsize;c++){
|
|
||||||
buff[line_chr++]=cheatfile_rawdata[c];
|
|
||||||
|
|
||||||
if(cheatfile_rawdata[c]=='\n'){
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
// process GameShark Code line
|
|
||||||
cp = vp = dp = NULL;
|
|
||||||
|
|
||||||
while ((buff[i] == ' ') || (buff[i] == '\t'))
|
|
||||||
i++; // skip initial whitespace
|
|
||||||
|
|
||||||
// check for blank line
|
|
||||||
if ((buff[i] == '\n') || (buff[i] == '\r')) //carriage return
|
|
||||||
{
|
|
||||||
line_chr=0;
|
|
||||||
continue; // skip
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((buff[i] == '#') || (buff[i] == ';')) {
|
|
||||||
line_chr=0;
|
|
||||||
continue; // skip
|
|
||||||
}
|
|
||||||
|
|
||||||
cp = &buff[i];
|
|
||||||
|
|
||||||
while ((buff[i] != ' ') && (buff[i] != '\t') && (buff[i] != '\n') && (buff[i] != '\r'))
|
|
||||||
i++;
|
|
||||||
|
|
||||||
buff[i] = 0;
|
|
||||||
i++;
|
|
||||||
|
|
||||||
while ((buff[i] == ' ') || (buff[i] == '\t'))
|
|
||||||
i++; // skip whitespace
|
|
||||||
|
|
||||||
vp = &buff[i];
|
|
||||||
while ((buff[i] != ' ') && (buff[i] != '\t') && (buff[i] != '\n') && (buff[i] != '\r'))
|
|
||||||
i++; // find end of GameShark code value
|
|
||||||
|
|
||||||
if ((buff[i] == ' ') || (buff[i] == '\t')) {
|
|
||||||
buff[i] =0;
|
|
||||||
i++;
|
|
||||||
|
|
||||||
while ((buff[i] == ' ') || (buff[i] == '\t'))
|
|
||||||
i++; // skip whitespace
|
|
||||||
|
|
||||||
if ((buff[i] != '\n') && (buff[i] != '\r') && (buff[i] != '#') && (buff[i] != ';')) {
|
|
||||||
dp = &buff[i];
|
|
||||||
|
|
||||||
while ((buff[i] != '\n') && (buff[i] != '\r'))
|
|
||||||
i++; // find end of GameShark code description
|
|
||||||
|
|
||||||
buff[i] =0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
buff[i] =0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dp) {
|
|
||||||
// starting new cheat
|
|
||||||
curr_cheat++;
|
|
||||||
|
|
||||||
gGSCodes[curr_cheat].description= strdup(dp);
|
|
||||||
gGSCodes[curr_cheat].gscodes = NULL;
|
|
||||||
gGSCodes[curr_cheat].count = 0;
|
|
||||||
gGSCodes[curr_cheat].state = 1;
|
|
||||||
gGSCodes[curr_cheat].mask = 0;
|
|
||||||
|
|
||||||
if (!ishexchar(vp[3]))
|
|
||||||
gGSCodes[curr_cheat].mask |= 0x000F;
|
|
||||||
|
|
||||||
if (!ishexchar(vp[2]))
|
|
||||||
gGSCodes[curr_cheat].mask |= 0x00F0;
|
|
||||||
|
|
||||||
if (!ishexchar(vp[1]))
|
|
||||||
gGSCodes[curr_cheat].mask |= 0x0F00;
|
|
||||||
|
|
||||||
if (!ishexchar(vp[0]))
|
|
||||||
gGSCodes[curr_cheat].mask |= 0xF000;
|
|
||||||
|
|
||||||
gGSCodes[curr_cheat].value = 0;
|
|
||||||
offset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (curr_cheat < 0)
|
|
||||||
continue; // safety check
|
|
||||||
|
|
||||||
temp[0] = cp[0];
|
|
||||||
temp[1] = cp[1];
|
|
||||||
temp[2] = 0;
|
|
||||||
type = strtol(temp, (char **)NULL, 16);
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case 0x50:
|
|
||||||
// patch codes - unimplemented, also skips next line
|
|
||||||
// 5000XXYY 00ZZ
|
|
||||||
// TTTTTTTT VVVV
|
|
||||||
//skip next line missing
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x80:
|
|
||||||
// write 8-bit value to (cached) ram continuously
|
|
||||||
// 80XXYYYY 00ZZ
|
|
||||||
if (gGSCodes[curr_cheat].gscodes)
|
|
||||||
gGSCodes[curr_cheat].gscodes = realloc(gGSCodes[curr_cheat].gscodes, offset + 16);
|
|
||||||
else
|
|
||||||
gGSCodes[curr_cheat].gscodes = malloc(16);
|
|
||||||
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset], cp, 9);
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset+9], vp, 5);
|
|
||||||
|
|
||||||
gGSCodes[curr_cheat].count++;
|
|
||||||
offset += 16;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x81:
|
|
||||||
// write 16-bit value to (cached) ram continuously
|
|
||||||
// 81XXYYYY ZZZZ
|
|
||||||
if (gGSCodes[curr_cheat].gscodes)
|
|
||||||
gGSCodes[curr_cheat].gscodes = realloc(gGSCodes[curr_cheat].gscodes, offset + 16);
|
|
||||||
else
|
|
||||||
gGSCodes[curr_cheat].gscodes = malloc(16);
|
|
||||||
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset], cp, 9);
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset+9], vp, 5);
|
|
||||||
|
|
||||||
gGSCodes[curr_cheat].count++;
|
|
||||||
offset += 16;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x88:
|
|
||||||
// write 8-bit value to (cached) ram on GS button pressed - unimplemented
|
|
||||||
// 88XXYYYY 00ZZ
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x89:
|
|
||||||
// write 16-bit value to (cached) ram on GS button pressed - unimplemented
|
|
||||||
// 89XXYYYY ZZZZ
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xA0:
|
|
||||||
// write 8-bit value to (uncached) ram continuously
|
|
||||||
// A0XXYYYY 00ZZ => 3C1A A0XX 375A YYYY 241B 00ZZ A35B 0000
|
|
||||||
if (gGSCodes[curr_cheat].gscodes)
|
|
||||||
gGSCodes[curr_cheat].gscodes = realloc(gGSCodes[curr_cheat].gscodes, offset + 16);
|
|
||||||
else
|
|
||||||
gGSCodes[curr_cheat].gscodes = malloc(16);
|
|
||||||
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset], cp, 9);
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset+9], vp, 5);
|
|
||||||
gGSCodes[curr_cheat].count++;
|
|
||||||
offset += 16;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xA1:
|
|
||||||
// write 16-bit value to (uncached) ram continuously
|
|
||||||
// A1XXYYYY ZZZZ => 3C1A A0XX 375A YYYY 241B ZZZZ A75B 0000
|
|
||||||
if (gGSCodes[curr_cheat].gscodes)
|
|
||||||
gGSCodes[curr_cheat].gscodes = realloc(gGSCodes[curr_cheat].gscodes, offset + 16);
|
|
||||||
else
|
|
||||||
gGSCodes[curr_cheat].gscodes = malloc(16);
|
|
||||||
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset], cp, 9);
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset+9], vp, 5);
|
|
||||||
gGSCodes[curr_cheat].count++;
|
|
||||||
offset += 16;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xCC:
|
|
||||||
// deactivate expansion ram using 3rd method
|
|
||||||
// CC000000 0000
|
|
||||||
if (gGSCodes[curr_cheat].gscodes)
|
|
||||||
gGSCodes[curr_cheat].gscodes = realloc(gGSCodes[curr_cheat].gscodes, offset + 16);
|
|
||||||
else
|
|
||||||
gGSCodes[curr_cheat].gscodes = malloc(16);
|
|
||||||
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset], cp, 9);
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset+9], vp, 5);
|
|
||||||
gGSCodes[curr_cheat].count++;
|
|
||||||
offset += 16;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xD0:
|
|
||||||
// do next gs code if ram location is equal to 8-bit value
|
|
||||||
// D0XXYYYY 00ZZ
|
|
||||||
if (gGSCodes[curr_cheat].gscodes)
|
|
||||||
gGSCodes[curr_cheat].gscodes = realloc(gGSCodes[curr_cheat].gscodes, offset + 16);
|
|
||||||
else
|
|
||||||
gGSCodes[curr_cheat].gscodes = malloc(16);
|
|
||||||
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset], cp, 9);
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset+9], vp, 5);
|
|
||||||
gGSCodes[curr_cheat].count++;
|
|
||||||
offset += 16;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xD1:
|
|
||||||
// do next gs code if ram location is equal to 16-bit value
|
|
||||||
// D1XXYYYY ZZZZ
|
|
||||||
if (gGSCodes[curr_cheat].gscodes)
|
|
||||||
gGSCodes[curr_cheat].gscodes = realloc(gGSCodes[curr_cheat].gscodes, offset + 16);
|
|
||||||
else
|
|
||||||
gGSCodes[curr_cheat].gscodes = malloc(16);
|
|
||||||
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset], cp, 9);
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset+9], vp, 5);
|
|
||||||
gGSCodes[curr_cheat].count++;
|
|
||||||
offset += 16;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xD2:
|
|
||||||
// do next gs code if ram location is not equal to 8-bit value
|
|
||||||
// D2XXYYYY 00ZZ
|
|
||||||
if (gGSCodes[curr_cheat].gscodes)
|
|
||||||
gGSCodes[curr_cheat].gscodes = realloc(gGSCodes[curr_cheat].gscodes, offset + 16);
|
|
||||||
else
|
|
||||||
gGSCodes[curr_cheat].gscodes = malloc(16);
|
|
||||||
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset], cp, 9);
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset+9], vp, 5);
|
|
||||||
gGSCodes[curr_cheat].count++;
|
|
||||||
offset += 16;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xD3:
|
|
||||||
// do next gs code if ram location is not equal to 16-bit value
|
|
||||||
// D1XXYYYY ZZZZ
|
|
||||||
if (gGSCodes[curr_cheat].gscodes)
|
|
||||||
gGSCodes[curr_cheat].gscodes = realloc(gGSCodes[curr_cheat].gscodes, offset + 16);
|
|
||||||
else
|
|
||||||
gGSCodes[curr_cheat].gscodes = malloc(16);
|
|
||||||
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset], cp, 9);
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset+9], vp, 5);
|
|
||||||
gGSCodes[curr_cheat].count++;
|
|
||||||
offset += 16;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xDD:
|
|
||||||
// deactivate expansion ram using 2nd method
|
|
||||||
// DD000000 0000
|
|
||||||
if (gGSCodes[curr_cheat].gscodes)
|
|
||||||
gGSCodes[curr_cheat].gscodes = realloc(gGSCodes[curr_cheat].gscodes, offset + 16);
|
|
||||||
else
|
|
||||||
gGSCodes[curr_cheat].gscodes = malloc(16);
|
|
||||||
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset], cp, 9);
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset+9], vp, 5);
|
|
||||||
gGSCodes[curr_cheat].count++;
|
|
||||||
offset += 16;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xDE:
|
|
||||||
// set game boot address
|
|
||||||
// DEXXXXXX 0000
|
|
||||||
if (gGSCodes[curr_cheat].gscodes)
|
|
||||||
gGSCodes[curr_cheat].gscodes = realloc(gGSCodes[curr_cheat].gscodes, offset + 16);
|
|
||||||
else
|
|
||||||
gGSCodes[curr_cheat].gscodes = malloc(16);
|
|
||||||
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset], cp, 9);
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset+9], vp, 5);
|
|
||||||
gGSCodes[curr_cheat].count++;
|
|
||||||
offset += 16;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xEE:
|
|
||||||
// deactivate expansion ram using 1st method
|
|
||||||
// EE000000 0000
|
|
||||||
if (gGSCodes[curr_cheat].gscodes)
|
|
||||||
gGSCodes[curr_cheat].gscodes = realloc(gGSCodes[curr_cheat].gscodes, offset + 16);
|
|
||||||
else
|
|
||||||
gGSCodes[curr_cheat].gscodes = malloc(16);
|
|
||||||
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset], cp, 9);
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset+9], vp, 5);
|
|
||||||
gGSCodes[curr_cheat].count++;
|
|
||||||
offset += 16;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xF0:
|
|
||||||
// write 8-bit value to (cached) ram before boot
|
|
||||||
// F0XXXXXX 00YY
|
|
||||||
if (gGSCodes[curr_cheat].gscodes)
|
|
||||||
gGSCodes[curr_cheat].gscodes = realloc(gGSCodes[curr_cheat].gscodes, offset + 16);
|
|
||||||
else
|
|
||||||
gGSCodes[curr_cheat].gscodes = malloc(16);
|
|
||||||
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset], cp, 9);
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset+9], vp, 5);
|
|
||||||
gGSCodes[curr_cheat].count++;
|
|
||||||
offset += 16;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xF1:
|
|
||||||
// write 16-bit value to (cached) ram before boot
|
|
||||||
// F1XXXXXX YYYY
|
|
||||||
if (gGSCodes[curr_cheat].gscodes)
|
|
||||||
gGSCodes[curr_cheat].gscodes = realloc(gGSCodes[curr_cheat].gscodes, offset + 16);
|
|
||||||
else
|
|
||||||
gGSCodes[curr_cheat].gscodes = malloc(16);
|
|
||||||
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset], cp, 9);
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset+9], vp, 5);
|
|
||||||
gGSCodes[curr_cheat].count++;
|
|
||||||
offset += 16;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xFF:
|
|
||||||
// set code base
|
|
||||||
// FFXXXXXX 0000
|
|
||||||
if (gGSCodes[curr_cheat].gscodes)
|
|
||||||
gGSCodes[curr_cheat].gscodes = realloc(gGSCodes[curr_cheat].gscodes, offset + 16);
|
|
||||||
else
|
|
||||||
gGSCodes[curr_cheat].gscodes = malloc(16);
|
|
||||||
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset], cp, 9);
|
|
||||||
memcpy(&gGSCodes[curr_cheat].gscodes[offset+9], vp, 5);
|
|
||||||
gGSCodes[curr_cheat].count++;
|
|
||||||
offset += 16;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
line_chr=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
curr_cheat++;
|
|
||||||
gGSCodes[curr_cheat].count = 0xFFFF; // end of table
|
|
||||||
gGSCodes[curr_cheat].gscodes = NULL;
|
|
||||||
gGSCodes[curr_cheat].state = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0; //ok
|
/*
|
||||||
|
* Size of the cheat list can never be more than half the size of the YAML
|
||||||
|
* Minimum YAML example:
|
||||||
|
* A:-80001234 FFFF
|
||||||
|
* Which is exactly 16 bytes.
|
||||||
|
* The cheat list in this case fits into exactly 8 bytes (2 words):
|
||||||
|
* 0x80001234, 0x0000FFFF
|
||||||
|
*/
|
||||||
|
list1 = calloc(1, fsize + 2); // Plus 2 words to be safe
|
||||||
|
if (!list1) {
|
||||||
|
// Free
|
||||||
|
free(cheatfile);
|
||||||
|
return -2; // Out of memory
|
||||||
|
}
|
||||||
|
list2 = &list1[fsize / sizeof(u32) / 2];
|
||||||
|
cheat_lists[0] = list1;
|
||||||
|
cheat_lists[1] = list2;
|
||||||
|
|
||||||
|
resp = fatReadFile(cheatfile, fsize / 512); //1 cluster
|
||||||
|
|
||||||
|
yaml_parser_set_input_string(&parser, cheatfile, strlen(cheatfile));
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (!yaml_parser_parse(&parser, &event)) {
|
||||||
|
// Free
|
||||||
|
yaml_parser_delete(&parser);
|
||||||
|
yaml_event_delete(&event);
|
||||||
|
free(cheatfile);
|
||||||
|
free(cheat_lists[0]);
|
||||||
|
cheat_lists[0] = 0;
|
||||||
|
cheat_lists[1] = 0;
|
||||||
|
|
||||||
|
return -3; // Parse error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process YAML
|
||||||
|
switch (event.type) {
|
||||||
|
case YAML_MAPPING_START_EVENT:
|
||||||
|
// Begin code block
|
||||||
|
is_code = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case YAML_SEQUENCE_START_EVENT:
|
||||||
|
// Begin code lines
|
||||||
|
is_code = 1;
|
||||||
|
code_on = (event.data.sequence_start.tag ?
|
||||||
|
!!strcasecmp(event.data.sequence_start.tag, "!off") :
|
||||||
|
1
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case YAML_SEQUENCE_END_EVENT:
|
||||||
|
// End code lines
|
||||||
|
is_code = 0;
|
||||||
|
code_on = 1;
|
||||||
|
repeater = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case YAML_SCALAR_EVENT:
|
||||||
|
// Code line
|
||||||
|
if (!is_code || !code_on) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
address = strtoul(event.data.scalar.value, &next, 16);
|
||||||
|
value = strtoul(next, NULL, 16);
|
||||||
|
|
||||||
|
// Do not check code types within "repeater data"
|
||||||
|
if (repeater) {
|
||||||
|
repeater--;
|
||||||
|
*list2++ = address;
|
||||||
|
*list2++ = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine destination cheat_list for the code type
|
||||||
|
switch (address >> 24) {
|
||||||
|
|
||||||
|
// Uncessary code types
|
||||||
|
case 0x20: // Clear code list
|
||||||
|
case 0xCC: // Exception Handler Selection
|
||||||
|
case 0xDE: // Entry Point
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Boot-time cheats
|
||||||
|
case 0xEE: // Disable Expansion Pak
|
||||||
|
case 0xF0: // 8-bit Boot-Time Write
|
||||||
|
case 0xF1: // 16-bit Boot-Time Write
|
||||||
|
case 0xFF: // Cheat Engine Location
|
||||||
|
*list1++ = address;
|
||||||
|
*list1++ = value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// In-game cheats
|
||||||
|
case 0x50: // Repeater/Patch
|
||||||
|
// Validate repeater count
|
||||||
|
if (address & 0x0000FF00) {
|
||||||
|
repeater = 1;
|
||||||
|
*list2++ = address;
|
||||||
|
*list2++ = value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Everything else
|
||||||
|
default:
|
||||||
|
if (!address) {
|
||||||
|
// TODO: Support special code types! :)
|
||||||
|
}
|
||||||
|
// Fall-through!
|
||||||
|
|
||||||
|
case 0xD0: // 8-bit Equal-To Conditional
|
||||||
|
case 0xD1: // 16-bit Equal-To Conditional
|
||||||
|
case 0xD2: // 8-bit Not-Equal-To Conditional
|
||||||
|
case 0xD3: // 16-bit Not-Equal-To Conditional
|
||||||
|
// Validate 16-bit codes
|
||||||
|
if ((address & 0x01000001) == 0x01000001) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*list2++ = address;
|
||||||
|
*list2++ = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case YAML_STREAM_END_EVENT:
|
||||||
|
// And we're outta here!
|
||||||
|
done = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
yaml_event_delete(&event);
|
||||||
|
} while (!done);
|
||||||
|
|
||||||
|
// Free
|
||||||
|
yaml_parser_delete(&parser);
|
||||||
|
free(cheatfile);
|
||||||
|
|
||||||
|
return repeater; // Ok or repeater error
|
||||||
}
|
}
|
||||||
|
|
||||||
void timing(display_context_t disp){
|
void timing(display_context_t disp){
|
||||||
@ -2536,33 +2333,34 @@ void timing(display_context_t disp){
|
|||||||
printText(tmp, 3, -1, disp);
|
printText(tmp, 3, -1, disp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bootRom(display_context_t disp, int silent){
|
void bootRom(display_context_t disp, int silent) {
|
||||||
if(boot_cic!=0){
|
if (boot_cic != 0) {
|
||||||
if(boot_save!=0){
|
if (boot_save != 0){
|
||||||
u8 cfg_file[32];
|
u8 cfg_file[32];
|
||||||
u8 found=0;
|
u8 found=0;
|
||||||
u8 resp=0;
|
u8 resp=0;
|
||||||
u8 tmp[32];
|
u8 tmp[32];
|
||||||
|
|
||||||
//set cfg file with last loaded cart info and save-type
|
//set cfg file with last loaded cart info and save-type
|
||||||
sprintf(cfg_file, "/ED64/%s/LAST.CRT",save_path);
|
sprintf(cfg_file, "/ED64/%s/LAST.CRT", save_path);
|
||||||
|
|
||||||
resp = fatCreateRecIfNotExist(cfg_file, 0);
|
resp = fatCreateRecIfNotExist(cfg_file, 0);
|
||||||
resp = fatOpenFileByeName(cfg_file, 1); //512 bytes fix one cluster
|
resp = fatOpenFileByeName(cfg_file, 1); //512 bytes fix one cluster
|
||||||
|
|
||||||
static uint8_t cfg_file_data[512] = { 0 };
|
static uint8_t cfg_file_data[512] = { 0 };
|
||||||
cfg_file_data[0]=boot_save;
|
cfg_file_data[0] = boot_save;
|
||||||
cfg_file_data[1]=boot_cic;
|
cfg_file_data[1] = boot_cic;
|
||||||
scopy(rom_filename, cfg_file_data+2);
|
scopy(rom_filename, cfg_file_data + 2);
|
||||||
|
|
||||||
fatWriteFile(&cfg_file_data, 1);
|
fatWriteFile(&cfg_file_data, 1);
|
||||||
|
|
||||||
sleep(500);
|
sleep(500);
|
||||||
//set the fpga cart-save tpye
|
|
||||||
|
|
||||||
|
//set the fpga cart-save type
|
||||||
evd_setSaveType(boot_save);
|
evd_setSaveType(boot_save);
|
||||||
|
|
||||||
if (debug) printText("try to restore save from sd", 3, -1, disp);
|
if (debug) {
|
||||||
|
printText("try to restore save from sd", 3, -1, disp);
|
||||||
|
}
|
||||||
resp = saveTypeFromSd(disp, rom_filename, boot_save);
|
resp = saveTypeFromSd(disp, rom_filename, boot_save);
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
@ -2583,43 +2381,35 @@ void bootRom(display_context_t disp, int silent){
|
|||||||
cart = info >> 16;
|
cart = info >> 16;
|
||||||
country = (info >> 8) & 0xFF;
|
country = (info >> 8) & 0xFF;
|
||||||
|
|
||||||
if(cheats_on){
|
u32 *cheat_lists[2] = { NULL, NULL };
|
||||||
gCheats=1;
|
if (cheats_on) {
|
||||||
|
gCheats = 1;
|
||||||
printText("try to load cheat-file...", 3, -1, disp);
|
printText("try to load cheat-file...", 3, -1, disp);
|
||||||
|
|
||||||
char cheat_filename[64];
|
char cheat_filename[64];
|
||||||
sprintf(cheat_filename,"/ED64/CHEATS/%s.cht",rom_filename);
|
sprintf(cheat_filename, "/ED64/CHEATS/%s.yml", rom_filename);
|
||||||
|
|
||||||
int ok = readCheatFile(cheat_filename);
|
|
||||||
if(ok==0) {
|
|
||||||
if(!silent)
|
|
||||||
printText("cheats found...", 3, -1, disp);
|
|
||||||
|
|
||||||
|
int ok = readCheatFile(cheat_filename, cheat_lists);
|
||||||
|
if (ok == 0) {
|
||||||
|
printText("cheats found...", 3, -1, disp);
|
||||||
sleep(600);
|
sleep(600);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(!silent)
|
printText("cheats not found...", 3, -1, disp);
|
||||||
printText("cheats not found...", 3, -1, disp);
|
|
||||||
|
|
||||||
gCheats=0;
|
|
||||||
sleep(2000);
|
sleep(2000);
|
||||||
|
gCheats = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
gCheats=0;
|
gCheats = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
disable_interrupts();
|
disable_interrupts();
|
||||||
if(!silent){
|
int bios_cic = getCicType(1);
|
||||||
if(gCheats)
|
|
||||||
printText("cheat boot", 3, -1, disp);
|
|
||||||
else
|
|
||||||
printText("normal boot", 3, -1, disp);
|
|
||||||
}
|
|
||||||
int bios_cic=getCicType(1);
|
|
||||||
|
|
||||||
if(checksum_fix_on)
|
if (checksum_fix_on) {
|
||||||
checksum_sdram();
|
checksum_sdram();
|
||||||
|
}
|
||||||
|
|
||||||
evd_lockRegs();
|
evd_lockRegs();
|
||||||
sleep(1000);
|
sleep(1000);
|
||||||
@ -2630,7 +2420,7 @@ void bootRom(display_context_t disp, int silent){
|
|||||||
graphics_fill_screen(disp, 0x000000FF);
|
graphics_fill_screen(disp, 0x000000FF);
|
||||||
display_show(disp);
|
display_show(disp);
|
||||||
|
|
||||||
simulate_boot(boot_cic, bios_cic); // boot_cic
|
simulate_boot(boot_cic, bios_cic, cheat_lists); // boot_cic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4176,13 +3966,17 @@ int main(void) {
|
|||||||
drawBoxNumber(disp,2);
|
drawBoxNumber(disp,2);
|
||||||
display_show(disp);
|
display_show(disp);
|
||||||
|
|
||||||
printText("About: ", 9, 9, disp);
|
printText("About: ", 9, 8, disp);
|
||||||
printText(" ", 9, -1, disp);
|
printText(" ", 9, -1, disp);
|
||||||
printText("ALT64: v0.1.8.6", 9, -1, disp);
|
printText("ALT64: v0.1.8.6-cheat", 9, -1, disp);
|
||||||
printText("by saturnu", 9, -1, disp);
|
printText("by saturnu", 9, -1, disp);
|
||||||
printText(" ", 9, -1, disp);
|
printText(" ", 9, -1, disp);
|
||||||
|
printText("Code engine by:", 9, -1, disp);
|
||||||
|
printText("Jay Oster", 9, -1, disp);
|
||||||
|
printText(" ", 9, -1, disp);
|
||||||
printText("thanks to:", 9, -1, disp);
|
printText("thanks to:", 9, -1, disp);
|
||||||
printText("Krikzz", 9, -1, disp);
|
printText("Krikzz", 9, -1, disp);
|
||||||
|
printText("Richard Weick", 9, -1, disp);
|
||||||
printText("ChillyWilly", 9, -1, disp);
|
printText("ChillyWilly", 9, -1, disp);
|
||||||
printText("ShaunTaylor", 9, -1, disp);
|
printText("ShaunTaylor", 9, -1, disp);
|
||||||
printText("Conle", 9, -1, disp);
|
printText("Conle", 9, -1, disp);
|
||||||
|
21
menu.h
21
menu.h
@ -25,7 +25,7 @@ void dma_read_s(void * ram_address, unsigned long pi_address, unsigned long len)
|
|||||||
void readSDcard(display_context_t disp, char *directory);
|
void readSDcard(display_context_t disp, char *directory);
|
||||||
int readConfigFile(void);
|
int readConfigFile(void);
|
||||||
//void readCheatFile(display_context_t disp);
|
//void readCheatFile(display_context_t disp);
|
||||||
int readCheatFile(char *filename);
|
int readCheatFile(char *filename, u32 *cheat_lists[2]);
|
||||||
static int configHandler(void* user, const char* section, const char* name, const char* value);
|
static int configHandler(void* user, const char* section, const char* name, const char* value);
|
||||||
int saveTypeToSd(display_context_t disp, char* save_filename ,int tpye);
|
int saveTypeToSd(display_context_t disp, char* save_filename ,int tpye);
|
||||||
int saveTypeFromSd(display_context_t disp, char* rom_name, int stype);
|
int saveTypeFromSd(display_context_t disp, char* rom_name, int stype);
|
||||||
@ -87,22 +87,3 @@ void drawRomConfigBox(display_context_t disp,int line);
|
|||||||
* @return An aligned address guaranteed to be >= the unaligned address
|
* @return An aligned address guaranteed to be >= the unaligned address
|
||||||
*/
|
*/
|
||||||
#define ALIGN_16BYTE(x) ((void *)(((uint32_t)(x)+15) & 0xFFFFFFF0))
|
#define ALIGN_16BYTE(x) ((void *)(((uint32_t)(x)+15) & 0xFFFFFFF0))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
50
utils.h
50
utils.h
@ -4,7 +4,7 @@
|
|||||||
#include <libdragon.h>
|
#include <libdragon.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
|
|
||||||
0000h (1 byte): initial PI_BSB_DOM1_LAT_REG value (0x80)
|
0000h (1 byte): initial PI_BSB_DOM1_LAT_REG value (0x80)
|
||||||
0001h (1 byte): initial PI_BSB_DOM1_PGS_REG value (0x37)
|
0001h (1 byte): initial PI_BSB_DOM1_PGS_REG value (0x37)
|
||||||
@ -31,6 +31,8 @@
|
|||||||
0040h - 0FFFh (1008 dwords): Boot code
|
0040h - 0FFFh (1008 dwords): Boot code
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define DP_BASE_REG 0x04100000
|
||||||
|
#define VI_BASE_REG 0x04400000
|
||||||
#define PI_BASE_REG 0x04600000
|
#define PI_BASE_REG 0x04600000
|
||||||
#define PIF_RAM_START 0x1FC007C0
|
#define PIF_RAM_START 0x1FC007C0
|
||||||
|
|
||||||
@ -92,6 +94,29 @@
|
|||||||
#define PI_STATUS_IO_BUSY 0x02
|
#define PI_STATUS_IO_BUSY 0x02
|
||||||
#define PI_STATUS_DMA_BUSY 0x01
|
#define PI_STATUS_DMA_BUSY 0x01
|
||||||
|
|
||||||
|
#define DPC_START (DP_BASE_REG + 0x00)
|
||||||
|
#define DPC_END (DP_BASE_REG + 0x04)
|
||||||
|
#define DPC_CURRENT (DP_BASE_REG + 0x08)
|
||||||
|
#define DPC_STATUS (DP_BASE_REG + 0x0C)
|
||||||
|
#define DPC_CLOCK (DP_BASE_REG + 0x10)
|
||||||
|
#define DPC_BUFBUSY (DP_BASE_REG + 0x14)
|
||||||
|
#define DPC_PIPEBUSY (DP_BASE_REG + 0x18)
|
||||||
|
#define DPC_TMEM (DP_BASE_REG + 0x1C)
|
||||||
|
|
||||||
|
#define VI_CONTROL (VI_BASE_REG + 0x00)
|
||||||
|
#define VI_FRAMEBUFFER (VI_BASE_REG + 0x04)
|
||||||
|
#define VI_WIDTH (VI_BASE_REG + 0x08)
|
||||||
|
#define VI_V_INT (VI_BASE_REG + 0x0C)
|
||||||
|
#define VI_CUR_LINE (VI_BASE_REG + 0x10)
|
||||||
|
#define VI_TIMING (VI_BASE_REG + 0x14)
|
||||||
|
#define VI_V_SYNC (VI_BASE_REG + 0x18)
|
||||||
|
#define VI_H_SYNC (VI_BASE_REG + 0x1C)
|
||||||
|
#define VI_H_SYNC2 (VI_BASE_REG + 0x20)
|
||||||
|
#define VI_H_LIMITS (VI_BASE_REG + 0x24)
|
||||||
|
#define VI_COLOR_BURST (VI_BASE_REG + 0x28)
|
||||||
|
#define VI_H_SCALE (VI_BASE_REG + 0x2C)
|
||||||
|
#define VI_VSCALE (VI_BASE_REG + 0x30)
|
||||||
|
|
||||||
#define PHYS_TO_K0(x) ((u32)(x)|0x80000000) /* physical to kseg0 */
|
#define PHYS_TO_K0(x) ((u32)(x)|0x80000000) /* physical to kseg0 */
|
||||||
#define K0_TO_PHYS(x) ((u32)(x)&0x1FFFFFFF) /* kseg0 to physical */
|
#define K0_TO_PHYS(x) ((u32)(x)&0x1FFFFFFF) /* kseg0 to physical */
|
||||||
#define PHYS_TO_K1(x) ((u32)(x)|0xA0000000) /* physical to kseg1 */
|
#define PHYS_TO_K1(x) ((u32)(x)|0xA0000000) /* physical to kseg1 */
|
||||||
@ -112,7 +137,7 @@
|
|||||||
#define FRAM_EXECUTE_CMD 0xD2000000
|
#define FRAM_EXECUTE_CMD 0xD2000000
|
||||||
#define FRAM_STATUS_MODE_CMD 0xE1000000
|
#define FRAM_STATUS_MODE_CMD 0xE1000000
|
||||||
#define FRAM_ERASE_OFFSET_CMD 0x4B000000
|
#define FRAM_ERASE_OFFSET_CMD 0x4B000000
|
||||||
#define FRAM_WRITE_OFFSET_CMD 0xA5000000
|
#define FRAM_WRITE_OFFSET_CMD 0xA5000000
|
||||||
#define FRAM_ERASE_MODE_CMD 0x78000000
|
#define FRAM_ERASE_MODE_CMD 0x78000000
|
||||||
#define FRAM_WRITE_MODE_CMD 0xB4000000
|
#define FRAM_WRITE_MODE_CMD 0xB4000000
|
||||||
#define FRAM_READ_MODE_CMD 0xF0000000
|
#define FRAM_READ_MODE_CMD 0xF0000000
|
||||||
@ -128,6 +153,22 @@
|
|||||||
#define CIC_6105 5
|
#define CIC_6105 5
|
||||||
#define CIC_6106 6
|
#define CIC_6106 6
|
||||||
|
|
||||||
|
#if !defined(MIN)
|
||||||
|
#define MIN(a, b) ({ \
|
||||||
|
__typeof__ (a) _a = (a); \
|
||||||
|
__typeof__ (b) _b = (b); \
|
||||||
|
_a < _b ? _a : _b; \
|
||||||
|
})
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(MAX)
|
||||||
|
#define MAX(a, b) ({ \
|
||||||
|
__typeof__ (a) _a = (a); \
|
||||||
|
__typeof__ (b) _b = (b); \
|
||||||
|
_a > _b ? _a : _b; \
|
||||||
|
})
|
||||||
|
#endif
|
||||||
|
|
||||||
sprite_t *loadImage32DFS(char *fname);
|
sprite_t *loadImage32DFS(char *fname);
|
||||||
sprite_t *loadImageDFS(char *fname);
|
sprite_t *loadImageDFS(char *fname);
|
||||||
sprite_t *loadImage32(u8 *tbuf, int size);
|
sprite_t *loadImage32(u8 *tbuf, int size);
|
||||||
@ -142,8 +183,7 @@ void swap_header(unsigned char* header, int loadlength);
|
|||||||
|
|
||||||
void restoreTiming(void);
|
void restoreTiming(void);
|
||||||
|
|
||||||
void simulate_boot(u32 boot_cic, u8 bios_cic);
|
void simulate_boot(u32 boot_cic, u8 bios_cic, u32 *cheat_list[2]);
|
||||||
void globalTest(void);
|
|
||||||
|
|
||||||
|
|
||||||
u8 getCicType(u8 bios_cic);
|
u8 getCicType(u8 bios_cic);
|
||||||
@ -161,7 +201,7 @@ int getSRAM128( uint8_t *buffer);
|
|||||||
int getEeprom4k( uint8_t *buffer);
|
int getEeprom4k( uint8_t *buffer);
|
||||||
int getEeprom16k( uint8_t *buffer);
|
int getEeprom16k( uint8_t *buffer);
|
||||||
int getFlashRAM( uint8_t *buffer);
|
int getFlashRAM( uint8_t *buffer);
|
||||||
|
|
||||||
int setSRAM(uint8_t *buffer,int size);
|
int setSRAM(uint8_t *buffer,int size);
|
||||||
int setSRAM32( uint8_t *buffer);
|
int setSRAM32( uint8_t *buffer);
|
||||||
int setSRAM128( uint8_t *buffer);
|
int setSRAM128( uint8_t *buffer);
|
||||||
|
Loading…
Reference in New Issue
Block a user