From: notaz Date: Wed, 2 Sep 2009 16:05:54 +0000 (+0000) Subject: new memory handling, but asm and mappers need update. X-Git-Tag: v1.85~281 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=af37bca858874b5cbd5ab126eaba1fad6ff7ab72;p=picodrive.git new memory handling, but asm and mappers need update. Some cleanup and magic bit removal as a bonus. git-svn-id: file:///home/notaz/opt/svn/PicoDrive@768 be3aeb3a-fb24-0410-a615-afba39da0efa --- diff --git a/pico/cart.c b/pico/cart.c index 8614a162..5c04fa40 100644 --- a/pico/cart.c +++ b/pico/cart.c @@ -572,13 +572,10 @@ int PicoCartInsert(unsigned char *rom,unsigned int romsize) PicoLoadStateHook = NULL; carthw_chunks = NULL; - PicoMemReset(); - if (!(PicoAHW & (PAHW_MCD|PAHW_SMS))) PicoCartDetect(); // setup correct memory map for loaded ROM - // call PicoMemReset again due to possible memmap change switch (PicoAHW) { default: elprintf(EL_STATUS|EL_ANOMALY, "starting in unknown hw configuration: %x", PicoAHW); @@ -588,7 +585,6 @@ int PicoCartInsert(unsigned char *rom,unsigned int romsize) case PAHW_PICO: PicoMemSetupPico(); break; case PAHW_SMS: PicoMemSetupMS(); break; } - PicoMemReset(); if (PicoAHW & PAHW_SMS) PicoPowerMS(); @@ -627,6 +623,12 @@ 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]; +} + /* * various cart-specific things, which can't be handled by generic code * (maybe I should start using CRC for this stuff?) @@ -634,28 +636,28 @@ static int name_cmp(const char *name) static void PicoCartDetect(void) { int sram_size = 0, csum; - Pico.m.sram_reg = 0; + Pico.m.sram_status = 0; - csum = PicoRead32(0x18c) & 0xffff; + csum = rom_read32(0x18c) & 0xffff; if (Pico.rom[0x1B1] == 'R' && Pico.rom[0x1B0] == 'A') { if (Pico.rom[0x1B2] & 0x40) { // EEPROM - SRam.start = PicoRead32(0x1B4) & ~1; // zero address is used for clock by some games - SRam.end = PicoRead32(0x1B8); + 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_reg |= 4; + Pico.m.sram_status |= SRS_EEPROM; } else { // normal SRAM - SRam.start = PicoRead32(0x1B4) & ~0xff; - SRam.end = PicoRead32(0x1B8) | 1; + 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_reg |= 0x10; // SRAM was detected + Pico.m.sram_status |= SRS_DETECTED; } if (sram_size <= 0) { @@ -713,7 +715,7 @@ static void PicoCartDetect(void) name_cmp("RINGS OF POWER") == 0) { SRam.start = SRam.end = 0x200000; - Pico.m.sram_reg = 0x14; + Pico.m.sram_status = SRS_DETECTED|SRS_EEPROM; SRam.eeprom_abits = 0; SRam.eeprom_bit_cl = 6; SRam.eeprom_bit_in = 7; @@ -725,7 +727,7 @@ static void PicoCartDetect(void) { SRam.start = 0x300000; SRam.end = 0x380001; - Pico.m.sram_reg = 0x14; + Pico.m.sram_status = SRS_DETECTED|SRS_EEPROM; SRam.eeprom_type = 2; SRam.eeprom_abits = 0; SRam.eeprom_bit_cl = 1; diff --git a/pico/cd/area.c b/pico/cd/area.c index 88fe8828..757d8fb9 100644 --- a/pico/cd/area.c +++ b/pico/cd/area.c @@ -273,11 +273,11 @@ readend: if (PicoAHW & PAHW_MCD) { /* after load events */ - if (Pico_mcd->s68k_regs[3]&4) // 1M mode? + if (Pico_mcd->s68k_regs[3] & 4) // 1M mode? wram_2M_to_1M(Pico_mcd->word_ram2M); - PicoMemResetCD(Pico_mcd->s68k_regs[3]); + PicoMemRemapCD(Pico_mcd->s68k_regs[3]); #ifdef _ASM_CD_MEMORY_C - if (Pico_mcd->s68k_regs[3]&4) + if (Pico_mcd->s68k_regs[3] & 4) PicoMemResetCDdecode(Pico_mcd->s68k_regs[3]); #endif if (!(Pico_mcd->s68k_regs[0x36] & 1) && (Pico_mcd->scd.Status_CDC & 1)) diff --git a/pico/cd/memory.c b/pico/cd/memory.c index 8110a2e1..a26cac7e 100644 --- a/pico/cd/memory.c +++ b/pico/cd/memory.c @@ -1,48 +1,29 @@ // Memory I/O handlers for Sega/Mega CD. -// Loosely based on Gens code. -// (c) Copyright 2007, Grazvydas "notaz" Ignotas - +// (c) Copyright 2007-2009, Grazvydas "notaz" Ignotas #include "../pico_int.h" - -#include "../sound/ym2612.h" -#include "../sound/sn76496.h" +#include "../memory.h" #include "gfx_cd.h" #include "pcm.h" -#ifndef UTYPES_DEFINED -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned int u32; -#define UTYPES_DEFINED -#endif - -#ifdef _MSC_VER -#define rdprintf -#define wrdprintf -#define r3printf -#else -//#define rdprintf dprintf -#define rdprintf(...) -//#define wrdprintf dprintf -#define wrdprintf(...) -//#define r3printf elprintf -#define r3printf(...) -#endif +unsigned long s68k_read8_map [0x1000000 >> M68K_MEM_SHIFT]; +unsigned long s68k_read16_map [0x1000000 >> M68K_MEM_SHIFT]; +unsigned long s68k_write8_map [0x1000000 >> M68K_MEM_SHIFT]; +unsigned long s68k_write16_map[0x1000000 >> M68K_MEM_SHIFT]; -#ifdef EMU_CORE_DEBUG -extern u32 lastread_a, lastread_d[16], lastwrite_cyc_d[16]; -extern int lrp_cyc, lwp_cyc; -#undef USE_POLL_DETECT -#endif +MAKE_68K_READ8(s68k_read8, s68k_read8_map) +MAKE_68K_READ16(s68k_read16, s68k_read16_map) +MAKE_68K_READ32(s68k_read32, s68k_read16_map) +MAKE_68K_WRITE8(s68k_write8, s68k_write8_map) +MAKE_68K_WRITE16(s68k_write16, s68k_write16_map) +MAKE_68K_WRITE32(s68k_write32, s68k_write16_map) // ----------------------------------------------------------------- // poller detection #define POLL_LIMIT 16 #define POLL_CYCLES 124 -// int m68k_poll_addr, m68k_poll_cnt; unsigned int s68k_poll_adclk, s68k_poll_cnt; #ifndef _ASM_CD_MEMORY_C @@ -50,7 +31,6 @@ static u32 m68k_reg_read16(u32 a) { u32 d=0; a &= 0x3e; - // dprintf("m68k_regs r%2i: [%02x] @%06x", realsize&~1, a+(realsize&1), SekPc); switch (a) { case 0: @@ -58,7 +38,7 @@ static u32 m68k_reg_read16(u32 a) goto end; case 2: d = (Pico_mcd->s68k_regs[a]<<8) | (Pico_mcd->s68k_regs[a+1]&0xc7); - r3printf(EL_STATUS, "m68k_regs r3: %02x @%06x", (u8)d, SekPc); + elprintf(EL_CDREG3, "m68k_regs r3: %02x @%06x", (u8)d, SekPc); goto end; case 4: d = Pico_mcd->s68k_regs[4]<<8; @@ -74,7 +54,7 @@ static u32 m68k_reg_read16(u32 a) goto end; case 0xC: d = Pico_mcd->m.timer_stopwatch >> 16; - dprintf("m68k stopwatch timer read (%04x)", d); + elprintf(EL_CDREGS, "m68k stopwatch timer read (%04x)", d); goto end; } @@ -97,8 +77,8 @@ static #endif void m68k_reg_write8(u32 a, u32 d) { + u32 dold; a &= 0x3f; - // dprintf("m68k_regs w%2i: [%02x] %02x @%06x", realsize, a, d, SekPc); switch (a) { case 0: @@ -113,20 +93,21 @@ void m68k_reg_write8(u32 a, u32 d) if ((Pico_mcd->m.state_flags&1) && (d&3)==1) { SekResetS68k(); // S68k comes out of RESET or BRQ state Pico_mcd->m.state_flags&=~1; - dprintf("m68k: resetting s68k, cycles=%i", SekCyclesLeft); + elprintf(EL_CDREGS, "m68k: resetting s68k, cycles=%i", SekCyclesLeft); } + if (!(d & 1)) + d |= 2; // verified: reset also gives bus + if ((d ^ Pico_mcd->m.busreq) & 2) + PicoMemRemapCD(Pico_mcd->s68k_regs[3]); Pico_mcd->m.busreq = d; return; case 2: - dprintf("m68k: prg wp=%02x", d); + elprintf(EL_CDREGS, "m68k: prg wp=%02x", d); Pico_mcd->s68k_regs[2] = d; // really use s68k side register return; - case 3: { - u32 dold = Pico_mcd->s68k_regs[3]&0x1f; - r3printf(EL_STATUS, "m68k_regs w3: %02x @%06x", (u8)d, SekPc); - d &= 0xc2; - if ((dold>>6) != ((d>>6)&3)) - dprintf("m68k: prg bank: %i -> %i", (Pico_mcd->s68k_regs[a]>>6), ((d>>6)&3)); + case 3: + dold = Pico_mcd->s68k_regs[3]; + elprintf(EL_CDREG3, "m68k_regs w3: %02x @%06x", (u8)d, SekPc); //if ((Pico_mcd->s68k_regs[3]&4) != (d&4)) dprintf("m68k: ram mode %i mbit", (d&4) ? 1 : 2); //if ((Pico_mcd->s68k_regs[3]&2) != (d&2)) dprintf("m68k: %s", (d&4) ? ((d&2) ? "word swap req" : "noop?") : // ((d&2) ? "word ram to s68k" : "word ram to m68k")); @@ -139,7 +120,11 @@ void m68k_reg_write8(u32 a, u32 d) SekEndRun(20+16+10+12+16); } } - Pico_mcd->s68k_regs[3] = d | dold; // really use s68k side register + Pico_mcd->s68k_regs[3] = (d & 0xc2) | (dold & 0x1f); + if ((d ^ dold) & 0xc0) { + elprintf(EL_CDREGS, "m68k: prg bank: %i -> %i", (Pico_mcd->s68k_regs[a]>>6), ((d>>6)&3)); + PicoMemRemapCD(Pico_mcd->s68k_regs[3]); + } #ifdef USE_POLL_DETECT if ((s68k_poll_adclk&0xfe) == 2 && s68k_poll_cnt > POLL_LIMIT) { SekSetStopS68k(0); s68k_poll_adclk = 0; @@ -147,13 +132,13 @@ void m68k_reg_write8(u32 a, u32 d) } #endif return; - } case 6: Pico_mcd->bios[0x72 + 1] = d; // simple hint vector changer return; case 7: Pico_mcd->bios[0x72] = d; - dprintf("hint vector set to %08x", PicoRead32(0x70)); + elprintf(EL_CDREGS, "hint vector set to %04x%04x", + ((u16 *)Pico_mcd->bios)[0x70/2], ((u16 *)Pico_mcd->bios)[0x72/2]); return; case 0xf: d = (d << 1) | ((d >> 7) & 1); // rol8 1 (special case) @@ -229,14 +214,12 @@ u32 s68k_reg_read16(u32 a) { u32 d=0; - // dprintf("s68k_regs r%2i: [%02x] @ %06x", realsize&~1, a+(realsize&1), SekPcS68k); - switch (a) { case 0: return ((Pico_mcd->s68k_regs[0]&3)<<8) | 1; // ver = 0, not in reset state case 2: d = (Pico_mcd->s68k_regs[2]<<8) | (Pico_mcd->s68k_regs[3]&0x1f); - r3printf(EL_STATUS, "s68k_regs r3: %02x @%06x", (u8)d, SekPcS68k); + elprintf(EL_CDREG3, "s68k_regs r3: %02x @%06x", (u8)d, SekPcS68k); return s68k_poll_detect(a, d); case 6: return CDC_Read_Reg(); @@ -244,10 +227,10 @@ u32 s68k_reg_read16(u32 a) return Read_CDC_Host(1); // Gens returns 0 here on byte reads case 0xC: d = Pico_mcd->m.timer_stopwatch >> 16; - dprintf("s68k stopwatch timer read (%04x)", d); + elprintf(EL_CDREGS, "s68k stopwatch timer read (%04x)", d); return d; case 0x30: - dprintf("s68k int3 timer read (%02x)", Pico_mcd->s68k_regs[31]); + elprintf(EL_CDREGS, "s68k int3 timer read (%02x)", Pico_mcd->s68k_regs[31]); return Pico_mcd->s68k_regs[31]; case 0x34: // fader return 0; // no busy bit @@ -278,42 +261,40 @@ static #endif void s68k_reg_write8(u32 a, u32 d) { - //dprintf("s68k_regs w%2i: [%02x] %02x @ %06x", realsize, a, d, SekPcS68k); - // Warning: d might have upper bits set switch (a) { case 2: return; // only m68k can change WP case 3: { int dold = Pico_mcd->s68k_regs[3]; - r3printf(EL_STATUS, "s68k_regs w3: %02x @%06x", (u8)d, SekPcS68k); + elprintf(EL_CDREG3, "s68k_regs w3: %02x @%06x", (u8)d, SekPcS68k); d &= 0x1d; - d |= dold&0xc2; - if (d&4) + d |= dold & 0xc2; + if (d & 4) { if ((d ^ dold) & 5) { d &= ~2; // in case of mode or bank change we clear DMNA (m68k req) bit - PicoMemResetCD(d); + PicoMemRemapCD(d); } #ifdef _ASM_CD_MEMORY_C if ((d ^ dold) & 0x1d) PicoMemResetCDdecode(d); #endif if (!(dold & 4)) { - r3printf(EL_STATUS, "wram mode 2M->1M"); + elprintf(EL_CDREG3, "wram mode 2M->1M"); wram_2M_to_1M(Pico_mcd->word_ram2M); } } else { if (dold & 4) { - r3printf(EL_STATUS, "wram mode 1M->2M"); + elprintf(EL_CDREG3, "wram mode 1M->2M"); if (!(d&1)) { // it didn't set the ret bit, which means it doesn't want to give WRAM to m68k d &= ~3; d |= (dold&1) ? 2 : 1; // then give it to the one which had bank0 in 1M mode } wram_1M_to_2M(Pico_mcd->word_ram2M); - PicoMemResetCD(d); + PicoMemRemapCD(d); } // s68k can only set RET, writing 0 has no effect else if ((dold ^ d) & d & 1) { // RET being set @@ -326,7 +307,7 @@ void s68k_reg_write8(u32 a, u32 d) break; } case 4: - dprintf("s68k CDC dest: %x", d&7); + elprintf(EL_CDREGS, "s68k CDC dest: %x", d&7); Pico_mcd->s68k_regs[4] = (Pico_mcd->s68k_regs[4]&0xC0) | (d&7); // CDC mode return; case 5: @@ -336,22 +317,22 @@ void s68k_reg_write8(u32 a, u32 d) CDC_Write_Reg(d); return; case 0xa: - dprintf("s68k set CDC dma addr"); + elprintf(EL_CDREGS, "s68k set CDC dma addr"); break; case 0xc: case 0xd: - dprintf("s68k set stopwatch timer"); + elprintf(EL_CDREGS, "s68k set stopwatch timer"); Pico_mcd->m.timer_stopwatch = 0; return; case 0xe: Pico_mcd->s68k_regs[0xf] = (d>>1) | (d<<7); // ror8 1, Gens note: Dragons lair return; case 0x31: - dprintf("s68k set int3 timer: %02x", d); + elprintf(EL_CDREGS, "s68k set int3 timer: %02x", d); Pico_mcd->m.timer_int3 = (d & 0xff) << 16; break; case 0x33: // IRQ mask - dprintf("s68k irq mask: %02x", d); + elprintf(EL_CDREGS, "s68k irq mask: %02x", d); if ((d&(1<<4)) && (Pico_mcd->s68k_regs[0x37]&4) && !(Pico_mcd->s68k_regs[0x33]&(1<<4))) { CDD_Export_Status(); } @@ -384,438 +365,141 @@ void s68k_reg_write8(u32 a, u32 d) Pico_mcd->s68k_regs[a] = (u8) d; } +// ----------------------------------------------------------------- +// Main 68k +// ----------------------------------------------------------------- + +#ifndef _ASM_CD_MEMORY_C +#include "cell_map.c" +#endif -static u32 OtherRead16End(u32 a, int realsize) +// WORD RAM, cell aranged area (220000 - 23ffff) +static u32 PicoReadM68k8_cell(u32 a) { - u32 d=0; + int bank = Pico_mcd->s68k_regs[3] & 1; + a = (a&3) | (cell_map(a >> 2) << 2); // cell arranged + return Pico_mcd->word_ram1M[bank][a ^ 1]; +} -#ifndef _ASM_CD_MEMORY_C - if ((a&0xffffc0)==0xa12000) { - d=m68k_reg_read16(a); - goto end; - } +static u32 PicoReadM68k16_cell(u32 a) +{ + int bank = Pico_mcd->s68k_regs[3] & 1; + a = (a&2) | (cell_map(a >> 2) << 2); + return *(u16 *)(Pico_mcd->word_ram1M[bank] + a); +} - if (a==0x400000) { - if (SRam.data != NULL) d=3; // 64k cart - goto end; - } +static void PicoWriteM68k8_cell(u32 a, u32 d) +{ + int bank = Pico_mcd->s68k_regs[3] & 1; + a = (a&3) | (cell_map(a >> 2) << 2); + Pico_mcd->word_ram1M[bank][a ^ 1] = d; +} - if ((a&0xfe0000)==0x600000) { - if (SRam.data != NULL) { - d=SRam.data[((a>>1)&0xffff)+0x2000]; - if (realsize == 8) d|=d<<8; - } - goto end; +static void PicoWriteM68k16_cell(u32 a, u32 d) +{ + int bank = Pico_mcd->s68k_regs[3] & 1; + a = (a&3) | (cell_map(a >> 2) << 2); + *(u16 *)(Pico_mcd->word_ram1M[bank] + a) = d; +} + +// RAM cart (40000 - 7fffff, optional) +static u32 PicoReadM68k8_ramc(u32 a) +{ + u32 d = 0; + if (a == 0x400001) { + if (SRam.data != NULL) + d = 3; // 64k cart + return d; } - if (a==0x7ffffe) { - d=Pico_mcd->m.bcram_reg; - goto end; + if ((a & 0xfe0000) == 0x600000) { + if (SRam.data != NULL) + d = SRam.data[((a >> 1) & 0xffff) + 0x2000]; + return d; } -#endif - elprintf(EL_UIO, "m68k FIXME: unusual r%i: %06x @%06x", realsize&~1, (a&0xfffffe)+(realsize&1), SekPc); + if (a == 0x7fffff) + return Pico_mcd->m.bcram_reg; -#ifndef _ASM_CD_MEMORY_C -end: -#endif + elprintf(EL_UIO, "m68k unmapped r8 [%06x] @%06x", a, SekPc); return d; } - -static void OtherWrite8End(u32 a, u32 d, int realsize) +static u32 PicoReadM68k16_ramc(u32 a) { -#ifndef _ASM_CD_MEMORY_C - if ((a&0xffffc0)==0xa12000) { m68k_reg_write8(a, d); return; } + elprintf(EL_ANOMALY, "ramcart r16: [%06x] @%06x", a, SekPcS68k); + return PicoReadM68k8_ramc(a + 1); +} - if ((a&0xfe0000)==0x600000) { - if (SRam.data != NULL && (Pico_mcd->m.bcram_reg&1)) { - SRam.data[((a>>1)&0xffff)+0x2000]=d; +static void PicoWriteM68k8_ramc(u32 a, u32 d) +{ + if ((a & 0xfe0000) == 0x600000) { + if (SRam.data != NULL && (Pico_mcd->m.bcram_reg & 1)) { + SRam.data[((a>>1) & 0xffff) + 0x2000] = d; SRam.changed = 1; } return; } - if (a==0x7fffff) { - Pico_mcd->m.bcram_reg=d; + if (a == 0x7fffff) { + Pico_mcd->m.bcram_reg = d; return; } -#endif - elprintf(EL_UIO, "m68k FIXME: strange w%i: [%06x], %08x @%06x", realsize, a&0xffffff, d, SekPc); + elprintf(EL_UIO, "m68k unmapped w8 [%06x] %02x @%06x", a, d & 0xff, SekPc); } -#ifndef _ASM_CD_MEMORY_C -#define _CD_MEMORY_C -#undef _ASM_MEMORY_C -#include "../memory_cmn.c" -#include "cell_map.c" -#endif - - -// ----------------------------------------------------------------- -// Read Rom and read Ram - -#ifdef _ASM_CD_MEMORY_C -u32 PicoReadM68k8(u32 a); -#else -u32 PicoReadM68k8(u32 a) +static void PicoWriteM68k16_ramc(u32 a, u32 d) { - u32 d=0; - - a&=0xffffff; - - switch (a >> 17) - { - case 0x00>>1: // BIOS: 000000 - 020000 - d = *(u8 *)(Pico_mcd->bios+(a^1)); - break; - case 0x02>>1: // prg RAM - if ((Pico_mcd->m.busreq&3)!=1) { - u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6]; - d = *(prg_bank+((a^1)&0x1ffff)); - } - break; - case 0x20>>1: // word RAM: 200000 - 220000 - wrdprintf("m68k_wram r8: [%06x] @%06x", a, SekPc); - a &= 0x1ffff; - if (Pico_mcd->s68k_regs[3]&4) { // 1M mode? - int bank = Pico_mcd->s68k_regs[3]&1; - d = Pico_mcd->word_ram1M[bank][a^1]; - } else { - // allow access in any mode, like Gens does - d = Pico_mcd->word_ram2M[a^1]; - } - wrdprintf("ret = %02x", (u8)d); - break; - case 0x22>>1: // word RAM: 220000 - 240000 - wrdprintf("m68k_wram r8: [%06x] @%06x", a, SekPc); - if (Pico_mcd->s68k_regs[3]&4) { // 1M mode? - int bank = Pico_mcd->s68k_regs[3]&1; - a = (a&3) | (cell_map(a >> 2) << 2); // cell arranged - d = Pico_mcd->word_ram1M[bank][a^1]; - } else { - // allow access in any mode, like Gens does - d = Pico_mcd->word_ram2M[(a^1)&0x3ffff]; - } - wrdprintf("ret = %02x", (u8)d); - break; - case 0xc0>>1: case 0xc2>>1: case 0xc4>>1: case 0xc6>>1: - case 0xc8>>1: case 0xca>>1: case 0xcc>>1: case 0xce>>1: - case 0xd0>>1: case 0xd2>>1: case 0xd4>>1: case 0xd6>>1: - case 0xd8>>1: case 0xda>>1: case 0xdc>>1: case 0xde>>1: - // VDP - if ((a&0xe700e0)==0xc00000) - d=PicoVideoRead8(a); - break; - case 0xe0>>1: case 0xe2>>1: case 0xe4>>1: case 0xe6>>1: - case 0xe8>>1: case 0xea>>1: case 0xec>>1: case 0xee>>1: - case 0xf0>>1: case 0xf2>>1: case 0xf4>>1: case 0xf6>>1: - case 0xf8>>1: case 0xfa>>1: case 0xfc>>1: case 0xfe>>1: - // RAM: - d = *(u8 *)(Pico.ram+((a^1)&0xffff)); - break; - default: - if ((a&0xff4000)==0xa00000) { d=z80Read8(a); break; } // Z80 Ram - if ((a&0xffffc0)==0xa12000) - rdprintf("m68k_regs r8: [%02x] @%06x", a&0x3f, SekPc); - - d=OtherRead16(a&~1, 8|(a&1)); if ((a&1)==0) d>>=8; - - if ((a&0xffffc0)==0xa12000) - rdprintf("ret = %02x", (u8)d); - break; - } - - - elprintf(EL_IO, "r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc); -#ifdef EMU_CORE_DEBUG - if (a>=Pico.romsize) { - lastread_a = a; - lastread_d[lrp_cyc++&15] = d; - } -#endif - return d; + elprintf(EL_ANOMALY, "ramcart w16: [%06x] %04x @%06x", a, d, SekPcS68k); + PicoWriteM68k8_ramc(a + 1, d); } -#endif - -#ifdef _ASM_CD_MEMORY_C -u32 PicoReadM68k16(u32 a); -#else -static u32 PicoReadM68k16(u32 a) +// IO/control/cd registers (a10000 - ...) +static u32 PicoReadM68k8_io(u32 a) { - u32 d=0; - - a&=0xfffffe; - - switch (a >> 17) - { - case 0x00>>1: // BIOS: 000000 - 020000 - d = *(u16 *)(Pico_mcd->bios+a); - break; - case 0x02>>1: // prg RAM - if ((Pico_mcd->m.busreq&3)!=1) { - u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6]; - wrdprintf("m68k_prgram r16: [%i,%06x] @%06x", Pico_mcd->s68k_regs[3]>>6, a, SekPc); - d = *(u16 *)(prg_bank+(a&0x1fffe)); - wrdprintf("ret = %04x", d); - } - break; - case 0x20>>1: // word RAM: 200000 - 220000 - wrdprintf("m68k_wram r16: [%06x] @%06x", a, SekPc); - a &= 0x1fffe; - if (Pico_mcd->s68k_regs[3]&4) { // 1M mode? - int bank = Pico_mcd->s68k_regs[3]&1; - d = *(u16 *)(Pico_mcd->word_ram1M[bank]+a); - } else { - // allow access in any mode, like Gens does - d = *(u16 *)(Pico_mcd->word_ram2M+a); - } - wrdprintf("ret = %04x", d); - break; - case 0x22>>1: // word RAM: 220000 - 240000 - wrdprintf("m68k_wram r16: [%06x] @%06x", a, SekPc); - if (Pico_mcd->s68k_regs[3]&4) { // 1M mode? - int bank = Pico_mcd->s68k_regs[3]&1; - a = (a&2) | (cell_map(a >> 2) << 2); // cell arranged - d = *(u16 *)(Pico_mcd->word_ram1M[bank]+a); - } else { - // allow access in any mode, like Gens does - d = *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); - } - wrdprintf("ret = %04x", d); - break; - case 0xc0>>1: case 0xc2>>1: case 0xc4>>1: case 0xc6>>1: - case 0xc8>>1: case 0xca>>1: case 0xcc>>1: case 0xce>>1: - case 0xd0>>1: case 0xd2>>1: case 0xd4>>1: case 0xd6>>1: - case 0xd8>>1: case 0xda>>1: case 0xdc>>1: case 0xde>>1: - // VDP - if ((a&0xe700e0)==0xc00000) - d=PicoVideoRead(a); - break; - case 0xe0>>1: case 0xe2>>1: case 0xe4>>1: case 0xe6>>1: - case 0xe8>>1: case 0xea>>1: case 0xec>>1: case 0xee>>1: - case 0xf0>>1: case 0xf2>>1: case 0xf4>>1: case 0xf6>>1: - case 0xf8>>1: case 0xfa>>1: case 0xfc>>1: case 0xfe>>1: - // RAM: - d=*(u16 *)(Pico.ram+(a&0xfffe)); - break; - default: - if ((a&0xffffc0)==0xa12000) - rdprintf("m68k_regs r16: [%02x] @%06x", a&0x3f, SekPc); - - d = OtherRead16(a, 16); - - if ((a&0xffffc0)==0xa12000) - rdprintf("ret = %04x", d); - break; - } - - - elprintf(EL_IO, "r16: %06x, %04x @%06x", a&0xffffff, d, SekPc); -#ifdef EMU_CORE_DEBUG - if (a>=Pico.romsize) { - lastread_a = a; - lastread_d[lrp_cyc++&15] = d; - } -#endif - return d; + u32 d; + if ((a & 0xff00) == 0x2000) { // a12000 - a120ff + d = m68k_reg_read16(a); // TODO: m68k_reg_read8 + if (!(a & 1)) + d >>= 8; + d &= 0xff; + elprintf(EL_CDREGS, "m68k_regs r8: [%02x] %02x @%06x", a & 0x3f, d, SekPc); + return d; + } + + // fallback to default MD handler + return PicoRead8_io(a); } -#endif - -#ifdef _ASM_CD_MEMORY_C -u32 PicoReadM68k32(u32 a); -#else -static u32 PicoReadM68k32(u32 a) +static u32 PicoReadM68k16_io(u32 a) { - u32 d=0; - - a&=0xfffffe; - - switch (a >> 17) - { - case 0x00>>1: { // BIOS: 000000 - 020000 - u16 *pm=(u16 *)(Pico_mcd->bios+a); - d = (pm[0]<<16)|pm[1]; - break; - } - case 0x02>>1: // prg RAM - if ((Pico_mcd->m.busreq&3)!=1) { - u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6]; - u16 *pm=(u16 *)(prg_bank+(a&0x1fffe)); - d = (pm[0]<<16)|pm[1]; - } - break; - case 0x20>>1: // word RAM: 200000 - 220000 - wrdprintf("m68k_wram r32: [%06x] @%06x", a, SekPc); - a&=0x1fffe; - if (Pico_mcd->s68k_regs[3]&4) { // 1M mode? - int bank = Pico_mcd->s68k_regs[3]&1; - u16 *pm=(u16 *)(Pico_mcd->word_ram1M[bank]+a); - d = (pm[0]<<16)|pm[1]; - } else { - // allow access in any mode, like Gens does - u16 *pm=(u16 *)(Pico_mcd->word_ram2M+a); - d = (pm[0]<<16)|pm[1]; - } - wrdprintf("ret = %08x", d); - break; - case 0x22>>1: // word RAM: 220000 - 240000 - wrdprintf("m68k_wram r32: [%06x] @%06x", a, SekPc); - if (Pico_mcd->s68k_regs[3]&4) { // 1M mode, cell arranged? - u32 a1, a2; - int bank = Pico_mcd->s68k_regs[3]&1; - a1 = (a&2) | (cell_map(a >> 2) << 2); - if (a&2) a2 = cell_map((a+2) >> 2) << 2; - else a2 = a1 + 2; - d = *(u16 *)(Pico_mcd->word_ram1M[bank]+a1) << 16; - d |= *(u16 *)(Pico_mcd->word_ram1M[bank]+a2); - } else { - // allow access in any mode, like Gens does - u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); - d = (pm[0]<<16)|pm[1]; - } - wrdprintf("ret = %08x", d); - break; - case 0xc0>>1: case 0xc2>>1: case 0xc4>>1: case 0xc6>>1: - case 0xc8>>1: case 0xca>>1: case 0xcc>>1: case 0xce>>1: - case 0xd0>>1: case 0xd2>>1: case 0xd4>>1: case 0xd6>>1: - case 0xd8>>1: case 0xda>>1: case 0xdc>>1: case 0xde>>1: - // VDP - d = (PicoVideoRead(a)<<16)|PicoVideoRead(a+2); - break; - case 0xe0>>1: case 0xe2>>1: case 0xe4>>1: case 0xe6>>1: - case 0xe8>>1: case 0xea>>1: case 0xec>>1: case 0xee>>1: - case 0xf0>>1: case 0xf2>>1: case 0xf4>>1: case 0xf6>>1: - case 0xf8>>1: case 0xfa>>1: case 0xfc>>1: case 0xfe>>1: { - // RAM: - u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); - d = (pm[0]<<16)|pm[1]; - break; - } - default: - if ((a&0xffffc0)==0xa12000) - rdprintf("m68k_regs r32: [%02x] @%06x", a&0x3f, SekPc); - - d = (OtherRead16(a, 32)<<16)|OtherRead16(a+2, 32); - - if ((a&0xffffc0)==0xa12000) - rdprintf("ret = %08x", d); - break; + u32 d; + if ((a & 0xff00) == 0x2000) { + d = m68k_reg_read16(a); + elprintf(EL_CDREGS, "m68k_regs r16: [%02x] %04x @%06x", a & 0x3f, d, SekPc); + return d; } - - elprintf(EL_IO, "r32: %06x, %08x @%06x", a&0xffffff, d, SekPc); -#ifdef EMU_CORE_DEBUG - if (a>=Pico.romsize) { - lastread_a = a; - lastread_d[lrp_cyc++&15] = d; - } -#endif - return d; + return PicoRead16_io(a); } -#endif - -// ----------------------------------------------------------------- - -#ifdef _ASM_CD_MEMORY_C -void PicoWriteM68k8(u32 a,u8 d); -#else -void PicoWriteM68k8(u32 a,u8 d) +static void PicoWriteM68k8_io(u32 a, u32 d) { - elprintf(EL_IO, "w8 : %06x, %02x @%06x", a&0xffffff, d, SekPc); -#ifdef EMU_CORE_DEBUG - lastwrite_cyc_d[lwp_cyc++&15] = d; -#endif - - if ((a&0xe00000)==0xe00000) { // Ram - *(u8 *)(Pico.ram+((a^1)&0xffff)) = d; - return; - } - - // prg RAM - if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) { - u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6]; - *(u8 *)(prg_bank+((a^1)&0x1ffff))=d; - return; - } - - a&=0xffffff; - - // word RAM - if ((a&0xfc0000)==0x200000) { - wrdprintf("m68k_wram w8: [%06x] %02x @%06x", a, d, SekPc); - if (Pico_mcd->s68k_regs[3]&4) { // 1M mode? - int bank = Pico_mcd->s68k_regs[3]&1; - if (a >= 0x220000) - a = (a&3) | (cell_map(a >> 2) << 2); // cell arranged - else a &= 0x1ffff; - *(u8 *)(Pico_mcd->word_ram1M[bank]+(a^1))=d; - } else { - // allow access in any mode, like Gens does - *(u8 *)(Pico_mcd->word_ram2M+((a^1)&0x3ffff))=d; - } - return; - } - - if ((a&0xffffc0)==0xa12000) { - rdprintf("m68k_regs w8: [%02x] %02x @%06x", a&0x3f, d, SekPc); + if ((a & 0xff00) == 0x2000) { // a12000 - a120ff + elprintf(EL_CDREGS, "m68k_regs w8: [%02x] %02x @%06x", a&0x3f, d, SekPc); m68k_reg_write8(a, d); return; } - OtherWrite8(a,d); + PicoWrite16_io(a, d); } -#endif - -#ifdef _ASM_CD_MEMORY_C -void PicoWriteM68k16(u32 a,u16 d); -#else -static void PicoWriteM68k16(u32 a,u16 d) +static void PicoWriteM68k16_io(u32 a, u32 d) { - elprintf(EL_IO, "w16: %06x, %04x", a&0xffffff, d); -#ifdef EMU_CORE_DEBUG - lastwrite_cyc_d[lwp_cyc++&15] = d; -#endif - - if ((a&0xe00000)==0xe00000) { // Ram - *(u16 *)(Pico.ram+(a&0xfffe))=d; - return; - } - - // prg RAM - if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) { - u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6]; - wrdprintf("m68k_prgram w16: [%i,%06x] %04x @%06x", Pico_mcd->s68k_regs[3]>>6, a, d, SekPc); - *(u16 *)(prg_bank+(a&0x1fffe))=d; - return; - } - - a&=0xfffffe; - - // word RAM - if ((a&0xfc0000)==0x200000) { - wrdprintf("m68k_wram w16: [%06x] %04x @%06x", a, d, SekPc); - if (Pico_mcd->s68k_regs[3]&4) { // 1M mode? - int bank = Pico_mcd->s68k_regs[3]&1; - if (a >= 0x220000) - a = (a&2) | (cell_map(a >> 2) << 2); // cell arranged - else a &= 0x1fffe; - *(u16 *)(Pico_mcd->word_ram1M[bank]+a)=d; - } else { - // allow access in any mode, like Gens does - *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe))=d; - } - return; - } - - // regs - if ((a&0xffffc0)==0xa12000) { - rdprintf("m68k_regs w16: [%02x] %04x @%06x", a&0x3f, d, SekPc); + if ((a & 0xff00) == 0x2000) { // a12000 - a120ff + elprintf(EL_CDREGS, "m68k_regs w16: [%02x] %04x @%06x", a&0x3f, d, SekPc); +/* TODO FIXME? if (a == 0xe) { // special case, 2 byte writes would be handled differently Pico_mcd->s68k_regs[0xe] = d >> 8; #ifdef USE_POLL_DETECT @@ -826,434 +510,95 @@ static void PicoWriteM68k16(u32 a,u16 d) #endif return; } - m68k_reg_write8(a, d>>8); - m68k_reg_write8(a+1,d&0xff); - return; - } - - // VDP - if ((a&0xe700e0)==0xc00000) { - PicoVideoWrite(a,(u16)d); - return; - } - - OtherWrite16(a,d); -} -#endif - - -#ifdef _ASM_CD_MEMORY_C -void PicoWriteM68k32(u32 a,u32 d); -#else -static void PicoWriteM68k32(u32 a,u32 d) -{ - elprintf(EL_IO, "w32: %06x, %08x", a&0xffffff, d); -#ifdef EMU_CORE_DEBUG - lastwrite_cyc_d[lwp_cyc++&15] = d; -#endif - - if ((a&0xe00000)==0xe00000) - { - // Ram: - u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); - pm[0]=(u16)(d>>16); pm[1]=(u16)d; - return; - } - - // prg RAM - if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) { - u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6]; - u16 *pm=(u16 *)(prg_bank+(a&0x1fffe)); - pm[0]=(u16)(d>>16); pm[1]=(u16)d; - return; - } - - a&=0xfffffe; - - // word RAM - if ((a&0xfc0000)==0x200000) { - if (d != 0) // don't log clears - wrdprintf("m68k_wram w32: [%06x] %08x @%06x", a, d, SekPc); - if (Pico_mcd->s68k_regs[3]&4) { // 1M mode? - int bank = Pico_mcd->s68k_regs[3]&1; - if (a >= 0x220000) { // cell arranged - u32 a1, a2; - a1 = (a&2) | (cell_map(a >> 2) << 2); - if (a&2) a2 = cell_map((a+2) >> 2) << 2; - else a2 = a1 + 2; - *(u16 *)(Pico_mcd->word_ram1M[bank]+a1) = d >> 16; - *(u16 *)(Pico_mcd->word_ram1M[bank]+a2) = d; - } else { - u16 *pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe)); - pm[0]=(u16)(d>>16); pm[1]=(u16)d; - } - } else { - // allow access in any mode, like Gens does - u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); - pm[0]=(u16)(d>>16); pm[1]=(u16)d; - } +*/ + m68k_reg_write8(a, d >> 8); + m68k_reg_write8(a + 1, d & 0xff); return; } - if ((a&0xffffc0)==0xa12000) { - rdprintf("m68k_regs w32: [%02x] %08x @%06x", a&0x3f, d, SekPc); - if ((a&0x3e) == 0xe) dprintf("m68k FIXME: w32 [%02x]", a&0x3f); - } - - // VDP - if ((a&0xe700e0)==0xc00000) - { - PicoVideoWrite(a, (u16)(d>>16)); - PicoVideoWrite(a+2,(u16)d); - return; - } - - OtherWrite16(a, (u16)(d>>16)); - OtherWrite16(a+2,(u16)d); + PicoWrite16_io(a, d); } -#endif - // ----------------------------------------------------------------- -// S68k +// Sub 68k // ----------------------------------------------------------------- -#ifdef _ASM_CD_MEMORY_C -u32 PicoReadS68k8(u32 a); -#else -static u32 PicoReadS68k8(u32 a) +static u32 s68k_unmapped_read8(u32 a) { - u32 d=0; - -#ifdef EMU_CORE_DEBUG - u32 ab=a&0xfffffe; -#endif - a&=0xffffff; - - // prg RAM - if (a < 0x80000) { - d = *(Pico_mcd->prg_ram+(a^1)); - goto end; - } - - // regs - if ((a&0xfffe00) == 0xff8000) { - a &= 0x1ff; - rdprintf("s68k_regs r8: [%02x] @ %06x", a, SekPcS68k); - if (a >= 0x0e && a < 0x30) { - d = Pico_mcd->s68k_regs[a]; - s68k_poll_detect(a, d); - rdprintf("ret = %02x", (u8)d); - goto end; - } - else if (a >= 0x58 && a < 0x68) - d = gfx_cd_read(a&~1); - else d = s68k_reg_read16(a&~1); - if ((a&1)==0) d>>=8; - rdprintf("ret = %02x", (u8)d); - goto end; - } - - // word RAM (2M area) - if ((a&0xfc0000)==0x080000) { // 080000-0bffff - // test: batman returns - wrdprintf("s68k_wram2M r8: [%06x] @%06x", a, SekPcS68k); - if (Pico_mcd->s68k_regs[3]&4) { // 1M decode mode? - int bank = (Pico_mcd->s68k_regs[3]&1)^1; - d = Pico_mcd->word_ram1M[bank][((a>>1)^1)&0x1ffff]; - if (a&1) d &= 0x0f; - else d >>= 4; - } else { - // allow access in any mode, like Gens does - d = Pico_mcd->word_ram2M[(a^1)&0x3ffff]; - } - wrdprintf("ret = %02x", (u8)d); - goto end; - } - - // word RAM (1M area) - if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff - int bank; - wrdprintf("s68k_wram1M r8: [%06x] @%06x", a, SekPcS68k); -// if (!(Pico_mcd->s68k_regs[3]&4)) -// dprintf("s68k_wram1M FIXME: wrong mode"); - bank = (Pico_mcd->s68k_regs[3]&1)^1; - d = Pico_mcd->word_ram1M[bank][(a^1)&0x1ffff]; - wrdprintf("ret = %02x", (u8)d); - goto end; - } - - // PCM - if ((a&0xff8000)==0xff0000) { - elprintf(EL_IO, "s68k_pcm r8: [%06x] @%06x", a, SekPcS68k); - a &= 0x7fff; - if (a >= 0x2000) - d = Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a>>1)&0xfff]; - else if (a >= 0x20) { - a &= 0x1e; - d = Pico_mcd->pcm.ch[a>>2].addr >> PCM_STEP_SHIFT; - if (a & 2) d >>= 8; - } - elprintf(EL_IO, "ret = %02x", (u8)d); - goto end; - } - - // bram - if ((a&0xff0000)==0xfe0000) { - d = Pico_mcd->bram[(a>>1)&0x1fff]; - goto end; - } - - elprintf(EL_UIO, "s68k r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPcS68k); - - end: - - elprintf(EL_IO, "s68k r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPcS68k); -#ifdef EMU_CORE_DEBUG - lastread_a = ab; - lastread_d[lrp_cyc++&15] = d; -#endif - return d; + elprintf(EL_UIO, "s68k unmapped r8 [%06x] @%06x", a, SekPc); + return 0; } -#endif - -#ifdef _ASM_CD_MEMORY_C -u32 PicoReadS68k16(u32 a); -#else -static u32 PicoReadS68k16(u32 a) +static u32 s68k_unmapped_read16(u32 a) { - u32 d=0; - -#ifdef EMU_CORE_DEBUG - u32 ab=a&0xfffffe; -#endif - a&=0xfffffe; - - // prg RAM - if (a < 0x80000) { - wrdprintf("s68k_prgram r16: [%06x] @%06x", a, SekPcS68k); - d = *(u16 *)(Pico_mcd->prg_ram+a); - wrdprintf("ret = %04x", d); - goto end; - } - - // regs - if ((a&0xfffe00) == 0xff8000) { - a &= 0x1fe; - rdprintf("s68k_regs r16: [%02x] @ %06x", a, SekPcS68k); - if (a >= 0x58 && a < 0x68) - d = gfx_cd_read(a); - else d = s68k_reg_read16(a); - rdprintf("ret = %04x", d); - goto end; - } - - // word RAM (2M area) - if ((a&0xfc0000)==0x080000) { // 080000-0bffff - wrdprintf("s68k_wram2M r16: [%06x] @%06x", a, SekPcS68k); - if (Pico_mcd->s68k_regs[3]&4) { // 1M decode mode? - int bank = (Pico_mcd->s68k_regs[3]&1)^1; - d = Pico_mcd->word_ram1M[bank][((a>>1)^1)&0x1ffff]; - d |= d << 4; d &= ~0xf0; - } else { - // allow access in any mode, like Gens does - d = *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); - } - wrdprintf("ret = %04x", d); - goto end; - } - - // word RAM (1M area) - if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff - int bank; - wrdprintf("s68k_wram1M r16: [%06x] @%06x", a, SekPcS68k); -// if (!(Pico_mcd->s68k_regs[3]&4)) -// dprintf("s68k_wram1M FIXME: wrong mode"); - bank = (Pico_mcd->s68k_regs[3]&1)^1; - d = *(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe)); - wrdprintf("ret = %04x", d); - goto end; - } - - // bram - if ((a&0xff0000)==0xfe0000) { - dprintf("FIXME: s68k_bram r16: [%06x] @%06x", a, SekPcS68k); - a = (a>>1)&0x1fff; - d = Pico_mcd->bram[a++]; // Gens does little endian here, and so do we.. - d|= Pico_mcd->bram[a++] << 8; // This is most likely wrong - dprintf("ret = %04x", d); - goto end; - } - - // PCM - if ((a&0xff8000)==0xff0000) { - dprintf("FIXME: s68k_pcm r16: [%06x] @%06x", a, SekPcS68k); - a &= 0x7fff; - if (a >= 0x2000) - d = Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a>>1)&0xfff]; - else if (a >= 0x20) { - a &= 0x1e; - d = Pico_mcd->pcm.ch[a>>2].addr >> PCM_STEP_SHIFT; - if (a & 2) d >>= 8; - } - dprintf("ret = %04x", d); - goto end; - } + elprintf(EL_UIO, "s68k unmapped r16 [%06x] @%06x", a, SekPc); + return 0; +} - elprintf(EL_UIO, "s68k r16: %06x, %04x @%06x", a&0xffffff, d, SekPcS68k); +static void s68k_unmapped_write8(u32 a, u32 d) +{ + elprintf(EL_UIO, "s68k unmapped w8 [%06x] %02x @%06x", a, d & 0xff, SekPc); +} - end: +static void s68k_unmapped_write16(u32 a, u32 d) +{ + elprintf(EL_UIO, "s68k unmapped w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc); +} - elprintf(EL_IO, "s68k r16: %06x, %04x @%06x", a&0xffffff, d, SekPcS68k); -#ifdef EMU_CORE_DEBUG - lastread_a = ab; - lastread_d[lrp_cyc++&15] = d; -#endif +// decode (080000 - 0bffff, in 1M mode) +static u32 PicoReadS68k8_dec(u32 a) +{ + u32 d, bank; + bank = (Pico_mcd->s68k_regs[3] & 1) ^ 1; + d = Pico_mcd->word_ram1M[bank][((a >> 1) ^ 1) & 0x1ffff]; + if (a & 1) + d &= 0x0f; + else + d >>= 4; return d; } -#endif - -#ifdef _ASM_CD_MEMORY_C -u32 PicoReadS68k32(u32 a); -#else -static u32 PicoReadS68k32(u32 a) +static u32 PicoReadS68k16_dec(u32 a) { - u32 d=0; - -#ifdef EMU_CORE_DEBUG - u32 ab=a&0xfffffe; -#endif - a&=0xfffffe; - - // prg RAM - if (a < 0x80000) { - u16 *pm=(u16 *)(Pico_mcd->prg_ram+a); - d = (pm[0]<<16)|pm[1]; - goto end; - } - - // regs - if ((a&0xfffe00) == 0xff8000) { - a &= 0x1fe; - rdprintf("s68k_regs r32: [%02x] @ %06x", a, SekPcS68k); - if (a >= 0x58 && a < 0x68) - d = (gfx_cd_read(a)<<16)|gfx_cd_read(a+2); - else d = (s68k_reg_read16(a)<<16)|s68k_reg_read16(a+2); - rdprintf("ret = %08x", d); - goto end; - } - - // word RAM (2M area) - if ((a&0xfc0000)==0x080000) { // 080000-0bffff - wrdprintf("s68k_wram2M r32: [%06x] @%06x", a, SekPcS68k); - if (Pico_mcd->s68k_regs[3]&4) { // 1M decode mode? - int bank = (Pico_mcd->s68k_regs[3]&1)^1; - a >>= 1; - d = Pico_mcd->word_ram1M[bank][((a+0)^1)&0x1ffff] << 16; - d |= Pico_mcd->word_ram1M[bank][((a+1)^1)&0x1ffff]; - d |= d << 4; d &= 0x0f0f0f0f; - } else { - // allow access in any mode, like Gens does - u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); d = (pm[0]<<16)|pm[1]; - } - wrdprintf("ret = %08x", d); - goto end; - } - - // word RAM (1M area) - if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff - int bank; - u16 *pm; - wrdprintf("s68k_wram1M r32: [%06x] @%06x", a, SekPcS68k); -// if (!(Pico_mcd->s68k_regs[3]&4)) -// dprintf("s68k_wram1M FIXME: wrong mode"); - bank = (Pico_mcd->s68k_regs[3]&1)^1; - pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe)); d = (pm[0]<<16)|pm[1]; - wrdprintf("ret = %08x", d); - goto end; - } - - // PCM - if ((a&0xff8000)==0xff0000) { - dprintf("s68k_pcm r32: [%06x] @%06x", a, SekPcS68k); - a &= 0x7fff; - if (a >= 0x2000) { - a >>= 1; - d = Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][a&0xfff] << 16; - d |= Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a+1)&0xfff]; - } else if (a >= 0x20) { - a &= 0x1e; - if (a & 2) { - a >>= 2; - d = (Pico_mcd->pcm.ch[a].addr >> (PCM_STEP_SHIFT-8)) & 0xff0000; - d |= (Pico_mcd->pcm.ch[(a+1)&7].addr >> PCM_STEP_SHIFT) & 0xff; - } else { - d = Pico_mcd->pcm.ch[a>>2].addr >> PCM_STEP_SHIFT; - d = ((d<<16)&0xff0000) | ((d>>8)&0xff); // PCM chip is LE - } - } - dprintf("ret = %08x", d); - goto end; - } - - // bram - if ((a&0xff0000)==0xfe0000) { - dprintf("FIXME: s68k_bram r32: [%06x] @%06x", a, SekPcS68k); - a = (a>>1)&0x1fff; - d = Pico_mcd->bram[a++] << 16; // middle endian? TODO: verify against Fusion.. - d|= Pico_mcd->bram[a++] << 24; - d|= Pico_mcd->bram[a++]; - d|= Pico_mcd->bram[a++] << 8; - dprintf("ret = %08x", d); - goto end; - } - - elprintf(EL_UIO, "s68k r32: %06x, %08x @%06x", a&0xffffff, d, SekPcS68k); - - end: - - elprintf(EL_IO, "s68k r32: %06x, %08x @%06x", a&0xffffff, d, SekPcS68k); -#ifdef EMU_CORE_DEBUG - if (ab > 0x78) { // not vectors and stuff - lastread_a = ab; - lastread_d[lrp_cyc++&15] = d; - } -#endif + u32 d, bank; + bank = (Pico_mcd->s68k_regs[3] & 1) ^ 1; + d = Pico_mcd->word_ram1M[bank][((a >> 1) ^ 1) & 0x1ffff]; + d |= d << 4; + d &= ~0xf0; return d; } -#endif - -#ifndef _ASM_CD_MEMORY_C /* check: jaguar xj 220 (draws entire world using decode) */ -static void decode_write8(u32 a, u8 d, int r3) +static void PicoWriteS68k8_dec(u32 a, u32 d) { - u8 *pd = Pico_mcd->word_ram1M[(r3 & 1)^1] + (((a>>1)^1)&0x1ffff); - u8 oldmask = (a&1) ? 0xf0 : 0x0f; + u8 r3 = Pico_mcd->s68k_regs[3]; + u8 *pd = &Pico_mcd->word_ram1M[(r3 & 1) ^ 1][((a >> 1) ^ 1) & 0x1ffff]; + u8 oldmask = (a & 1) ? 0xf0 : 0x0f; r3 &= 0x18; d &= 0x0f; - if (!(a&1)) d <<= 4; + if (!(a & 1)) + d <<= 4; if (r3 == 8) { - if ((!(*pd & (~oldmask))) && d) goto do_it; + if ((!(*pd & (~oldmask))) && d) + goto do_it; } else if (r3 > 8) { - if (d) goto do_it; - } else { + if (d) + goto do_it; + } else goto do_it; - } return; + do_it: *pd = d | (*pd & oldmask); } - -static void decode_write16(u32 a, u16 d, int r3) +static void PicoWriteS68k16_dec(u32 a, u32 d) { - u8 *pd = Pico_mcd->word_ram1M[(r3 & 1)^1] + (((a>>1)^1)&0x1ffff); + u8 r3 = Pico_mcd->s68k_regs[3]; + u8 *pd = &Pico_mcd->word_ram1M[(r3 & 1) ^ 1][((a >> 1) ^ 1) & 0x1ffff]; //if ((a & 0x3ffff) < 0x28000) return; @@ -1275,279 +620,173 @@ static void decode_write16(u32 a, u16 d, int r3) *pd = d; } } -#endif -// ----------------------------------------------------------------- +// backup RAM (fe0000 - feffff) +static u32 PicoReadS68k8_bram(u32 a) +{ + return Pico_mcd->bram[(a>>1)&0x1fff]; +} -#ifdef _ASM_CD_MEMORY_C -void PicoWriteS68k8(u32 a,u8 d); -#else -static void PicoWriteS68k8(u32 a,u8 d) +static u32 PicoReadS68k16_bram(u32 a) { - elprintf(EL_IO, "s68k w8 : %06x, %02x @%06x", a&0xffffff, d, SekPcS68k); + u32 d; + elprintf(EL_ANOMALY, "FIXME: s68k_bram r16: [%06x] @%06x", a, SekPcS68k); + a = (a >> 1) & 0x1fff; + d = Pico_mcd->bram[a++]; + d|= Pico_mcd->bram[a++] << 8; // probably wrong, TODO: verify + return d; +} - a&=0xffffff; +static void PicoWriteS68k8_bram(u32 a, u32 d) +{ + Pico_mcd->bram[(a >> 1) & 0x1fff] = d; + SRam.changed = 1; +} -#ifdef EMU_CORE_DEBUG - lastwrite_cyc_d[lwp_cyc++&15] = d; -#endif +static void PicoWriteS68k16_bram(u32 a, u32 d) +{ + elprintf(EL_ANOMALY, "s68k_bram w16: [%06x] %04x @%06x", a, d, SekPcS68k); + a = (a >> 1) & 0x1fff; + Pico_mcd->bram[a++] = d; + Pico_mcd->bram[a++] = d >> 8; // TODO: verify.. + SRam.changed = 1; +} - // prg RAM - if (a < 0x80000) { - u8 *pm=(u8 *)(Pico_mcd->prg_ram+(a^1)); - if (a >= (Pico_mcd->s68k_regs[2]<<8)) *pm=d; - return; - } +// PCM and registers (ff0000 - ffffff) +static u32 PicoReadS68k8_pr(u32 a) +{ + u32 d = 0; // regs - if ((a&0xfffe00) == 0xff8000) { + if ((a & 0xfe00) == 0x8000) { a &= 0x1ff; - rdprintf("s68k_regs w8: [%02x] %02x @ %06x", a, d, SekPcS68k); - if (a >= 0x58 && a < 0x68) - gfx_cd_write16(a&~1, (d<<8)|d); - else s68k_reg_write8(a,d); - return; - } - - // word RAM (2M area) - if ((a&0xfc0000)==0x080000) { // 080000-0bffff - int r3 = Pico_mcd->s68k_regs[3]; - wrdprintf("s68k_wram2M w8: [%06x] %02x @%06x", a, d, SekPcS68k); - if (r3 & 4) { // 1M decode mode? - decode_write8(a, d, r3); - } else { - // allow access in any mode, like Gens does - *(u8 *)(Pico_mcd->word_ram2M+((a^1)&0x3ffff))=d; + elprintf(EL_CDREGS, "s68k_regs r8: [%02x] @ %06x", a, SekPcS68k); + if (a >= 0x0e && a < 0x30) { + d = Pico_mcd->s68k_regs[a]; + s68k_poll_detect(a, d); + elprintf(EL_CDREGS, "ret = %02x", (u8)d); + return d; } - return; - } - - // word RAM (1M area) - if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff - // Wing Commander tries to write here in wrong mode - int bank; - if (d) - wrdprintf("s68k_wram1M w8: [%06x] %02x @%06x", a, d, SekPcS68k); -// if (!(Pico_mcd->s68k_regs[3]&4)) -// dprintf("s68k_wram1M FIXME: wrong mode"); - bank = (Pico_mcd->s68k_regs[3]&1)^1; - *(u8 *)(Pico_mcd->word_ram1M[bank]+((a^1)&0x1ffff))=d; - return; + else if (a >= 0x58 && a < 0x68) + d = gfx_cd_read(a & ~1); + else d = s68k_reg_read16(a & ~1); + if (!(a & 1)) + d >>= 8; + elprintf(EL_CDREGS, "ret = %02x", (u8)d); + return d & 0xff; } // PCM - if ((a&0xff8000)==0xff0000) { + if ((a & 0x8000) == 0x0000) { a &= 0x7fff; if (a >= 0x2000) - Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a>>1)&0xfff] = d; - else if (a < 0x12) - pcm_write(a>>1, d); - return; - } - - // bram - if ((a&0xff0000)==0xfe0000) { - Pico_mcd->bram[(a>>1)&0x1fff] = d; - SRam.changed = 1; - return; + d = Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a >> 1) & 0xfff]; + else if (a >= 0x20) { + a &= 0x1e; + d = Pico_mcd->pcm.ch[a>>2].addr >> PCM_STEP_SHIFT; + if (a & 2) + d >>= 8; + } + return d & 0xff; } - elprintf(EL_UIO, "s68k w8 : %06x, %02x @%06x", a&0xffffff, d, SekPcS68k); + return s68k_unmapped_read8(a); } -#endif - -#ifdef _ASM_CD_MEMORY_C -void PicoWriteS68k16(u32 a,u16 d); -#else -static void PicoWriteS68k16(u32 a,u16 d) +static u32 PicoReadS68k16_pr(u32 a) { - elprintf(EL_IO, "s68k w16: %06x, %04x @%06x", a&0xffffff, d, SekPcS68k); - - a&=0xfffffe; - -#ifdef EMU_CORE_DEBUG - lastwrite_cyc_d[lwp_cyc++&15] = d; -#endif - - // prg RAM - if (a < 0x80000) { - wrdprintf("s68k_prgram w16: [%06x] %04x @%06x", a, d, SekPcS68k); - if (a >= (Pico_mcd->s68k_regs[2]<<8)) // needed for Dungeon Explorer - *(u16 *)(Pico_mcd->prg_ram+a)=d; - return; - } + u32 d = 0; // regs - if ((a&0xfffe00) == 0xff8000) { + if ((a & 0xfe00) == 0x8000) { a &= 0x1fe; - rdprintf("s68k_regs w16: [%02x] %04x @ %06x", a, d, SekPcS68k); - if (a >= 0x58 && a < 0x68) - gfx_cd_write16(a, d); - else { - if (a == 0xe) { // special case, 2 byte writes would be handled differently - Pico_mcd->s68k_regs[0xf] = d; - return; - } - s68k_reg_write8(a, d>>8); - s68k_reg_write8(a+1,d&0xff); - } - return; + elprintf(EL_CDREGS, "s68k_regs r16: [%02x] @ %06x", a, SekPcS68k); + if (0x58 <= a && a < 0x68) + d = gfx_cd_read(a); + else d = s68k_reg_read16(a); + elprintf(EL_CDREGS, "ret = %04x", d); + return d; } - // word RAM (2M area) - if ((a&0xfc0000)==0x080000) { // 080000-0bffff - int r3 = Pico_mcd->s68k_regs[3]; - wrdprintf("s68k_wram2M w16: [%06x] %04x @%06x", a, d, SekPcS68k); - if (r3 & 4) { // 1M decode mode? - decode_write16(a, d, r3); - } else { - // allow access in any mode, like Gens does - *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe))=d; + // PCM + if ((a & 0x8000) == 0x0000) { + //elprintf(EL_ANOMALY, "FIXME: s68k_pcm r16: [%06x] @%06x", a, SekPcS68k); + a &= 0x7fff; + if (a >= 0x2000) + d = Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a>>1)&0xfff]; + else if (a >= 0x20) { + a &= 0x1e; + d = Pico_mcd->pcm.ch[a>>2].addr >> PCM_STEP_SHIFT; + if (a & 2) d >>= 8; } - return; + elprintf(EL_CDREGS, "ret = %04x", d); + return d; } - // word RAM (1M area) - if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff - int bank; - if (d) - wrdprintf("s68k_wram1M w16: [%06x] %04x @%06x", a, d, SekPcS68k); -// if (!(Pico_mcd->s68k_regs[3]&4)) -// dprintf("s68k_wram1M FIXME: wrong mode"); - bank = (Pico_mcd->s68k_regs[3]&1)^1; - *(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe))=d; + return s68k_unmapped_read16(a); +} + +static void PicoWriteS68k8_pr(u32 a, u32 d) +{ + // regs + if ((a & 0xfe00) == 0x8000) { + a &= 0x1ff; + elprintf(EL_CDREGS, "s68k_regs w8: [%02x] %02x @ %06x", a, d, SekPcS68k); + if (0x58 <= a && a < 0x68) + gfx_cd_write16(a&~1, (d<<8)|d); + else s68k_reg_write8(a,d); return; } // PCM - if ((a&0xff8000)==0xff0000) { + if ((a & 0x8000) == 0x0000) { a &= 0x7fff; if (a >= 0x2000) Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a>>1)&0xfff] = d; else if (a < 0x12) - pcm_write(a>>1, d & 0xff); - return; - } - - // bram - if ((a&0xff0000)==0xfe0000) { - dprintf("s68k_bram w16: [%06x] %04x @%06x", a, d, SekPcS68k); - a = (a>>1)&0x1fff; - Pico_mcd->bram[a++] = d; // Gens does little endian here, an so do we.. - Pico_mcd->bram[a++] = d >> 8; - SRam.changed = 1; + pcm_write(a>>1, d); return; } - elprintf(EL_UIO, "s68k w16: %06x, %04x @%06x", a&0xffffff, d, SekPcS68k); + s68k_unmapped_write8(a, d); } -#endif - -#ifdef _ASM_CD_MEMORY_C -void PicoWriteS68k32(u32 a,u32 d); -#else -static void PicoWriteS68k32(u32 a,u32 d) +static void PicoWriteS68k16_pr(u32 a, u32 d) { - elprintf(EL_IO, "s68k w32: %06x, %08x @%06x", a&0xffffff, d, SekPcS68k); - - a&=0xfffffe; - -#ifdef EMU_CORE_DEBUG - lastwrite_cyc_d[lwp_cyc++&15] = d; -#endif - - // prg RAM - if (a < 0x80000) { - if (a >= (Pico_mcd->s68k_regs[2]<<8)) { - u16 *pm=(u16 *)(Pico_mcd->prg_ram+a); - pm[0]=(u16)(d>>16); pm[1]=(u16)d; - } - return; - } - // regs - if ((a&0xfffe00) == 0xff8000) { + if ((a & 0xfe00) == 0x8000) { a &= 0x1fe; - rdprintf("s68k_regs w32: [%02x] %08x @ %06x", a, d, SekPcS68k); - if (a >= 0x58 && a < 0x68) { - gfx_cd_write16(a, d>>16); - gfx_cd_write16(a+2, d&0xffff); - } else { - if ((a&0x1fe) == 0xe) dprintf("s68k FIXME: w32 [%02x]", a&0x3f); - s68k_reg_write8(a, d>>24); - s68k_reg_write8(a+1,(d>>16)&0xff); - s68k_reg_write8(a+2,(d>>8) &0xff); - s68k_reg_write8(a+3, d &0xff); - } - return; - } - - // word RAM (2M area) - if ((a&0xfc0000)==0x080000) { // 080000-0bffff - int r3 = Pico_mcd->s68k_regs[3]; - wrdprintf("s68k_wram2M w32: [%06x] %08x @%06x", a, d, SekPcS68k); - if (r3 & 4) { // 1M decode mode? - decode_write16(a , d >> 16, r3); - decode_write16(a+2, d , r3); - } else { - // allow access in any mode, like Gens does - u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); - pm[0]=(u16)(d>>16); pm[1]=(u16)d; + elprintf(EL_CDREGS, "s68k_regs w16: [%02x] %04x @ %06x", a, d, SekPcS68k); + if (a >= 0x58 && a < 0x68) + gfx_cd_write16(a, d); + else { + if (a == 0xe) { + // special case, 2 byte writes would be handled differently + // TODO: verify + Pico_mcd->s68k_regs[0xf] = d; + return; + } + s68k_reg_write8(a, d >> 8); + s68k_reg_write8(a + 1, d & 0xff); } return; } - // word RAM (1M area) - if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff - int bank; - u16 *pm; - if (d) - wrdprintf("s68k_wram1M w32: [%06x] %08x @%06x", a, d, SekPcS68k); -// if (!(Pico_mcd->s68k_regs[3]&4)) -// dprintf("s68k_wram1M FIXME: wrong mode"); - bank = (Pico_mcd->s68k_regs[3]&1)^1; - pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe)); - pm[0]=(u16)(d>>16); pm[1]=(u16)d; - return; - } - // PCM - if ((a&0xff8000)==0xff0000) { + if ((a & 0x8000) == 0x0000) { a &= 0x7fff; - if (a >= 0x2000) { - a >>= 1; - Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][a&0xfff] = (d >> 16); - Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a+1)&0xfff] = d; - } else if (a < 0x12) { - a >>= 1; - pcm_write(a, (d>>16) & 0xff); - pcm_write(a+1, d & 0xff); - } - return; - } - - // bram - if ((a&0xff0000)==0xfe0000) { - dprintf("s68k_bram w32: [%06x] %08x @%06x", a, d, SekPcS68k); - a = (a>>1)&0x1fff; - Pico_mcd->bram[a++] = d >> 16; // middle endian? verify? - Pico_mcd->bram[a++] = d >> 24; - Pico_mcd->bram[a++] = d; - Pico_mcd->bram[a++] = d >> 8; - SRam.changed = 1; + if (a >= 0x2000) + Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a>>1)&0xfff] = d; + else if (a < 0x12) + pcm_write(a>>1, d & 0xff); return; } - elprintf(EL_UIO, "s68k w32: %06x, %08x @%06x", a&0xffffff, d, SekPcS68k); + s68k_unmapped_write16(a, d); } -#endif - // ----------------------------------------------------------------- - #ifdef EMU_C68K static __inline int PicoMemBaseM68k(u32 pc) { @@ -1616,9 +855,45 @@ static u32 PicoCheckPcS68k(u32 pc) } #endif -#ifndef _ASM_CD_MEMORY_C -void PicoMemResetCD(int r3) +// TODO: probably split +void PicoMemRemapCD(int r3) { + void *bank; + + // PRG RAM + if (Pico_mcd->m.busreq & 2) { + bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3] >> 6]; + cpu68k_map_all_ram(0x020000, 0x03ffff, bank, 0); + } + else { + m68k_map_unmap(0x020000, 0x03ffff); + } + + // WORD RAM + if (!(r3 & 4)) { + // 2M mode. XXX: allowing access in all cases for simplicity + bank = Pico_mcd->word_ram2M; + cpu68k_map_all_ram(0x200000, 0x23ffff, bank, 0); + cpu68k_map_all_ram(0x080000, 0x0bffff, bank, 1); + // TODO: handle 0x0c0000 + } + else { + bank = Pico_mcd->word_ram1M[r3 & 1]; + cpu68k_map_all_ram(0x200000, 0x21ffff, bank, 0); + bank = Pico_mcd->word_ram1M[(r3 & 1) ^ 1]; + cpu68k_map_all_ram(0x0c0000, 0x0effff, bank, 1); + // "cell arrange" on m68k + cpu68k_map_set(m68k_read8_map, 0x220000, 0x23ffff, PicoReadM68k8_cell, 1); + cpu68k_map_set(m68k_read16_map, 0x220000, 0x23ffff, PicoReadM68k16_cell, 1); + cpu68k_map_set(m68k_write8_map, 0x220000, 0x23ffff, PicoWriteM68k8_cell, 1); + cpu68k_map_set(m68k_write16_map, 0x220000, 0x23ffff, PicoWriteM68k16_cell, 1); + // "decode format" on s68k + cpu68k_map_set(s68k_read8_map, 0x080000, 0x0bffff, PicoReadS68k8_dec, 1); + cpu68k_map_set(s68k_read16_map, 0x080000, 0x0bffff, PicoReadS68k16_dec, 1); + cpu68k_map_set(s68k_write8_map, 0x080000, 0x0bffff, PicoWriteS68k8_dec, 1); + cpu68k_map_set(s68k_write16_map, 0x080000, 0x0bffff, PicoWriteS68k16_dec, 1); + } + #ifdef EMU_F68K // update fetchmap.. int i; @@ -1636,7 +911,6 @@ void PicoMemResetCD(int r3) } #endif } -#endif #ifdef EMU_M68K static void m68k_mem_setup_cd(void); @@ -1644,43 +918,69 @@ static void m68k_mem_setup_cd(void); PICO_INTERNAL void PicoMemSetupCD(void) { - // additional handlers for common code - PicoRead16Hook = OtherRead16End; - PicoWrite8Hook = OtherWrite8End; + // setup default main68k map + PicoMemSetup(); + + // PicoMemRemapCD() will set up RAMs, so not done here + + // main68k map (BIOS mapped by PicoMemSetup()): + // RAM cart + if (PicoOpt & POPT_EN_MCD_RAMCART) { + cpu68k_map_set(m68k_read8_map, 0x400000, 0x7fffff, PicoReadM68k8_ramc, 1); + cpu68k_map_set(m68k_read16_map, 0x400000, 0x7fffff, PicoReadM68k16_ramc, 1); + cpu68k_map_set(m68k_write8_map, 0x400000, 0x7fffff, PicoWriteM68k8_ramc, 1); + cpu68k_map_set(m68k_write16_map, 0x400000, 0x7fffff, PicoWriteM68k16_ramc, 1); + } + + // registers/IO: + cpu68k_map_set(m68k_read8_map, 0xa10000, 0xa1ffff, PicoReadM68k8_io, 1); + cpu68k_map_set(m68k_read16_map, 0xa10000, 0xa1ffff, PicoReadM68k16_io, 1); + cpu68k_map_set(m68k_write8_map, 0xa10000, 0xa1ffff, PicoWriteM68k8_io, 1); + cpu68k_map_set(m68k_write16_map, 0xa10000, 0xa1ffff, PicoWriteM68k16_io, 1); + + // sub68k map + cpu68k_map_set(s68k_read8_map, 0x000000, 0xffffff, s68k_unmapped_read8, 1); + cpu68k_map_set(s68k_read16_map, 0x000000, 0xffffff, s68k_unmapped_read16, 1); + cpu68k_map_set(s68k_write8_map, 0x000000, 0xffffff, s68k_unmapped_write8, 1); + cpu68k_map_set(s68k_write16_map, 0x000000, 0xffffff, s68k_unmapped_write16, 1); + + // PRG RAM + cpu68k_map_set(s68k_read8_map, 0x000000, 0x07ffff, Pico_mcd->prg_ram, 0); + cpu68k_map_set(s68k_read16_map, 0x000000, 0x07ffff, Pico_mcd->prg_ram, 0); + cpu68k_map_set(s68k_write8_map, 0x000000, 0x07ffff, Pico_mcd->prg_ram, 0); + cpu68k_map_set(s68k_write16_map, 0x000000, 0x07ffff, Pico_mcd->prg_ram, 0); + + // BRAM + cpu68k_map_set(s68k_read8_map, 0xfe0000, 0xfeffff, PicoReadS68k8_bram, 1); + cpu68k_map_set(s68k_read16_map, 0xfe0000, 0xfeffff, PicoReadS68k16_bram, 1); + cpu68k_map_set(s68k_write8_map, 0xfe0000, 0xfeffff, PicoWriteS68k8_bram, 1); + cpu68k_map_set(s68k_write16_map, 0xfe0000, 0xfeffff, PicoWriteS68k16_bram, 1); + + // PCM, regs + cpu68k_map_set(s68k_read8_map, 0xff0000, 0xffffff, PicoReadS68k8_pr, 1); + cpu68k_map_set(s68k_read16_map, 0xff0000, 0xffffff, PicoReadS68k16_pr, 1); + cpu68k_map_set(s68k_write8_map, 0xff0000, 0xffffff, PicoWriteS68k8_pr, 1); + cpu68k_map_set(s68k_write16_map, 0xff0000, 0xffffff, PicoWriteS68k16_pr, 1); #ifdef EMU_C68K - // Setup m68k memory callbacks: - PicoCpuCM68k.checkpc=PicoCheckPcM68k; - PicoCpuCM68k.fetch8 =PicoCpuCM68k.read8 =PicoReadM68k8; - PicoCpuCM68k.fetch16=PicoCpuCM68k.read16=PicoReadM68k16; - PicoCpuCM68k.fetch32=PicoCpuCM68k.read32=PicoReadM68k32; - PicoCpuCM68k.write8 =PicoWriteM68k8; - PicoCpuCM68k.write16=PicoWriteM68k16; - PicoCpuCM68k.write32=PicoWriteM68k32; + PicoCpuCM68k.checkpc = PicoCheckPcM68k; // s68k - PicoCpuCS68k.checkpc=PicoCheckPcS68k; - PicoCpuCS68k.fetch8 =PicoCpuCS68k.read8 =PicoReadS68k8; - PicoCpuCS68k.fetch16=PicoCpuCS68k.read16=PicoReadS68k16; - PicoCpuCS68k.fetch32=PicoCpuCS68k.read32=PicoReadS68k32; - PicoCpuCS68k.write8 =PicoWriteS68k8; - PicoCpuCS68k.write16=PicoWriteS68k16; - PicoCpuCS68k.write32=PicoWriteS68k32; + PicoCpuCS68k.checkpc = PicoCheckPcS68k; + PicoCpuCS68k.fetch8 = PicoCpuCS68k.read8 = s68k_read8; + PicoCpuCS68k.fetch16 = PicoCpuCS68k.read16 = s68k_read16; + PicoCpuCS68k.fetch32 = PicoCpuCS68k.read32 = s68k_read32; + PicoCpuCS68k.write8 = s68k_write8; + PicoCpuCS68k.write16 = s68k_write16; + PicoCpuCS68k.write32 = s68k_write32; #endif #ifdef EMU_F68K - // m68k - PicoCpuFM68k.read_byte =PicoReadM68k8; - PicoCpuFM68k.read_word =PicoReadM68k16; - PicoCpuFM68k.read_long =PicoReadM68k32; - PicoCpuFM68k.write_byte=PicoWriteM68k8; - PicoCpuFM68k.write_word=PicoWriteM68k16; - PicoCpuFM68k.write_long=PicoWriteM68k32; // s68k - PicoCpuFS68k.read_byte =PicoReadS68k8; - PicoCpuFS68k.read_word =PicoReadS68k16; - PicoCpuFS68k.read_long =PicoReadS68k32; - PicoCpuFS68k.write_byte=PicoWriteS68k8; - PicoCpuFS68k.write_word=PicoWriteS68k16; - PicoCpuFS68k.write_long=PicoWriteS68k32; + PicoCpuFS68k.read_byte = s68k_read8; + PicoCpuFS68k.read_word = s68k_read16; + PicoCpuFS68k.read_long = s68k_read32; + PicoCpuFS68k.write_byte = s68k_write8; + PicoCpuFS68k.write_word = s68k_write16; + PicoCpuFS68k.write_long = s68k_write32; // setup FAME fetchmap { @@ -1705,13 +1005,12 @@ PICO_INTERNAL void PicoMemSetupCD(void) // WORD RAM 2M area for (i = M68K_FETCHBANK1*0x08/0x100; i < M68K_FETCHBANK1 && (i<<(24-FAMEC_FETCHBITS)) < 0xc0000; i++) PicoCpuFS68k.Fetch[i] = (unsigned int)Pico_mcd->word_ram2M - 0x80000; - // PicoMemResetCD() will setup word ram for both + // PicoMemRemapCD() will setup word ram for both } #endif #ifdef EMU_M68K m68k_mem_setup_cd(); #endif - z80_mem_setup(); // m68k_poll_addr = m68k_poll_cnt = 0; s68k_poll_adclk = s68k_poll_cnt = 0; @@ -1719,23 +1018,30 @@ PICO_INTERNAL void PicoMemSetupCD(void) #ifdef EMU_M68K +u32 m68k_read8(u32 a); +u32 m68k_read16(u32 a); +u32 m68k_read32(u32 a); +void m68k_write8(u32 a, u8 d); +void m68k_write16(u32 a, u16 d); +void m68k_write32(u32 a, u32 d); + static unsigned int PicoReadCD8w (unsigned int a) { - return m68ki_cpu_p == &PicoCpuMS68k ? PicoReadS68k8(a) : PicoReadM68k8(a); + return m68ki_cpu_p == &PicoCpuMS68k ? s68k_read8(a) : m68k_read8(a); } static unsigned int PicoReadCD16w(unsigned int a) { - return m68ki_cpu_p == &PicoCpuMS68k ? PicoReadS68k16(a) : PicoReadM68k16(a); + return m68ki_cpu_p == &PicoCpuMS68k ? s68k_read16(a) : m68k_read16(a); } static unsigned int PicoReadCD32w(unsigned int a) { - return m68ki_cpu_p == &PicoCpuMS68k ? PicoReadS68k32(a) : PicoReadM68k32(a); + return m68ki_cpu_p == &PicoCpuMS68k ? s68k_read32(a) : m68k_read32(a); } static void PicoWriteCD8w (unsigned int a, unsigned char d) { - if (m68ki_cpu_p == &PicoCpuMS68k) PicoWriteS68k8(a, d); else PicoWriteM68k8(a, d); + if (m68ki_cpu_p == &PicoCpuMS68k) s68k_write8(a, d); else m68k_write8(a, d); } static void PicoWriteCD16w(unsigned int a, unsigned short d) { - if (m68ki_cpu_p == &PicoCpuMS68k) PicoWriteS68k16(a, d); else PicoWriteM68k16(a, d); + if (m68ki_cpu_p == &PicoCpuMS68k) s68k_write16(a, d); else m68k_write16(a, d); } static void PicoWriteCD32w(unsigned int a, unsigned int d) { - if (m68ki_cpu_p == &PicoCpuMS68k) PicoWriteS68k32(a, d); else PicoWriteM68k32(a, d); + if (m68ki_cpu_p == &PicoCpuMS68k) s68k_write32(a, d); else m68k_write32(a, d); } // these are allowed to access RAM diff --git a/pico/cd/pico.c b/pico/cd/pico.c index 73351580..8c0bf254 100644 --- a/pico/cd/pico.c +++ b/pico/cd/pico.c @@ -30,6 +30,7 @@ PICO_INTERNAL void PicoPowerMCD(void) memset(Pico_mcd->pcm_ram, 0, sizeof(Pico_mcd->pcm_ram)); memset(Pico_mcd->bram, 0, sizeof(Pico_mcd->bram)); memcpy(Pico_mcd->bram + sizeof(Pico_mcd->bram) - fmt_size, formatted_bram, fmt_size); + PicoMemRemapCD(1); } PICO_INTERNAL int PicoResetMCD(void) @@ -45,13 +46,12 @@ PICO_INTERNAL int PicoResetMCD(void) Reset_CD(); LC89510_Reset(); gfx_cd_reset(); - PicoMemResetCD(1); #ifdef _ASM_CD_MEMORY_C //PicoMemResetCDdecode(1); // don't have to call this in 2M mode #endif // use SRam.data for RAM cart - if (PicoOpt&POPT_EN_MCD_RAMCART) { + if (PicoOpt & POPT_EN_MCD_RAMCART) { if (SRam.data == NULL) SRam.data = calloc(1, 0x12000); } diff --git a/pico/debug.c b/pico/debug.c index d6b91bdd..89bdde31 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_reg, 4), bit(Pico.m.sram_reg, 2), SRam.eeprom_type); MVP; - sprintf(dstrp, "sram range: %06x-%06x, reg: %02x\n", SRam.start, SRam.end, Pico.m.sram_reg); MVP; + 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; 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/memory.c b/pico/memory.c index 819ead8e..aa2a54e7 100644 --- a/pico/memory.c +++ b/pico/memory.c @@ -1,32 +1,148 @@ // This is part of Pico Library // (c) Copyright 2004 Dave, All rights reserved. -// (c) Copyright 2006,2007 notaz, All rights reserved. +// (c) Copyright 2006-2009 notaz, All rights reserved. // Free for non-commercial use. // For commercial use, separate licencing terms must be obtained. #include "pico_int.h" +#include "memory.h" #include "sound/ym2612.h" #include "sound/sn76496.h" -#ifndef UTYPES_DEFINED -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned int u32; -#define UTYPES_DEFINED -#endif - extern unsigned int lastSSRamWrite; // used by serial eeprom code -#ifdef _ASM_MEMORY_C -u32 PicoRead8(u32 a); -u32 PicoRead16(u32 a); -void PicoWrite8(u32 a,u8 d); -void PicoWriteRomHW_SSF2(u32 a,u32 d); -#endif +unsigned long m68k_read8_map [0x1000000 >> M68K_MEM_SHIFT]; +unsigned long m68k_read16_map [0x1000000 >> M68K_MEM_SHIFT]; +unsigned long m68k_write8_map [0x1000000 >> M68K_MEM_SHIFT]; +unsigned long m68k_write16_map[0x1000000 >> M68K_MEM_SHIFT]; + +static void xmap_set(unsigned long *map, int shift, int start_addr, int end_addr, + void *func_or_mh, int is_func) +{ + unsigned long addr = (unsigned long)func_or_mh; + int mask = (1 << shift) - 1; + int i; + + if ((start_addr & mask) != 0 || (end_addr & mask) != mask) { + elprintf(EL_STATUS|EL_ANOMALY, "xmap_set: tried to map bad range: %06x-%06x", + start_addr, end_addr); + return; + } + + if (addr & 1) { + elprintf(EL_STATUS|EL_ANOMALY, "xmap_set: ptr is not aligned: %08lx", addr); + return; + } + + if (!is_func) + addr -= start_addr; + + for (i = start_addr >> shift; i <= end_addr >> shift; i++) { + map[i] = addr >> 1; + if (is_func) + map[i] |= 1 << (sizeof(addr) * 8 - 1); + } +} + +void z80_map_set(unsigned long *map, int start_addr, int end_addr, + void *func_or_mh, int is_func) +{ + xmap_set(map, Z80_MEM_SHIFT, start_addr, end_addr, func_or_mh, is_func); +} + +void cpu68k_map_set(unsigned long *map, int start_addr, int end_addr, + void *func_or_mh, int is_func) +{ + xmap_set(map, M68K_MEM_SHIFT, start_addr, end_addr, func_or_mh, is_func); +} + +// more specialized/optimized function (does same as above) +void cpu68k_map_all_ram(int start_addr, int end_addr, void *ptr, int is_sub) +{ + unsigned long *r8map, *r16map, *w8map, *w16map; + unsigned long addr = (unsigned long)ptr; + int shift = M68K_MEM_SHIFT; + int i; + + if (!is_sub) { + r8map = m68k_read8_map; + r16map = m68k_read16_map; + w8map = m68k_write8_map; + w16map = m68k_write16_map; + } else { + r8map = s68k_read8_map; + r16map = s68k_read16_map; + w8map = s68k_write8_map; + w16map = s68k_write16_map; + } + + addr -= start_addr; + addr >>= 1; + for (i = start_addr >> shift; i <= end_addr >> shift; i++) + r8map[i] = r16map[i] = w8map[i] = w16map[i] = addr; +} + +static u32 m68k_unmapped_read8(u32 a) +{ + elprintf(EL_UIO, "m68k unmapped r8 [%06x] @%06x", a, SekPc); + return 0; // assume pulldown, as if MegaCD2 was attached +} + +static u32 m68k_unmapped_read16(u32 a) +{ + elprintf(EL_UIO, "m68k unmapped r16 [%06x] @%06x", a, SekPc); + return 0; +} + +static void m68k_unmapped_write8(u32 a, u32 d) +{ + elprintf(EL_UIO, "m68k unmapped w8 [%06x] %02x @%06x", a, d & 0xff, SekPc); +} + +static void m68k_unmapped_write16(u32 a, u32 d) +{ + elprintf(EL_UIO, "m68k unmapped w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc); +} + +void m68k_map_unmap(int start_addr, int end_addr) +{ + unsigned long addr; + int shift = M68K_MEM_SHIFT; + int i; + + addr = (unsigned long)m68k_unmapped_read8; + for (i = start_addr >> shift; i <= end_addr >> shift; i++) + m68k_read8_map[i] = (addr >> 1) | (1 << 31); + + addr = (unsigned long)m68k_unmapped_read16; + for (i = start_addr >> shift; i <= end_addr >> shift; i++) + m68k_read16_map[i] = (addr >> 1) | (1 << 31); + + addr = (unsigned long)m68k_unmapped_write8; + for (i = start_addr >> shift; i <= end_addr >> shift; i++) + m68k_write8_map[i] = (addr >> 1) | (1 << 31); + + addr = (unsigned long)m68k_unmapped_write16; + for (i = start_addr >> shift; i <= end_addr >> shift; i++) + m68k_write16_map[i] = (addr >> 1) | (1 << 31); +} + +MAKE_68K_READ8(m68k_read8, m68k_read8_map) +MAKE_68K_READ16(m68k_read16, m68k_read16_map) +MAKE_68K_READ32(m68k_read32, m68k_read16_map) +MAKE_68K_WRITE8(m68k_write8, m68k_write8_map) +MAKE_68K_WRITE16(m68k_write16, m68k_write16_map) +MAKE_68K_WRITE32(m68k_write32, m68k_write16_map) + +// ----------------------------------------------------------------- + +static u32 ym2612_read_local_68k(void); +static int ym2612_write_local(u32 a, u32 d, int is_from_z80); +static void z80_mem_setup(void); #ifdef EMU_CORE_DEBUG @@ -95,15 +211,10 @@ PICO_INTERNAL void PicoInitPc(u32 pc) PicoCheckPc(pc); } -#ifndef _ASM_MEMORY_C -PICO_INTERNAL_ASM void PicoMemReset(void) -{ -} -#endif - // ----------------------------------------------------------------- +// memmap helpers -int PadRead(int i) +static int PadRead(int i) { int pad,value,data_reg; pad=~PicoPadInt[i]; // Get inverse of pad MXYZ SACB RLDU @@ -135,77 +246,80 @@ int PadRead(int i) return value; // will mirror later } - -#ifndef _ASM_MEMORY_C -static -#endif -u32 SRAMRead(u32 a) +static u32 io_ports_read(u32 a) { - unsigned int sreg = Pico.m.sram_reg; - if (!(sreg & 0x10) && (sreg & 1) && a > 0x200001) { // not yet detected SRAM - elprintf(EL_SRAMIO, "normal sram detected."); - Pico.m.sram_reg|=0x10; // should be normal SRAM + u32 d; + a = (a>>1) & 0xf; + switch (a) { + case 0: d = Pico.m.hardware; break; // Hardware value (Version register) + case 1: d = PadRead(0); break; + case 2: d = PadRead(1); break; + default: d = Pico.ioports[a]; break; // IO ports can be used as RAM } - if (sreg & 4) // EEPROM read - return SRAMReadEEPROM(); - else // if(sreg & 1) // (sreg&5) is one of prerequisites - return *(u8 *)(SRam.data-SRam.start+a); + return d; } -#ifndef _ASM_MEMORY_C -static -#endif -u32 SRAMRead16(u32 a) +static void io_ports_write(u32 a, u32 d) { - u32 d; - if (Pico.m.sram_reg & 4) { - d = SRAMReadEEPROM(); - d |= d << 8; - } else { - u8 *pm=(u8 *)(SRam.data-SRam.start+a); - d =*pm++ << 8; - d|=*pm++; + a = (a>>1) & 0xf; + + // 6 button gamepad: if TH went from 0 to 1, gamepad changes state + if (1 <= a && a <= 2 && (PicoOpt & POPT_6BTN_PAD)) + { + Pico.m.padDelay[a - 1] = 0; + if (!(Pico.ioports[a] & 0x40) && (d & 0x40)) + Pico.m.padTHPhase[a - 1]++; } - return d; + + // cartain IO ports can be used as RAM + Pico.ioports[a] = d; } -static void SRAMWrite(u32 a, u32 d) +static void ctl_write_z80busreq(u32 d) { - unsigned int sreg = Pico.m.sram_reg; - if(!(sreg & 0x10)) { - // not detected SRAM - if((a&~1)==0x200000) { - elprintf(EL_SRAMIO, "eeprom detected."); - sreg|=4; // this should be a game with EEPROM (like NBA Jam) - SRam.start=0x200000; SRam.end=SRam.start+1; - } else - elprintf(EL_SRAMIO, "normal sram detected."); - sreg|=0x10; - Pico.m.sram_reg=sreg; + d&=1; d^=1; + elprintf(EL_BUSREQ, "set_zrun: %i->%i [%i] @%06x", Pico.m.z80Run, d, SekCyclesDone(), SekPc); + if (d ^ Pico.m.z80Run) + { + if (d) + { + z80_cycle_cnt = cycles_68k_to_z80(SekCyclesDone()); + } + else + { + z80stopCycle = SekCyclesDone(); + if ((PicoOpt&POPT_EN_Z80) && !Pico.m.z80_reset) + PicoSyncZ80(z80stopCycle); + } + Pico.m.z80Run = d; } - if(sreg & 4) { // EEPROM write - // 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); - SRAMUpdPending(a, d); - } else { - int old=sreg; - SRAMWriteEEPROM(sreg>>6); // execute pending - SRAMUpdPending(a, d); - if ((old^Pico.m.sram_reg)&0xc0) // update time only if SDA/SCL changed - lastSSRamWrite = SekCyclesDoneT(); +} + +static void ctl_write_z80reset(u32 d) +{ + d&=1; d^=1; + elprintf(EL_BUSREQ, "set_zreset: %i->%i [%i] @%06x", Pico.m.z80_reset, d, SekCyclesDone(), SekPc); + if (d ^ Pico.m.z80_reset) + { + if (d) + { + if ((PicoOpt&POPT_EN_Z80) && Pico.m.z80Run) + PicoSyncZ80(SekCyclesDone()); + YM2612ResetChip(); + timers_reset(); } - } else if(!(sreg & 2)) { - u8 *pm=(u8 *)(SRam.data-SRam.start+a); - if(*pm != (u8)d) { - SRam.changed = 1; - *pm=(u8)d; + else + { + z80_cycle_cnt = cycles_68k_to_z80(SekCyclesDone()); + z80_reset(); } + Pico.m.z80_reset = d; } } + // for nonstandard reads +// TODO: mv to carthw static u32 OtherRead16End(u32 a, int realsize) { u32 d=0; @@ -283,18 +397,8 @@ end: return d; } - -//extern UINT32 mz80GetRegisterValue(void *, UINT32); - static void OtherWrite8End(u32 a,u32 d,int realsize) { - // sram - if(a >= SRam.start && a <= SRam.end) { - elprintf(EL_SRAMIO, "sram w8 [%06x] %02x @ %06x", a, d, SekPc); - SRAMWrite(a, d); - return; - } - #ifdef _ASM_MEMORY_C // special ROM hardware (currently only banking and sram reg supported) if((a&0xfffff1) == 0xA130F1) { @@ -305,8 +409,8 @@ static void OtherWrite8End(u32 a,u32 d,int realsize) // sram access register if(a == 0xA130F1) { elprintf(EL_SRAMIO, "sram reg=%02x", d); - Pico.m.sram_reg &= ~3; - Pico.m.sram_reg |= (u8)(d&3); + Pico.m.sram_status &= ~(SRS_MAPPED|SRS_READONLY); + Pico.m.sram_status |= (u8)(d&3); return; } #endif @@ -317,185 +421,314 @@ static void OtherWrite8End(u32 a,u32 d,int realsize) Pico.m.prot_bytes[(a>>2)&1] = (u8)d; } -#include "memory_cmn.c" +// ----------------------------------------------------------------- +// 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 (srs & SRS_EEPROM) + d = EEPROM_read(); + else + d = *(u8 *)(SRam.data - SRam.start + a); + elprintf(EL_SRAMIO, "sram r8 [%06x] %02x @ %06x", a, d, SekPc); + return d; + } -// ----------------------------------------------------------------- -// Read Rom and read Ram + if (a < Pico.romsize) + return Pico.rom[a ^ 1]; + + return m68k_unmapped_read8(a); +} -#ifndef _ASM_MEMORY_C -PICO_INTERNAL_ASM u32 PicoRead8(u32 a) +static u32 PicoRead16_sram(u32 a) { - u32 d=0; + int srs = Pico.m.sram_status; + u32 d; + if (SRam.end >= a && a >= SRam.start && (srs & (SRS_MAPPED|SRS_EEPROM))) + { + if (srs & SRS_EEPROM) { + d = EEPROM_read(); + d |= d << 8; + } else { + u8 *pm = (u8 *)(SRam.data - SRam.start + a); + d = pm[0] << 8; + d |= pm[1]; + } + elprintf(EL_SRAMIO, "sram r16 [%06x] %04x @ %06x", a, d, SekPc); + return d; + } - if ((a&0xe00000)==0xe00000) { d = *(u8 *)(Pico.ram+((a^1)&0xffff)); goto end; } // Ram + if (a < Pico.romsize) + return *(u16 *)(Pico.rom + a); - a&=0xffffff; + return m68k_unmapped_read16(a); +} -#ifndef EMU_CORE_DEBUG - // sram - if (a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg&5)) { - d = SRAMRead(a); - elprintf(EL_SRAMIO, "sram r8 [%06x] %02x @ %06x", a, d, SekPc); - goto end; +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 + { + // 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(); + } } -#endif + else if (!(srs & SRS_READONLY)) { + u8 *pm=(u8 *)(SRam.data - SRam.start + a); + if (*pm != (u8)d) { + SRam.changed = 1; + *pm = (u8)d; + } + } +} - if (a>=8; + if ((a & 0x4000) == 0x0000) + d = Pico.zram[a & 0x1fff]; + else if ((a & 0x6000) == 0x4000) // 0x4000-0x5fff + d = ym2612_read_local_68k(); + else + elprintf(EL_UIO|EL_ANOMALY, "68k bad read [%06x] @%06x", a, SekPc); + return d; +} -end: - elprintf(EL_IO, "r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc); -#ifdef EMU_CORE_DEBUG - if (a>=Pico.romsize) { - lastread_a = a; - lastread_d[lrp_cyc++&15] = (u8)d; +static u32 PicoRead16_z80(u32 a) +{ + u32 d = PicoRead8_z80(a); + return d | (d << 8); +} + +static void PicoWrite8_z80(u32 a, u32 d) +{ + if ((Pico.m.z80Run & 1) || Pico.m.z80_reset) { + // verified on real hw + elprintf(EL_ANOMALY, "68k z80 write with no bus or reset! [%06x] %02x @ %06x", a, d&0xff, SekPc); + return; + } + + if ((a & 0x4000) == 0x0000) { // z80 RAM + SekCyclesBurn(2); // hack + Pico.zram[a & 0x1fff] = (u8)d; + return; + } + if ((a & 0x6000) == 0x4000) { // FM Sound + if (PicoOpt & POPT_EN_FM) + emustatus |= ym2612_write_local(a&3, d&0xff, 0)&1; + return; + } + // TODO: probably other VDP access too? Maybe more mirrors? + if ((a & 0x7ff9) == 0x7f11) { // PSG Sound + if (PicoOpt & POPT_EN_PSG) + SN76496Write(d); + return; + } +#if !defined(_ASM_MEMORY_C) || defined(_ASM_MEMORY_C_AMIPS) + if ((a & 0x7f00) == 0x6000) // Z80 BANK register + { + Pico.m.z80_bank68k >>= 1; + Pico.m.z80_bank68k |= d << 8; + Pico.m.z80_bank68k &= 0x1ff; // 9 bits and filled in the new top one + elprintf(EL_Z80BNK, "z80 bank=%06x", Pico.m.z80_bank68k << 15); + return; } #endif - return d; + elprintf(EL_UIO|EL_ANOMALY, "68k bad write [%06x] %02x @ %06x", a, d&0xff, SekPc); } -PICO_INTERNAL_ASM u32 PicoRead16(u32 a) +static void PicoWrite16_z80(u32 a, u32 d) { - u32 d=0; - - if ((a&0xe00000)==0xe00000) { d=*(u16 *)(Pico.ram+(a&0xfffe)); goto end; } // Ram + // for RAM, only most significant byte is sent + // TODO: verify remaining accesses + PicoWrite8_z80(a, d >> 8); +} - a&=0xfffffe; +// IO/control area (0xa10000 - 0xa1ffff) +u32 PicoRead8_io(u32 a) +{ + u32 d; -#ifndef EMU_CORE_DEBUG - // sram - if (a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg&5)) { - d = SRAMRead16(a); - elprintf(EL_SRAMIO, "sram r16 [%06x] %04x @ %06x", a, d, SekPc); + if ((a & 0xffe0) == 0x0000) { // I/O ports + d = io_ports_read(a); goto end; } -#endif - if (a=Pico.romsize) { - lastread_a = a; - lastread_d[lrp_cyc++&15] = d; + if ((a & 0xff01) == 0x1100) { // z80 busreq (verified) + d |= (Pico.m.z80Run | Pico.m.z80_reset) & 1; + elprintf(EL_BUSREQ, "get_zrun: %02x [%i] @%06x", d, SekCyclesDone(), SekPc); + goto end; } -#endif + + d = m68k_unmapped_read8(a); +end: return d; } -PICO_INTERNAL_ASM u32 PicoRead32(u32 a) +u32 PicoRead16_io(u32 a) { - 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; + u32 d; - // sram - if(a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg&5)) { - d = (SRAMRead16(a)<<16)|SRAMRead16(a+2); - elprintf(EL_SRAMIO, "sram r32 [%06x] %08x @ %06x", a, d, SekPc); + if ((a & 0xffe0) == 0x0000) { // I/O ports + d = io_ports_read(a); goto end; } - if (a=Pico.romsize) { - lastread_a = a; - lastread_d[lrp_cyc++&15] = d; + if ((a & 0xff00) == 0x1100) { // z80 busreq + d |= ((Pico.m.z80Run | Pico.m.z80_reset) & 1) << 8; + elprintf(EL_BUSREQ, "get_zrun: %04x [%i] @%06x", d, SekCyclesDone(), SekPc); + goto end; } -#endif + + d = m68k_unmapped_read16(a); +end: return d; } -#endif -// ----------------------------------------------------------------- -// Write Ram +void PicoWrite8_io(u32 a, u32 d) +{ + if ((a & 0xffe1) == 0x0001) { // I/O ports (verified: only LSB!) + io_ports_write(a, d); + return; + } + if ((a & 0xff01) == 0x1100) { // z80 busreq + ctl_write_z80busreq(d); + return; + } + if ((a & 0xff01) == 0x1200) { // z80 reset + ctl_write_z80reset(d); + return; + } + 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); + return; + } + m68k_unmapped_write8(a, d); +} -#if !defined(_ASM_MEMORY_C) || defined(_ASM_MEMORY_C_AMIPS) -PICO_INTERNAL_ASM void PicoWrite8(u32 a,u8 d) +void PicoWrite16_io(u32 a, u32 d) { - elprintf(EL_IO, "w8 : %06x, %02x @%06x", a&0xffffff, d, SekPc); -#ifdef EMU_CORE_DEBUG - lastwrite_cyc_d[lwp_cyc++&15] = d; -#endif + if ((a & 0xffe0) == 0x0000) { // I/O ports (verified: only LSB!) + io_ports_write(a, d); + return; + } + if ((a & 0xff00) == 0x1100) { // z80 busreq + ctl_write_z80busreq(d >> 8); + return; + } + if ((a & 0xff00) == 0x1200) { // z80 reset + ctl_write_z80reset(d >> 8); + return; + } + 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); + return; + } + m68k_unmapped_write16(a, d); +} - if ((a&0xe00000)==0xe00000) { *(u8 *)(Pico.ram+((a^1)&0xffff))=d; return; } // Ram - log_io(a, 8, 1); +// VDP area (0xc00000 - 0xdfffff) +// TODO: verify if lower byte goes to PSG on word writes +static u32 PicoRead8_vdp(u32 a) +{ + if ((a & 0x00e0) == 0x0000) + return PicoVideoRead8(a); - a&=0xffffff; - OtherWrite8(a,d); + elprintf(EL_UIO|EL_ANOMALY, "68k bad read [%06x] @%06x", a, SekPc); + return 0; } -#endif -void PicoWrite16(u32 a,u16 d) +static u32 PicoRead16_vdp(u32 a) { - elprintf(EL_IO, "w16: %06x, %04x", a&0xffffff, d); -#ifdef EMU_CORE_DEBUG - lastwrite_cyc_d[lwp_cyc++&15] = d; -#endif - - if ((a&0xe00000)==0xe00000) { *(u16 *)(Pico.ram+(a&0xfffe))=d; return; } // Ram - log_io(a, 16, 1); + if ((a & 0x00e0) == 0x0000) + return PicoVideoRead(a); - a&=0xfffffe; - if ((a&0xe700e0)==0xc00000) { PicoVideoWrite(a,(u16)d); return; } // VDP - OtherWrite16(a,d); + elprintf(EL_UIO|EL_ANOMALY, "68k bad read [%06x] @%06x", a, SekPc); + return 0; } -static void PicoWrite32(u32 a,u32 d) +static void PicoWrite8_vdp(u32 a, u32 d) { - elprintf(EL_IO, "w32: %06x, %08x @%06x", a&0xffffff, d, SekPc); -#ifdef EMU_CORE_DEBUG - lastwrite_cyc_d[lwp_cyc++&15] = d; -#endif - - if ((a&0xe00000)==0xe00000) - { - // Ram: - u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); - pm[0]=(u16)(d>>16); pm[1]=(u16)d; + if ((a & 0x00f9) == 0x0011) { // PSG Sound + if (PicoOpt & POPT_EN_PSG) + SN76496Write(d); return; } - log_io(a, 32, 1); - - a&=0xfffffe; - if ((a&0xe700e0)==0xc00000) - { - // VDP: - PicoVideoWrite(a, (u16)(d>>16)); - PicoVideoWrite(a+2,(u16)d); + if ((a & 0x00e0) == 0x0000) { + d &= 0xff; + PicoVideoWrite(a, d | (d << 8)); return; } - OtherWrite16(a, (u16)(d>>16)); - OtherWrite16(a+2,(u16)d); + elprintf(EL_UIO|EL_ANOMALY, "68k bad write [%06x] %02x @%06x", a, d & 0xff, SekPc); } +static void PicoWrite16_vdp(u32 a, u32 d) +{ + if ((a & 0x00f9) == 0x0010) { // PSG Sound + if (PicoOpt & POPT_EN_PSG) + SN76496Write(d); + return; + } + if ((a & 0x00e0) == 0x0000) { + PicoVideoWrite(a, d); + return; + } + + elprintf(EL_UIO|EL_ANOMALY, "68k bad write [%06x] %04x @%06x", a, d & 0xffff, SekPc); +} // ----------------------------------------------------------------- +// TODO: rm static void OtherWrite16End(u32 a,u32 d,int realsize) { PicoWrite8Hook(a, d>>8, realsize); @@ -520,23 +753,80 @@ static void m68k_mem_setup(void); PICO_INTERNAL void PicoMemSetup(void) { + int mask, rs, a; + + // setup the memory map + cpu68k_map_set(m68k_read8_map, 0x000000, 0xffffff, m68k_unmapped_read8, 1); + cpu68k_map_set(m68k_read16_map, 0x000000, 0xffffff, m68k_unmapped_read16, 1); + cpu68k_map_set(m68k_write8_map, 0x000000, 0xffffff, m68k_unmapped_write8, 1); + cpu68k_map_set(m68k_write16_map, 0x000000, 0xffffff, m68k_unmapped_write16, 1); + + // ROM + // align to bank size. We know ROM loader allocated enough for this + mask = (1 << M68K_MEM_SHIFT) - 1; + rs = (Pico.romsize + mask) & ~mask; + cpu68k_map_set(m68k_read8_map, 0x000000, rs - 1, Pico.rom, 0); + 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) { + rs = (rs + mask) & ~mask; + if (SRam.start + rs >= 0x1000000) + rs = 0x1000000 - SRam.start; + cpu68k_map_set(m68k_read8_map, SRam.start, SRam.start + rs - 1, PicoRead8_sram, 1); + cpu68k_map_set(m68k_read16_map, SRam.start, SRam.start + rs - 1, PicoRead16_sram, 1); + cpu68k_map_set(m68k_write8_map, SRam.start, SRam.start + rs - 1, PicoWrite8_sram, 1); + cpu68k_map_set(m68k_write16_map, SRam.start, SRam.start + rs - 1, PicoWrite16_sram, 1); + } + + // Z80 region + cpu68k_map_set(m68k_read8_map, 0xa00000, 0xa0ffff, PicoRead8_z80, 1); + cpu68k_map_set(m68k_read16_map, 0xa00000, 0xa0ffff, PicoRead16_z80, 1); + cpu68k_map_set(m68k_write8_map, 0xa00000, 0xa0ffff, PicoWrite8_z80, 1); + cpu68k_map_set(m68k_write16_map, 0xa00000, 0xa0ffff, PicoWrite16_z80, 1); + + // IO/control region + cpu68k_map_set(m68k_read8_map, 0xa10000, 0xa1ffff, PicoRead8_io, 1); + cpu68k_map_set(m68k_read16_map, 0xa10000, 0xa1ffff, PicoRead16_io, 1); + cpu68k_map_set(m68k_write8_map, 0xa10000, 0xa1ffff, PicoWrite8_io, 1); + cpu68k_map_set(m68k_write16_map, 0xa10000, 0xa1ffff, PicoWrite16_io, 1); + + // VDP region + for (a = 0xc00000; a < 0xe00000; a += 0x010000) { + if ((a & 0xe700e0) != 0xc00000) + continue; + cpu68k_map_set(m68k_read8_map, a, a + 0xffff, PicoRead8_vdp, 1); + cpu68k_map_set(m68k_read16_map, a, a + 0xffff, PicoRead16_vdp, 1); + cpu68k_map_set(m68k_write8_map, a, a + 0xffff, PicoWrite8_vdp, 1); + cpu68k_map_set(m68k_write16_map, a, a + 0xffff, PicoWrite16_vdp, 1); + } + + // RAM and it's mirrors + for (a = 0xe00000; a < 0x1000000; a += 0x010000) { + cpu68k_map_set(m68k_read8_map, a, a + 0xffff, Pico.ram, 0); + cpu68k_map_set(m68k_read16_map, a, a + 0xffff, Pico.ram, 0); + cpu68k_map_set(m68k_write8_map, a, a + 0xffff, Pico.ram, 0); + cpu68k_map_set(m68k_write16_map, a, a + 0xffff, Pico.ram, 0); + } + // Setup memory callbacks: #ifdef EMU_C68K - PicoCpuCM68k.checkpc=PicoCheckPc; - PicoCpuCM68k.fetch8 =PicoCpuCM68k.read8 =PicoRead8; - PicoCpuCM68k.fetch16=PicoCpuCM68k.read16=PicoRead16; - PicoCpuCM68k.fetch32=PicoCpuCM68k.read32=PicoRead32; - PicoCpuCM68k.write8 =PicoWrite8; - PicoCpuCM68k.write16=PicoWrite16; - PicoCpuCM68k.write32=PicoWrite32; + PicoCpuCM68k.checkpc = PicoCheckPc; + PicoCpuCM68k.fetch8 = PicoCpuCM68k.read8 = m68k_read8; + PicoCpuCM68k.fetch16 = PicoCpuCM68k.read16 = m68k_read16; + PicoCpuCM68k.fetch32 = PicoCpuCM68k.read32 = m68k_read32; + PicoCpuCM68k.write8 = m68k_write8; + PicoCpuCM68k.write16 = m68k_write16; + PicoCpuCM68k.write32 = m68k_write32; #endif #ifdef EMU_F68K - PicoCpuFM68k.read_byte =PicoRead8; - PicoCpuFM68k.read_word =PicoRead16; - PicoCpuFM68k.read_long =PicoRead32; - PicoCpuFM68k.write_byte=PicoWrite8; - PicoCpuFM68k.write_word=PicoWrite16; - PicoCpuFM68k.write_long=PicoWrite32; + PicoCpuFM68k.read_byte = m68k_read8; + PicoCpuFM68k.read_word = m68k_read16; + PicoCpuFM68k.read_long = m68k_read32; + PicoCpuFM68k.write_byte = m68k_write8; + PicoCpuFM68k.write_word = m68k_write16; + PicoCpuFM68k.write_long = m68k_write32; // setup FAME fetchmap { @@ -676,12 +966,12 @@ void m68k_write_memory_32(unsigned int address, unsigned int value) { pm68k_writ static void m68k_mem_setup(void) { - pm68k_read_memory_8 = PicoRead8; - pm68k_read_memory_16 = PicoRead16; - pm68k_read_memory_32 = PicoRead32; - pm68k_write_memory_8 = PicoWrite8; - pm68k_write_memory_16 = PicoWrite16; - pm68k_write_memory_32 = PicoWrite32; + pm68k_read_memory_8 = m68k_read8; + pm68k_read_memory_16 = m68k_read16; + pm68k_read_memory_32 = m68k_read32; + pm68k_write_memory_8 = m68k_write8; + pm68k_write_memory_16 = m68k_write16; + pm68k_write_memory_32 = m68k_write32; pm68k_read_memory_pcr_8 = m68k_read_memory_pcr_8; pm68k_read_memory_pcr_16 = m68k_read_memory_pcr_16; pm68k_read_memory_pcr_32 = m68k_read_memory_pcr_32; @@ -747,7 +1037,7 @@ void ym2612_sync_timers(int z80_cycles, int mode_old, int mode_new) } // ym2612 DAC and timer I/O handlers for z80 -int ym2612_write_local(u32 a, u32 d, int is_from_z80) +static int ym2612_write_local(u32 a, u32 d, int is_from_z80) { int addr; @@ -893,7 +1183,7 @@ static u32 MEMH_FUNC ym2612_read_local_z80(void) return ym2612.OPN.ST.status; } -u32 ym2612_read_local_68k(void) +static u32 ym2612_read_local_68k(void) { int xcycles = cycles_68k_to_z80(SekCyclesDone()) << 8; @@ -1001,10 +1291,8 @@ static unsigned char MEMH_FUNC z80_md_bank_read(unsigned short a) goto out; } + ret = m68k_read8(addr68k); elprintf(EL_ANOMALY, "z80->68k upper read [%06x] %02x", addr68k, ret); - if (PicoAHW & PAHW_MCD) - ret = PicoReadM68k8(addr68k); - else ret = PicoRead8(addr68k); out: elprintf(EL_Z80BNK, "z80->68k r8 [%06x] %02x", addr68k, ret); @@ -1047,9 +1335,7 @@ static void MEMH_FUNC z80_md_bank_write(unsigned int a, unsigned char data) addr68k += a & 0x7fff; elprintf(EL_Z80BNK, "z80->68k w8 [%06x] %02x", addr68k, data); - if (PicoAHW & PAHW_MCD) - PicoWriteM68k8(addr68k, data); - else PicoWrite8(addr68k, data); + m68k_write8(addr68k, data); } // ----------------------------------------------------------------- @@ -1065,7 +1351,7 @@ static void z80_md_out(unsigned short p, unsigned char d) elprintf(EL_ANOMALY, "Z80 port %04x write %02x", p, d); } -void z80_mem_setup(void) +static void z80_mem_setup(void) { z80_map_set(z80_read_map, 0x0000, 0x1fff, Pico.zram, 0); z80_map_set(z80_read_map, 0x2000, 0x3fff, Pico.zram, 0); diff --git a/pico/memory.h b/pico/memory.h new file mode 100644 index 00000000..63c51630 --- /dev/null +++ b/pico/memory.h @@ -0,0 +1,116 @@ +// memory map related stuff + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; + +#define M68K_MEM_SHIFT 16 + +extern unsigned long m68k_read8_map [0x1000000 >> M68K_MEM_SHIFT]; +extern unsigned long m68k_read16_map [0x1000000 >> M68K_MEM_SHIFT]; +extern unsigned long m68k_write8_map [0x1000000 >> M68K_MEM_SHIFT]; +extern unsigned long m68k_write16_map[0x1000000 >> M68K_MEM_SHIFT]; + +extern unsigned long s68k_read8_map [0x1000000 >> M68K_MEM_SHIFT]; +extern unsigned long s68k_read16_map [0x1000000 >> M68K_MEM_SHIFT]; +extern unsigned long s68k_write8_map [0x1000000 >> M68K_MEM_SHIFT]; +extern unsigned long s68k_write16_map[0x1000000 >> M68K_MEM_SHIFT]; + +void z80_map_set(unsigned long *map, int start_addr, int end_addr, + void *func_or_mh, int is_func); +void cpu68k_map_set(unsigned long *map, int start_addr, int end_addr, + void *func_or_mh, int is_func); +void cpu68k_map_all_ram(int start_addr, int end_addr, void *ptr, int is_sub); +void m68k_map_unmap(int start_addr, int end_addr); + +// top-level handlers that cores can use +// (or alternatively build them into themselves) +// XXX: unhandled: *16 and *32 might cross the bank boundaries +typedef u32 (cpu68k_read_f)(u32 a); +typedef void (cpu68k_write_f)(u32 a, u32 d); + +#define MAKE_68K_READ8(name, map) \ +u32 name(u32 a) \ +{ \ + unsigned long v; \ + a &= 0x00ffffff; \ + v = map[a >> M68K_MEM_SHIFT]; \ + if (v & 0x80000000) \ + return ((cpu68k_read_f *)(v << 1))(a); \ + else \ + return *(u8 *)((v << 1) + (a ^ 1)); \ +} + +#define MAKE_68K_READ16(name, map) \ +u32 name(u32 a) \ +{ \ + unsigned long v; \ + a &= 0x00fffffe; \ + v = map[a >> M68K_MEM_SHIFT]; \ + if (v & 0x80000000) \ + return ((cpu68k_read_f *)(v << 1))(a); \ + else \ + return *(u16 *)((v << 1) + a); \ +} + +#define MAKE_68K_READ32(name, map) \ +u32 name(u32 a) \ +{ \ + unsigned long v, vs; \ + u32 d; \ + a &= 0x00fffffe; \ + v = map[a >> M68K_MEM_SHIFT]; \ + vs = v << 1; \ + if (v & 0x80000000) { \ + d = ((cpu68k_read_f *)vs)(a) << 16; \ + d |= ((cpu68k_read_f *)vs)(a + 2); \ + } \ + else { \ + u16 *m = (u16 *)(vs + a); \ + d = (m[0] << 16) | m[1]; \ + } \ + return d; \ +} + +#define MAKE_68K_WRITE8(name, map) \ +void name(u32 a, u8 d) \ +{ \ + unsigned long v; \ + a &= 0x00ffffff; \ + v = map[a >> M68K_MEM_SHIFT]; \ + if (v & 0x80000000) \ + ((cpu68k_write_f *)(v << 1))(a, d); \ + else \ + *(u8 *)((v << 1) + (a ^ 1)) = d; \ +} + +#define MAKE_68K_WRITE16(name, map) \ +void name(u32 a, u16 d) \ +{ \ + unsigned long v; \ + a &= 0x00fffffe; \ + v = map[a >> M68K_MEM_SHIFT]; \ + if (v & 0x80000000) \ + ((cpu68k_write_f *)(v << 1))(a, d); \ + else \ + *(u16 *)((v << 1) + a) = d; \ +} + +#define MAKE_68K_WRITE32(name, map) \ +void name(u32 a, u32 d) \ +{ \ + unsigned long v, vs; \ + a &= 0x00fffffe; \ + v = map[a >> M68K_MEM_SHIFT]; \ + vs = v << 1; \ + if (v & 0x80000000) { \ + ((cpu68k_write_f *)vs)(a, d >> 16); \ + ((cpu68k_write_f *)vs)(a + 2, d); \ + } \ + else { \ + u16 *m = (u16 *)(vs + a); \ + m[0] = d >> 16; \ + m[1] = d; \ + } \ +} + diff --git a/pico/memory_cmn.c b/pico/memory_cmn.c deleted file mode 100644 index 266f807e..00000000 --- a/pico/memory_cmn.c +++ /dev/null @@ -1,237 +0,0 @@ -// common code for Memory.c and cd/Memory.c -// (c) Copyright 2006-2007, Grazvydas "notaz" Ignotas - -#ifndef UTYPES_DEFINED -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned int u32; -#define UTYPES_DEFINED -#endif - - -#ifndef _ASM_MEMORY_C -static -#endif -u8 z80Read8(u32 a) -{ - if(Pico.m.z80Run&1) return 0; - - a&=0x1fff; - - if (!(PicoOpt&POPT_EN_Z80)) - { - // Z80 disabled, do some faking - static u8 zerosent = 0; - if(a == Pico.m.z80_lastaddr) { // probably polling something - u8 d = Pico.m.z80_fakeval; - if((d & 0xf) == 0xf && !zerosent) { - d = 0; zerosent = 1; - } else { - Pico.m.z80_fakeval++; - zerosent = 0; - } - return d; - } else { - Pico.m.z80_fakeval = 0; - } - } - - Pico.m.z80_lastaddr = (u16) a; - return Pico.zram[a]; -} - -#ifndef _ASM_MEMORY_C -static -#endif -u32 z80ReadBusReq(void) -{ - u32 d = (Pico.m.z80Run | Pico.m.z80_reset) & 1; - elprintf(EL_BUSREQ, "get_zrun: %02x [%i] @%06x", d|0x80, SekCyclesDone(), SekPc); - return d|0x80; -} - -static void z80WriteBusReq(u32 d) -{ - d&=1; d^=1; - elprintf(EL_BUSREQ, "set_zrun: %i->%i [%i] @%06x", Pico.m.z80Run, d, SekCyclesDone(), SekPc); - if (d ^ Pico.m.z80Run) - { - if (d) - { - z80_cycle_cnt = cycles_68k_to_z80(SekCyclesDone()); - } - else - { - z80stopCycle = SekCyclesDone(); - if ((PicoOpt&POPT_EN_Z80) && !Pico.m.z80_reset) - PicoSyncZ80(z80stopCycle); - } - Pico.m.z80Run=d; - } -} - -static void z80WriteReset(u32 d) -{ - d&=1; d^=1; - elprintf(EL_BUSREQ, "set_zreset: %i->%i [%i] @%06x", Pico.m.z80_reset, d, SekCyclesDone(), SekPc); - if (d ^ Pico.m.z80_reset) - { - if (d) - { - if ((PicoOpt&POPT_EN_Z80) && Pico.m.z80Run) - PicoSyncZ80(SekCyclesDone()); - } - else - { - z80_cycle_cnt = cycles_68k_to_z80(SekCyclesDone()); - z80_reset(); - } - YM2612ResetChip(); - timers_reset(); - Pico.m.z80_reset=d; - } -} - -#ifndef _ASM_MEMORY_C -static -#endif -u32 OtherRead16(u32 a, int realsize) -{ - u32 d=0; - - if ((a&0xffffe0)==0xa10000) { // I/O ports - a=(a>>1)&0xf; - switch(a) { - case 0: d=Pico.m.hardware; break; // Hardware value (Version register) - case 1: d=PadRead(0); break; - case 2: d=PadRead(1); break; - default: d=Pico.ioports[a]; break; // IO ports can be used as RAM - } - d|=d<<8; - goto end; - } - - // rotate fakes next fetched instruction for Time Killers - if (a==0xa11100) { // z80 busreq - d=(z80ReadBusReq()<<8)|Pico.m.rotate++; - goto end; - } - - if ((a&0xff0000)==0xa00000) - { - if (Pico.m.z80Run&1) - elprintf(EL_ANOMALY, "68k z80 read with no bus! [%06x] @ %06x", a, SekPc); - if ((a&0x4000)==0x0000) { d=z80Read8(a); d|=d<<8; goto end; } // Z80 ram (not byteswaped) - if ((a&0x6000)==0x4000) { d=ym2612_read_local_68k(); goto end; } // 0x4000-0x5fff - - elprintf(EL_ANOMALY, "68k bad read [%06x]", a); - d=0xffff; - goto end; - } - - d = PicoRead16Hook(a, realsize); - -end: - return d; -} - -static void IoWrite8(u32 a, u32 d) -{ - a=(a>>1)&0xf; - // 6 button gamepad: if TH went from 0 to 1, gamepad changes state - if (PicoOpt&POPT_6BTN_PAD) - { - if (a==1) { - Pico.m.padDelay[0] = 0; - if(!(Pico.ioports[1]&0x40) && (d&0x40)) Pico.m.padTHPhase[0]++; - } - else if (a==2) { - Pico.m.padDelay[1] = 0; - if(!(Pico.ioports[2]&0x40) && (d&0x40)) Pico.m.padTHPhase[1]++; - } - } - Pico.ioports[a]=(u8)d; // IO ports can be used as RAM -} - -#ifndef _ASM_CD_MEMORY_C -static -#endif -void OtherWrite8(u32 a,u32 d) -{ -#if !defined(_ASM_MEMORY_C) || defined(_ASM_MEMORY_C_AMIPS) - if ((a&0xe700f9)==0xc00011||(a&0xff7ff9)==0xa07f11) { if(PicoOpt&2) SN76496Write(d); return; } // PSG Sound - if ((a&0xff4000)==0xa00000) { // z80 RAM - SekCyclesBurn(2); // hack - if (!(Pico.m.z80Run&1) && !Pico.m.z80_reset) Pico.zram[a&0x1fff]=(u8)d; - else elprintf(EL_ANOMALY, "68k z80 write with no bus or reset! [%06x] %02x @ %06x", a, d&0xff, SekPc); - return; - } - if ((a&0xff6000)==0xa04000) { if(PicoOpt&1) emustatus|=ym2612_write_local(a&3, d&0xff, 0)&1; return; } // FM Sound - if ((a&0xffffe0)==0xa10000) { IoWrite8(a, d); return; } // I/O ports -#endif - if (a==0xa11100) { z80WriteBusReq(d); return; } - if (a==0xa11200) { z80WriteReset(d); return; } - -#if !defined(_ASM_MEMORY_C) || defined(_ASM_MEMORY_C_AMIPS) - if ((a&0xff7f00)==0xa06000) // Z80 BANK register - { - Pico.m.z80_bank68k>>=1; - Pico.m.z80_bank68k|=(d&1)<<8; - Pico.m.z80_bank68k&=0x1ff; // 9 bits and filled in the new top one - elprintf(EL_Z80BNK, "z80 bank=%06x", Pico.m.z80_bank68k<<15); - return; - } -#endif - if ((a&0xe700e0)==0xc00000) { - d&=0xff; - PicoVideoWrite(a,(u16)(d|(d<<8))); // Byte access gets mirrored - return; - } - - PicoWrite8Hook(a, d&0xff, 8); -} - - -#ifndef _ASM_CD_MEMORY_C -static -#endif -void OtherWrite16(u32 a,u32 d) -{ - if (a==0xa11100) { z80WriteBusReq(d>>8); return; } - if ((a&0xffffe0)==0xa10000) { IoWrite8(a, d); return; } // I/O ports - if ((a&0xe700f8)==0xc00010||(a&0xff7ff8)==0xa07f10) { if(PicoOpt&2) SN76496Write(d); return; } // PSG Sound - if ((a&0xff6000)==0xa04000) { if(PicoOpt&1) emustatus|=ym2612_write_local(a&3, d&0xff, 0)&1; return; } // FM Sound - if ((a&0xff4000)==0xa00000) { // Z80 ram (MSB only) - if (!(Pico.m.z80Run&1) && !Pico.m.z80_reset) Pico.zram[a&0x1fff]=(u8)(d>>8); - else elprintf(EL_ANOMALY, "68k z80 write with no bus or reset! [%06x] %04x @ %06x", a, d&0xffff, SekPc); - return; - } - if (a==0xa11200) { z80WriteReset(d>>8); return; } - - if ((a&0xff7f00)==0xa06000) // Z80 BANK register - { - Pico.m.z80_bank68k>>=1; - Pico.m.z80_bank68k|=(d&1)<<8; - Pico.m.z80_bank68k&=0x1ff; // 9 bits and filled in the new top one - elprintf(EL_Z80BNK, "z80 bank=%06x", Pico.m.z80_bank68k<<15); - return; - } - -#ifndef _CD_MEMORY_C - if (a >= SRam.start && a <= SRam.end) { - elprintf(EL_SRAMIO, "sram w16 [%06x] %04x @ %06x", a, d, SekPc); - if ((Pico.m.sram_reg&0x16)==0x10) { // detected, not EEPROM, write not disabled - u8 *pm=(u8 *)(SRam.data-SRam.start+a); - *pm++=d>>8; - *pm++=d; - SRam.changed = 1; - } - else - SRAMWrite(a, d); - return; - } -#endif - - PicoWrite16Hook(a, d&0xffff, 16); -} - diff --git a/pico/misc.c b/pico/misc.c index 014ffa19..0ce14896 100644 --- a/pico/misc.c +++ b/pico/misc.c @@ -95,11 +95,11 @@ const unsigned char hcounts_32[] = { unsigned int lastSSRamWrite = 0xffff0000; -// sram_reg: LAtd sela (L=pending SCL, A=pending SDA, t=(unused), +// 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 SRAMWriteEEPROM(unsigned int d) // ???? ??la (l=SCL, a=SDA) +PICO_INTERNAL void EEPROM_write(unsigned int d) // ???? ??la (l=SCL, a=SDA) { - unsigned int sreg = Pico.m.sram_reg, saddr = Pico.m.eeprom_addr, scyc = Pico.m.eeprom_cycle, ssa = Pico.m.eeprom_slave; + 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); @@ -197,21 +197,21 @@ PICO_INTERNAL void SRAMWriteEEPROM(unsigned int d) // ???? ??la (l=SCL, a=SDA) } sreg &= ~3; sreg |= d&3; // remember SCL and SDA - Pico.m.sram_reg = (unsigned char) sreg; + 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 SRAMReadEEPROM(void) +PICO_INTERNAL_ASM unsigned int EEPROM_read(void) { unsigned int shift, d; unsigned int sreg, saddr, scyc, ssa, interval; // flush last pending write - SRAMWriteEEPROM(Pico.m.sram_reg>>6); + EEPROM_write(Pico.m.sram_status>>6); - sreg = Pico.m.sram_reg; saddr = Pico.m.eeprom_addr&0x1fff; scyc = Pico.m.eeprom_cycle; ssa = Pico.m.eeprom_slave; + 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" @@ -250,9 +250,9 @@ PICO_INTERNAL_ASM unsigned int SRAMReadEEPROM(void) return (d << SRam.eeprom_bit_out); } -PICO_INTERNAL void SRAMUpdPending(unsigned int a, unsigned int d) +PICO_INTERNAL void EEPROM_upd_pending(unsigned int a, unsigned int d) { - unsigned int d1, sreg = Pico.m.sram_reg; + unsigned int d1, sreg = Pico.m.sram_status; if (!((SRam.eeprom_abits^a)&1)) { @@ -269,7 +269,7 @@ PICO_INTERNAL void SRAMUpdPending(unsigned int a, unsigned int d) sreg |= d1<<6; } - Pico.m.sram_reg = (unsigned char) sreg; + Pico.m.sram_status = (unsigned char) sreg; } diff --git a/pico/patch.c b/pico/patch.c index dc5c91f5..99632dda 100644 --- a/pico/patch.c +++ b/pico/patch.c @@ -303,7 +303,8 @@ void PicoPatchPrepare(void) for (i = 0; i < PicoPatchCount; i++) { PicoPatches[i].addr &= ~1; - PicoPatches[i].data_old = PicoRead16(PicoPatches[i].addr); + if (PicoPatches[i].addr < Pico.romsize) + PicoPatches[i].data_old = *(unsigned short *)(Pico.rom + PicoPatches[i].addr); if (strstr(PicoPatches[i].name, "AUTO")) PicoPatches[i].active = 1; } @@ -333,9 +334,7 @@ void PicoPatchApply(void) } else { - /* RAM or some other weird patch */ - if (PicoPatches[i].active) - PicoWrite16(addr, PicoPatches[i].data); + /* TODO? */ } } } diff --git a/pico/pico.c b/pico/pico.c index 9b390c70..ab2302e3 100644 --- a/pico/pico.c +++ b/pico/pico.c @@ -57,7 +57,7 @@ void PicoExit(void) void PicoPower(void) { - unsigned char sram_reg=Pico.m.sram_reg; // must be preserved + unsigned char sram_status = Pico.m.sram_status; // must be preserved Pico.m.frame_count = 0; @@ -78,7 +78,7 @@ void PicoPower(void) if (PicoAHW & PAHW_MCD) PicoPowerMCD(); - Pico.m.sram_reg=sram_reg; + Pico.m.sram_status = sram_status; PicoReset(); } @@ -94,14 +94,16 @@ PICO_INTERNAL void PicoDetectRegion(void) else { // Read cartridge region data: - int region=PicoRead32(0x1f0); + unsigned short *rd = (unsigned short *)(Pico.rom + 0x1f0); + int region = (rd[0] << 16) | rd[1]; - for (i=0;i<4;i++) + for (i = 0; i < 4; i++) { - int c=0; + int c; - c=region>>(i<<3); c&=0xff; - if (c<=' ') continue; + c = region >> (i<<3); + c &= 0xff; + if (c <= ' ') continue; if (c=='J') support|=1; else if (c=='U') support|=4; @@ -139,7 +141,7 @@ PICO_INTERNAL void PicoDetectRegion(void) int PicoReset(void) { - unsigned char sram_reg=Pico.m.sram_reg; // must be preserved + unsigned char sram_status = Pico.m.sram_status; // must be preserved if (Pico.romsize <= 0) return 1; @@ -148,7 +150,6 @@ int PicoReset(void) if (PicoResetHook) PicoResetHook(); - PicoMemReset(); memset(&PicoPadInt,0,sizeof(PicoPadInt)); emustatus = 0; @@ -169,6 +170,7 @@ int PicoReset(void) Pico.m.dirtyPal = 1; Pico.m.z80_bank68k = 0; + Pico.m.z80_reset = 1; memset(Pico.zram, 0, sizeof(Pico.zram)); // ?? PicoDetectRegion(); @@ -192,11 +194,12 @@ int PicoReset(void) SekInitIdleDet(); // reset sram state; enable sram access by default if it doesn't overlap with ROM - Pico.m.sram_reg=sram_reg&0x14; - if (!(Pico.m.sram_reg&4) && Pico.romsize <= SRam.start) Pico.m.sram_reg |= 1; + 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; elprintf(EL_STATUS, "sram: det: %i; eeprom: %i; start: %06x; end: %06x", - (Pico.m.sram_reg>>4)&1, (Pico.m.sram_reg>>2)&1, SRam.start, SRam.end); + !!(sram_status & SRS_DETECTED), !!(sram_status & SRS_EEPROM), SRam.start, SRam.end); return 0; } diff --git a/pico/pico_int.h b/pico/pico_int.h index b5f4a95c..8c72bba2 100644 --- a/pico/pico_int.h +++ b/pico/pico_int.h @@ -255,7 +255,7 @@ 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_reg; // SRAM mode register. bit0: allow read? bit1: deny write? bit2: EEPROM? bit4: detected? (header or by access) + unsigned char sram_status; // 09 SRAM status. See SRS_* below unsigned short z80_bank68k; // 0a unsigned short z80_lastaddr; // this is for Z80 faking unsigned char z80_fakeval; @@ -293,6 +293,11 @@ struct Pico }; // sram +#define SRS_MAPPED (1 << 0) +#define SRS_READONLY (1 << 1) +#define SRS_EEPROM (1 << 2) +#define SRS_DETECTED (1 << 4) + struct PicoSRAM { unsigned char *data; // actual data @@ -435,26 +440,24 @@ void PicoDrawSetColorFormatMode4(int which); // memory.c PICO_INTERNAL void PicoInitPc(unsigned int pc); PICO_INTERNAL unsigned int PicoCheckPc(unsigned int pc); -PICO_INTERNAL_ASM unsigned int PicoRead32(unsigned int a); PICO_INTERNAL void PicoMemSetup(void); -PICO_INTERNAL_ASM void PicoMemReset(void); PICO_INTERNAL void PicoMemResetHooks(void); -PICO_INTERNAL int PadRead(int i); -PICO_INTERNAL int ym2612_write_local(unsigned int a, unsigned int d, int is_from_z80); -void z80_mem_setup(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); +void PicoWrite16_io(unsigned int a, unsigned int d); + +// pico/memory.c +PICO_INTERNAL void PicoMemSetupPico(void); // cd/memory.c PICO_INTERNAL void PicoMemSetupCD(void); -PICO_INTERNAL_ASM void PicoMemResetCD(int r3); +PICO_INTERNAL_ASM void PicoMemRemapCD(int r3); PICO_INTERNAL_ASM void PicoMemResetCDdecode(int r3); -// pico/memory.c -PICO_INTERNAL void PicoMemSetupPico(void); -PICO_INTERNAL unsigned int ym2612_read_local_68k(void); - // pico.c extern struct Pico Pico; extern struct PicoSRAM SRam; @@ -534,9 +537,9 @@ 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 SRAMWriteEEPROM(unsigned int d); -PICO_INTERNAL void SRAMUpdPending(unsigned int a, unsigned int d); -PICO_INTERNAL_ASM unsigned int SRAMReadEEPROM(void); +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 @@ -548,8 +551,6 @@ PICO_INTERNAL void z80_pack(unsigned char *data); PICO_INTERNAL void z80_unpack(unsigned char *data); PICO_INTERNAL void z80_reset(void); PICO_INTERNAL void z80_exit(void); -void z80_map_set(unsigned long *map, int start_addr, - int end_addr, void *func_or_mh, int is_func); // cd/misc.c PICO_INTERNAL_ASM void wram_2M_to_1M(unsigned char *m); @@ -595,6 +596,8 @@ void PicoFrameDrawOnlyMS(void); #define EL_SVP 0x00004000 /* SVP stuff */ #define EL_PICOHW 0x00008000 /* Pico stuff */ #define EL_IDLE 0x00010000 /* idle loop det. */ +#define EL_CDREGS 0x00020000 /* MCD: register access */ +#define EL_CDREG3 0x00040000 /* MCD: register 3 only */ #define EL_STATUS 0x40000000 /* status messages */ #define EL_ANOMALY 0x80000000 /* some unexpected conditions (during emulation) */ diff --git a/pico/sms.c b/pico/sms.c index e483291a..dfe7769e 100644 --- a/pico/sms.c +++ b/pico/sms.c @@ -9,6 +9,7 @@ * - H counter */ #include "pico_int.h" +#include "memory.h" #include "sound/sn76496.h" static unsigned char vdp_data_read(void) diff --git a/pico/sound/sound.c b/pico/sound/sound.c index b1204e22..6e0db26c 100644 --- a/pico/sound/sound.c +++ b/pico/sound/sound.c @@ -107,14 +107,9 @@ static void dac_recalculate(void) PICO_INTERNAL void PsndReset(void) { - void *ym2612_regs; - - // also clear the internal registers+addr line - ym2612_regs = YM2612GetRegs(); - memset(ym2612_regs, 0, 0x200+4); - timers_reset(); - + // PsndRerate calls YM2612Init, which also resets PsndRerate(0); + timers_reset(); } diff --git a/pico/z80if.c b/pico/z80if.c index 1b35e50c..63b79daf 100644 --- a/pico/z80if.c +++ b/pico/z80if.c @@ -6,32 +6,6 @@ unsigned long z80_read_map [0x10000 >> Z80_MEM_SHIFT]; unsigned long z80_write_map[0x10000 >> Z80_MEM_SHIFT]; -void MEMH_FUNC z80_map_set(unsigned long *map, int start_addr, int end_addr, - void *func_or_mh, int is_func) -{ - unsigned long addr = (unsigned long)func_or_mh; - int mask = (1 << Z80_MEM_SHIFT) - 1; - int i; - - if ((start_addr & mask) != 0 || (end_addr & mask) != mask) - elprintf(EL_STATUS|EL_ANOMALY, "z80_map_set: tried to map bad range: %04x-%04x", - start_addr, end_addr); - - if (addr & 1) { - elprintf(EL_STATUS|EL_ANOMALY, "z80_map_set: ptr is not aligned: %08lx", addr); - return; - } - - if (!is_func) - addr -= (start_addr >> Z80_MEM_SHIFT) << Z80_MEM_SHIFT; - - for (i = start_addr >> Z80_MEM_SHIFT; i <= end_addr >> Z80_MEM_SHIFT; i++) { - map[i] = addr >> 1; - if (is_func) - map[i] |= 1 << (sizeof(addr) * 8 - 1); - } -} - #ifdef _USE_MZ80 // memhandlers for mz80 core diff --git a/platform/common/common_arm.mak b/platform/common/common_arm.mak index 79b61fbc..397e7135 100644 --- a/platform/common/common_arm.mak +++ b/platform/common/common_arm.mak @@ -48,7 +48,7 @@ mkdirs: # deps pico/carthw/svp/compiler.o : ../../pico/carthw/svp/ssp16.o ../../pico/carthw/svp/gen_arm.c pico/pico.o pico/cd/pico.o : ../../pico/pico_cmn.c ../../pico/pico_int.h -pico/memory.o pico/cd/memory.o : ../../pico/memory_cmn.c ../../pico/pico_int.h +pico/memory.o pico/cd/memory.o : ../../pico/pico_int.h ../../pico/memory.h # build Cyclone ../../cpu/Cyclone/proj/Cyclone.s: diff --git a/platform/common/emu.c b/platform/common/emu.c index 4a95a3ff..4fcb7922 100644 --- a/platform/common/emu.c +++ b/platform/common/emu.c @@ -989,7 +989,8 @@ int emu_save_load_game(int load, int sram) } } else { sram_size = SRam.end-SRam.start+1; - if(Pico.m.sram_reg & 4) sram_size=0x2000; + if (Pico.m.sram_status & SRS_EEPROM) + sram_size = 0x2000; sram_data = SRam.data; } if (!sram_data) return 0; // SRam forcefully disabled for this game diff --git a/platform/common/revision.mak b/platform/common/revision.mak index 03093e36..2e92875f 100644 --- a/platform/common/revision.mak +++ b/platform/common/revision.mak @@ -1,7 +1,11 @@ platform/common/menu.o : revision.h revision.h: FORCE +ifndef NOREVISION @echo "#define REVISION \"`svn info -r HEAD | grep Revision | cut -c 11-`\"" > /tmp/r.tmp +else + @echo "#define REVISION \"0\"" > /tmp/r.tmp +endif @diff -q $@ /tmp/r.tmp > /dev/null 2>&1 || mv -f /tmp/r.tmp $@ FORCE: diff --git a/platform/gp2x/Makefile b/platform/gp2x/Makefile index 92e5d97e..ef631992 100644 --- a/platform/gp2x/Makefile +++ b/platform/gp2x/Makefile @@ -3,12 +3,12 @@ export CROSS = arm-linux- # settings #mz80 = 1 #debug_cyclone = 1 -asm_memory = 1 +#asm_memory = 1 # TODO asm_render = 1 asm_ym2612 = 1 asm_misc = 1 asm_cdpico = 1 -asm_cdmemory = 1 +#asm_cdmemory = 1 # TODO amalgamate = 0 #profile = 1 #use_musashi = 1 diff --git a/platform/linux/Makefile b/platform/linux/Makefile index 033d3bd5..2202db2f 100644 --- a/platform/linux/Makefile +++ b/platform/linux/Makefile @@ -103,7 +103,7 @@ include ../common/revision.mak pico/carthw/svp/compiler.o : ../../pico/carthw/svp/gen_arm.c pico/pico.o pico/cd/pico.o : ../../pico/pico_cmn.c ../../pico/pico_int.h -pico/memory.o pico/cd/memory.o : ../../pico/memory_cmn.c ../../pico/pico_int.h +pico/memory.o pico/cd/memory.o : ../../pico/pico_int.h ../../pico/memory.h ../../cpu/musashi/m68kops.c : @make -C ../../cpu/musashi