sharc: Use standard memory maps [O. Galibert]

This commit is contained in:
Olivier Galibert 2016-12-09 17:23:47 +01:00
parent 962fda50bc
commit 7f0ba30ec5
5 changed files with 164 additions and 624 deletions

View File

@ -52,29 +52,37 @@ enum
SHARC_B12, SHARC_B13, SHARC_B14, SHARC_B15
};
#define ROPCODE(pc) ((uint64_t)(m_internal_ram[((pc-0x20000) * 3) + 0]) << 32) | \
((uint64_t)(m_internal_ram[((pc-0x20000) * 3) + 1]) << 16) | \
((uint64_t)(m_internal_ram[((pc-0x20000) * 3) + 2]) << 0)
const device_type ADSP21062 = &device_creator<adsp21062_device>;
// This is just used to stop the debugger from complaining about executing from I/O space
static ADDRESS_MAP_START( internal_pgm, AS_PROGRAM, 64, adsp21062_device )
AM_RANGE(0x20000, 0x7ffff) AM_RAM AM_SHARE("x")
AM_RANGE(0x20000, 0x24fff) AM_READWRITE(pm0_r, pm0_w)
AM_RANGE(0x28000, 0x2cfff) AM_READWRITE(pm1_r, pm1_w)
AM_RANGE(0x30000, 0x34fff) AM_READWRITE(pm1_r, pm1_w)
AM_RANGE(0x38000, 0x3cfff) AM_READWRITE(pm1_r, pm1_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( internal_data, AS_DATA, 32, adsp21062_device )
AM_RANGE(0x00000, 0x000ff) AM_READWRITE(iop_r, iop_w)
AM_RANGE(0x20000, 0x27fff) AM_RAM AM_SHARE("block0")
AM_RANGE(0x28000, 0x2ffff) AM_RAM AM_SHARE("block1")
AM_RANGE(0x30000, 0x37fff) AM_RAM AM_SHARE("block1")
AM_RANGE(0x38000, 0x3ffff) AM_RAM AM_SHARE("block1")
AM_RANGE(0x40000, 0x4ffff) AM_READWRITE(dmw0_r, dmw0_w)
AM_RANGE(0x50000, 0x5ffff) AM_READWRITE(dmw1_r, dmw1_w)
AM_RANGE(0x60000, 0x6ffff) AM_READWRITE(dmw1_r, dmw1_w)
AM_RANGE(0x70000, 0x7ffff) AM_READWRITE(dmw1_r, dmw1_w)
ADDRESS_MAP_END
adsp21062_device::adsp21062_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: cpu_device(mconfig, ADSP21062, "ADSP21062", tag, owner, clock, "adsp21062", __FILE__)
, m_program_config("program", ENDIANNESS_LITTLE, 64, 24, -3, ADDRESS_MAP_NAME(internal_pgm))
, m_data_config("data", ENDIANNESS_LITTLE, 32, 32, -2)
, m_data_config("data", ENDIANNESS_LITTLE, 32, 32, -2, ADDRESS_MAP_NAME(internal_data))
, m_boot_mode(BOOT_MODE_HOST)
, m_cache(CACHE_SIZE + sizeof(sharc_internal_state))
, m_drcuml(nullptr)
, m_drcfe(nullptr)
, m_block0(*this, "block0")
, m_block1(*this, "block1")
, m_enable_drc(false)
{
}
@ -88,7 +96,7 @@ offs_t adsp21062_device::disasm_disassemble(std::ostream &stream, offs_t pc, con
void adsp21062_device::enable_recompiler()
{
m_enable_drc = true;
m_enable_drc = allow_drc();
}
@ -144,11 +152,98 @@ void adsp21062_device::sharc_iop_delayed_w(uint32_t reg, uint32_t data, int cycl
m_core->delayed_iop_timer->adjust(cycles_to_attotime(cycles), 0);
}
// 0 012 0h 0l 1h
// 1 453 2h 2l 1l
// 2 678 3h 3l 4h
// 3 ab9 5h 5l 4l
// 4 cde 6h 6l 7h
READ64_MEMBER( adsp21062_device::pm0_r)
{
offs_t slot = offset >> 12;
offs_t base = (offset & 0xfff) + (slot >> 1) * (3<<12);
if(slot & 1)
return (uint64_t(m_block0[base + 0x2000]) << 16) | (m_block0[base + 0x1000] & 0xffff);
else
return (uint64_t(m_block0[base ]) << 16) | (m_block0[base + 0x1000] >> 16);
}
WRITE64_MEMBER(adsp21062_device::pm0_w)
{
offs_t slot = offset >> 12;
offs_t base = (offset & 0xfff) + (slot >> 1) * (3<<12);
if(slot & 1) {
if(ACCESSING_BITS_0_15)
m_block0[base + 0x1000] = (m_block0[base + 0x1000] & 0xffff0000) | (data & 0xffff);
m_block0[base + 0x2000] = (m_block0[base + 0x2000] & ~(mem_mask >> 16)) | ((data & mem_mask) >> 16);
} else {
m_block0[base + 0x0000] = (m_block0[base + 0x0000] & ~(mem_mask >> 16)) | ((data & mem_mask) >> 16);
if(ACCESSING_BITS_0_15)
m_block0[base + 0x1000] = (m_block0[base + 0x1000] & 0xffff) | ((data & 0xffff) << 16);
}
}
READ64_MEMBER( adsp21062_device::pm1_r)
{
offs_t slot = offset >> 12;
offs_t base = (offset & 0xfff) + (slot >> 1) * (3<<12);
if(slot & 1)
return (uint64_t(m_block1[base + 0x2000]) << 16) | (m_block1[base + 0x1000] & 0xffff);
else
return (uint64_t(m_block1[base ]) << 16) | (m_block1[base + 0x1000] >> 16);
}
WRITE64_MEMBER(adsp21062_device::pm1_w)
{
offs_t slot = offset >> 12;
offs_t base = (offset & 0xfff) + (slot >> 1) * (3<<12);
if(slot & 1) {
if(ACCESSING_BITS_0_15)
m_block1[base + 0x1000] = (m_block1[base + 0x1000] & 0xffff0000) | (data & 0xffff);
m_block1[base + 0x2000] = (m_block1[base + 0x2000] & ~(mem_mask >> 16)) | ((data & mem_mask) >> 16);
} else {
m_block1[base + 0x0000] = (m_block1[base + 0x0000] & ~(mem_mask >> 16)) | ((data & mem_mask) >> 16);
if(ACCESSING_BITS_0_15)
m_block1[base + 0x1000] = (m_block1[base + 0x1000] & 0xffff) | ((data & 0xffff) << 16);
}
}
READ32_MEMBER( adsp21062_device::dmw0_r)
{
if(offset & 1)
return m_block0[offset >> 1] >> 16;
else
return m_block0[offset >> 1] & 0xffff;
}
WRITE32_MEMBER(adsp21062_device::dmw0_w)
{
if(offset & 1)
m_block0[offset >> 1] = (m_block0[offset >> 1] & 0xffff) | (data << 16);
else
m_block0[offset >> 1] = (m_block0[offset >> 1] & 0xffff0000) | (data & 0xffff);
}
READ32_MEMBER( adsp21062_device::dmw1_r)
{
if(offset & 1)
return m_block1[offset >> 1] >> 16;
else
return m_block1[offset >> 1] & 0xffff;
}
WRITE32_MEMBER(adsp21062_device::dmw1_w)
{
if(offset & 1)
m_block1[offset >> 1] = (m_block1[offset >> 1] & 0xffff) | (data << 16);
else
m_block1[offset >> 1] = (m_block1[offset >> 1] & 0xffff0000) | (data & 0xffff);
}
/* IOP registers */
uint32_t adsp21062_device::sharc_iop_r(uint32_t address)
READ32_MEMBER( adsp21062_device::iop_r)
{
switch (address)
switch (offset)
{
case 0x00: return 0; // System configuration
@ -156,13 +251,13 @@ uint32_t adsp21062_device::sharc_iop_r(uint32_t address)
{
return m_core->dma_status;
}
default: fatalerror("sharc_iop_r: Unimplemented IOP reg %02X at %08X\n", address, m_core->pc);
default: fatalerror("sharc_iop_r: Unimplemented IOP reg %02X at %08X\n", offset, m_core->pc);
}
}
void adsp21062_device::sharc_iop_w(uint32_t address, uint32_t data)
WRITE32_MEMBER(adsp21062_device::iop_w)
{
switch (address)
switch (offset)
{
case 0x00: break; // System configuration
case 0x02: break; // External Memory Wait State Configuration
@ -240,7 +335,7 @@ void adsp21062_device::sharc_iop_w(uint32_t address, uint32_t data)
case 0x4e: m_core->dma[7].ext_modifier = data; return;
case 0x4f: m_core->dma[7].ext_count = data; return;
default: fatalerror("sharc_iop_w: Unimplemented IOP reg %02X, %08X at %08X\n", address, data, m_core->pc);
default: fatalerror("sharc_iop_w: Unimplemented IOP reg %02X, %08X at %08X\n", offset, data, m_core->pc);
}
}
@ -297,7 +392,7 @@ void adsp21062_device::external_iop_write(uint32_t address, uint32_t data)
else
{
osd_printf_debug("SHARC IOP write %08X, %08X\n", address, data);
sharc_iop_w(address, data);
m_data->write_dword(address << 2, data);
}
}
@ -341,14 +436,10 @@ void adsp21062_device::device_start()
memset(m_core, 0, sizeof(sharc_internal_state));
m_program = &space(AS_PROGRAM);
m_direct = &m_program->direct();
m_data = &space(AS_DATA);
build_opcode_table();
m_internal_ram_block0 = &m_internal_ram[0];
m_internal_ram_block1 = &m_internal_ram[0x20000/2];
// init UML generator
uint32_t umlflags = 0;
m_drcuml = std::make_unique<drcuml_state>(*this, m_cache, umlflags, 1, 24, 0);
@ -615,8 +706,6 @@ void adsp21062_device::device_start()
save_item(NAME(m_core->px));
save_pointer(NAME(m_internal_ram), 2 * 0x10000);
save_item(NAME(m_core->opcode));
save_item(NAME(m_core->nfaddr));
@ -767,7 +856,8 @@ void adsp21062_device::device_start()
void adsp21062_device::device_reset()
{
memset(m_internal_ram, 0, 2 * 0x10000 * sizeof(uint16_t));
memset(m_block0, 0, 0x8000 * sizeof(uint32_t));
memset(m_block1, 0, 0x8000 * sizeof(uint32_t));
switch(m_boot_mode)
{
@ -898,6 +988,12 @@ void adsp21062_device::check_interrupts()
void adsp21062_device::execute_run()
{
static bool first = true;
if(first) {
first = false;
machine().debug_break();
}
if (m_enable_drc)
{
if (m_core->irq_pending != 0)
@ -931,9 +1027,15 @@ void adsp21062_device::execute_run()
m_core->astat_old_old = m_core->astat_old;
m_core->astat_old = m_core->astat;
static bool first = true;
if(first) {
first = false;
machine().debug_break();
}
debugger_instruction_hook(this, m_core->pc);
m_core->opcode = ROPCODE(m_core->pc);
m_core->opcode = m_program->read_qword(m_core->pc << 3);
// handle looping
if (m_core->pc == m_core->laddr.addr)
@ -1011,92 +1113,3 @@ void adsp21062_device::execute_run()
};
}
}
bool adsp21062_device::memory_read(address_spacenum spacenum, offs_t offset, int size, uint64_t &value)
{
if (spacenum == AS_PROGRAM)
{
int address = offset >> 3;
if (address >= 0x20000 && address < 0x30000)
{
switch (size)
{
case 1:
{
int frac = offset & 7;
value = (pm_read48(offset >> 3) >> ((frac^7) * 8)) & 0xff;
break;
}
case 8:
{
value = pm_read48(offset >> 3);
break;
}
}
}
else
{
value = 0;
}
}
else if (spacenum == AS_DATA)
{
int address = offset >> 2;
if (address >= 0x20000)
{
switch (size)
{
case 1:
{
int frac = offset & 3;
value = (dm_read32(offset >> 2) >> ((frac^3) * 8)) & 0xff;
break;
}
case 2:
{
int frac = (offset >> 1) & 1;
value = (dm_read32(offset >> 2) >> ((frac^1) * 16)) & 0xffff;
break;
}
case 4:
{
value = dm_read32(offset >> 2);
break;
}
}
}
else
{
value = 0;
}
}
return true;
}
bool adsp21062_device::memory_readop(offs_t offset, int size, uint64_t &value)
{
uint64_t mask = (size < 8) ? (((uint64_t)1 << (8 * size)) - 1) : ~(uint64_t)0;
int shift = 8 * (offset & 7);
offset >>= 3;
if (offset >= 0x20000 && offset < 0x28000)
{
uint64_t op = ((uint64_t)(m_internal_ram_block0[((offset-0x20000) * 3) + 0]) << 32) |
((uint64_t)(m_internal_ram_block0[((offset-0x20000) * 3) + 1]) << 16) |
((uint64_t)(m_internal_ram_block0[((offset-0x20000) * 3) + 2]) << 0);
value = (op >> shift) & mask;
return true;
}
else if (offset >= 0x28000 && offset < 0x30000)
{
uint64_t op = ((uint64_t)(m_internal_ram_block1[((offset-0x28000) * 3) + 0]) << 32) |
((uint64_t)(m_internal_ram_block1[((offset-0x28000) * 3) + 1]) << 16) |
((uint64_t)(m_internal_ram_block1[((offset-0x28000) * 3) + 2]) << 0);
value = (op >> shift) & mask;
return true;
}
return false;
}

View File

@ -171,6 +171,17 @@ public:
void enable_recompiler();
DECLARE_READ64_MEMBER( pm0_r);
DECLARE_WRITE64_MEMBER(pm0_w);
DECLARE_READ64_MEMBER( pm1_r);
DECLARE_WRITE64_MEMBER(pm1_w);
DECLARE_READ32_MEMBER( dmw0_r);
DECLARE_WRITE32_MEMBER(dmw0_w);
DECLARE_READ32_MEMBER( dmw1_r);
DECLARE_WRITE32_MEMBER(dmw1_w);
DECLARE_READ32_MEMBER( iop_r);
DECLARE_WRITE32_MEMBER(iop_w);
enum ASTAT_FLAGS
{
// ASTAT flags
@ -257,16 +268,12 @@ protected:
// device_memory_interface overrides
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const override { return (spacenum == AS_PROGRAM) ? &m_program_config : ( (spacenum == AS_DATA) ? &m_data_config : nullptr ); }
virtual bool memory_read(address_spacenum spacenum, offs_t offset, int size, uint64_t &value) override;
virtual bool memory_readop(offs_t offset, int size, uint64_t &value) override;
// device_disasm_interface overrides
virtual uint32_t disasm_min_opcode_bytes() const override { return 6; }
virtual uint32_t disasm_max_opcode_bytes() const override { return 6; }
virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override;
direct_read_data *m_direct;
private:
address_space_config m_program_config;
address_space_config m_data_config;
@ -448,21 +455,18 @@ private:
uml::code_handle *m_swap_r0_7;
uml::code_handle *m_swap_r8_15;
uint16_t *m_internal_ram_block0, *m_internal_ram_block1;
address_space *m_program;
address_space *m_data;
opcode_func m_sharc_op[512];
uint16_t m_internal_ram[2 * 0x10000]; // 2x 128KB
required_shared_ptr<uint32_t> m_block0, m_block1;
opcode_func m_sharc_op[512];
bool m_enable_drc;
inline void CHANGE_PC(uint32_t newpc);
inline void CHANGE_PC_DELAYED(uint32_t newpc);
void sharc_iop_delayed_w(uint32_t reg, uint32_t data, int cycles);
uint32_t sharc_iop_r(uint32_t address);
void sharc_iop_w(uint32_t address, uint32_t data);
uint32_t pm_read32(uint32_t address);
void pm_write32(uint32_t address, uint32_t data);
uint64_t pm_read48(uint32_t address);

View File

@ -18,7 +18,6 @@
using namespace uml;
#define USE_SWAPDQ 0
#define WRITE_SNOOP 0
// map variables
@ -114,24 +113,13 @@ inline void adsp21062_device::alloc_handle(drcuml_state *drcuml, code_handle **h
static void cfunc_unimplemented(void *param)
{
adsp21062_device *sharc = (adsp21062_device *)param;
sharc->sharc_cfunc_unimplemented();
}
static void cfunc_read_iop(void *param)
{
adsp21062_device *sharc = (adsp21062_device *)param;
sharc->sharc_cfunc_read_iop();
}
static void cfunc_write_iop(void *param)
{
adsp21062_device *sharc = (adsp21062_device *)param;
sharc->sharc_cfunc_write_iop();
}
static void cfunc_pcstack_overflow(void *param)
{
adsp21062_device *sharc = (adsp21062_device *)param;
@ -180,21 +168,6 @@ static void cfunc_unimplemented_shiftimm(void *param)
sharc->sharc_cfunc_unimplemented_shiftimm();
}
#if WRITE_SNOOP
void adsp21062_device::sharc_cfunc_write_snoop()
{
printf("Write %08X to %08X at %08X\n", m_core->arg0, m_core->arg1, m_core->arg2);
}
static void cfunc_write_snoop(void *param)
{
adsp21062_device *sharc = (adsp21062_device *)param;
sharc->sharc_cfunc_write_snoop();
}
#endif
void adsp21062_device::sharc_cfunc_unimplemented()
{
uint64_t op = m_core->arg64;
@ -213,16 +186,6 @@ void adsp21062_device::sharc_cfunc_unimplemented_shiftimm()
fatalerror("PC=%08X: Unimplemented shiftimm %04X%08X\n", m_core->pc, (uint32_t)(op >> 32), (uint32_t)(op));
}
void adsp21062_device::sharc_cfunc_read_iop()
{
m_core->arg1 = sharc_iop_r(m_core->arg0);
}
void adsp21062_device::sharc_cfunc_write_iop()
{
sharc_iop_w(m_core->arg0, m_core->arg1);
}
void adsp21062_device::sharc_cfunc_pcstack_overflow()
{
fatalerror("SHARC: PCStack overflow");
@ -334,16 +297,6 @@ void adsp21062_device::static_generate_memory_accessor(MEM_ACCESSOR_TYPE type, c
{
// I0 = read/write data
// I1 = address
// I2 is trashed
void* block0 = &m_internal_ram_block0[0];
void* block0_1 = &m_internal_ram_block0[1];
void* block0_2 = &m_internal_ram_block0[2];
void* block1 = &m_internal_ram_block1[0];
void* block1_1 = &m_internal_ram_block1[1];
void* block1_2 = &m_internal_ram_block1[2];
code_label label = 1;
drcuml_block *block = m_drcuml->begin_block(1024);
@ -354,298 +307,35 @@ void adsp21062_device::static_generate_memory_accessor(MEM_ACCESSOR_TYPE type, c
switch (type)
{
case MEM_ACCESSOR_PM_READ48:
UML_CMP(block, I1, IRAM_BLOCK0_START); // cmp i1,IRAM_BLOCK0_START
UML_JMPc(block, COND_B, label); // jb label1
UML_CMP(block, I1, IRAM_BLOCK0_END); // cmp i1,IRAM_BLOCK0_END
UML_JMPc(block, COND_A, label); // ja label1
// 0x20000 ... 0x27fff
UML_AND(block, I1, I1, 0x7fff); // and i1,i1,0x7fff
UML_MULS(block, I1, I1, I1, 3); // muls i1,3
UML_DLOAD(block, I0, block0, I1, SIZE_WORD, SCALE_x2); // dload i0,[block0],i1,word,scale_x2
UML_DSHL(block, I0, I0, 32); // dshl i0,i0,32
UML_DLOAD(block, I2, block0_1, I1, SIZE_WORD, SCALE_x2); // dload i2,[block0_1],i1,word,scale_x2
UML_DSHL(block, I2, I2, 16); // dshl i2,i2,16
UML_DOR(block, I0, I0, I2); // dor i0,i0,i2
UML_DLOAD(block, I2, block0_2, I1, SIZE_WORD, SCALE_x2); // dload i2,[block0_2],i1,word,scale_x2
UML_DOR(block, I0, I0, I2); // dor i0,i0,i2
UML_RET(block); // ret
UML_LABEL(block, label++); // label1:
UML_CMP(block, I1, IRAM_BLOCK1_START); // cmp i1,IRAM_BLOCK1_START
UML_JMPc(block, COND_B, label); // jb label2
UML_CMP(block, I1, IRAM_BLOCK1_END); // cmp i1,IRAM_BLOCK1_END
UML_JMPc(block, COND_A, label); // ja label2
// 0x28000 ... 0x3ffff
UML_AND(block, I1, I1, 0x7fff); // and i1,i1,0x7fff (block 1 is mirrored in 0x28000...2ffff, 0x30000...0x37fff and 0x38000...3ffff)
UML_MULS(block, I1, I1, I1, 3); // muls i1,3
UML_DLOAD(block, I0, block1, I1, SIZE_WORD, SCALE_x2); // dload i0,[block1],i1,word,scale_x2
UML_DSHL(block, I0, I0, 32); // dshl i0,i0,32
UML_DLOAD(block, I2, block1_1, I1, SIZE_WORD, SCALE_x2); // dload i2,[block1_1],i1,word,scale_x2
UML_DSHL(block, I2, I2, 16); // dshl i2,i2,16
UML_DOR(block, I0, I0, I2); // dor i0,i0,i2
UML_DLOAD(block, I2, block1_2, I1, SIZE_WORD, SCALE_x2); // dload i2,[block1_2],i1,word,scale_x2
UML_DOR(block, I0, I0, I2); // dor i0,i0,i2
UML_RET(block); // ret
UML_LABEL(block, label++); // label2:
UML_SHL(block, I1, I1, 3);
UML_READ(block, I0, I1, SIZE_QWORD, SPACE_PROGRAM);
break;
case MEM_ACCESSOR_PM_WRITE48:
UML_CMP(block, I1, IRAM_BLOCK0_START); // cmp i1,IRAM_BLOCK0_START
UML_JMPc(block, COND_B, label); // jb label1
UML_CMP(block, I1, IRAM_BLOCK0_END); // cmp i1,IRAM_BLOCK0_END
UML_JMPc(block, COND_A, label); // ja label1
// 0x20000 ... 0x27fff
UML_AND(block, I1, I1, 0x7fff); // and i1,i1,0x7fff
UML_MULS(block, I1, I1, I1, 3); // muls i1,3
UML_DSTORE(block, block0_2, I1, I0, SIZE_WORD, SCALE_x2); // dstore [block0_2],i1,i0,word,scale_x2
UML_DSHR(block, I0, I0, 16); // dshr i0,i0,16
UML_DSTORE(block, block0_1, I1, I0, SIZE_WORD, SCALE_x2); // dstore [block0_1],i1,i0,word,scale_x2
UML_DSHR(block, I0, I0, 16); // dshr i0,i0,16
UML_DSTORE(block, block0, I1, I0, SIZE_WORD, SCALE_x2); // dstore [block0],i1,i0,word,scale_x2
UML_SHL(block, I1, I1, 3);
UML_WRITE(block, I1, I0, SIZE_QWORD, SPACE_PROGRAM);
UML_MOV(block, mem(&m_core->force_recompile), 1);
UML_RET(block); // ret
UML_LABEL(block, label++); // label1:
UML_CMP(block, I1, IRAM_BLOCK1_START); // cmp i1,IRAM_BLOCK1_START
UML_JMPc(block, COND_B, label); // jb label2
UML_CMP(block, I1, IRAM_BLOCK1_END); // cmp i1,IRAM_BLOCK1_END
UML_JMPc(block, COND_A, label); // ja label2
// 0x28000 ... 0x3ffff
UML_AND(block, I1, I1, 0x7fff); // and i1,i1,0x7fff (block 1 is mirrored in 0x28000...2ffff, 0x30000...0x37fff and 0x38000...3ffff)
UML_MULS(block, I1, I1, I1, 3); // muls i1,3
UML_DSTORE(block, block1_2, I1, I0, SIZE_WORD, SCALE_x2); // dstore [block1_2],i1,i0,word,scale_x2
UML_DSHR(block, I0, I0, 16); // dshr i0,i0,16
UML_DSTORE(block, block1_1, I1, I0, SIZE_WORD, SCALE_x2); // dstore [block1_1],i1,i0,word,scale_x2
UML_DSHR(block, I0, I0, 16); // dshr i0,i0,16
UML_DSTORE(block, block1, I1, I0, SIZE_WORD, SCALE_x2); // dstore [block1],i1,i0,word,scale_x2
UML_RET(block); // ret
UML_LABEL(block, label++); // label2:
break;
case MEM_ACCESSOR_PM_READ32:
UML_CMP(block, I1, IRAM_BLOCK0_START); // cmp i1,IRAM_BLOCK0_START
UML_JMPc(block, COND_B, label); // jb label1
UML_CMP(block, I1, IRAM_BLOCK0_END); // cmp i1,IRAM_BLOCK0_END
UML_JMPc(block, COND_A, label); // ja label1
// 0x20000 ... 0x27fff
UML_AND(block, I1, I1, 0x7fff); // and i1,i1,0x7fff
UML_MULS(block, I1, I1, I1, 3); // muls i1,3
UML_LOAD(block, I0, block0, I1, SIZE_WORD, SCALE_x2); // load i0,[block0],i1,word,scale_x2
UML_SHL(block, I0, I0, 16); // shl i0,i0,16
UML_LOAD(block, I2, block0_1, I1, SIZE_WORD, SCALE_x2); // load i2,[block0_1],i1,word,scale_x2
UML_OR(block, I0, I0, I2); // or i0,i0,i2
UML_RET(block); // ret
UML_LABEL(block, label++); // label1:
UML_CMP(block, I1, IRAM_BLOCK1_START); // cmp i1,IRAM_BLOCK1_START
UML_JMPc(block, COND_B, label); // jb label2
UML_CMP(block, I1, IRAM_BLOCK1_END); // cmp i1,IRAM_BLOCK1_END
UML_JMPc(block, COND_A, label); // ja label2
// 0x28000 ... 0x3ffff
UML_AND(block, I1, I1, 0x7fff); // and i1,i1,0x7fff (block 1 is mirrored in 0x28000...2ffff, 0x30000...0x37fff and 0x38000...3ffff)
UML_MULS(block, I1, I1, I1, 3); // muls i1,3
UML_LOAD(block, I0, block1, I1, SIZE_WORD, SCALE_x2); // load i0,[block1],i1,word,scale_x2
UML_SHL(block, I0, I0, 16); // shl i0,i0,16
UML_LOAD(block, I2, block1_1, I1, SIZE_WORD, SCALE_x2); // load i2,[block1_1],i1,word,scale_x2
UML_OR(block, I0, I0, I2); // or i0,i0,i2
UML_RET(block); // ret
UML_LABEL(block, label++); // label2:
UML_SHL(block, I1, I1, 3);
UML_READ(block, I0, I1, SIZE_DWORD, SPACE_PROGRAM);
break;
case MEM_ACCESSOR_PM_WRITE32:
UML_CMP(block, I1, IRAM_BLOCK0_START); // cmp i1,IRAM_BLOCK0_START
UML_JMPc(block, COND_B, label); // jb label1
UML_CMP(block, I1, IRAM_BLOCK0_END); // cmp i1,IRAM_BLOCK0_END
UML_JMPc(block, COND_A, label); // ja label1
// 0x20000 ... 0x27fff
UML_AND(block, I1, I1, 0x7fff); // and i1,i1,0x7fff
UML_MULS(block, I1, I1, I1, 3); // muls i1,3
UML_STORE(block, block0_1, I1, I0, SIZE_WORD, SCALE_x2); // store [block0_1],i1,i0,word,scale_x2
UML_SHR(block, I0, I0, 16); // shr i0,i0,16
UML_STORE(block, block0, I1, I0, SIZE_WORD, SCALE_x2); // store [block0],i1,i0,word,scale_x2
UML_RET(block); // ret
UML_LABEL(block, label++); // label1:
UML_CMP(block, I1, IRAM_BLOCK1_START); // cmp i1,IRAM_BLOCK1_START
UML_JMPc(block, COND_B, label); // jb label2
UML_CMP(block, I1, IRAM_BLOCK1_END); // cmp i1,IRAM_BLOCK1_END
UML_JMPc(block, COND_A, label); // ja label2
// 0x28000 ... 0x3ffff
UML_AND(block, I1, I1, 0x7fff); // and i1,i1,0x7fff (block 1 is mirrored in 0x28000...2ffff, 0x30000...0x37fff and 0x38000...3ffff)
UML_MULS(block, I1, I1, I1, 3); // muls i1,3
UML_STORE(block, block1_1, I1, I0, SIZE_WORD, SCALE_x2); // store [block1_1],i1,i0,word,scale_x2
UML_SHR(block, I0, I0, 16); // shr i0,i0,16
UML_STORE(block, block1, I1, I0, SIZE_WORD, SCALE_x2); // store [block1],i1,i0,word,scale_x2
UML_RET(block); // ret
UML_LABEL(block, label++); // label2:
UML_SHL(block, I1, I1, 3);
UML_WRITE(block, I1, I0, SIZE_DWORD, SPACE_PROGRAM);
UML_MOV(block, mem(&m_core->force_recompile), 1);
break;
case MEM_ACCESSOR_DM_READ32:
UML_CMP(block, I1, IRAM_END); // cmp i1,IRAM_END
UML_JMPc(block, COND_BE, label); // jbe label1
// 0x80000 ...
UML_SHL(block, I1, I1, 2); // shl i1,i1,2
UML_READ(block, I0, I1, SIZE_DWORD, SPACE_DATA); // read i0,i1,dword,SPACE_DATA
UML_RET(block);
UML_LABEL(block, label++); // label1:
UML_CMP(block, I1, IRAM_BLOCK0_START); // cmp i1,IRAM_BLOCK0_START
UML_JMPc(block, COND_B, label); // jb label2
UML_CMP(block, I1, IRAM_BLOCK0_END); // cmp i1,IRAM_BLOCK0_END
UML_JMPc(block, COND_A, label); // ja label2
// 0x20000 ... 0x27fff
UML_AND(block, I1, I1, 0x7fff); // and i1,i1,0x7fff
UML_LOAD(block, I0, block0, I1, SIZE_WORD, SCALE_x4); // load i0,[block0],i1,word,scale_x4
UML_SHL(block, I0, I0, 16); // shl i0,i0,16
UML_LOAD(block, I2, block0_1, I1, SIZE_WORD, SCALE_x4); // load i2,[block0_1],i1,word,scale_x4
UML_OR(block, I0, I0, I2); // or i0,i0,i2
UML_RET(block);
UML_LABEL(block, label++); // label2:
UML_CMP(block, I1, IRAM_BLOCK1_START); // cmp i1,IRAM_BLOCK1_START
UML_JMPc(block, COND_B, label); // jb label3
UML_CMP(block, I1, IRAM_BLOCK1_END); // cmp i1,IRAM_BLOCK1_END
UML_JMPc(block, COND_A, label); // ja label3
// 0x28000 ... 0x3ffff
UML_AND(block, I1, I1, 0x7fff); // and i1,i1,0x7fff
UML_LOAD(block, I0, block1, I1, SIZE_WORD, SCALE_x4); // load i0,[block1],i1,word,scale_x4
UML_SHL(block, I0, I0, 16); // shl i0,i0,16
UML_LOAD(block, I2, block1_1, I1, SIZE_WORD, SCALE_x4); // load i2,[block1_1],i1,word,scale_x4
UML_OR(block, I0, I0, I2); // or i0,i0,i2
UML_RET(block);
UML_LABEL(block, label++); // Label3:
UML_CMP(block, I1, IOP_REGISTER_END); // cmp i1,IOP_REGISTER_END
UML_JMPc(block, COND_A, label); // ja label4
// IOP registers
UML_MOV(block, mem(&m_core->arg0), I1); // mov [m_core->arg0],i1
UML_CALLC(block, cfunc_read_iop, this); // callc cfunc_read_iop
UML_MOV(block, I0, mem(&m_core->arg1)); // mov i0,[m_core->arg1]
UML_RET(block);
UML_LABEL(block, label++); // label4:
UML_CMP(block, I1, IRAM_SHORT_BLOCK0_START); // cmp i1,IRAM_SHORT_BLOCK0_START
UML_JMPc(block, COND_B, label+1); // jb label6
UML_CMP(block, I1, IRAM_SHORT_BLOCK0_END); // cmp i1,IRAM_SHORT_BLOCK0_END
UML_JMPc(block, COND_A, label+1); // ja label6
// 0x40000 ... 0x4ffff
UML_AND(block, I1, I1, 0xffff); // and i1,i1,0xffff
UML_XOR(block, I1, I1, 1); // xor i1,i1,1
UML_TEST(block, mem(&m_core->mode1), 0x4000); // test [m_core->mode1],0x4000
UML_JMPc(block, COND_Z, label); // jz label5
UML_LOADS(block, I0, block0, I1, SIZE_WORD, SCALE_x2); // loads i0,[block0],i1,word,scale_x2
UML_RET(block);
UML_LABEL(block, label++); // label5:
UML_LOAD(block, I0, block0, I1, SIZE_WORD, SCALE_x2); // load i0,[block0],i1,word,scale_x2
UML_RET(block);
UML_LABEL(block, label++); // label6:
UML_CMP(block, I1, IRAM_SHORT_BLOCK1_START); // cmp i1,IRAM_SHORT_BLOCK1_START
UML_JMPc(block, COND_B, label+1); // jb label8
UML_CMP(block, I1, IRAM_SHORT_BLOCK1_END); // cmp i1,IRAM_SHORT_BLOCK1_END
UML_JMPc(block, COND_A, label+1); // ja label8
// 0x50000 ... 0x7ffff
UML_AND(block, I1, I1, 0xffff); // and i1,i1,0xffff
UML_XOR(block, I1, I1, 1); // xor i1,i1,1
UML_TEST(block, mem(&m_core->mode1), 0x4000); // test [m_core->mode1],0x4000
UML_JMPc(block, COND_Z, label); // jz label7
UML_LOADS(block, I0, block1, I1, SIZE_WORD, SCALE_x2); // loads i0,[block1],i1,word,scale_x2
UML_RET(block);
UML_LABEL(block, label++); // label7:
UML_LOAD(block, I0, block1, I1, SIZE_WORD, SCALE_x2); // load i0,[block1],i1,word,scale_x2
UML_RET(block);
UML_LABEL(block, label++); // label8:
UML_SHL(block, I1, I1, 2);
UML_READ(block, I0, I1, SIZE_DWORD, SPACE_DATA);
break;
case MEM_ACCESSOR_DM_WRITE32:
#if WRITE_SNOOP
//UML_CMP(block, I1, 0x283eb);
UML_CMP(block, I1, 0x2400047);
UML_JMPc(block, COND_NE, label);
UML_MOV(block, mem(&m_core->arg0), I0);
UML_MOV(block, mem(&m_core->arg1), I1);
UML_MOV(block, mem(&m_core->arg2), mem(&m_core->pc));
UML_CALLC(block, cfunc_write_snoop, this);
UML_LABEL(block, label++);
#endif
UML_CMP(block, I1, IRAM_END); // cmp i1,IRAM_END
UML_JMPc(block, COND_BE, label); // jbe label1
// 0x80000 ...
UML_SHL(block, I1, I1, 2); // shl i1,i1,2
UML_WRITE(block, I1, I0, SIZE_DWORD, SPACE_DATA); // write i1,i0,dword,SPACE_DATA
UML_RET(block);
UML_LABEL(block, label++); // label1:
UML_CMP(block, I1, IRAM_BLOCK0_START); // cmp i1,IRAM_BLOCK0_START
UML_JMPc(block, COND_B, label); // jb label2
UML_CMP(block, I1, IRAM_BLOCK0_END); // cmp i1,IRAM_BLOCK0_END
UML_JMPc(block, COND_A, label); // ja label2
// 0x20000 ... 0x27fff
UML_AND(block, I1, I1, 0x7fff); // and i1,i1,0x7fff
UML_STORE(block, block0_1, I1, I0, SIZE_WORD, SCALE_x4); // store [block0_1],i1,i0,word,scale_x4
UML_SHR(block, I0, I0, 16); // shr i0,i0,16
UML_STORE(block, block0, I1, I0, SIZE_WORD, SCALE_x4); // store [block0],i1,i0,word,scale_x4
UML_RET(block);
UML_LABEL(block, label++); // label2:
UML_CMP(block, I1, IRAM_BLOCK1_START); // cmp i1,IRAM_BLOCK1_START
UML_JMPc(block, COND_B, label); // jb label3
UML_CMP(block, I1, IRAM_BLOCK1_END); // cmp i1,IRAM_BLOCK1_END
UML_JMPc(block, COND_A, label); // ja label3
// 0x28000 ... 0x3ffff
UML_AND(block, I1, I1, 0x7fff); // and i1,i1,0x7fff
UML_STORE(block, block1_1, I1, I0, SIZE_WORD, SCALE_x4); // store [block1_1],i1,i0,word,scale_x4
UML_SHR(block, I0, I0, 16); // shr i0,i0,16
UML_STORE(block, block1, I1, I0, SIZE_WORD, SCALE_x4); // store [block1],i1,i0,word,scale_x4
UML_RET(block);
UML_LABEL(block, label++); // Label3:
UML_CMP(block, I1, IOP_REGISTER_END); // cmp i1,IOP_REGISTER_END
UML_JMPc(block, COND_A, label); // ja label4
// IOP registers
UML_MOV(block, mem(&m_core->arg0), I1); // mov [m_core->arg0],i1
UML_MOV(block, mem(&m_core->arg1), I0); // mov [m_core->arg1],i0
UML_CALLC(block, cfunc_write_iop, this); // callc cfunc_write_iop
UML_RET(block);
UML_LABEL(block, label++); // label4:
UML_CMP(block, I1, IRAM_SHORT_BLOCK0_START); // cmp i1,IRAM_SHORT_BLOCK0_START
UML_JMPc(block, COND_B, label); // jb label5
UML_CMP(block, I1, IRAM_SHORT_BLOCK0_END); // cmp i1,IRAM_SHORT_BLOCK0_END
UML_JMPc(block, COND_A, label); // ja label5
// 0x40000 ... 0x4ffff
UML_AND(block, I1, I1, 0xffff); // and i1,i1,0xffff
UML_XOR(block, I1, I1, 1); // xor i1,i1,1
UML_STORE(block, block0, I1, I0, SIZE_WORD, SCALE_x2); // store [block0],i1,i0,word,scale_x2
UML_RET(block);
UML_LABEL(block, label++); // label5:
UML_CMP(block, I1, IRAM_SHORT_BLOCK1_START); // cmp i1,IRAM_SHORT_BLOCK1_START
UML_JMPc(block, COND_B, label); // jb label6
UML_CMP(block, I1, IRAM_SHORT_BLOCK1_END); // cmp i1,IRAM_SHORT_BLOCK1_END
UML_JMPc(block, COND_A, label); // ja label6
// 0x50000 ... 0x7ffff
UML_AND(block, I1, I1, 0xffff); // and i1,i1,0xffff
UML_XOR(block, I1, I1, 1); // xor i1,i1,1
UML_STORE(block, block1, I1, I0, SIZE_WORD, SCALE_x2); // store [block1],i1,i0,word,scale_x2
UML_RET(block);
UML_LABEL(block, label++); // label6:
UML_SHL(block, I1, I1, 2);
UML_WRITE(block, I1, I0, SIZE_DWORD, SPACE_DATA);
break;
}

View File

@ -4,201 +4,30 @@
uint32_t adsp21062_device::pm_read32(uint32_t address)
{
if (address >= 0x20000 && address < 0x28000)
{
uint32_t addr = (address & 0x7fff) * 3;
return (uint32_t)(m_internal_ram_block0[addr + 0] << 16) |
(m_internal_ram_block0[addr + 1]);
}
else if (address >= 0x28000 && address < 0x40000)
{
// block 1 is mirrored in 0x28000...2ffff, 0x30000...0x37fff and 0x38000...3ffff
uint32_t addr = (address & 0x7fff) * 3;
return (uint32_t)(m_internal_ram_block1[addr + 0] << 16) |
(m_internal_ram_block1[addr + 1]);
}
else {
fatalerror("SHARC: PM Bus Read32 %08X at %08X\n", address, m_core->pc);
}
return m_program->read_dword(address << 3);
}
void adsp21062_device::pm_write32(uint32_t address, uint32_t data)
{
if (address >= 0x20000 && address < 0x28000)
{
uint32_t addr = (address & 0x7fff) * 3;
m_internal_ram_block0[addr + 0] = (uint16_t)(data >> 16);
m_internal_ram_block0[addr + 1] = (uint16_t)(data);
return;
}
else if (address >= 0x28000 && address < 0x40000)
{
// block 1 is mirrored in 0x28000...2ffff, 0x30000...0x37fff and 0x38000...3ffff
uint32_t addr = (address & 0x7fff) * 3;
m_internal_ram_block1[addr + 0] = (uint16_t)(data >> 16);
m_internal_ram_block1[addr + 1] = (uint16_t)(data);
return;
}
else {
fatalerror("SHARC: PM Bus Write32 %08X, %08X at %08X\n", address, data, m_core->pc);
}
m_program->write_dword(address << 3, data);
}
uint64_t adsp21062_device::pm_read48(uint32_t address)
{
if ((address >= 0x20000 && address < 0x28000))
{
uint32_t addr = (address & 0x7fff) * 3;
return ((uint64_t)(m_internal_ram_block0[addr + 0]) << 32) |
((uint64_t)(m_internal_ram_block0[addr + 1]) << 16) |
((uint64_t)(m_internal_ram_block0[addr + 2]) << 0);
}
else if (address >= 0x28000 && address < 0x40000)
{
// block 1 is mirrored in 0x28000...2ffff, 0x30000...0x37fff and 0x38000...3ffff
uint32_t addr = (address & 0x7fff) * 3;
return ((uint64_t)(m_internal_ram_block1[addr + 0]) << 32) |
((uint64_t)(m_internal_ram_block1[addr + 1]) << 16) |
((uint64_t)(m_internal_ram_block1[addr + 2]) << 0);
}
else {
fatalerror("SHARC: PM Bus Read48 %08X at %08X\n", address, m_core->pc);
}
return 0;
return m_program->read_qword(address << 3);
}
void adsp21062_device::pm_write48(uint32_t address, uint64_t data)
{
if ((address >= 0x20000 && address < 0x28000))
{
uint32_t addr = (address & 0x7fff) * 3;
m_internal_ram_block0[addr + 0] = (uint16_t)(data >> 32);
m_internal_ram_block0[addr + 1] = (uint16_t)(data >> 16);
m_internal_ram_block0[addr + 2] = (uint16_t)(data);
return;
}
else if (address >= 0x28000 && address < 0x40000)
{
// block 1 is mirrored in 0x28000...2ffff, 0x30000...0x37fff and 0x38000...3ffff
uint32_t addr = (address & 0x7fff) * 3;
m_internal_ram_block1[addr + 0] = (uint16_t)(data >> 32);
m_internal_ram_block1[addr + 1] = (uint16_t)(data >> 16);
m_internal_ram_block1[addr + 2] = (uint16_t)(data);
return;
}
else {
fatalerror("SHARC: PM Bus Write48 %08X, %04X%08X at %08X\n", address, (uint16_t)(data >> 32),(uint32_t)data, m_core->pc);
}
m_program->write_qword(address << 3, data);
}
uint32_t adsp21062_device::dm_read32(uint32_t address)
{
if (address < 0x100)
{
return sharc_iop_r(address);
}
else if (address >= 0x20000 && address < 0x28000)
{
uint32_t addr = (address & 0x7fff) * 2;
return (uint32_t)(m_internal_ram_block0[addr + 0] << 16) |
(m_internal_ram_block0[addr + 1]);
}
else if (address >= 0x28000 && address < 0x40000)
{
// block 1 is mirrored in 0x28000...2ffff, 0x30000...0x37fff and 0x38000...3ffff
uint32_t addr = (address & 0x7fff) * 2;
return (uint32_t)(m_internal_ram_block1[addr + 0] << 16) |
(m_internal_ram_block1[addr + 1]);
}
// short word addressing
else if (address >= 0x40000 && address < 0x50000)
{
uint32_t addr = address & 0xffff;
uint16_t r = m_internal_ram_block0[addr ^ 1];
if (m_core->mode1 & 0x4000)
{
// sign-extend
return (int32_t)(int16_t)(r);
}
else
{
return (uint32_t)(r);
}
}
else if (address >= 0x50000 && address < 0x80000)
{
// block 1 is mirrored in 0x50000...5ffff, 0x60000...0x6ffff and 0x70000...7ffff
uint32_t addr = address & 0xffff;
uint16_t r = m_internal_ram_block1[addr ^ 1];
if (m_core->mode1 & 0x4000)
{
// sign-extend
return (int32_t)(int16_t)(r);
}
else
{
return (uint32_t)(r);
}
}
return m_data->read_dword(address << 2);
}
void adsp21062_device::dm_write32(uint32_t address, uint32_t data)
{
if (address < 0x100)
{
sharc_iop_w(address, data);
return;
}
else if (address >= 0x20000 && address < 0x28000)
{
uint32_t addr = (address & 0x7fff) * 2;
m_internal_ram_block0[addr + 0] = (uint16_t)(data >> 16);
m_internal_ram_block0[addr + 1] = (uint16_t)(data);
return;
}
else if (address >= 0x28000 && address < 0x40000)
{
// block 1 is mirrored in 0x28000...2ffff, 0x30000...0x37fff and 0x38000...3ffff
uint32_t addr = (address & 0x7fff) * 2;
m_internal_ram_block1[addr + 0] = (uint16_t)(data >> 16);
m_internal_ram_block1[addr + 1] = (uint16_t)(data);
return;
}
// short word addressing
else if (address >= 0x40000 && address < 0x50000)
{
uint32_t addr = address & 0xffff;
m_internal_ram_block0[addr ^ 1] = data;
return;
}
else if (address >= 0x50000 && address < 0x80000)
{
// block 1 is mirrored in 0x50000...5ffff, 0x60000...0x6ffff and 0x70000...7ffff
uint32_t addr = address & 0xffff;
m_internal_ram_block1[addr ^ 1] = data;
return;
}
m_data->write_dword(address << 2, data);
}

View File

@ -878,6 +878,7 @@ u64 debugger_cpu::read_opcode(address_space &space, offs_t address, int size)
/* dump opcodes in qwords from a qword-sized bus */
case 88:
case 86: // sharc case, 48-bits opcodes
break;
default:
@ -925,6 +926,7 @@ u64 debugger_cpu::read_opcode(address_space &space, offs_t address, int size)
break;
case 8:
case 6:
result = space.direct().read_qword(address & ~7, addrxor);
if (!QWORD_ALIGNED(address))
{
@ -3426,6 +3428,7 @@ void device_debug::tracer::update(offs_t pc)
// log this PC
m_nextdex = (m_nextdex + 1) % TRACE_LOOPS;
m_history[m_nextdex] = pc;
fflush(&m_file);
}
@ -3437,6 +3440,7 @@ void device_debug::tracer::vprintf(const char *format, va_list va)
{
// pass through to the file
vfprintf(&m_file, format, va);
fflush(&m_file);
}