From 45f2f245f51ef0c0d37df3c998595c132bfcaffa Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 5 Sep 2009 21:13:30 +0000 Subject: [PATCH] Finish migrating to new mem handling. Make carthw db external. Still need to fix asm and protection emulation. git-svn-id: file:///home/notaz/opt/svn/PicoDrive@769 be3aeb3a-fb24-0410-a615-afba39da0efa --- cpu/musashi/m68kconf.h | 2 +- cpu/musashi/m68kcpu.h | 4 +- pico/area.c | 4 + pico/cart.c | 389 +++++++++++++++++++++++------------ pico/carthw.cfg | 180 ++++++++++++++++ pico/carthw/carthw.c | 185 ++++++++--------- pico/carthw/carthw.h | 7 +- pico/carthw/svp/memory.c | 114 +++++----- pico/carthw/svp/ssp16.c | 2 + pico/carthw/svp/svp.c | 6 +- pico/cd/memory.c | 92 --------- pico/debug.c | 4 +- pico/eeprom.c | 208 +++++++++++++++++++ pico/memory.c | 232 +++++---------------- pico/memory.h | 3 + pico/misc.c | 187 ----------------- pico/patch.c | 6 - pico/pico.c | 21 +- pico/pico/memory.c | 236 ++++----------------- pico/pico/pico.c | 2 +- pico/pico_int.h | 46 +++-- pico/z80if.c | 1 - platform/common/emu.c | 6 +- platform/gizmondo/emu.c | 2 +- platform/gp2x/Makefile | 5 +- platform/gp2x/emu.c | 2 +- platform/linux/Makefile | 6 +- platform/linux/gp2x.c | 1 + platform/linux/port_config.h | 2 +- platform/pandora/emu.c | 2 +- 30 files changed, 939 insertions(+), 1018 deletions(-) create mode 100644 pico/carthw.cfg create mode 100644 pico/eeprom.c diff --git a/cpu/musashi/m68kconf.h b/cpu/musashi/m68kconf.h index 730cf98..e2bddaf 100644 --- a/cpu/musashi/m68kconf.h +++ b/cpu/musashi/m68kconf.h @@ -75,7 +75,7 @@ * and m68k_read_pcrelative_xx() for PC-relative addressing. * If off, all read requests from the CPU will be redirected to m68k_read_xx() */ -#define M68K_SEPARATE_READS OPT_ON +#define M68K_SEPARATE_READS OPT_OFF /* If ON, the CPU will call m68k_write_32_pd() when it executes move.l with a * predecrement destination EA mode instead of m68k_write_32(). diff --git a/cpu/musashi/m68kcpu.h b/cpu/musashi/m68kcpu.h index eb7a513..7b050f7 100644 --- a/cpu/musashi/m68kcpu.h +++ b/cpu/musashi/m68kcpu.h @@ -2011,8 +2011,8 @@ void m68ki_exception_interrupt(uint int_level) FLAG_INT_MASK = int_level<<8; /* Get the new PC */ - //new_pc = m68ki_read_data_32((vector<<2) + REG_VBR); - new_pc = m68k_read_immediate_32((vector<<2) + REG_VBR); // notaz hack + new_pc = m68ki_read_data_32((vector<<2) + REG_VBR); + //new_pc = m68k_read_immediate_32((vector<<2) + REG_VBR); // notaz hack /* If vector is uninitialized, call the uninitialized interrupt vector */ if(new_pc == 0) diff --git a/pico/area.c b/pico/area.c index 8a14d55..4ac71df 100644 --- a/pico/area.c +++ b/pico/area.c @@ -144,6 +144,10 @@ static int PicoAreaScan(int is_write, unsigned int ver, void *PmovFile) SCAN_VAR(Pico.m ,"misc") SCAN_VAR(Pico.video,"video") + // no longer keeping eeprom data in sram_reg + if (!is_write && (Pico.m.sram_reg & 4)) + Pico.m.sram_reg = SRR_MAPPED; + if (is_write) z80_pack(cpu_z80); ret = SCAN_VAR(cpu_z80,"cpu_z80") diff --git a/pico/cart.c b/pico/cart.c index 5c04fa4..5eb89c9 100644 --- a/pico/cart.c +++ b/pico/cart.c @@ -15,7 +15,8 @@ static const char *rom_exts[] = { "bin", "gen", "smd", "iso", "sms", "gg", "sg" }; -void (*PicoCartUnloadHook)(void) = NULL; +void (*PicoCartUnloadHook)(void); +void (*PicoCartMemSetup)(void); void (*PicoCartLoadProgressCB)(int percent) = NULL; void (*PicoCDLoadProgressCB)(const char *fname, int percent) = NULL; // handled in Pico/cd/cd_file.c @@ -565,7 +566,7 @@ int PicoCartInsert(unsigned char *rom,unsigned int romsize) PicoAHW &= PAHW_MCD|PAHW_SMS; - PicoMemResetHooks(); + PicoCartMemSetup = NULL; PicoDmaHook = NULL; PicoResetHook = NULL; PicoLineHook = NULL; @@ -586,6 +587,9 @@ int PicoCartInsert(unsigned char *rom,unsigned int romsize) case PAHW_SMS: PicoMemSetupMS(); break; } + if (PicoCartMemSetup != NULL) + PicoCartMemSetup(); + if (PicoAHW & PAHW_SMS) PicoPowerMS(); else @@ -611,178 +615,311 @@ void PicoCartUnload(void) static int rom_strcmp(int rom_offset, const char *s1) { int i, len = strlen(s1); - const char *s_rom = (const char *)Pico.rom + rom_offset; + const char *s_rom = (const char *)Pico.rom; for (i = 0; i < len; i++) - if (s1[i] != s_rom[i^1]) + if (s1[i] != s_rom[(i + rom_offset) ^ 1]) return 1; return 0; } -static int name_cmp(const char *name) -{ - return rom_strcmp(0x150, name); -} - static unsigned int rom_read32(int addr) { unsigned short *m = (unsigned short *)(Pico.rom + addr); return (m[0] << 16) | m[1]; } +static char *sskip(char *s) +{ + while (*s && isspace_(*s)) + s++; + return s; +} + +static void rstrip(char *s) +{ + char *p; + for (p = s + strlen(s) - 1; p >= s; p--) + if (isspace_(*p)) + *p = 0; +} + +static int is_expr(const char *expr, char **pr) +{ + int len = strlen(expr); + char *p = *pr; + + if (strncmp(expr, p, len) != 0) + return 0; + p = sskip(p + len); + if (*p != '=') + return 0; // wrong or malformed + + *pr = sskip(p + 1); + return 1; +} + +static void parse_carthw(int *fill_sram) +{ + int line = 0, any_checks_passed = 0, skip_sect = 0; + char buff[256], *p, *r; + FILE *f; + + f = fopen("carthw.cfg", "r"); + if (f == NULL) { + elprintf(EL_STATUS, "couldn't open carthw.txt!"); + return; + } + + while ((p = fgets(buff, sizeof(buff), f))) + { + line++; + p = sskip(p); + if (*p == 0 || *p == '#') + continue; + + if (*p == '[') { + any_checks_passed = 0; + skip_sect = 0; + continue; + } + + if (skip_sect) + continue; + + /* look for checks */ + if (is_expr("check_str", &p)) + { + int offs; + offs = strtoul(p, &r, 0); + if (offs < 0 || offs > Pico.romsize) { + elprintf(EL_STATUS, "carthw:%d: check_str offs out of range: %d\n", line, offs); + goto bad; + } + p = sskip(r); + if (*p != ',') + goto bad; + p = sskip(p + 1); + if (*p != '"') + goto bad; + p++; + r = strchr(p, '"'); + if (r == NULL) + goto bad; + *r = 0; + + if (rom_strcmp(offs, p) == 0) + any_checks_passed = 1; + else + skip_sect = 1; + continue; + } + else if (is_expr("check_size_gt", &p)) + { + int size; + size = strtoul(p, &r, 0); + if (r == p || size < 0) + goto bad; + + if (Pico.romsize > size) + any_checks_passed = 1; + else + skip_sect = 1; + continue; + } + else if (is_expr("check_csum", &p)) + { + int csum; + csum = strtoul(p, &r, 0); + if (r == p || (csum & 0xffff0000)) + goto bad; + + if (csum == (rom_read32(0x18c) & 0xffff)) + any_checks_passed = 1; + else + skip_sect = 1; + continue; + } + + /* now time for actions */ + if (is_expr("hw", &p)) { + if (!any_checks_passed) + goto no_checks; + rstrip(p); + + if (strcmp(p, "svp") == 0) + PicoSVPStartup(); + else if (strcmp(p, "pico") == 0) + PicoInitPico(); + else if (strcmp(p, "x_in_1_mapper") == 0) + carthw_Xin1_startup(); + else if (strcmp(p, "realtec_mapper") == 0) + carthw_realtec_startup(); + else if (strcmp(p, "radica_mapper") == 0) + carthw_radica_startup(); + else { + elprintf(EL_STATUS, "carthw:%d: unsupported mapper: %s", line, p); + skip_sect = 1; + } + continue; + } + if (is_expr("sram_range", &p)) { + int start, end; + + if (!any_checks_passed) + goto no_checks; + rstrip(p); + + start = strtoul(p, &r, 0); + if (r == p) + goto bad; + p = sskip(r); + if (*p != ',') + goto bad; + p = sskip(p + 1); + end = strtoul(p, &r, 0); + if (r == p) + goto bad; + if (((start | end) & 0xff000000) || start > end) { + elprintf(EL_STATUS, "carthw:%d: bad sram_range: %08x - %08x", line, start, end); + goto bad_nomsg; + } + SRam.start = start; + SRam.end = end; + continue; + } + else if (is_expr("prop", &p)) { + if (!any_checks_passed) + goto no_checks; + rstrip(p); + + if (strcmp(p, "no_sram") == 0) + SRam.flags &= ~SRF_ENABLED; + else if (strcmp(p, "no_eeprom") == 0) + SRam.flags &= ~SRF_EEPROM; + else if (strcmp(p, "filled_sram") == 0) + *fill_sram = 1; + else { + elprintf(EL_STATUS, "carthw:%d: unsupported prop: %s", line, p); + goto bad_nomsg; + } + continue; + } + else if (is_expr("eeprom_type", &p)) { + int type; + if (!any_checks_passed) + goto no_checks; + rstrip(p); + + type = strtoul(p, &r, 0); + if (r == p || type < 0) + goto bad; + SRam.eeprom_type = type; + SRam.flags |= SRF_EEPROM; + continue; + } + else if (is_expr("eeprom_lines", &p)) { + int scl, sda_in, sda_out; + if (!any_checks_passed) + goto no_checks; + rstrip(p); + + scl = strtoul(p, &r, 0); + if (r == p || scl < 0 || scl > 15) + goto bad; + p = sskip(r); + if (*p++ != ',') + goto bad; + sda_in = strtoul(p, &r, 0); + if (r == p || sda_in < 0 || sda_in > 15) + goto bad; + p = sskip(r); + if (*p++ != ',') + goto bad; + sda_out = strtoul(p, &r, 0); + if (r == p || sda_out < 0 || sda_out > 15) + goto bad; + + SRam.eeprom_bit_cl = scl; + SRam.eeprom_bit_in = sda_in; + SRam.eeprom_bit_out= sda_out; + continue; + } + + +bad: + elprintf(EL_STATUS, "carthw:%d: unrecognized expression: %s", line, buff); +bad_nomsg: + skip_sect = 1; + continue; + +no_checks: + elprintf(EL_STATUS, "carthw:%d: command without any checks before it: %s", line, buff); + skip_sect = 1; + continue; + } + fclose(f); +} + /* * various cart-specific things, which can't be handled by generic code - * (maybe I should start using CRC for this stuff?) */ static void PicoCartDetect(void) { - int sram_size = 0, csum; - Pico.m.sram_status = 0; + int fill_sram = 0, csum; csum = rom_read32(0x18c) & 0xffff; + memset(&SRam, 0, sizeof(SRam)); if (Pico.rom[0x1B1] == 'R' && Pico.rom[0x1B0] == 'A') { + SRam.start = rom_read32(0x1B4) & ~0xff000001; // align + SRam.end = (rom_read32(0x1B8) & ~0xff000000) | 1; if (Pico.rom[0x1B2] & 0x40) - { // EEPROM - SRam.start = rom_read32(0x1B4) & ~1; // zero address is used for clock by some games - SRam.end = rom_read32(0x1B8); - sram_size = 0x2000; - Pico.m.sram_status |= SRS_EEPROM; - } else { - // normal SRAM - SRam.start = rom_read32(0x1B4) & ~0xff; - SRam.end = rom_read32(0x1B8) | 1; - sram_size = SRam.end - SRam.start + 1; - } - SRam.start &= ~0xff000000; - SRam.end &= ~0xff000000; - Pico.m.sram_status |= SRS_DETECTED; + SRam.flags |= SRF_EEPROM; + SRam.flags |= SRF_ENABLED; } - if (sram_size <= 0) + if (SRam.end == 0 || SRam.start > SRam.end) { // some games may have bad headers, like S&K and Sonic3 // note: majority games use 0x200000 as starting address, but there are some which // use something else (0x300000 by HardBall '95). Luckily they have good headers. SRam.start = 0x200000; SRam.end = 0x203FFF; - sram_size = 0x004000; - } - - // this game actually doesn't have SRAM, but some weird protection - if (rom_strcmp(0x120, "PUGGSY") == 0) - { - SRam.start = SRam.end = sram_size = 0; - } - - if (sram_size) - { - SRam.data = (unsigned char *) calloc(sram_size, 1); - if (SRam.data == NULL) return; + SRam.flags |= SRF_ENABLED; } - SRam.changed = 0; // set EEPROM defaults, in case it gets detected SRam.eeprom_type = 0; // 7bit (24C01) - SRam.eeprom_abits = 3; // eeprom access must be odd addr for: bit0 ~ cl, bit1 ~ in SRam.eeprom_bit_cl = 1; SRam.eeprom_bit_in = 0; SRam.eeprom_bit_out= 0; - // some known EEPROM data (thanks to EkeEke) - if (name_cmp("COLLEGE SLAM") == 0 || - name_cmp("FRANK THOMAS BIGHURT BASEBAL") == 0) - { - SRam.eeprom_type = 3; - SRam.eeprom_abits = 2; - SRam.eeprom_bit_cl = 0; - } - else if (name_cmp("NBA JAM TOURNAMENT EDITION") == 0 || - name_cmp("NFL QUARTERBACK CLUB") == 0) - { - SRam.eeprom_type = 2; - SRam.eeprom_abits = 2; - SRam.eeprom_bit_cl = 0; - } - else if (name_cmp("NBA JAM") == 0) - { - SRam.eeprom_type = 2; - SRam.eeprom_bit_out = 1; - SRam.eeprom_abits = 0; - } - else if (name_cmp("NHLPA HOCKEY '93") == 0 || - name_cmp("NHLPA Hockey '93") == 0 || - name_cmp("RINGS OF POWER") == 0) - { - SRam.start = SRam.end = 0x200000; - Pico.m.sram_status = SRS_DETECTED|SRS_EEPROM; - SRam.eeprom_abits = 0; - SRam.eeprom_bit_cl = 6; - SRam.eeprom_bit_in = 7; - SRam.eeprom_bit_out= 7; - } - else if ( name_cmp("MICRO MACHINES II") == 0 || - (name_cmp(" ") == 0 && // Micro Machines {Turbo Tournament '96, Military - It's a Blast!} - (csum == 0x165e || csum == 0x168b || csum == 0xCEE0 || csum == 0x2C41))) - { - SRam.start = 0x300000; - SRam.end = 0x380001; - Pico.m.sram_status = SRS_DETECTED|SRS_EEPROM; - SRam.eeprom_type = 2; - SRam.eeprom_abits = 0; - SRam.eeprom_bit_cl = 1; - SRam.eeprom_bit_in = 0; - SRam.eeprom_bit_out= 7; - } - - // SVP detection - else if (name_cmp("Virtua Racing") == 0 || - name_cmp("VIRTUA RACING") == 0) - { - PicoSVPStartup(); - } - - // Pico - else if (rom_strcmp(0x100, "SEGA PICO") == 0 || - rom_strcmp(0x100, "IMA IKUNOUJYUKU") == 0) // what is that supposed to mean? - { - PicoInitPico(); - } + parse_carthw(&fill_sram); - // Detect 12-in-1 mapper - else if ((name_cmp("ROBOCOP 3") == 0 && Pico.romsize == 0x200000) || - (rom_strcmp(0x160, "FLICKY") == 0 && Pico.romsize >= 0x200000) || - (name_cmp(" SHOVE IT!") == 0 && Pico.romsize >= 0x200000) || - (name_cmp("MS PACMAN") == 0 && Pico.romsize >= 0x200000) || // bad dump? - (name_cmp("ALIEN 3") == 0 && Pico.romsize == 0x200000)) + if (SRam.flags & SRF_ENABLED) { - carthw_12in1_startup(); - } + if (SRam.flags & SRF_EEPROM) + SRam.size = 0x2000; + else + SRam.size = SRam.end - SRam.start + 1; - // Realtec mapper - else if (Pico.romsize == 512*1024 && ( - rom_strcmp(0x94, "THE EARTH DEFEND") == 0 || - rom_strcmp(0xfe, "WISEGAME 11-03-1993") == 0 || // Funny World - rom_strcmp(0x95, "MALLET LEGEND ") == 0)) // Whac-A-Critter - { - carthw_realtec_startup(); - } + SRam.data = calloc(SRam.size, 1); + if (SRam.data == NULL) + SRam.flags &= ~SRF_ENABLED; - // Radica mapper - else if (name_cmp("KID CHAMELEON") == 0 && Pico.romsize > 0x100000) - { - carthw_radica_startup(); + if (SRam.eeprom_type == 1) // 1 == 0 in PD EEPROM code + SRam.eeprom_type = 0; } - // Some games malfunction if SRAM is not filled with 0xff - if (name_cmp("DINO DINI'S SOCCER") == 0 || - name_cmp("MICRO MACHINES II") == 0) + if ((SRam.flags & SRF_ENABLED) && fill_sram) { - memset(SRam.data, 0xff, sram_size); + elprintf(EL_STATUS, "SRAM fill"); + memset(SRam.data, 0xff, SRam.size); } // Unusual region 'code' if (rom_strcmp(0x1f0, "EUROPE") == 0 || rom_strcmp(0x1f0, "Europe") == 0) - *(int *) (Pico.rom+0x1f0) = 0x20204520; + *(int *) (Pico.rom + 0x1f0) = 0x20204520; } diff --git a/pico/carthw.cfg b/pico/carthw.cfg new file mode 100644 index 0000000..140cb0a --- /dev/null +++ b/pico/carthw.cfg @@ -0,0 +1,180 @@ +# hardware (hw = ...): +# svp - Sega Virtua Processor +# pico - Sega Pico (not really cart hw, but convenient to support here) +# +# cartridge properties (prop = ...): +# no_sram - don't emulate sram/EEPROM even if ROM headers tell it's there +# no_eeprom - save storage is not EEPROM, even if ROM headers tell it is +# filled_sram - save storage needs to be initialized with FFh instead of 00h +# +# mappers (hw = ...): +# x_in_1_mapper - used in many *-in-1 pirate carts +# realtec_mapper +# radica_mapper - similar to x_in_1_mapper +# +# save storage memory range (inclusive, overrides ROM header): +# sram_range = +# +# EEPROM: +# eeprom_type = <1|2|3> - enable EEPROM, use type X (7bit, 2 addr words, 3 addr words). +# See EkeEke's gen_eeprom.pdf "mode" descriptions for 24Cxx EEPROMs. +# eeprom_lines = +# - select data bus pins that are connected to EEPROM +# SCL, SDA_IN and SDA_OUT pins (0-15 for D0-D15). + +[Virtua Racing - SVP] +check_str = 0x150, "Virtua Racing" +hw = svp + +[Virtua Racing - SVP] +check_str = 0x150, "VIRTUA RACING" +hw = svp + +[Pico] +check_str = 0x100, "SEGA PICO" +hw = pico + +[Pico] +check_str = 0x100, "IMA IKUNOUJYUKU" +hw = pico + +# sram emulation triggers some protection for this one +[Puggsy] +check_str = 0x120, "PUGGSY" +prop = no_sram + +# game has problems if it's save RAM is not initialized with FFh: +[Dino Dini's Soccer] +check_str = 0x150, "DINO DINI'S SOCCER" +prop = filled_sram + +[Micro Machines 2 - Turbo Tournament] +check_str = 0x150, "MICRO MACHINES II" +prop = filled_sram + +# detect *_in_1 based on first game and if it's larger than it should be, +# as some dumps look like to be incomplete. +# This will also pick overdumps, but those should still work with the mapper applied. +[12-in-1 (Unl)] +check_str = 0x120, "FLICKY" +check_size_gt = 0x020000 +hw = x_in_1_mapper + +[4-in-1] +check_str = 0x150, "ROBOCOP 3" +check_size_gt = 0x080000 +hw = x_in_1_mapper + +[4-in-1 a1] +check_str = 0x150, "ALIEN 3" +check_size_gt = 0x080000 +hw = x_in_1_mapper + +[Super 15-in-1] +check_str = 0x150, " SHOVE IT!" +check_size_gt = 0x020000 +hw = x_in_1_mapper + +[Super 19-in-1] +check_str = 0x150, "MS PACMAN" +check_size_gt = 0x020000 +hw = x_in_1_mapper + +# radica +[radica_v1] +check_str = 0x150, "KID CHAMELEON" +check_size_gt = 0x100000 +hw = radica_mapper + +# realtec +[Earth Defend, The (Unl)] +check_str = 0x94, "THE EARTH DEFEND" +hw = realtec_mapper + +[Funny World & Balloon Boy (Unl)] +check_str = 0xfe, "WISEGAME 11-03-1993" +hw = realtec_mapper + +[Whac-A-Critter (Unl)] +check_str = 0x95, "MALLET LEGEND" +hw = realtec_mapper + +# EEPROM games - thanks to EkeEke for most of this info +[College Slam] +check_str = 0x150, "COLLEGE SLAM" +eeprom_type = 3 +eeprom_lines = 8,0,0 + +[Frank Thomas Big Hurt Baseball] +check_str = 0x150, "FRANK THOMAS BIGHURT BASEBAL" +eeprom_type = 3 +eeprom_lines = 8,0,0 + +[MICRO MACHINES II] +check_str = 0x150, "MICRO MACHINES II" +sram_range = 0x300000,0x380001 +eeprom_type = 2 +eeprom_lines = 9,8,7 + +[Micro Machines - Turbo Tournament '96] +check_str = 0x150, " " +check_csum = 0x165e +sram_range = 0x300000,0x380001 +eeprom_type = 2 +eeprom_lines = 9,8,7 + +[Micro Machines - Turbo Tournament '96] +check_str = 0x150, " " +check_csum = 0x2c41 +sram_range = 0x300000,0x380001 +eeprom_type = 2 +eeprom_lines = 9,8,7 + +[Micro Machines Military] +check_str = 0x150, " " +check_csum = 0x168b +sram_range = 0x300000,0x380001 +eeprom_type = 2 +eeprom_lines = 9,8,7 + +[Micro Machines Military] +check_str = 0x150, " " +check_csum = 0xcee0 +sram_range = 0x300000,0x380001 +eeprom_type = 2 +eeprom_lines = 9,8,7 + +[NBA Jam] +check_str = 0x150, "NBA JAM " +eeprom_type = 2 +eeprom_lines = 1,0,1 + +[NBA Jam Tournament Edition] +check_str = 0x150, "NBA JAM TOURNAMENT EDITION" +sram_range = 0x200000,0x200001 +eeprom_type = 2 +eeprom_lines = 8,0,0 + +[NFL Quarterback Club] +check_str = 0x150, "NFL QUARTERBACK CLUB" +eeprom_type = 2 +eeprom_lines = 8,0,0 + +[NHLPA Hockey '93] +check_str = 0x150, "NHLPA Hockey '93" +sram_range = 0x200000,0x200001 +eeprom_type = 1 +eeprom_lines = 6,7,7 + +[NHLPA Hockey '93] +check_str = 0x150, "NHLPA HOCKEY '93" +sram_range = 0x200000,0x200001 +eeprom_type = 1 +eeprom_lines = 6,7,7 + +[Rings of Power] +check_str = 0x150, "RINGS OF POWER" +sram_range = 0x200000,0x200001 +eeprom_type = 1 +eeprom_lines = 6,7,7 + diff --git a/pico/carthw/carthw.c b/pico/carthw/carthw.c index 19bd031..6424f1e 100644 --- a/pico/carthw/carthw.c +++ b/pico/carthw/carthw.c @@ -1,86 +1,79 @@ /* * Support for a few cart mappers. * - * (c) Copyright 2008, Grazvydas "notaz" Ignotas + * (c) Copyright 2008-2009, Grazvydas "notaz" Ignotas * Free for non-commercial use. * - * - * I should better do some pointer stuff here. But as none of these bankswitch - * while the game runs, memcpy will suffice. */ #include "../pico_int.h" +#include "../memory.h" -/* 12-in-1 and 4-in-1. Assuming >= 2MB ROMs here. */ -static unsigned int carthw_12in1_baddr = 0; - -static carthw_state_chunk carthw_12in1_state[] = -{ - { CHUNK_CARTHW, sizeof(carthw_12in1_baddr), &carthw_12in1_baddr }, - { 0, 0, NULL } -}; - -static unsigned int carthw_12in1_read16(unsigned int a, int realsize) -{ - // ?? - elprintf(EL_UIO, "12-in-1: read [%06x] @ %06x", a, SekPc); - return 0; -} +/* Common *-in-1 pirate mapper. + * Switches banks based on addr lines when /TIME is set. + * TODO: verify + */ +static unsigned int carthw_Xin1_baddr = 0; -static void carthw_12in1_write8(unsigned int a, unsigned int d, int realsize) +static void carthw_Xin1_do(u32 a, int mask, int shift) { int len; - if (a < 0xA13000 || a >= 0xA13040) { - /* 4-in-1 has Real Deal Boxing, which uses serial eeprom, - * but I really doubt that pirate cart had it */ - if (a != 0x200001) - elprintf(EL_ANOMALY, "12-in-1: unexpected write [%06x] %02x @ %06x", a, d, SekPc); - return; - } - - carthw_12in1_baddr = a; - a &= 0x3f; a <<= 16; + carthw_Xin1_baddr = a; + a &= mask; + a <<= shift; len = Pico.romsize - a; if (len <= 0) { - elprintf(EL_ANOMALY|EL_STATUS, "12-in-1: missing bank @ %06x", a); + elprintf(EL_ANOMALY|EL_STATUS, "X-in-1: missing bank @ %06x", a); return; } - memcpy(Pico.rom, Pico.rom + Pico.romsize + a, len); + len = (len + M68K_BANK_MASK) & ~M68K_BANK_MASK; + cpu68k_map_set(m68k_read8_map, 0x000000, len - 1, Pico.rom + a, 0); + cpu68k_map_set(m68k_read16_map, 0x000000, len - 1, Pico.rom + a, 0); } -static void carthw_12in1_reset(void) +static carthw_state_chunk carthw_Xin1_state[] = { - carthw_12in1_write8(0xA13000, 0, 0); + { CHUNK_CARTHW, sizeof(carthw_Xin1_baddr), &carthw_Xin1_baddr }, + { 0, 0, NULL } +}; + +// TODO: test a0, reads, w16 +static void carthw_Xin1_write8(u32 a, u32 d) +{ + if ((a & 0xffff00) != 0xa13000) { + PicoWrite8_io(a, d); + return; + } + + carthw_Xin1_do(a, 0x3f, 16); } -static void carthw_12in1_statef(void) +static void carthw_Xin1_mem_setup(void) { - carthw_12in1_write8(carthw_12in1_baddr, 0, 0); + cpu68k_map_set(m68k_write8_map, 0xa10000, 0xa1ffff, carthw_Xin1_write8, 1); } -void carthw_12in1_startup(void) +static void carthw_Xin1_reset(void) { - void *tmp; + carthw_Xin1_write8(0xa13000, 0); +} - elprintf(EL_STATUS, "12-in-1 mapper detected"); +static void carthw_Xin1_statef(void) +{ + carthw_Xin1_write8(carthw_Xin1_baddr, 0); +} - tmp = realloc(Pico.rom, Pico.romsize * 2); - if (tmp == NULL) - { - elprintf(EL_STATUS, "OOM"); - return; - } - Pico.rom = tmp; - memcpy(Pico.rom + Pico.romsize, Pico.rom, Pico.romsize); +void carthw_Xin1_startup(void) +{ + elprintf(EL_STATUS, "X-in-1 mapper startup"); - PicoRead16Hook = carthw_12in1_read16; - PicoWrite8Hook = carthw_12in1_write8; - PicoResetHook = carthw_12in1_reset; - PicoLoadStateHook = carthw_12in1_statef; - carthw_chunks = carthw_12in1_state; + PicoCartMemSetup = carthw_Xin1_mem_setup; + PicoResetHook = carthw_Xin1_reset; + PicoLoadStateHook = carthw_Xin1_statef; + carthw_chunks = carthw_Xin1_state; } @@ -88,9 +81,8 @@ void carthw_12in1_startup(void) * http://www.sharemation.com/TascoDLX/REALTEC%20Cart%20Mapper%20-%20description%20v1.txt */ static int realtec_bank = 0x80000000, realtec_size = 0x80000000; -static int realtec_romsize = 0; -static void carthw_realtec_write8(unsigned int a, unsigned int d, int realsize) +static void carthw_realtec_write8(u32 a, u32 d) { int i, bank_old = realtec_bank, size_old = realtec_size; @@ -121,105 +113,92 @@ static void carthw_realtec_write8(unsigned int a, unsigned int d, int realsize) (realtec_bank != bank_old || realtec_size != size_old)) { elprintf(EL_ANOMALY, "realtec: new bank %06x, size %06x", realtec_bank, realtec_size, SekPc); - if (realtec_size > realtec_romsize - realtec_bank || realtec_bank >= realtec_romsize) + if (realtec_size > Pico.romsize - realtec_bank) { elprintf(EL_ANOMALY, "realtec: bank too large / out of range?"); return; } - for (i = 0; i < 0x400000; i += realtec_size) - memcpy(Pico.rom + i, Pico.rom + 0x400000 + realtec_bank, realtec_size); + for (i = 0; i < 0x400000; i += realtec_size) { + cpu68k_map_set(m68k_read8_map, i, realtec_size - 1, Pico.rom + realtec_bank, 0); + cpu68k_map_set(m68k_read16_map, i, realtec_size - 1, Pico.rom + realtec_bank, 0); + } } } static void carthw_realtec_reset(void) { int i; + /* map boot code */ - for (i = 0; i < 0x400000; i += 0x2000) - memcpy(Pico.rom + i, Pico.rom + 0x400000 + realtec_romsize - 0x2000, 0x2000); + for (i = 0; i < 0x400000; i += M68K_BANK_SIZE) { + cpu68k_map_set(m68k_read8_map, i, i + M68K_BANK_SIZE - 1, Pico.rom + Pico.romsize, 0); + cpu68k_map_set(m68k_read16_map, i, i + M68K_BANK_SIZE - 1, Pico.rom + Pico.romsize, 0); + } + cpu68k_map_set(m68k_write8_map, 0x400000, 0x400000 + M68K_BANK_SIZE - 1, carthw_realtec_write8, 1); realtec_bank = realtec_size = 0x80000000; } void carthw_realtec_startup(void) { void *tmp; + int i; - elprintf(EL_STATUS, "Realtec mapper detected"); + elprintf(EL_STATUS, "Realtec mapper startup"); - realtec_romsize = Pico.romsize; - Pico.romsize = 0x400000; - tmp = realloc(Pico.rom, 0x400000 + realtec_romsize); + // allocate additional bank for boot code + // (we know those ROMs have aligned size) + tmp = realloc(Pico.rom, Pico.romsize + M68K_BANK_SIZE); if (tmp == NULL) { elprintf(EL_STATUS, "OOM"); return; } Pico.rom = tmp; - memcpy(Pico.rom + 0x400000, Pico.rom, realtec_romsize); - PicoWrite8Hook = carthw_realtec_write8; + // create bank for boot code + for (i = 0; i < M68K_BANK_SIZE; i += 0x2000) + memcpy(Pico.rom + Pico.romsize + i, Pico.rom + Pico.romsize - 0x2000, 0x2000); + PicoResetHook = carthw_realtec_reset; } /* Radica mapper, based on DevSter's info * http://devster.monkeeh.com/sega/radica/ + * XXX: mostly the same as X-in-1, merge? */ -static unsigned int carthw_radica_baddr = 0; - -static carthw_state_chunk carthw_radica_state[] = -{ - { CHUNK_CARTHW, sizeof(carthw_radica_baddr), &carthw_radica_baddr }, - { 0, 0, NULL } -}; - -static unsigned int carthw_radica_read16(unsigned int a, int realsize) +static u32 carthw_radica_read16(u32 a) { - if ((a & 0xffff80) != 0xa13000) { - elprintf(EL_UIO, "radica: r16 %06x", a); - return 0; - } + if ((a & 0xffff00) != 0xa13000) + return PicoRead16_io(a); - carthw_radica_baddr = a; - a = (a & 0x7e) << 15; - if (a >= Pico.romsize) { - elprintf(EL_ANOMALY|EL_STATUS, "radica: missing bank @ %06x", a); - return 0; - } - memcpy(Pico.rom, Pico.rom + Pico.romsize + a, Pico.romsize - a); + carthw_Xin1_do(a, 0x7e, 15); return 0; } +static void carthw_radica_mem_setup(void) +{ + cpu68k_map_set(m68k_read16_map, 0xa10000, 0xa1ffff, carthw_radica_read16, 1); +} + static void carthw_radica_statef(void) { - carthw_radica_read16(carthw_radica_baddr, 0); + carthw_radica_read16(carthw_Xin1_baddr); } static void carthw_radica_reset(void) { - memcpy(Pico.rom, Pico.rom + Pico.romsize, Pico.romsize); + carthw_radica_read16(0xa13000); } void carthw_radica_startup(void) { - void *tmp; + elprintf(EL_STATUS, "Radica mapper startup"); - elprintf(EL_STATUS, "Radica mapper detected"); - - tmp = realloc(Pico.rom, Pico.romsize * 2); - if (tmp == NULL) - { - elprintf(EL_STATUS, "OOM"); - return; - } - Pico.rom = tmp; - memcpy(Pico.rom + Pico.romsize, Pico.rom, Pico.romsize); - - PicoRead16Hook = carthw_radica_read16; - PicoResetHook = carthw_radica_reset; + PicoCartMemSetup = carthw_radica_mem_setup; + PicoResetHook = carthw_radica_reset; PicoLoadStateHook = carthw_radica_statef; - carthw_chunks = carthw_radica_state; + carthw_chunks = carthw_Xin1_state; } - diff --git a/pico/carthw/carthw.h b/pico/carthw/carthw.h index 6813205..7ca0c3d 100644 --- a/pico/carthw/carthw.h +++ b/pico/carthw/carthw.h @@ -12,12 +12,9 @@ extern svp_t *svp; void PicoSVPInit(void); void PicoSVPStartup(void); - -unsigned int PicoSVPRead16(unsigned int a, int realsize); -void PicoSVPWrite8 (unsigned int a, unsigned int d, int realsize); -void PicoSVPWrite16(unsigned int a, unsigned int d, int realsize); +void PicoSVPMemSetup(void); /* misc */ -void carthw_12in1_startup(void); +void carthw_Xin1_startup(void); void carthw_realtec_startup(void); void carthw_radica_startup(void); diff --git a/pico/carthw/svp/memory.c b/pico/carthw/svp/memory.c index 7f182fe..5e69962 100644 --- a/pico/carthw/svp/memory.c +++ b/pico/carthw/svp/memory.c @@ -7,32 +7,9 @@ #include "../../pico_int.h" +#include "../../memory.h" -#ifndef UTYPES_DEFINED -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned int u32; -#define UTYPES_DEFINED -#endif - -#define CLEAR_DETECT(pc_start,pc_end,text) \ - if (d == 0 && SekPc >= pc_start && SekPc < pc_end) \ - { \ - if (!clearing_ram) \ - elprintf(EL_SVP, text); \ - clearing_ram = 1; \ - return; \ - } - -unsigned int PicoSVPRead16(unsigned int a, int realsize) -{ - unsigned int d = 0; - static int a15004_looping = 0; - - // dram: 300000-31ffff - if ((a & 0xfe0000) == 0x300000) - d = *(u16 *)(svp->dram + (a&0x1fffe)); - +/* // "cell arrange" 1: 390000-39ffff else if ((a & 0xff0000) == 0x390000) { // this is rewritten 68k code @@ -48,9 +25,15 @@ unsigned int PicoSVPRead16(unsigned int a, int realsize) a1 = (a1 & 0x7801) | ((a1 & 0x1e) << 6) | ((a1 & 0x7e0) >> 4); d = ((u16 *)svp->dram)[a1]; } +*/ + +// IO/control area (0xa10000 - 0xa1ffff) +static u32 PicoRead16_svpr(u32 a) +{ + u32 d = 0; // regs - else if ((a & 0xfffff0) == 0xa15000) { + if ((a & 0xfffff0) == 0xa15000) { switch (a & 0xf) { case 0: case 2: @@ -60,44 +43,41 @@ unsigned int PicoSVPRead16(unsigned int a, int realsize) case 4: d = svp->ssp1601.gr[SSP_PM0].h; svp->ssp1601.gr[SSP_PM0].h &= ~1; - if (d&1) a15004_looping = 0; break; } - } - else - elprintf(EL_UIO|EL_SVP|EL_ANOMALY, "SVP FIXME: unhandled r%i: [%06x] %04x @%06x", realsize, a&0xffffff, d, SekPc); - if (!a15004_looping) - elprintf(EL_SVP, "SVP r%i: [%06x] %04x @%06x", realsize, a&0xffffff, d, SekPc); - - if (a == 0xa15004 && !(d&1)) { - if (!a15004_looping) - elprintf(EL_SVP, "SVP det TIGHT loop: a15004"); - a15004_looping = 1; +#if EL_LOGMASK & EL_SVP + { + static int a15004_looping = 0; + if (a == 0xa15004 && (d & 1)) + a15004_looping = 0; + + if (!a15004_looping) + elprintf(EL_SVP, "SVP r%i: [%06x] %04x @%06x", realsize, a, d, SekPc); + + if (a == 0xa15004 && !(d&1)) { + if (!a15004_looping) + elprintf(EL_SVP, "SVP det TIGHT loop: a15004"); + a15004_looping = 1; + } + else + a15004_looping = 0; + } +#endif + return d; } - else a15004_looping = 0; //if (a == 0x30fe02 && d == 0) // elprintf(EL_ANOMALY, "SVP lag?"); - return d; + return PicoRead16_io(a); } -void PicoSVPWrite8(unsigned int a, unsigned int d, int realsize) +static void PicoWrite16_svpr(u32 a, u32 d) { - elprintf(EL_UIO|EL_SVP|EL_ANOMALY, "!!! SVP w%i: [%06x], %08x @%06x", realsize, a&0xffffff, d, SekPc); -} - -void PicoSVPWrite16(unsigned int a, unsigned int d, int realsize) -{ - static int clearing_ram = 0; + elprintf(EL_SVP, "SVP w16: [%06x] %04x @%06x", a, d, SekPc); - // DRAM - if ((a & 0xfe0000) == 0x300000) - *(u16 *)(svp->dram + (a&0x1fffe)) = d; - - // regs - else if ((a & 0xfffff0) == 0xa15000) { + if ((a & 0xfffff0) == 0xa15000) { if (a == 0xa15000 || a == 0xa15002) { // just guessing here svp->ssp1601.gr[SSP_XST].h = d; @@ -106,24 +86,34 @@ void PicoSVPWrite16(unsigned int a, unsigned int d, int realsize) } //else if (a == 0xa15006) svp->ssp1601.gr[SSP_PM0].h = d | (d << 1); // 0xa15006 probably has 'halt' + return; } - else - elprintf(EL_UIO|EL_SVP|EL_ANOMALY, "SVP FIXME: unhandled w%i: [%06x] %04x @%06x", realsize, a&0xffffff, d, SekPc); - + PicoWrite16_io(a, d); +/* if (a == 0x30fe06 && d != 0) svp->ssp1601.emu_status &= ~SSP_WAIT_30FE06; if (a == 0x30fe08 && d != 0) svp->ssp1601.emu_status &= ~SSP_WAIT_30FE08; +*/ +} + +void PicoSVPMemSetup(void) +{ + // 68k memmap: + // DRAM + cpu68k_map_set(m68k_read8_map, 0x300000, 0x31ffff, svp->dram, 0); + cpu68k_map_set(m68k_read16_map, 0x300000, 0x31ffff, svp->dram, 0); + cpu68k_map_set(m68k_write8_map, 0x300000, 0x31ffff, svp->dram, 0); + cpu68k_map_set(m68k_write16_map, 0x300000, 0x31ffff, svp->dram, 0); - // debug: detect RAM clears.. - CLEAR_DETECT(0x0221dc, 0x0221f0, "SVP RAM CLEAR (full) @ 0221C2"); - CLEAR_DETECT(0x02204c, 0x022068, "SVP RAM CLEAR 300000-31ffbf (1) @ 022032"); - CLEAR_DETECT(0x021900, 0x021ff0, "SVP RAM CLEAR 300000-305fff"); - CLEAR_DETECT(0x0220b0, 0x0220cc, "SVP RAM CLEAR 300000-31ffbf (2) @ 022096"); - clearing_ram = 0; + // DRAM (cell arrange) - TODO - elprintf(EL_SVP, "SVP w%i: [%06x] %04x @%06x", realsize, a&0xffffff, d, SekPc); + // regs + cpu68k_map_set(m68k_read8_map, 0xa10000, 0xa1ffff, PicoRead8_io, 1); // PicoRead8_svpr + cpu68k_map_set(m68k_read16_map, 0xa10000, 0xa1ffff, PicoRead16_svpr, 1); + cpu68k_map_set(m68k_write8_map, 0xa10000, 0xa1ffff, PicoWrite8_io, 1); // PicoWrite8_svpr + cpu68k_map_set(m68k_write16_map, 0xa10000, 0xa1ffff, PicoWrite16_svpr, 1); } diff --git a/pico/carthw/svp/ssp16.c b/pico/carthw/svp/ssp16.c index 1d59406..7118727 100644 --- a/pico/carthw/svp/ssp16.c +++ b/pico/carthw/svp/ssp16.c @@ -647,12 +647,14 @@ static void write_XST(u32 d) static u32 read_PM4(void) { u32 d = pm_io(4, 0, 0); +/* TODO? if (d == 0) { switch (GET_PPC_OFFS()) { case 0x0854: ssp->emu_status |= SSP_WAIT_30FE08; elprintf(EL_SVP, "det TIGHT loop: [30fe08]"); break; case 0x4f12: ssp->emu_status |= SSP_WAIT_30FE06; elprintf(EL_SVP, "det TIGHT loop: [30fe06]"); break; } } +*/ if (d != (u32)-1) return d; // can be removed? elprintf(EL_SVP|EL_ANOMALY, "PM4 raw r %04x @ %04x", rPM4, GET_PPC_OFFS()); diff --git a/pico/carthw/svp/svp.c b/pico/carthw/svp/svp.c index 17d4aea..504f8d3 100644 --- a/pico/carthw/svp/svp.c +++ b/pico/carthw/svp/svp.c @@ -121,7 +121,7 @@ void PicoSVPStartup(void) { void *tmp; - elprintf(EL_SVP, "SVP init"); + elprintf(EL_STATUS, "SVP startup"); tmp = realloc(Pico.rom, 0x200000 + sizeof(*svp)); if (tmp == NULL) @@ -150,9 +150,7 @@ void PicoSVPStartup(void) #endif // init ok, setup hooks.. - PicoRead16Hook = PicoSVPRead16; - PicoWrite8Hook = PicoSVPWrite8; - PicoWrite16Hook = PicoSVPWrite16; + PicoCartMemSetup = PicoSVPMemSetup; PicoDmaHook = PicoSVPDma; PicoResetHook = PicoSVPReset; PicoLineHook = PicoSVPLine; diff --git a/pico/cd/memory.c b/pico/cd/memory.c index a26cac7..1e6a9c9 100644 --- a/pico/cd/memory.c +++ b/pico/cd/memory.c @@ -1044,101 +1044,12 @@ static void PicoWriteCD32w(unsigned int a, unsigned int d) { if (m68ki_cpu_p == &PicoCpuMS68k) s68k_write32(a, d); else m68k_write32(a, d); } -// these are allowed to access RAM -static unsigned int m68k_read_pcrelative_CD8 (unsigned int a) -{ - a&=0xffffff; - if(m68ki_cpu_p == &PicoCpuMS68k) { - if (a < 0x80000) return *(u8 *)(Pico_mcd->prg_ram+(a^1)); // PRG Ram - if ((a&0xfc0000)==0x080000 && !(Pico_mcd->s68k_regs[3]&4)) // word RAM (2M area: 080000-0bffff) - return *(u8 *)(Pico_mcd->word_ram2M+((a^1)&0x3ffff)); - if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // word RAM (1M area: 0c0000-0dffff) - int bank = (Pico_mcd->s68k_regs[3]&1)^1; - return *(u8 *)(Pico_mcd->word_ram1M[bank]+((a^1)&0x1ffff)); - } - elprintf(EL_ANOMALY, "s68k_read_pcrelative_CD8 FIXME: can't handle %06x", a); - } else { - if((a&0xe00000)==0xe00000) return *(u8 *)(Pico.ram+((a^1)&0xffff)); // Ram - if(a<0x20000) return *(u8 *)(Pico.rom+(a^1)); // Bios - if((a&0xfc0000)==0x200000) { // word RAM - if(!(Pico_mcd->s68k_regs[3]&4)) // 2M? - return *(u8 *)(Pico_mcd->word_ram2M+((a^1)&0x3ffff)); - else if (a < 0x220000) { - int bank = Pico_mcd->s68k_regs[3]&1; - return *(u8 *)(Pico_mcd->word_ram1M[bank]+((a^1)&0x1ffff)); - } - } - elprintf(EL_ANOMALY, "m68k_read_pcrelative_CD8 FIXME: can't handle %06x", a); - } - return 0;//(u8) lastread_d; -} -static unsigned int m68k_read_pcrelative_CD16(unsigned int a) -{ - a&=0xffffff; - if(m68ki_cpu_p == &PicoCpuMS68k) { - if (a < 0x80000) return *(u16 *)(Pico_mcd->prg_ram+(a&~1)); // PRG Ram - if ((a&0xfc0000)==0x080000 && !(Pico_mcd->s68k_regs[3]&4)) // word RAM (2M area: 080000-0bffff) - return *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); - if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // word RAM (1M area: 0c0000-0dffff) - int bank = (Pico_mcd->s68k_regs[3]&1)^1; - return *(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe)); - } - elprintf(EL_ANOMALY, "s68k_read_pcrelative_CD16 FIXME: can't handle %06x", a); - } else { - if((a&0xe00000)==0xe00000) return *(u16 *)(Pico.ram+(a&0xfffe)); // Ram - if(a<0x20000) return *(u16 *)(Pico.rom+(a&~1)); // Bios - if((a&0xfc0000)==0x200000) { // word RAM - if(!(Pico_mcd->s68k_regs[3]&4)) // 2M? - return *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); - else if (a < 0x220000) { - int bank = Pico_mcd->s68k_regs[3]&1; - return *(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe)); - } - } - elprintf(EL_ANOMALY, "m68k_read_pcrelative_CD16 FIXME: can't handle %06x", a); - } - return 0; -} -static unsigned int m68k_read_pcrelative_CD32(unsigned int a) -{ - u16 *pm; - a&=0xffffff; - if(m68ki_cpu_p == &PicoCpuMS68k) { - if (a < 0x80000) { u16 *pm=(u16 *)(Pico_mcd->prg_ram+(a&~1)); return (pm[0]<<16)|pm[1]; } // PRG Ram - if ((a&0xfc0000)==0x080000 && !(Pico_mcd->s68k_regs[3]&4)) // word RAM (2M area: 080000-0bffff) - { pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); return (pm[0]<<16)|pm[1]; } - if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // word RAM (1M area: 0c0000-0dffff) - int bank = (Pico_mcd->s68k_regs[3]&1)^1; - pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe)); - return (pm[0]<<16)|pm[1]; - } - elprintf(EL_ANOMALY, "s68k_read_pcrelative_CD32 FIXME: can't handle %06x", a); - } else { - if((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); return (pm[0]<<16)|pm[1]; } // Ram - if(a<0x20000) { u16 *pm=(u16 *)(Pico.rom+(a&~1)); return (pm[0]<<16)|pm[1]; } - if((a&0xfc0000)==0x200000) { // word RAM - if(!(Pico_mcd->s68k_regs[3]&4)) // 2M? - { pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); return (pm[0]<<16)|pm[1]; } - else if (a < 0x220000) { - int bank = Pico_mcd->s68k_regs[3]&1; - pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe)); - return (pm[0]<<16)|pm[1]; - } - } - elprintf(EL_ANOMALY, "m68k_read_pcrelative_CD32 FIXME: can't handle %06x", a); - } - return 0; -} - extern unsigned int (*pm68k_read_memory_8) (unsigned int address); extern unsigned int (*pm68k_read_memory_16)(unsigned int address); extern unsigned int (*pm68k_read_memory_32)(unsigned int address); extern void (*pm68k_write_memory_8) (unsigned int address, unsigned char value); extern void (*pm68k_write_memory_16)(unsigned int address, unsigned short value); extern void (*pm68k_write_memory_32)(unsigned int address, unsigned int value); -extern unsigned int (*pm68k_read_memory_pcr_8) (unsigned int address); -extern unsigned int (*pm68k_read_memory_pcr_16)(unsigned int address); -extern unsigned int (*pm68k_read_memory_pcr_32)(unsigned int address); static void m68k_mem_setup_cd(void) { @@ -1148,9 +1059,6 @@ static void m68k_mem_setup_cd(void) pm68k_write_memory_8 = PicoWriteCD8w; pm68k_write_memory_16 = PicoWriteCD16w; pm68k_write_memory_32 = PicoWriteCD32w; - pm68k_read_memory_pcr_8 = m68k_read_pcrelative_CD8; - pm68k_read_memory_pcr_16 = m68k_read_pcrelative_CD16; - pm68k_read_memory_pcr_32 = m68k_read_pcrelative_CD32; } #endif // EMU_M68K diff --git a/pico/debug.c b/pico/debug.c index 89bdde3..6a3b2d2 100644 --- a/pico/debug.c +++ b/pico/debug.c @@ -35,8 +35,8 @@ char *PDebugMain(void) sprintf(dstrp, "mode set 4: %02x\n", (r=reg[0xC])); MVP; sprintf(dstrp, "interlace: %i%i, cells: %i, shadow: %i\n", bit(r,2), bit(r,1), (r&0x80) ? 40 : 32, bit(r,3)); MVP; sprintf(dstrp, "scroll size: w: %i, h: %i SRAM: %i; eeprom: %i (%i)\n", reg[0x10]&3, (reg[0x10]&0x30)>>4, - bit(Pico.m.sram_status, 4), bit(Pico.m.sram_status, 2), SRam.eeprom_type); MVP; - sprintf(dstrp, "sram range: %06x-%06x, reg: %02x\n", SRam.start, SRam.end, Pico.m.sram_status); MVP; + !!(SRam.flags & SRF_ENABLED), !!(SRam.flags & SRF_EEPROM), SRam.eeprom_type); MVP; + sprintf(dstrp, "sram range: %06x-%06x, reg: %02x\n", SRam.start, SRam.end, Pico.m.sram_reg); MVP; sprintf(dstrp, "pend int: v:%i, h:%i, vdp status: %04x\n", bit(pv->pending_ints,5), bit(pv->pending_ints,4), pv->status); MVP; sprintf(dstrp, "pal: %i, hw: %02x, frame#: %i\n", Pico.m.pal, Pico.m.hardware, Pico.m.frame_count); MVP; #if defined(EMU_C68K) diff --git a/pico/eeprom.c b/pico/eeprom.c new file mode 100644 index 0000000..f0f1b70 --- /dev/null +++ b/pico/eeprom.c @@ -0,0 +1,208 @@ +/* + * rarely used EEPROM code + * + * (see Genesis Plus for Wii/GC code and docs for info, + * full game list and better code). + */ + +#include "pico_int.h" + +static unsigned int last_write = 0xffff0000; + +// eeprom_status: LA.. s.la (L=pending SCL, A=pending SDA, +// s=started, l=old SCL, a=old SDA) +static void EEPROM_write_do(unsigned int d) // ???? ??la (l=SCL, a=SDA) +{ + unsigned int sreg = Pico.m.eeprom_status, saddr = Pico.m.eeprom_addr; + unsigned int scyc = Pico.m.eeprom_cycle, ssa = Pico.m.eeprom_slave; + + elprintf(EL_EEPROM, "eeprom: scl/sda: %i/%i -> %i/%i, newtime=%i", (sreg&2)>>1, sreg&1, + (d&2)>>1, d&1, SekCyclesDoneT() - last_write); + saddr &= 0x1fff; + + if(sreg & d & 2) { + // SCL was and is still high.. + if((sreg & 1) && !(d&1)) { + // ..and SDA went low, means it's a start command, so clear internal addr reg and clock counter + elprintf(EL_EEPROM, "eeprom: -start-"); + //saddr = 0; + scyc = 0; + sreg |= 8; + } else if(!(sreg & 1) && (d&1)) { + // SDA went high == stop command + elprintf(EL_EEPROM, "eeprom: -stop-"); + sreg &= ~8; + } + } + else if((sreg & 8) && !(sreg & 2) && (d&2)) + { + // we are started and SCL went high - next cycle + scyc++; // pre-increment + if(SRam.eeprom_type) { + // X24C02+ + if((ssa&1) && scyc == 18) { + scyc = 9; + saddr++; // next address in read mode + /*if(SRam.eeprom_type==2) saddr&=0xff; else*/ saddr&=0x1fff; // mask + } + else if(SRam.eeprom_type == 2 && scyc == 27) scyc = 18; + else if(scyc == 36) scyc = 27; + } else { + // X24C01 + if(scyc == 18) { + scyc = 9; // wrap + if(saddr&1) { saddr+=2; saddr&=0xff; } // next addr in read mode + } + } + elprintf(EL_EEPROM, "eeprom: scyc: %i", scyc); + } + else if((sreg & 8) && (sreg & 2) && !(d&2)) + { + // we are started and SCL went low (falling edge) + if(SRam.eeprom_type) { + // X24C02+ + if(scyc == 9 || scyc == 18 || scyc == 27); // ACK cycles + else if( (SRam.eeprom_type == 3 && scyc > 27) || (SRam.eeprom_type == 2 && scyc > 18) ) { + if(!(ssa&1)) { + // data write + unsigned char *pm=SRam.data+saddr; + *pm <<= 1; *pm |= d&1; + if(scyc == 26 || scyc == 35) { + saddr=(saddr&~0xf)|((saddr+1)&0xf); // only 4 (?) lowest bits are incremented + elprintf(EL_EEPROM, "eeprom: write done, addr inc to: %x, last byte=%02x", saddr, *pm); + } + SRam.changed = 1; + } + } else if(scyc > 9) { + if(!(ssa&1)) { + // we latch another addr bit + saddr<<=1; + if(SRam.eeprom_type == 2) saddr&=0xff; else saddr&=0x1fff; // mask + saddr|=d&1; + if(scyc==17||scyc==26) { + elprintf(EL_EEPROM, "eeprom: addr reg done: %x", saddr); + if(scyc==17&&SRam.eeprom_type==2) { saddr&=0xff; saddr|=(ssa<<7)&0x700; } // add device bits too + } + } + } else { + // slave address + ssa<<=1; ssa|=d&1; + if(scyc==8) elprintf(EL_EEPROM, "eeprom: slave done: %x", ssa); + } + } else { + // X24C01 + if(scyc == 9); // ACK cycle, do nothing + else if(scyc > 9) { + if(!(saddr&1)) { + // data write + unsigned char *pm=SRam.data+(saddr>>1); + *pm <<= 1; *pm |= d&1; + if(scyc == 17) { + saddr=(saddr&0xf9)|((saddr+2)&6); // only 2 lowest bits are incremented + elprintf(EL_EEPROM, "eeprom: write done, addr inc to: %x, last byte=%02x", saddr>>1, *pm); + } + SRam.changed = 1; + } + } else { + // we latch another addr bit + saddr<<=1; saddr|=d&1; saddr&=0xff; + if(scyc==8) elprintf(EL_EEPROM, "eeprom: addr done: %x", saddr>>1); + } + } + } + + sreg &= ~3; sreg |= d&3; // remember SCL and SDA + Pico.m.eeprom_status = (unsigned char) sreg; + Pico.m.eeprom_cycle = (unsigned char) scyc; + Pico.m.eeprom_slave = (unsigned char) ssa; + Pico.m.eeprom_addr = (unsigned short)saddr; +} + +static void EEPROM_upd_pending(unsigned int d) +{ + unsigned int d1, sreg = Pico.m.eeprom_status; + + sreg &= ~0xc0; + + // SCL + d1 = (d >> SRam.eeprom_bit_cl) & 1; + sreg |= d1 << 7; + + // SDA in + d1 = (d >> SRam.eeprom_bit_in) & 1; + sreg |= d1 << 6; + + Pico.m.eeprom_status = (unsigned char) sreg; +} + +void EEPROM_write16(unsigned int d) +{ + // this diff must be at most 16 for NBA Jam to work + if (SekCyclesDoneT() - last_write < 16) { + // just update pending state + elprintf(EL_EEPROM, "eeprom: skip because cycles=%i", + SekCyclesDoneT() - last_write); + EEPROM_upd_pending(d); + } else { + int srs = Pico.m.eeprom_status; + EEPROM_write_do(srs >> 6); // execute pending + EEPROM_upd_pending(d); + if ((srs ^ Pico.m.eeprom_status) & 0xc0) // update time only if SDA/SCL changed + last_write = SekCyclesDoneT(); + } +} + +void EEPROM_write8(unsigned int a, unsigned int d) +{ + unsigned char *wb = Pico.m.eeprom_wb; + wb[a & 1] = d; + EEPROM_write16((wb[0] << 8) | wb[1]); +} + +unsigned int EEPROM_read(void) +{ + unsigned int shift, d; + unsigned int sreg, saddr, scyc, ssa, interval; + + // flush last pending write + EEPROM_write_do(Pico.m.eeprom_status>>6); + + sreg = Pico.m.eeprom_status; saddr = Pico.m.eeprom_addr&0x1fff; scyc = Pico.m.eeprom_cycle; ssa = Pico.m.eeprom_slave; + interval = SekCyclesDoneT() - last_write; + d = (sreg>>6)&1; // use SDA as "open bus" + + // NBA Jam is nasty enough to read raising the SCL and starting the new cycle. + // this is probably valid because data changes occur while SCL is low and data can be read + // before it's actual cycle begins. + if (!(sreg&0x80) && interval >= 24) { + elprintf(EL_EEPROM, "eeprom: early read, cycles=%i", interval); + scyc++; + } + + if (!(sreg & 8)); // not started, use open bus + else if (scyc == 9 || scyc == 18 || scyc == 27) { + elprintf(EL_EEPROM, "eeprom: r ack"); + d = 0; + } else if (scyc > 9 && scyc < 18) { + // started and first command word received + shift = 17-scyc; + if (SRam.eeprom_type) { + // X24C02+ + if (ssa&1) { + elprintf(EL_EEPROM, "eeprom: read: addr %02x, cycle %i, reg %02x", saddr, scyc, sreg); + if (shift==0) elprintf(EL_EEPROM, "eeprom: read done, byte %02x", SRam.data[saddr]); + d = (SRam.data[saddr]>>shift)&1; + } + } else { + // X24C01 + if (saddr&1) { + elprintf(EL_EEPROM, "eeprom: read: addr %02x, cycle %i, reg %02x", saddr>>1, scyc, sreg); + if (shift==0) elprintf(EL_EEPROM, "eeprom: read done, byte %02x", SRam.data[saddr>>1]); + d = (SRam.data[saddr>>1]>>shift)&1; + } + } + } + + return (d << SRam.eeprom_bit_out); +} + diff --git a/pico/memory.c b/pico/memory.c index aa2a54e..2eaac2a 100644 --- a/pico/memory.c +++ b/pico/memory.c @@ -320,7 +320,7 @@ static void ctl_write_z80reset(u32 d) // for nonstandard reads // TODO: mv to carthw -static u32 OtherRead16End(u32 a, int realsize) +u32 OtherRead16End(u32 a, int realsize) { u32 d=0; @@ -364,7 +364,7 @@ static u32 OtherRead16End(u32 a, int realsize) // our default behaviour is to return whatever was last written a 0x400000-0x7fffff range (used by Squirrel King (R) [!]) // Lion King II, The (Unl) [!] writes @ 400000 and wants to get that val @ 400002 and wites another val // @ 400004 which is expected @ 400006, so we really remember 2 values here - d = Pico.m.prot_bytes[(a>>2)&1]<<8; +/// d = Pico.m.prot_bytes[(a>>2)&1]<<8; } else if (a == 0xa13000 && Pico.romsize >= 1024*1024) { if (*(int *)(Pico.rom+0xc8af0) == 0x30133013 && *(int *)(Pico.rom+0xc8af4) == 0x000f0240) { // Rockman X3 (Unl) [!] @@ -397,28 +397,11 @@ end: return d; } -static void OtherWrite8End(u32 a,u32 d,int realsize) +void OtherWrite8End(u32 a,u32 d,int realsize) { -#ifdef _ASM_MEMORY_C - // special ROM hardware (currently only banking and sram reg supported) - if((a&0xfffff1) == 0xA130F1) { - PicoWriteRomHW_SSF2(a, d); // SSF2 or SRAM - return; - } -#else - // sram access register - if(a == 0xA130F1) { - elprintf(EL_SRAMIO, "sram reg=%02x", d); - Pico.m.sram_status &= ~(SRS_MAPPED|SRS_READONLY); - Pico.m.sram_status |= (u8)(d&3); - return; - } -#endif - elprintf(EL_UIO, "strange w%i: %06x, %08x @%06x", realsize, a&0xffffff, d, SekPc); - // for games with simple protection devices, discovered by Haze if ((a>>22) == 1) - Pico.m.prot_bytes[(a>>2)&1] = (u8)d; +;/// Pico.m.prot_bytes[(a>>2)&1] = (u8)d; } // ----------------------------------------------------------------- @@ -426,18 +409,20 @@ static void OtherWrite8End(u32 a,u32 d,int realsize) // cart (save) RAM area (usually 0x200000 - ...) static u32 PicoRead8_sram(u32 a) { - int srs = Pico.m.sram_status; u32 d; - if (SRam.end >= a && a >= SRam.start && (srs & (SRS_MAPPED|SRS_EEPROM))) + if (SRam.start <= a && a <= SRam.end && (Pico.m.sram_reg & SRR_MAPPED)) { - if (srs & SRS_EEPROM) + if (SRam.flags & SRF_EEPROM) { d = EEPROM_read(); - else + if (!(a & 1)) + d >>= 8; + } else d = *(u8 *)(SRam.data - SRam.start + a); - elprintf(EL_SRAMIO, "sram r8 [%06x] %02x @ %06x", a, d, SekPc); + elprintf(EL_SRAMIO, "sram r8 [%06x] %02x @ %06x", a, d, SekPc); return d; } + // XXX: this is banking unfriendly if (a < Pico.romsize) return Pico.rom[a ^ 1]; @@ -446,14 +431,12 @@ static u32 PicoRead8_sram(u32 a) static u32 PicoRead16_sram(u32 a) { - int srs = Pico.m.sram_status; u32 d; - if (SRam.end >= a && a >= SRam.start && (srs & (SRS_MAPPED|SRS_EEPROM))) + if (SRam.end >= a && a >= SRam.start && (Pico.m.sram_reg & SRR_MAPPED)) { - if (srs & SRS_EEPROM) { + if (SRam.flags & SRF_EEPROM) d = EEPROM_read(); - d |= d << 8; - } else { + else { u8 *pm = (u8 *)(SRam.data - SRam.start + a); d = pm[0] << 8; d |= pm[1]; @@ -470,25 +453,18 @@ static u32 PicoRead16_sram(u32 a) static void PicoWrite8_sram(u32 a, u32 d) { - unsigned int srs = Pico.m.sram_status; - elprintf(EL_SRAMIO, "sram wX [%06x] %02x @ %06x", a, d & 0xffff, SekPc); - if (srs & SRS_EEPROM) // EEPROM write + if (a > SRam.end || a < SRam.start || !(Pico.m.sram_reg & SRR_MAPPED)) { + m68k_unmapped_write8(a, d); + return; + } + + elprintf(EL_SRAMIO, "sram w8 [%06x] %02x @ %06x", a, d & 0xff, SekPc); + if (SRam.flags & SRF_EEPROM) { - // this diff must be at most 16 for NBA Jam to work - if (SekCyclesDoneT() - lastSSRamWrite < 16) { - // just update pending state - elprintf(EL_EEPROM, "eeprom: skip because cycles=%i", - SekCyclesDoneT() - lastSSRamWrite); - EEPROM_upd_pending(a, d); - } else { - EEPROM_write(srs >> 6); // execute pending - EEPROM_upd_pending(a, d); - if ((srs ^ Pico.m.sram_status) & 0xc0) // update time only if SDA/SCL changed - lastSSRamWrite = SekCyclesDoneT(); - } + EEPROM_write8(a, d); } - else if (!(srs & SRS_READONLY)) { - u8 *pm=(u8 *)(SRam.data - SRam.start + a); + else { + u8 *pm = (u8 *)(SRam.data - SRam.start + a); if (*pm != (u8)d) { SRam.changed = 1; *pm = (u8)d; @@ -498,8 +474,24 @@ static void PicoWrite8_sram(u32 a, u32 d) static void PicoWrite16_sram(u32 a, u32 d) { - // XXX: hardware could easily use MSB too.. - PicoWrite8_sram(a + 1, d); + if (a > SRam.end || a < SRam.start || !(Pico.m.sram_reg & SRR_MAPPED)) { + m68k_unmapped_write16(a, d); + return; + } + + elprintf(EL_SRAMIO, "sram w16 [%06x] %04x @ %06x", a, d & 0xffff, SekPc); + if (SRam.flags & SRF_EEPROM) + { + EEPROM_write16(d); + } + else { + // XXX: hardware could easily use MSB too.. + u8 *pm = (u8 *)(SRam.data - SRam.start + a); + if (*pm != (u8)d) { + SRam.changed = 1; + *pm = (u8)d; + } + } } // z80 area (0xa00000 - 0xa0ffff) @@ -645,8 +637,8 @@ void PicoWrite8_io(u32 a, u32 d) } if (a == 0xa130f1) { // sram access register elprintf(EL_SRAMIO, "sram reg=%02x", d); - Pico.m.sram_status &= ~(SRS_MAPPED|SRS_READONLY); - Pico.m.sram_status |= (u8)(d & 3); + Pico.m.sram_reg &= ~(SRR_MAPPED|SRR_READONLY); + Pico.m.sram_reg |= (u8)(d & 3); return; } m68k_unmapped_write8(a, d); @@ -668,8 +660,8 @@ void PicoWrite16_io(u32 a, u32 d) } if (a == 0xa130f0) { // sram access register elprintf(EL_SRAMIO, "sram reg=%02x", d); - Pico.m.sram_status &= ~(SRS_MAPPED|SRS_READONLY); - Pico.m.sram_status |= (u8)(d & 3); + Pico.m.sram_reg &= ~(SRR_MAPPED|SRR_READONLY); + Pico.m.sram_reg |= (u8)(d & 3); return; } m68k_unmapped_write16(a, d); @@ -728,25 +720,6 @@ static void PicoWrite16_vdp(u32 a, u32 d) // ----------------------------------------------------------------- -// TODO: rm -static void OtherWrite16End(u32 a,u32 d,int realsize) -{ - PicoWrite8Hook(a, d>>8, realsize); - PicoWrite8Hook(a+1,d&0xff, realsize); -} - -u32 (*PicoRead16Hook) (u32 a, int realsize) = OtherRead16End; -void (*PicoWrite8Hook) (u32 a, u32 d, int realsize) = OtherWrite8End; -void (*PicoWrite16Hook)(u32 a, u32 d, int realsize) = OtherWrite16End; - -PICO_INTERNAL void PicoMemResetHooks(void) -{ - // default unmapped/cart specific handlers - PicoRead16Hook = OtherRead16End; - PicoWrite8Hook = OtherWrite8End; - PicoWrite16Hook = OtherWrite16End; -} - #ifdef EMU_M68K static void m68k_mem_setup(void); #endif @@ -769,8 +742,8 @@ PICO_INTERNAL void PicoMemSetup(void) cpu68k_map_set(m68k_read16_map, 0x000000, rs - 1, Pico.rom, 0); // Common case of on-cart (save) RAM, usually at 0x200000-... - rs = SRam.end - SRam.start; - if (rs > 0 && SRam.data != NULL) { + if ((SRam.flags & SRF_ENABLED) && SRam.data != NULL) { + rs = SRam.end - SRam.start; rs = (rs + mask) & ~mask; if (SRam.start + rs >= 0x1000000) rs = 0x1000000 - SRam.start; @@ -849,7 +822,6 @@ PICO_INTERNAL void PicoMemSetup(void) z80_mem_setup(); } -/* some nasty things below :( */ #ifdef EMU_M68K unsigned int (*pm68k_read_memory_8) (unsigned int address) = NULL; unsigned int (*pm68k_read_memory_16)(unsigned int address) = NULL; @@ -857,103 +829,6 @@ unsigned int (*pm68k_read_memory_32)(unsigned int address) = NULL; void (*pm68k_write_memory_8) (unsigned int address, unsigned char value) = NULL; void (*pm68k_write_memory_16)(unsigned int address, unsigned short value) = NULL; void (*pm68k_write_memory_32)(unsigned int address, unsigned int value) = NULL; -unsigned int (*pm68k_read_memory_pcr_8) (unsigned int address) = NULL; -unsigned int (*pm68k_read_memory_pcr_16)(unsigned int address) = NULL; -unsigned int (*pm68k_read_memory_pcr_32)(unsigned int address) = NULL; - -// these are here for core debugging mode -static unsigned int m68k_read_8 (unsigned int a, int do_fake) -{ - a&=0xffffff; - if(a68k upper read [%06x] %02x", addr68k, ret); -out: elprintf(EL_Z80BNK, "z80->68k r8 [%06x] %02x", addr68k, ret); return ret; } diff --git a/pico/memory.h b/pico/memory.h index 63c5163..a143047 100644 --- a/pico/memory.h +++ b/pico/memory.h @@ -5,6 +5,9 @@ typedef unsigned short u16; typedef unsigned int u32; #define M68K_MEM_SHIFT 16 +// minimum size we can map +#define M68K_BANK_SIZE (1 << M68K_MEM_SHIFT) +#define M68K_BANK_MASK (M68K_BANK_SIZE - 1) extern unsigned long m68k_read8_map [0x1000000 >> M68K_MEM_SHIFT]; extern unsigned long m68k_read16_map [0x1000000 >> M68K_MEM_SHIFT]; diff --git a/pico/misc.c b/pico/misc.c index 0ce1489..4e344fc 100644 --- a/pico/misc.c +++ b/pico/misc.c @@ -86,193 +86,6 @@ const unsigned char hcounts_32[] = { }; -// rarely used EEPROM SRAM code -// known games which use this: -// Wonder Boy in Monster World, Megaman - The Wily Wars (X24C01, 128 bytes) - -// (see Genesis Plus for Wii/GC code and docs for info, -// full game list and better code). - -unsigned int lastSSRamWrite = 0xffff0000; - -// sram_status: LAtd sela (L=pending SCL, A=pending SDA, t=(unused), -// d=SRAM was detected (header or by access), s=started, e=save is EEPROM, l=old SCL, a=old SDA) -PICO_INTERNAL void EEPROM_write(unsigned int d) // ???? ??la (l=SCL, a=SDA) -{ - unsigned int sreg = Pico.m.sram_status, saddr = Pico.m.eeprom_addr, scyc = Pico.m.eeprom_cycle, ssa = Pico.m.eeprom_slave; - - elprintf(EL_EEPROM, "eeprom: scl/sda: %i/%i -> %i/%i, newtime=%i", (sreg&2)>>1, sreg&1, - (d&2)>>1, d&1, SekCyclesDoneT()-lastSSRamWrite); - saddr&=0x1fff; - - if(sreg & d & 2) { - // SCL was and is still high.. - if((sreg & 1) && !(d&1)) { - // ..and SDA went low, means it's a start command, so clear internal addr reg and clock counter - elprintf(EL_EEPROM, "eeprom: -start-"); - //saddr = 0; - scyc = 0; - sreg |= 8; - } else if(!(sreg & 1) && (d&1)) { - // SDA went high == stop command - elprintf(EL_EEPROM, "eeprom: -stop-"); - sreg &= ~8; - } - } - else if((sreg & 8) && !(sreg & 2) && (d&2)) - { - // we are started and SCL went high - next cycle - scyc++; // pre-increment - if(SRam.eeprom_type) { - // X24C02+ - if((ssa&1) && scyc == 18) { - scyc = 9; - saddr++; // next address in read mode - /*if(SRam.eeprom_type==2) saddr&=0xff; else*/ saddr&=0x1fff; // mask - } - else if(SRam.eeprom_type == 2 && scyc == 27) scyc = 18; - else if(scyc == 36) scyc = 27; - } else { - // X24C01 - if(scyc == 18) { - scyc = 9; // wrap - if(saddr&1) { saddr+=2; saddr&=0xff; } // next addr in read mode - } - } - elprintf(EL_EEPROM, "eeprom: scyc: %i", scyc); - } - else if((sreg & 8) && (sreg & 2) && !(d&2)) - { - // we are started and SCL went low (falling edge) - if(SRam.eeprom_type) { - // X24C02+ - if(scyc == 9 || scyc == 18 || scyc == 27); // ACK cycles - else if( (SRam.eeprom_type == 3 && scyc > 27) || (SRam.eeprom_type == 2 && scyc > 18) ) { - if(!(ssa&1)) { - // data write - unsigned char *pm=SRam.data+saddr; - *pm <<= 1; *pm |= d&1; - if(scyc == 26 || scyc == 35) { - saddr=(saddr&~0xf)|((saddr+1)&0xf); // only 4 (?) lowest bits are incremented - elprintf(EL_EEPROM, "eeprom: write done, addr inc to: %x, last byte=%02x", saddr, *pm); - } - SRam.changed = 1; - } - } else if(scyc > 9) { - if(!(ssa&1)) { - // we latch another addr bit - saddr<<=1; - if(SRam.eeprom_type == 2) saddr&=0xff; else saddr&=0x1fff; // mask - saddr|=d&1; - if(scyc==17||scyc==26) { - elprintf(EL_EEPROM, "eeprom: addr reg done: %x", saddr); - if(scyc==17&&SRam.eeprom_type==2) { saddr&=0xff; saddr|=(ssa<<7)&0x700; } // add device bits too - } - } - } else { - // slave address - ssa<<=1; ssa|=d&1; - if(scyc==8) elprintf(EL_EEPROM, "eeprom: slave done: %x", ssa); - } - } else { - // X24C01 - if(scyc == 9); // ACK cycle, do nothing - else if(scyc > 9) { - if(!(saddr&1)) { - // data write - unsigned char *pm=SRam.data+(saddr>>1); - *pm <<= 1; *pm |= d&1; - if(scyc == 17) { - saddr=(saddr&0xf9)|((saddr+2)&6); // only 2 lowest bits are incremented - elprintf(EL_EEPROM, "eeprom: write done, addr inc to: %x, last byte=%02x", saddr>>1, *pm); - } - SRam.changed = 1; - } - } else { - // we latch another addr bit - saddr<<=1; saddr|=d&1; saddr&=0xff; - if(scyc==8) elprintf(EL_EEPROM, "eeprom: addr done: %x", saddr>>1); - } - } - } - - sreg &= ~3; sreg |= d&3; // remember SCL and SDA - Pico.m.sram_status = (unsigned char) sreg; - Pico.m.eeprom_cycle= (unsigned char) scyc; - Pico.m.eeprom_slave= (unsigned char) ssa; - Pico.m.eeprom_addr = (unsigned short)saddr; -} - -PICO_INTERNAL_ASM unsigned int EEPROM_read(void) -{ - unsigned int shift, d; - unsigned int sreg, saddr, scyc, ssa, interval; - - // flush last pending write - EEPROM_write(Pico.m.sram_status>>6); - - sreg = Pico.m.sram_status; saddr = Pico.m.eeprom_addr&0x1fff; scyc = Pico.m.eeprom_cycle; ssa = Pico.m.eeprom_slave; - interval = SekCyclesDoneT()-lastSSRamWrite; - d = (sreg>>6)&1; // use SDA as "open bus" - - // NBA Jam is nasty enough to read raising the SCL and starting the new cycle. - // this is probably valid because data changes occur while SCL is low and data can be read - // before it's actual cycle begins. - if (!(sreg&0x80) && interval >= 24) { - elprintf(EL_EEPROM, "eeprom: early read, cycles=%i", interval); - scyc++; - } - - if (!(sreg & 8)); // not started, use open bus - else if (scyc == 9 || scyc == 18 || scyc == 27) { - elprintf(EL_EEPROM, "eeprom: r ack"); - d = 0; - } else if (scyc > 9 && scyc < 18) { - // started and first command word received - shift = 17-scyc; - if (SRam.eeprom_type) { - // X24C02+ - if (ssa&1) { - elprintf(EL_EEPROM, "eeprom: read: addr %02x, cycle %i, reg %02x", saddr, scyc, sreg); - if (shift==0) elprintf(EL_EEPROM, "eeprom: read done, byte %02x", SRam.data[saddr]); - d = (SRam.data[saddr]>>shift)&1; - } - } else { - // X24C01 - if (saddr&1) { - elprintf(EL_EEPROM, "eeprom: read: addr %02x, cycle %i, reg %02x", saddr>>1, scyc, sreg); - if (shift==0) elprintf(EL_EEPROM, "eeprom: read done, byte %02x", SRam.data[saddr>>1]); - d = (SRam.data[saddr>>1]>>shift)&1; - } - } - } - - return (d << SRam.eeprom_bit_out); -} - -PICO_INTERNAL void EEPROM_upd_pending(unsigned int a, unsigned int d) -{ - unsigned int d1, sreg = Pico.m.sram_status; - - if (!((SRam.eeprom_abits^a)&1)) - { - // SCL - sreg &= ~0x80; - d1 = (d >> SRam.eeprom_bit_cl) & 1; - sreg |= d1<<7; - } - if (!(((SRam.eeprom_abits>>1)^a)&1)) - { - // SDA in - sreg &= ~0x40; - d1 = (d >> SRam.eeprom_bit_in) & 1; - sreg |= d1<<6; - } - - Pico.m.sram_status = (unsigned char) sreg; -} - - #ifndef _ASM_MISC_C typedef struct { diff --git a/pico/patch.c b/pico/patch.c index 99632dd..b961e80 100644 --- a/pico/patch.c +++ b/pico/patch.c @@ -213,12 +213,6 @@ unsigned int PicoRead16(unsigned int a); void PicoWrite16(unsigned int a, unsigned short d); -/* avoid dependency on newer glibc */ -static int isspace_(int c) -{ - return (0x09 <= c && c <= 0x0d) || c == ' '; -} - void PicoPatchUnload(void) { if (PicoPatches != NULL) diff --git a/pico/pico.c b/pico/pico.c index ab2302e..f2da10b 100644 --- a/pico/pico.c +++ b/pico/pico.c @@ -40,8 +40,6 @@ void PicoInit(void) PicoInitMCD(); PicoSVPInit(); - - SRam.data=0; } // to be called once on emu exit @@ -52,13 +50,12 @@ void PicoExit(void) PicoCartUnload(); z80_exit(); - if (SRam.data) free(SRam.data); SRam.data=0; + if (SRam.data) + free(SRam.data); } void PicoPower(void) { - unsigned char sram_status = Pico.m.sram_status; // must be preserved - Pico.m.frame_count = 0; // clear all memory of the emulated machine @@ -78,7 +75,6 @@ void PicoPower(void) if (PicoAHW & PAHW_MCD) PicoPowerMCD(); - Pico.m.sram_status = sram_status; PicoReset(); } @@ -141,8 +137,6 @@ PICO_INTERNAL void PicoDetectRegion(void) int PicoReset(void) { - unsigned char sram_status = Pico.m.sram_status; // must be preserved - if (Pico.romsize <= 0) return 1; @@ -194,12 +188,13 @@ int PicoReset(void) SekInitIdleDet(); // reset sram state; enable sram access by default if it doesn't overlap with ROM - Pico.m.sram_status = sram_status & (SRS_DETECTED|SRS_EEPROM); - if (!(Pico.m.sram_status & SRS_EEPROM) && Pico.romsize <= SRam.start) - Pico.m.sram_status |= SRS_MAPPED; + Pico.m.sram_reg = 0; + if ((SRam.flags & SRF_EEPROM) || Pico.romsize <= SRam.start) + Pico.m.sram_reg |= SRR_MAPPED; - elprintf(EL_STATUS, "sram: det: %i; eeprom: %i; start: %06x; end: %06x", - !!(sram_status & SRS_DETECTED), !!(sram_status & SRS_EEPROM), SRam.start, SRam.end); + if (SRam.flags & SRF_ENABLED) + elprintf(EL_STATUS, "sram: %06x - %06x; eeprom: %i", SRam.start, SRam.end, + !!(SRam.flags & SRF_EEPROM)); return 0; } diff --git a/pico/pico/memory.c b/pico/pico/memory.c index f124a06..4bdc84b 100644 --- a/pico/pico/memory.c +++ b/pico/pico/memory.c @@ -1,32 +1,28 @@ #include "../pico_int.h" +#include "../memory.h" #include "../sound/sn76496.h" -#ifndef UTYPES_DEFINED -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned int u32; -#define UTYPES_DEFINED -#endif - - -// ----------------------------------------------------------------- -// Read Rom and read Ram - -static u32 PicoReadPico8(u32 a) +/* +void dump(u16 w) { - u32 d=0; - - if ((a&0xe00000)==0xe00000) { d = *(u8 *)(Pico.ram+((a^1)&0xffff)); goto end; } // Ram - if (a> 8); + sprintf(fname, "ldump%i.bin", num); + if (f[num] == NULL) + f[num] = fopen(fname, "wb"); + fwrite(&w, 1, 2, f[num]); + //fclose(f); +} +*/ - if ((a&0xfffff0)==0xc00000) { // VDP - d=PicoVideoRead8(a); - goto end; - } +static u32 PicoRead8_pico(u32 a) +{ + u32 d = 0; - if ((a&0xffffe0)==0x800000) // Pico I/O + if ((a & 0xffffe0) == 0x800000) // Pico I/O { switch (a & 0x1f) { @@ -44,120 +40,42 @@ static u32 PicoReadPico8(u32 a) case 0x0d: d = (1 << (PicoPicohw.page & 7)) - 1; break; case 0x12: d = PicoPicohw.fifo_bytes == 0 ? 0x80 : 0; break; // guess default: - elprintf(EL_UIO, "r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc); - break; + goto unhandled; } + return d; } - //elprintf(EL_UIO, "r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc); - -end: - elprintf(EL_IO, "r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc); +unhandled: + elprintf(EL_UIO, "m68k unmapped r8 [%06x] @%06x", a, SekPc); return d; } -static u32 PicoReadPico16(u32 a) +static u32 PicoRead16_pico(u32 a) { - u32 d=0; - - if ((a&0xe00000)==0xe00000) { d=*(u16 *)(Pico.ram+(a&0xfffe)); goto end; } // Ram - - a&=0xfffffe; - - if (a 0x3f) ? 0 : (0x3f - PicoPicohw.fifo_bytes); else if (a == 0x800012) d = PicoPicohw.fifo_bytes == 0 ? 0x8000 : 0; // guess else - elprintf(EL_UIO, "r16: %06x, %04x @%06x", a&0xffffff, d, SekPc); - - //elprintf(EL_UIO, "r16: %06x, %04x @%06x", a&0xffffff, d, SekPc); + elprintf(EL_UIO, "m68k unmapped r16 [%06x] @%06x", a, SekPc); -end: - elprintf(EL_IO, "r16: %06x, %04x @%06x", a&0xffffff, d, SekPc); return d; } -static u32 PicoReadPico32(u32 a) +static void PicoWrite8_pico(u32 a, u32 d) { - u32 d=0; - - if ((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); d = (pm[0]<<16)|pm[1]; goto end; } // Ram - - a&=0xfffffe; - - if (a> 8); - sprintf(fname, "ldump%i.bin", num); - if (f[num] == NULL) - f[num] = fopen(fname, "wb"); - fwrite(&w, 1, 2, f[num]); - //fclose(f); -} -*/ - -static void PicoWritePico8(u32 a,u8 d) -{ - elprintf(EL_IO, "w8 : %06x, %02x @%06x", a&0xffffff, d, SekPc); - - if ((a&0xe00000)==0xe00000) { *(u8 *)(Pico.ram+((a^1)&0xffff))=d; return; } // Ram - - a&=0xffffff; - if ((a&0xfffff9)==0xc00011) { if (PicoOpt&2) SN76496Write(d); return; } // PSG Sound - - if ((a&0xfffff0)==0xc00000) { // VDP - d&=0xff; - PicoVideoWrite(a,(u16)(d|(d<<8))); // Byte access gets mirrored - return; - } - - switch (a & 0x1f) { + switch (a & ~0x800000) { case 0x19: case 0x1b: case 0x1d: case 0x1f: break; // 'S' 'E' 'G' 'A' default: - elprintf(EL_UIO, "w8 : %06x, %02x @%06x", a&0xffffff, d, SekPc); + elprintf(EL_UIO, "m68k unmapped w8 [%06x] %02x @%06x", a, d & 0xff, SekPc); break; } - //elprintf(EL_UIO, "w8 : %06x, %02x @%06x", a&0xffffff, d, SekPc); } -static void PicoWritePico16(u32 a,u16 d) +static void PicoWrite16_pico(u32 a, u32 d) { - elprintf(EL_IO, "w16: %06x, %04x", a&0xffffff, d); - - if ((a&0xe00000)==0xe00000) { *(u16 *)(Pico.ram+(a&0xfffe))=d; return; } // Ram - - a&=0xfffffe; - if ((a&0xfffff0)==0xc00000) { PicoVideoWrite(a,(u16)d); return; } // VDP - //if (a == 0x800010) dump(d); if (a == 0x800010) { @@ -179,97 +97,21 @@ static void PicoWritePico16(u32 a,u16 d) PicoReratePico(); } else - elprintf(EL_UIO, "w16: %06x, %04x", a&0xffffff, d); - - //elprintf(EL_UIO, "w16: %06x, %04x", a&0xffffff, d); -} - -static void PicoWritePico32(u32 a,u32 d) -{ - elprintf(EL_IO, "w32: %06x, %08x", a&0xffffff, d); - - if ((a&0xe00000)==0xe00000) - { - // Ram: - u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); - pm[0]=(u16)(d>>16); pm[1]=(u16)d; - return; - } - - a&=0xfffffe; - if ((a&0xfffff0)==0xc00000) - { - // VDP: - PicoVideoWrite(a, (u16)(d>>16)); - PicoVideoWrite(a+2,(u16)d); - return; - } - - elprintf(EL_UIO, "w32: %06x, %08x", a&0xffffff, d); + elprintf(EL_UIO, "m68k unmapped w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc); } -#ifdef EMU_M68K -extern unsigned int (*pm68k_read_memory_8) (unsigned int address); -extern unsigned int (*pm68k_read_memory_16)(unsigned int address); -extern unsigned int (*pm68k_read_memory_32)(unsigned int address); -extern void (*pm68k_write_memory_8) (unsigned int address, unsigned char value); -extern void (*pm68k_write_memory_16)(unsigned int address, unsigned short value); -extern void (*pm68k_write_memory_32)(unsigned int address, unsigned int value); -extern unsigned int (*pm68k_read_memory_pcr_8) (unsigned int address); -extern unsigned int (*pm68k_read_memory_pcr_16)(unsigned int address); -extern unsigned int (*pm68k_read_memory_pcr_32)(unsigned int address); - -static unsigned int m68k_read_memory_pcrp_8(unsigned int a) -{ - if((a&0xe00000)==0xe00000) return *(u8 *)(Pico.ram+((a^1)&0xffff)); // Ram - return 0; -} - -static unsigned int m68k_read_memory_pcrp_16(unsigned int a) -{ - if((a&0xe00000)==0xe00000) return *(u16 *)(Pico.ram+(a&0xfffe)); // Ram - return 0; -} - -static unsigned int m68k_read_memory_pcrp_32(unsigned int a) -{ - if((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); return (pm[0]<<16)|pm[1]; } // Ram - return 0; -} -#endif // EMU_M68K - PICO_INTERNAL void PicoMemSetupPico(void) { -#ifdef EMU_C68K - PicoCpuCM68k.checkpc=PicoCheckPc; - PicoCpuCM68k.fetch8 =PicoCpuCM68k.read8 =PicoReadPico8; - PicoCpuCM68k.fetch16=PicoCpuCM68k.read16=PicoReadPico16; - PicoCpuCM68k.fetch32=PicoCpuCM68k.read32=PicoReadPico32; - PicoCpuCM68k.write8 =PicoWritePico8; - PicoCpuCM68k.write16=PicoWritePico16; - PicoCpuCM68k.write32=PicoWritePico32; -#endif -#ifdef EMU_M68K - pm68k_read_memory_8 = PicoReadPico8; - pm68k_read_memory_16 = PicoReadPico16; - pm68k_read_memory_32 = PicoReadPico32; - pm68k_write_memory_8 = PicoWritePico8; - pm68k_write_memory_16 = PicoWritePico16; - pm68k_write_memory_32 = PicoWritePico32; - pm68k_read_memory_pcr_8 = m68k_read_memory_pcrp_8; - pm68k_read_memory_pcr_16 = m68k_read_memory_pcrp_16; - pm68k_read_memory_pcr_32 = m68k_read_memory_pcrp_32; -#endif -#ifdef EMU_F68K - // use standard setup, only override handlers PicoMemSetup(); - PicoCpuFM68k.read_byte =PicoReadPico8; - PicoCpuFM68k.read_word =PicoReadPico16; - PicoCpuFM68k.read_long =PicoReadPico32; - PicoCpuFM68k.write_byte=PicoWritePico8; - PicoCpuFM68k.write_word=PicoWritePico16; - PicoCpuFM68k.write_long=PicoWritePico32; -#endif + + // no MD IO or Z80 on Pico + m68k_map_unmap(0x400000, 0xbfffff); + + // map Pico I/O + cpu68k_map_set(m68k_read8_map, 0x800000, 0x80ffff, PicoRead8_pico, 1); + cpu68k_map_set(m68k_read16_map, 0x800000, 0x80ffff, PicoRead16_pico, 1); + cpu68k_map_set(m68k_write8_map, 0x800000, 0x80ffff, PicoWrite8_pico, 1); + cpu68k_map_set(m68k_write16_map, 0x800000, 0x80ffff, PicoWrite16_pico, 1); } diff --git a/pico/pico/pico.c b/pico/pico/pico.c index 298e57e..d85aeb5 100644 --- a/pico/pico/pico.c +++ b/pico/pico/pico.c @@ -75,7 +75,7 @@ static void PicoResetPico(void) PICO_INTERNAL void PicoInitPico(void) { - elprintf(EL_STATUS, "Pico detected"); + elprintf(EL_STATUS, "Pico startup"); PicoLineHook = PicoLinePico; PicoResetHook = PicoResetPico; diff --git a/pico/pico_int.h b/pico/pico_int.h index 8c72bba..cb12bc1 100644 --- a/pico/pico_int.h +++ b/pico/pico_int.h @@ -255,18 +255,19 @@ struct PicoMisc char dirtyPal; // 06 Is the palette dirty (1 - change @ this frame, 2 - some time before) unsigned char hardware; // 07 Hardware value for country unsigned char pal; // 08 1=PAL 0=NTSC - unsigned char sram_status; // 09 SRAM status. See SRS_* below + unsigned char sram_reg; // 09 SRAM reg. See SRR_* below unsigned short z80_bank68k; // 0a unsigned short z80_lastaddr; // this is for Z80 faking - unsigned char z80_fakeval; + unsigned char pad0; unsigned char z80_reset; // z80 reset held unsigned char padDelay[2]; // 10 gamepad phase time outs, so we count a delay unsigned short eeprom_addr; // EEPROM address register - unsigned char eeprom_cycle; // EEPROM SRAM cycle number + unsigned char eeprom_cycle; // EEPROM cycle number unsigned char eeprom_slave; // EEPROM slave word for X24C02 and better SRAMs - unsigned char prot_bytes[2]; // simple protection faking + unsigned char eeprom_status; + unsigned char pad1; unsigned short dma_xfers; // 18 - unsigned char pad[2]; + unsigned char eeprom_wb[2]; // EEPROM latch/write buffer unsigned int frame_count; // 1c for movies and idle det }; @@ -293,24 +294,26 @@ struct Pico }; // sram -#define SRS_MAPPED (1 << 0) -#define SRS_READONLY (1 << 1) -#define SRS_EEPROM (1 << 2) -#define SRS_DETECTED (1 << 4) +#define SRR_MAPPED (1 << 0) +#define SRR_READONLY (1 << 1) + +#define SRF_ENABLED (1 << 0) +#define SRF_EEPROM (1 << 1) struct PicoSRAM { unsigned char *data; // actual data unsigned int start; // start address in 68k address space unsigned int end; - unsigned char unused1; // 0c: unused + unsigned char flags; // 0c: SRF_* unsigned char unused2; unsigned char changed; - unsigned char eeprom_type; // eeprom type: 0: 7bit (24C01), 2: device with 2 addr words (X24C02+), 3: dev with 3 addr words - unsigned char eeprom_abits; // eeprom access must be odd addr for: bit0 ~ cl, bit1 ~ out + unsigned char eeprom_type; // eeprom type: 0: 7bit (24C01), 2: 2 addr words (X24C02+), 3: 3 addr words + unsigned char unused3; unsigned char eeprom_bit_cl; // bit number for cl unsigned char eeprom_bit_in; // bit number for in unsigned char eeprom_bit_out; // bit number for out + unsigned int size; }; // MCD @@ -414,6 +417,7 @@ extern areaseek *areaSeek; extern areaclose *areaClose; // cart.c +extern void (*PicoCartMemSetup)(void); extern void (*PicoCartUnloadHook)(void); // debug.c @@ -441,10 +445,6 @@ void PicoDrawSetColorFormatMode4(int which); PICO_INTERNAL void PicoInitPc(unsigned int pc); PICO_INTERNAL unsigned int PicoCheckPc(unsigned int pc); PICO_INTERNAL void PicoMemSetup(void); -PICO_INTERNAL void PicoMemResetHooks(void); -extern unsigned int (*PicoRead16Hook)(unsigned int a, int realsize); -extern void (*PicoWrite8Hook) (unsigned int a,unsigned int d,int realsize); -extern void (*PicoWrite16Hook)(unsigned int a,unsigned int d,int realsize); unsigned int PicoRead8_io(unsigned int a); unsigned int PicoRead16_io(unsigned int a); void PicoWrite8_io(unsigned int a, unsigned int d); @@ -537,14 +537,16 @@ PICO_INTERNAL_ASM unsigned int PicoVideoRead8(unsigned int a); extern int (*PicoDmaHook)(unsigned int source, int len, unsigned short **srcp, unsigned short **limitp); // misc.c -PICO_INTERNAL void EEPROM_write(unsigned int d); -PICO_INTERNAL void EEPROM_upd_pending(unsigned int a, unsigned int d); -PICO_INTERNAL_ASM unsigned int EEPROM_read(void); PICO_INTERNAL_ASM void memcpy16(unsigned short *dest, unsigned short *src, int count); PICO_INTERNAL_ASM void memcpy16bswap(unsigned short *dest, void *src, int count); PICO_INTERNAL_ASM void memcpy32(int *dest, int *src, int count); // 32bit word count PICO_INTERNAL_ASM void memset32(int *dest, int c, int count); +// eeprom.c +void EEPROM_write8(unsigned int a, unsigned int d); +void EEPROM_write16(unsigned int d); +unsigned int EEPROM_read(void); + // z80 functionality wrappers PICO_INTERNAL void z80_init(void); PICO_INTERNAL void z80_pack(unsigned char *data); @@ -574,6 +576,12 @@ void PicoMemSetupMS(void); void PicoFrameMS(void); void PicoFrameDrawOnlyMS(void); +/* avoid dependency on newer glibc */ +static __inline int isspace_(int c) +{ + return (0x09 <= c && c <= 0x0d) || c == ' '; +} + // emulation event logging #ifndef EL_LOGMASK #define EL_LOGMASK 0 diff --git a/pico/z80if.c b/pico/z80if.c index 63b79da..f48da99 100644 --- a/pico/z80if.c +++ b/pico/z80if.c @@ -106,7 +106,6 @@ PICO_INTERNAL void z80_reset(void) Cz80_Set_Reg(&CZ80, CZ80_IY, 0xffff); Cz80_Set_Reg(&CZ80, CZ80_SP, 0x2000); #endif - Pico.m.z80_fakeval = 0; // for faking when Z80 is disabled } // XXX TODO: should better use universal z80 save format diff --git a/platform/common/emu.c b/platform/common/emu.c index 4fcb792..6fc25b4 100644 --- a/platform/common/emu.c +++ b/platform/common/emu.c @@ -977,7 +977,7 @@ int emu_save_load_game(int load, int sram) int truncate = 1; if (PicoAHW & PAHW_MCD) { - if (PicoOpt&POPT_EN_MCD_RAMCART) { + if (PicoOpt & POPT_EN_MCD_RAMCART) { sram_size = 0x12000; sram_data = SRam.data; if (sram_data) @@ -988,9 +988,7 @@ int emu_save_load_game(int load, int sram) truncate = 0; // the .brm may contain RAM cart data after normal brm } } else { - sram_size = SRam.end-SRam.start+1; - if (Pico.m.sram_status & SRS_EEPROM) - sram_size = 0x2000; + sram_size = SRam.size; sram_data = SRam.data; } if (!sram_data) return 0; // SRam forcefully disabled for this game diff --git a/platform/gizmondo/emu.c b/platform/gizmondo/emu.c index b8b1068..1ba4d76 100644 --- a/platform/gizmondo/emu.c +++ b/platform/gizmondo/emu.c @@ -170,7 +170,7 @@ static void blit(const char *fps, const char *notice) vidConvCpyRGB565(localPal, Pico.cram, 0x40); } // a hack for VR - if (PicoRead16Hook == PicoSVPRead16) + if (PicoAHW & PAHW_SVP) memset32((int *)(PicoDraw2FB+328*8+328*223), 0xe0e0e0e0, 328); if (!(Pico.video.reg[12]&1)) lines_flags|=0x10000; if (currentConfig.EmuOpt&0x4000) diff --git a/platform/gp2x/Makefile b/platform/gp2x/Makefile index ef63199..817237a 100644 --- a/platform/gp2x/Makefile +++ b/platform/gp2x/Makefile @@ -64,8 +64,9 @@ OBJS += platform/common/emu.o platform/common/menu.o platform/common/fonts.o pla ifeq "$(amalgamate)" "1" OBJS += ../../picoAll.o else -OBJS += pico/area.o pico/cart.o pico/memory.o pico/misc.o pico/pico.o pico/sek.o pico/z80if.o \ - pico/videoport.o pico/draw2.o pico/draw.o pico/mode4.o pico/sms.o pico/patch.o pico/debug.o +OBJS += pico/area.o pico/cart.o pico/memory.o pico/pico.o pico/sek.o pico/z80if.o \ + pico/videoport.o pico/draw2.o pico/draw.o pico/mode4.o pico/sms.o \ + pico/misc.o pico/eeprom.o pico/patch.o pico/debug.o # Pico - CD OBJS += pico/cd/pico.o pico/cd/memory.o pico/cd/sek.o pico/cd/LC89510.o \ pico/cd/cd_sys.o pico/cd/cd_file.o pico/cd/cue.o pico/cd/gfx_cd.o \ diff --git a/platform/gp2x/emu.c b/platform/gp2x/emu.c index 77e33f2..97b28b6 100644 --- a/platform/gp2x/emu.c +++ b/platform/gp2x/emu.c @@ -327,7 +327,7 @@ void pemu_update_display(const char *fps, const char *notice) gp2x_video_setpalette(localPal, ret); } // a hack for VR - if (PicoRead16Hook == PicoSVPRead16) + if (PicoAHW & PAHW_SVP) memset32((int *)(PicoDraw2FB+328*8+328*223), 0xe0e0e0e0, 328); // do actual copy vidcpyM2(g_screen_ptr, PicoDraw2FB+328*8, diff --git a/platform/linux/Makefile b/platform/linux/Makefile index 2202db2..3ec56b9 100644 --- a/platform/linux/Makefile +++ b/platform/linux/Makefile @@ -32,9 +32,9 @@ OBJS += platform/gp2x/in_gp2x.o endif # Pico -OBJS += pico/area.o pico/cart.o pico/memory.o pico/misc.o pico/pico.o pico/sek.o \ +OBJS += pico/area.o pico/cart.o pico/memory.o pico/pico.o pico/sek.o \ pico/videoport.o pico/draw2.o pico/draw.o pico/z80if.o pico/patch.o \ - pico/mode4.o pico/sms.o pico/debug.o + pico/mode4.o pico/sms.o pico/misc.o pico/eeprom.o pico/debug.o # Pico - CD OBJS += pico/cd/pico.o pico/cd/memory.o pico/cd/sek.o pico/cd/LC89510.o \ pico/cd/cd_sys.o pico/cd/cd_file.o pico/cd/cue.o pico/cd/gfx_cd.o \ @@ -55,7 +55,7 @@ OBJS += unzip/unzip.o unzip/unzip_stream.o ifeq "$(use_musashi)" "1" DEFINES += EMU_M68K OBJS += cpu/musashi/m68kops.o cpu/musashi/m68kcpu.o -OBJS += cpu/musashi/m68kdasm.o +#OBJS += cpu/musashi/m68kdasm.o endif ifeq "$(use_fame)" "1" DEFINES += EMU_F68K diff --git a/platform/linux/gp2x.c b/platform/linux/gp2x.c index 27216ee..e1b8c97 100644 --- a/platform/linux/gp2x.c +++ b/platform/linux/gp2x.c @@ -425,6 +425,7 @@ void *gp2x_video_setpalette = gp2x_video_setpalette_; void *gp2x_video_RGB_setscaling = do_nothing; void *gp2x_video_wait_vsync = do_nothing; void *gp2x_set_cpuclk = do_nothing; +void *gp2x_read_battery = do_nothing; void *set_lcd_custom_rate = do_nothing; void *unset_lcd_custom_rate = do_nothing; void *set_lcd_gamma = do_nothing; diff --git a/platform/linux/port_config.h b/platform/linux/port_config.h index fc2e118..05a903c 100644 --- a/platform/linux/port_config.h +++ b/platform/linux/port_config.h @@ -26,7 +26,7 @@ #define SIMPLE_WRITE_SOUND 0 #define mix_32_to_16l_stereo_lvl mix_32_to_16l_stereo -#define EL_LOGMASK (EL_ANOMALY|EL_STATUS|EL_UIO|EL_IDLE)//|EL_VDPDMA|EL_HVCNT|EL_ASVDP)//|EL_SVP) +#define EL_LOGMASK (EL_ANOMALY|EL_STATUS|EL_UIO|EL_IDLE|EL_SRAMIO|EL_EEPROM)//|EL_VDPDMA|EL_HVCNT|EL_ASVDP)//|EL_SVP) // EL_VDPDMA|EL_ASVDP|EL_SR) // |EL_BUSREQ|EL_Z80BNK) //#define dprintf(f,...) printf("%05i:%03i: " f "\n",Pico.m.frame_count,Pico.m.scanline,##__VA_ARGS__) diff --git a/platform/pandora/emu.c b/platform/pandora/emu.c index 3fbda4a..af3474a 100644 --- a/platform/pandora/emu.c +++ b/platform/pandora/emu.c @@ -253,7 +253,7 @@ static void blit(const char *fps, const char *notice) // gp2x_video_setpalette(localPal, 0x40); } // a hack for VR - if (PicoRead16Hook == PicoSVPRead16) + if (PicoAHW & PAHW_SVP) memset32((int *)(PicoDraw2FB+328*8+328*223), 0xe0e0e0e0, 328); // do actual copy vidCpyM2((unsigned char *)g_screen_ptr+g_screen_width*8, PicoDraw2FB+328*8); -- 2.39.2