mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 15:27:46 -04:00
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
This commit is contained in:
parent
c238eec8f5
commit
af37bca858
20 changed files with 1173 additions and 1720 deletions
30
pico/cart.c
30
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;
|
||||
|
|
|
@ -275,7 +275,7 @@ readend:
|
|||
/* after load events */
|
||||
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)
|
||||
PicoMemResetCDdecode(Pico_mcd->s68k_regs[3]);
|
||||
|
|
1510
pico/cd/memory.c
1510
pico/cd/memory.c
File diff suppressed because it is too large
Load diff
|
@ -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,7 +46,6 @@ 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
|
||||
|
|
|
@ -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)
|
||||
|
|
810
pico/memory.c
810
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)
|
||||
{
|
||||
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
|
||||
}
|
||||
if (sreg & 4) // EEPROM read
|
||||
return SRAMReadEEPROM();
|
||||
else // if(sreg & 1) // (sreg&5) is one of prerequisites
|
||||
return *(u8 *)(SRam.data-SRam.start+a);
|
||||
}
|
||||
|
||||
#ifndef _ASM_MEMORY_C
|
||||
static
|
||||
#endif
|
||||
u32 SRAMRead16(u32 a)
|
||||
static u32 io_ports_read(u32 a)
|
||||
{
|
||||
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;
|
||||
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
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
static void SRAMWrite(u32 a, u32 d)
|
||||
static void io_ports_write(u32 a, 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;
|
||||
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]++;
|
||||
}
|
||||
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();
|
||||
|
||||
// cartain IO ports can be used as RAM
|
||||
Pico.ioports[a] = d;
|
||||
}
|
||||
} else if(!(sreg & 2)) {
|
||||
u8 *pm=(u8 *)(SRam.data-SRam.start+a);
|
||||
if(*pm != (u8)d) {
|
||||
SRam.changed = 1;
|
||||
*pm=(u8)d;
|
||||
|
||||
static void ctl_write_z80busreq(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 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
|
||||
{
|
||||
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"
|
||||
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// Read Rom and read Ram
|
||||
|
||||
#ifndef _ASM_MEMORY_C
|
||||
PICO_INTERNAL_ASM u32 PicoRead8(u32 a)
|
||||
// cart (save) RAM area (usually 0x200000 - ...)
|
||||
static u32 PicoRead8_sram(u32 a)
|
||||
{
|
||||
u32 d=0;
|
||||
|
||||
if ((a&0xe00000)==0xe00000) { d = *(u8 *)(Pico.ram+((a^1)&0xffff)); goto end; } // Ram
|
||||
|
||||
a&=0xffffff;
|
||||
|
||||
#ifndef EMU_CORE_DEBUG
|
||||
// sram
|
||||
if (a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg&5)) {
|
||||
d = SRAMRead(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);
|
||||
goto end;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (a<Pico.romsize) { d = *(u8 *)(Pico.rom+(a^1)); goto end; } // Rom
|
||||
log_io(a, 8, 0);
|
||||
if ((a&0xff4000)==0xa00000) { d=z80Read8(a); goto end; } // Z80 Ram
|
||||
|
||||
if ((a&0xe700e0)==0xc00000) { d=PicoVideoRead8(a); goto end; } // VDP
|
||||
|
||||
d=OtherRead16(a&~1, 8);
|
||||
if ((a&1)==0) d>>=8;
|
||||
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
return d;
|
||||
}
|
||||
|
||||
PICO_INTERNAL_ASM u32 PicoRead16(u32 a)
|
||||
if (a < Pico.romsize)
|
||||
return Pico.rom[a ^ 1];
|
||||
|
||||
return m68k_unmapped_read8(a);
|
||||
}
|
||||
|
||||
static u32 PicoRead16_sram(u32 a)
|
||||
{
|
||||
u32 d=0;
|
||||
|
||||
if ((a&0xe00000)==0xe00000) { d=*(u16 *)(Pico.ram+(a&0xfffe)); goto end; } // Ram
|
||||
|
||||
a&=0xfffffe;
|
||||
|
||||
#ifndef EMU_CORE_DEBUG
|
||||
// sram
|
||||
if (a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg&5)) {
|
||||
d = SRAMRead16(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();
|
||||
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);
|
||||
goto end;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (a<Pico.romsize) { d = *(u16 *)(Pico.rom+a); goto end; } // Rom
|
||||
log_io(a, 16, 0);
|
||||
|
||||
if ((a&0xe700e0)==0xc00000)
|
||||
d = PicoVideoRead(a);
|
||||
else d = OtherRead16(a, 16);
|
||||
|
||||
end:
|
||||
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;
|
||||
}
|
||||
|
||||
PICO_INTERNAL_ASM u32 PicoRead32(u32 a)
|
||||
if (a < Pico.romsize)
|
||||
return *(u16 *)(Pico.rom + a);
|
||||
|
||||
return m68k_unmapped_read16(a);
|
||||
}
|
||||
|
||||
static void PicoWrite8_sram(u32 a, u32 d)
|
||||
{
|
||||
u32 d=0;
|
||||
|
||||
if ((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); d = (pm[0]<<16)|pm[1]; goto end; } // Ram
|
||||
|
||||
a&=0xfffffe;
|
||||
|
||||
// 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);
|
||||
goto end;
|
||||
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();
|
||||
}
|
||||
}
|
||||
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<Pico.romsize) { u16 *pm=(u16 *)(Pico.rom+a); d = (pm[0]<<16)|pm[1]; goto end; } // Rom
|
||||
log_io(a, 32, 0);
|
||||
|
||||
if ((a&0xe700e0)==0xc00000)
|
||||
d = (PicoVideoRead(a)<<16)|PicoVideoRead(a+2);
|
||||
else d = (OtherRead16(a, 32)<<16)|OtherRead16(a+2, 32);
|
||||
|
||||
end:
|
||||
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;
|
||||
static void PicoWrite16_sram(u32 a, u32 d)
|
||||
{
|
||||
// XXX: hardware could easily use MSB too..
|
||||
PicoWrite8_sram(a + 1, d);
|
||||
}
|
||||
#endif
|
||||
|
||||
// z80 area (0xa00000 - 0xa0ffff)
|
||||
// TODO: verify mirrors VDP and bank reg (bank area mirroring verified)
|
||||
static u32 PicoRead8_z80(u32 a)
|
||||
{
|
||||
u32 d = 0xff;
|
||||
if ((Pico.m.z80Run & 1) || Pico.m.z80_reset) {
|
||||
elprintf(EL_ANOMALY, "68k z80 read with no bus! [%06x] @ %06x", a, SekPc);
|
||||
// open bus. Pulled down if MegaCD2 is attached.
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// Write Ram
|
||||
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)
|
||||
PICO_INTERNAL_ASM void PicoWrite8(u32 a,u8 d)
|
||||
if ((a & 0x7f00) == 0x6000) // Z80 BANK register
|
||||
{
|
||||
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) { *(u8 *)(Pico.ram+((a^1)&0xffff))=d; return; } // Ram
|
||||
log_io(a, 8, 1);
|
||||
|
||||
a&=0xffffff;
|
||||
OtherWrite8(a,d);
|
||||
}
|
||||
#endif
|
||||
|
||||
void PicoWrite16(u32 a,u16 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) { *(u16 *)(Pico.ram+(a&0xfffe))=d; return; } // Ram
|
||||
log_io(a, 16, 1);
|
||||
|
||||
a&=0xfffffe;
|
||||
if ((a&0xe700e0)==0xc00000) { PicoVideoWrite(a,(u16)d); return; } // VDP
|
||||
OtherWrite16(a,d);
|
||||
}
|
||||
|
||||
static void PicoWrite32(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;
|
||||
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;
|
||||
}
|
||||
log_io(a, 32, 1);
|
||||
#endif
|
||||
elprintf(EL_UIO|EL_ANOMALY, "68k bad write [%06x] %02x @ %06x", a, d&0xff, SekPc);
|
||||
}
|
||||
|
||||
a&=0xfffffe;
|
||||
if ((a&0xe700e0)==0xc00000)
|
||||
static void PicoWrite16_z80(u32 a, u32 d)
|
||||
{
|
||||
// VDP:
|
||||
PicoVideoWrite(a, (u16)(d>>16));
|
||||
PicoVideoWrite(a+2,(u16)d);
|
||||
// for RAM, only most significant byte is sent
|
||||
// TODO: verify remaining accesses
|
||||
PicoWrite8_z80(a, d >> 8);
|
||||
}
|
||||
|
||||
// IO/control area (0xa10000 - 0xa1ffff)
|
||||
u32 PicoRead8_io(u32 a)
|
||||
{
|
||||
u32 d;
|
||||
|
||||
if ((a & 0xffe0) == 0x0000) { // I/O ports
|
||||
d = io_ports_read(a);
|
||||
goto end;
|
||||
}
|
||||
|
||||
// faking open bus (MegaCD pulldowns don't work here curiously)
|
||||
d = Pico.m.rotate++;
|
||||
d ^= d << 6;
|
||||
|
||||
// bit8 seems to be readable in this range
|
||||
if ((a & 0xfc01) == 0x1000)
|
||||
d &= ~0x01;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
d = m68k_unmapped_read8(a);
|
||||
end:
|
||||
return d;
|
||||
}
|
||||
|
||||
u32 PicoRead16_io(u32 a)
|
||||
{
|
||||
u32 d;
|
||||
|
||||
if ((a & 0xffe0) == 0x0000) { // I/O ports
|
||||
d = io_ports_read(a);
|
||||
goto end;
|
||||
}
|
||||
|
||||
// faking open bus
|
||||
d = (Pico.m.rotate += 0x41);
|
||||
d ^= (d << 5) ^ (d << 8);
|
||||
|
||||
// bit8 seems to be readable in this range
|
||||
if ((a & 0xfc00) == 0x1000)
|
||||
d &= ~0x0100;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
d = m68k_unmapped_read16(a);
|
||||
end:
|
||||
return d;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void PicoWrite16_io(u32 a, u32 d)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
elprintf(EL_UIO|EL_ANOMALY, "68k bad read [%06x] @%06x", a, SekPc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 PicoRead16_vdp(u32 a)
|
||||
{
|
||||
if ((a & 0x00e0) == 0x0000)
|
||||
return PicoVideoRead(a);
|
||||
|
||||
elprintf(EL_UIO|EL_ANOMALY, "68k bad read [%06x] @%06x", a, SekPc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void PicoWrite8_vdp(u32 a, u32 d)
|
||||
{
|
||||
if ((a & 0x00f9) == 0x0011) { // PSG Sound
|
||||
if (PicoOpt & POPT_EN_PSG)
|
||||
SN76496Write(d);
|
||||
return;
|
||||
}
|
||||
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.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);
|
||||
|
|
116
pico/memory.h
Normal file
116
pico/memory.h
Normal file
|
@ -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; \
|
||||
} \
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
20
pico/misc.c
20
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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? */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
23
pico/pico.c
23
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,13 +94,15 @@ 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++)
|
||||
{
|
||||
int c=0;
|
||||
int c;
|
||||
|
||||
c=region>>(i<<3); c&=0xff;
|
||||
c = region >> (i<<3);
|
||||
c &= 0xff;
|
||||
if (c <= ' ') continue;
|
||||
|
||||
if (c=='J') support|=1;
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,25 +440,23 @@ 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);
|
||||
|
||||
// cd/memory.c
|
||||
PICO_INTERNAL void PicoMemSetupCD(void);
|
||||
PICO_INTERNAL_ASM void PicoMemResetCD(int r3);
|
||||
PICO_INTERNAL_ASM void PicoMemResetCDdecode(int r3);
|
||||
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);
|
||||
PICO_INTERNAL unsigned int ym2612_read_local_68k(void);
|
||||
|
||||
// cd/memory.c
|
||||
PICO_INTERNAL void PicoMemSetupCD(void);
|
||||
PICO_INTERNAL_ASM void PicoMemRemapCD(int r3);
|
||||
PICO_INTERNAL_ASM void PicoMemResetCDdecode(int r3);
|
||||
|
||||
// pico.c
|
||||
extern struct Pico Pico;
|
||||
|
@ -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) */
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
* - H counter
|
||||
*/
|
||||
#include "pico_int.h"
|
||||
#include "memory.h"
|
||||
#include "sound/sn76496.h"
|
||||
|
||||
static unsigned char vdp_data_read(void)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
26
pico/z80if.c
26
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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue