some monon disassembly helpers [anonymous] (#5504)

* some monon disassembly helpers [anonymous]

* typo (nw)

* not used (nw)

* split into ax208 and axc51 (nw)
This commit is contained in:
David Haywood 2019-08-19 21:36:20 +01:00 committed by R. Belmont
parent 37fbf79854
commit 41230a84fc
8 changed files with 334 additions and 32 deletions

View File

@ -8,13 +8,16 @@
AX208 SoC AX208 SoC
Notes: Notes:
AXC51CORE:
somes sources indicate that the extended opcode encoding may change
on some CPU models despite all being 'AXC51CORE' however we lack solid
information on this at present.
AX208: AX208:
The CPU has a bootloader that sets a few things up + copies data to RAM The CPU has 0x2000 bytes of internal ROM mapped at 0x8000-0x9fff providing
from the Flash meomry. This will need to be simulated. bootcode, operating kernel and many standard library functions
*****************************************************************************/ *****************************************************************************/
@ -23,14 +26,44 @@
#include "axc51-core.h" #include "axc51-core.h"
#include "axc51-core_dasm.h" #include "axc51-core_dasm.h"
DEFINE_DEVICE_TYPE(AXC51CORE, axc51core_cpu_device, "axc51core", "AppoTech AXC51-CORE")
DEFINE_DEVICE_TYPE(AX208, ax208_cpu_device, "ax208", "AppoTech AX208 (AXC51-CORE)") DEFINE_DEVICE_TYPE(AX208, ax208_cpu_device, "ax208", "AppoTech AX208 (AXC51-CORE)")
// AXC51CORE (base device)
axc51core_cpu_device::axc51core_cpu_device(const machine_config& mconfig, device_type type, const char* tag, device_t* owner, uint32_t clock, int program_width, int data_width, uint8_t features)
: mcs51_cpu_device(mconfig, type, tag, owner, clock, program_width, data_width, features)
{
}
axc51core_cpu_device::axc51core_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: axc51core_cpu_device(mconfig, AXC51CORE, tag, owner, clock, 0, 7)
{
}
std::unique_ptr<util::disasm_interface> axc51core_cpu_device::create_disassembler()
{
return std::make_unique<axc51core_disassembler>();
}
// AX208 (specific CPU)
ax208_cpu_device::ax208_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) ax208_cpu_device::ax208_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: mcs51_cpu_device(mconfig, AX208, tag, owner, clock, 0, 7) : axc51core_cpu_device(mconfig, AX208, tag, owner, clock, 0, 7)
{ {
} }
std::unique_ptr<util::disasm_interface> ax208_cpu_device::create_disassembler() std::unique_ptr<util::disasm_interface> ax208_cpu_device::create_disassembler()
{ {
return std::make_unique<axc51core_disassembler>(); return std::make_unique<ax208_disassembler>();
}
ROM_START( ax208 )
ROM_REGION( 0x2000, "rom", 0 )
ROM_LOAD("ax208.rom", 0x0000, 0x2000, NO_DUMP )
ROM_END
const tiny_rom_entry *ax208_cpu_device::device_rom_region() const
{
return ROM_NAME( ax208 );
} }

View File

@ -17,9 +17,22 @@
#include "mcs51.h" #include "mcs51.h"
DECLARE_DEVICE_TYPE(AXC51CORE, axc51core_cpu_device)
DECLARE_DEVICE_TYPE(AX208, ax208_cpu_device) DECLARE_DEVICE_TYPE(AX208, ax208_cpu_device)
class ax208_cpu_device : public mcs51_cpu_device class axc51core_cpu_device : public mcs51_cpu_device
{
public:
// construction/destruction
axc51core_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
axc51core_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int program_width, int data_width, uint8_t features = 0);
protected:
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
};
class ax208_cpu_device : public axc51core_cpu_device
{ {
public: public:
// construction/destruction // construction/destruction
@ -27,6 +40,7 @@ public:
protected: protected:
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
virtual const tiny_rom_entry *device_rom_region() const override;
}; };
#endif // MAME_CPU_MCS51_AXC51_CORE_H #endif // MAME_CPU_MCS51_AXC51_CORE_H

View File

@ -13,6 +13,7 @@
#include "emu.h" #include "emu.h"
#include "axc51-core_dasm.h" #include "axc51-core_dasm.h"
// SOME of these might be AX208 specific, we do not currently hvae enough information to split it into AXC51 / AX208 however
const axc51core_disassembler::mem_info axc51core_disassembler::axc51core_names[] = { const axc51core_disassembler::mem_info axc51core_disassembler::axc51core_names[] = {
// SFR Registers // SFR Registers
@ -196,6 +197,151 @@ const axc51core_disassembler::mem_info axc51core_disassembler::axc51core_names[]
{ -1 } { -1 }
}; };
// based on extracted symbol table, note 0x8000 - 0x8ca3 is likely boot code, interrupt code, kernel etc.
// this should be the same for all ax208 CPUs as they are thought to all use the same internal ROM
const ax208_disassembler::ax208_bios_info ax208_disassembler::bios_call_names[] = {
{ 0x8000, "entry point" },
{ 0x8006, "unknown, used" },
{ 0x8009, "unknown, used" },
{ 0x8ca4, "_STRCHR" },
{ 0x8dd6, "_STRLEN" },
{ 0x8eb7, "_tolower" },
{ 0x8ec8, "_toupper" },
{ 0x900f, "_isalpha" },
{ 0x902a, "_iscntrl" },
{ 0x9038, "_isdigit" },
{ 0x9047, "_isalnum" },
{ 0x906d, "_isgraph" },
{ 0x907c, "_isprint" },
{ 0x908b, "_ispunct" },
{ 0x90bb, "_islower" },
{ 0x90ca, "_isupper" },
{ 0x90d9, "_isspace" },
{ 0x90ec, "_isxdigit" },
{ 0x91e2, "COPY" },
{ 0x9208, "SCDIV" },
{ 0x922a, "CLDPTR" },
{ 0x9243, "CLDIPTR" },
{ 0x9267, "CLDOPTR" },
{ 0x9294, "CLDIOPTR" },
{ 0x92cb, "CILDPTR" },
{ 0x92ed, "CILDOPTR" },
{ 0x9320, "CSTPTR" },
{ 0x9332, "CSTOPTR" },
{ 0x9354, "UIDIV" },
{ 0x93a9, "SIDIV" },
{ 0x93df, "IILDX" },
{ 0x93f5, "ILDIX" },
{ 0x940b, "ILDPTR" },
{ 0x9436, "ILDIPTR" },
{ 0x946b, "ILDOPTR" },
{ 0x94a3, "ILDIOPTR" },
{ 0x94ef, "IILDPTR" },
{ 0x9527, "IILDOPTR" },
{ 0x9574, "ISTPTR" },
{ 0x9593, "ISTOPTR" },
{ 0x95c0, "LADD" },
{ 0x95cd, "LSUB" },
{ 0x95db, "LMUL" },
{ 0x9666, "ULDIV" },
{ 0x96f8, "LAND" },
{ 0x9705, "LOR" },
{ 0x9712, "LXOR" },
{ 0x971f, "LNOT" },
{ 0x972c, "LNEG" },
{ 0x973a, "SLCMP" },
{ 0x9750, "ULCMP" },
{ 0x9761, "ULSHR" },
{ 0x9774, "SLSHR" },
{ 0x9788, "LSHL" },
{ 0x979b, "LLDPTR" },
{ 0x97bb, "LLDOPTR" },
{ 0x97eb, "LSTPTR" },
{ 0x9805, "LSTOPTR" },
{ 0x9829, "LILDPTR" },
{ 0x9849, "LILDOPTR" },
{ 0x9879, "LLDIPTR" },
{ 0x9899, "LLDIOPTR" },
{ 0x98c9, "LLDIDATA" },
{ 0x98d5, "LLDXDATA" },
{ 0x98e1, "LLDPDATA" },
{ 0x98ed, "LLDCODE" },
{ 0x98fd, "LLDIDATA0" },
{ 0x990a, "LLDXDATA0" },
{ 0x9916, "LLDPDATA0" },
{ 0x9923, "LLDCODE0" },
{ 0x9933, "LLDPTR0" },
{ 0x9953, "LLDOPTR0" },
{ 0x9983, "LLDIIDATA1" },
{ 0x9985, "LLDIIDATA8" },
{ 0x998c, "LLDIIDATA" },
{ 0x99a3, "LLDIXDATA1" },
{ 0x99a5, "LLDIXDATA8" },
{ 0x99ac, "LLDIXDATA" },
{ 0x99d8, "LLDIPDATA1" },
{ 0x99da, "LLDIPDATA8" },
{ 0x99e1, "LLDIPDATA" },
{ 0x99f8, "LILDIDATA1" },
{ 0x99fa, "LILDIDATA8" },
{ 0x9a01, "LILDIDATA" },
{ 0x9a18, "LILDXDATA1" },
{ 0x9a1a, "LILDXDATA8" },
{ 0x9a21, "LILDXDATA" },
{ 0x9a4d, "LILDPDATA1" },
{ 0x9a4f, "LILDPDATA8" },
{ 0x9a56, "LILDPDATA" },
{ 0x9a6d, "LSTIDATA" },
{ 0x9a79, "LSTXDATA" },
{ 0x9a85, "LSTPDATA" },
{ 0x9a91, "LSTKIDATA" },
{ 0x9aaa, "LSTKXDATA" },
{ 0x9adb, "LSTKPDATA" },
{ 0x9af4, "LSTKPTR" },
{ 0x9b0e, "LSTKOPTR" },
{ 0x9b32, "BCAST_L" },
{ 0x9b3b, "OFFX256" },
{ 0x9b4c, "OFFXADD" },
{ 0x9b58, "OFFXADD1" },
{ 0x9b61, "PLDIDATA" },
{ 0x9b6a, "PLDIIDATA" },
{ 0x9b7a, "PILDIDATA" },
{ 0x9b8a, "PSTIDATA" },
{ 0x9b93, "PLDXDATA" },
{ 0x9b9c, "PLDIXDATA" },
{ 0x9bb3, "PILDXDATA" },
{ 0x9bca, "PSTXDATA" },
{ 0x9bd3, "PLDPDATA" },
{ 0x9bdc, "PLDIPDATA" },
{ 0x9bec, "PILDPDATA" },
{ 0x9bfc, "PSTPDATA" },
{ 0x9c05, "PLDCODE" },
{ 0x9c11, "PLDPTR" },
{ 0x9c31, "PLDIPTR" },
{ 0x9c53, "PILDPTR" },
{ 0x9c75, "PSTPTR" },
{ 0x9cc4, "PSTPTRR" },
{ 0x9cf4, "PLDOPTR" },
{ 0x9d24, "PLDIOPTR" },
{ 0x9d56, "PILDOPTR" },
{ 0x9d88, "PSTOPTR" },
{ 0x9de1, "CCASE" },
{ 0x9e07, "ICASE" },
{ 0x9e34, "LCASE" },
{ 0x9e6e, "ICALL" },
{ 0x9e72, "ICALL2" },
{ 0x9e74, "MEMSET" },
{ 0x9ea0, "LROL" },
{ 0x9eb4, "LROR" },
{ 0x9ec8, "SLDIV" },
{ 0x9f47, "SPI_ENCRYPT_ON3" },
{ 0x9f5c, "_lshift9" },
{ 0x9fdc, "SPI_ENCRYPT_CLOSE" },
{ -1, "unknown" }
};
axc51core_disassembler::axc51core_disassembler() : mcs51_disassembler(axc51core_names) axc51core_disassembler::axc51core_disassembler() : mcs51_disassembler(axc51core_names)
{ {
} }
@ -814,6 +960,7 @@ offs_t axc51core_disassembler::disassemble_extended_a5(std::ostream& stream, uns
return (PC - pc) | flags | SUPPORTED; return (PC - pc) | flags | SUPPORTED;
} }
offs_t axc51core_disassembler::disassemble_op(std::ostream& stream, unsigned PC, offs_t pc, const data_buffer& opcodes, const data_buffer& params, uint8_t op) offs_t axc51core_disassembler::disassemble_op(std::ostream& stream, unsigned PC, offs_t pc, const data_buffer& opcodes, const data_buffer& params, uint8_t op)
{ {
uint32_t flags = 0; uint32_t flags = 0;
@ -831,3 +978,62 @@ offs_t axc51core_disassembler::disassemble_op(std::ostream& stream, unsigned PC,
} }
ax208_disassembler::ax208_disassembler() : axc51core_disassembler(axc51core_names)
{
}
void ax208_disassembler::disassemble_op_ljmp(std::ostream& stream, unsigned &PC, const data_buffer& params)
{
uint16_t addr = (params.r8(PC++) << 8) & 0xff00;
addr |= params.r8(PC++);
if ((addr >= 0x8000) && (addr < 0xa000))
{
int i = 0;
int lookaddr = -1;
const char* lookname;
do
{
lookaddr = bios_call_names[i].addr;
lookname = bios_call_names[i].name;
if (lookaddr == addr)
break;
i++;
} while (lookaddr != -1);
util::stream_format(stream, "ljmp $%04X (%s)", addr, lookname);
}
else
{
util::stream_format(stream, "ljmp $%04X", addr);
}
}
void ax208_disassembler::disassemble_op_lcall(std::ostream& stream, unsigned &PC, const data_buffer& params)
{
uint16_t addr = (params.r8(PC++)<<8) & 0xff00;
addr|= params.r8(PC++);
if ((addr >= 0x8000) && (addr < 0xa000))
{
int i = 0;
int lookaddr = -1;
const char* lookname;
do
{
lookaddr = bios_call_names[i].addr;
lookname = bios_call_names[i].name;
if (lookaddr == addr)
break;
i++;
} while (lookaddr != -1);
util::stream_format(stream, "lcall $%04X (%s)", addr, lookname);
}
else
{
util::stream_format(stream, "lcall $%04X", addr);
}
}

View File

@ -21,6 +21,9 @@ class axc51core_disassembler : public mcs51_disassembler
{ {
public: public:
axc51core_disassembler(); axc51core_disassembler();
axc51core_disassembler(const mem_info* names) : mcs51_disassembler(names) {};
virtual ~axc51core_disassembler() = default; virtual ~axc51core_disassembler() = default;
static const mem_info axc51core_names[]; static const mem_info axc51core_names[];
@ -37,5 +40,24 @@ private:
}; };
class ax208_disassembler : public axc51core_disassembler
{
public:
ax208_disassembler();
virtual ~ax208_disassembler() = default;
struct ax208_bios_info {
int addr;
const char *name;
};
static const ax208_bios_info bios_call_names[];
protected:
virtual void disassemble_op_ljmp(std::ostream& stream, unsigned &PC, const data_buffer& params) override;
virtual void disassemble_op_lcall(std::ostream& stream, unsigned &PC, const data_buffer& params) override;
};
#endif // MAME_CPU_MCS51_AXC51_CORE_DASM_H #endif // MAME_CPU_MCS51_AXC51_CORE_DASM_H

View File

@ -408,6 +408,20 @@ std::string mcs51_disassembler::get_bit_address( uint8_t arg ) const
} }
} }
void mcs51_disassembler::disassemble_op_ljmp(std::ostream& stream, unsigned &PC, const data_buffer& params)
{
uint16_t addr = (params.r8(PC++)<<8) & 0xff00;
addr|= params.r8(PC++);
util::stream_format(stream, "ljmp $%04X", addr);
}
void mcs51_disassembler::disassemble_op_lcall(std::ostream& stream, unsigned &PC, const data_buffer& params)
{
uint16_t addr = (params.r8(PC++)<<8) & 0xff00;
addr|= params.r8(PC++);
util::stream_format(stream, "lcall $%04X", addr);
}
offs_t mcs51_disassembler::disassemble_op(std::ostream &stream, unsigned PC, offs_t pc, const data_buffer &opcodes, const data_buffer &params, uint8_t op) offs_t mcs51_disassembler::disassemble_op(std::ostream &stream, unsigned PC, offs_t pc, const data_buffer &opcodes, const data_buffer &params, uint8_t op)
{ {
uint32_t flags = 0; uint32_t flags = 0;
@ -439,9 +453,7 @@ offs_t mcs51_disassembler::disassemble_op(std::ostream &stream, unsigned PC, off
//LJMP code addr //LJMP code addr
case 0x02: /* 1: 0000 0010 */ case 0x02: /* 1: 0000 0010 */
addr = (params.r8(PC++)<<8) & 0xff00; disassemble_op_ljmp(stream, PC, params);
addr|= params.r8(PC++);
util::stream_format(stream, "ljmp $%04X", addr);
break; break;
//RR A //RR A
@ -501,9 +513,7 @@ offs_t mcs51_disassembler::disassemble_op(std::ostream &stream, unsigned PC, off
//LCALL code addr //LCALL code addr
case 0x12: /* 1: 0001 0010 */ case 0x12: /* 1: 0001 0010 */
addr = (params.r8(PC++)<<8) & 0xff00; disassemble_op_lcall(stream, PC, params);
addr|= params.r8(PC++);
util::stream_format(stream, "lcall $%04X", addr);
flags = STEP_OVER; flags = STEP_OVER;
break; break;

View File

@ -66,6 +66,8 @@ public:
virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params) override; virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params) override;
protected: protected:
virtual void disassemble_op_ljmp(std::ostream& stream, unsigned& PC, const data_buffer& params);
virtual void disassemble_op_lcall(std::ostream& stream, unsigned& PC, const data_buffer& params);
virtual offs_t disassemble_op(std::ostream &stream, unsigned PC, offs_t pc, const data_buffer &opcodes, const data_buffer &params, uint8_t op); virtual offs_t disassemble_op(std::ostream &stream, unsigned PC, offs_t pc, const data_buffer &opcodes, const data_buffer &params, uint8_t op);
std::string get_data_address( uint8_t arg ) const; std::string get_data_address( uint8_t arg ) const;

View File

@ -30,7 +30,8 @@ public:
m_screen(*this, "screen"), m_screen(*this, "screen"),
m_palette(*this, "palette"), m_palette(*this, "palette"),
m_mainram(*this, "mainram"), m_mainram(*this, "mainram"),
m_otherram(*this, "otherram") m_otherram(*this, "otherram"),
m_bootcopy(0)
{ } { }
void monon_color(machine_config &config); void monon_color(machine_config &config);
@ -54,6 +55,7 @@ private:
DECLARE_DEVICE_IMAGE_LOAD_MEMBER(cart_load); DECLARE_DEVICE_IMAGE_LOAD_MEMBER(cart_load);
void monon_color_map(address_map &map); void monon_color_map(address_map &map);
int m_bootcopy;
}; };
void monon_color_state::machine_start() void monon_color_state::machine_start()
@ -63,18 +65,37 @@ void monon_color_state::machine_start()
memcpy(maincpu, flash+0x200, 0x1e00); // 0x4000-0x5dff fixed code? memcpy(maincpu, flash+0x200, 0x1e00); // 0x4000-0x5dff fixed code?
// there are a whole bunch of blocks that map at 0x5e00 (boot code jumps straight to 0x5e00)
memcpy(maincpu+0x1e00, flash+0x2000, 0x1000); // BANK0 - clears RAM, sets up stack etc. but then jumps to 0x9xxx where we have nothing (probably the correct initial block tho) }
// memcpy(maincpu+0x1e00, flash+0x4200, 0x0a00); // BANK1 - just set register + a jump (to function that writes to UART)
// memcpy(maincpu+0x1e00, flash+0x4c00, 0x0a00); // BANK2
// memcpy(maincpu+0x1e00, flash+0x5600, 0x0a00); // BANK3
// memcpy(maincpu+0x1e00, flash+0x6000, 0x0a00); // BANK4 - ends up reting with nothing on the stack void monon_color_state::machine_reset()
// memcpy(maincpu+0x1e00, flash+0x6a00, 0x0a00); // BANK5 {
// memcpy(maincpu+0x1e00, flash+0x7400, 0x0a00); // BANK6 m_maincpu->set_state_int(MCS51_PC, 0x4000);
// memcpy(maincpu+0x1e00, flash+0x7e00, 0x0a00); // BANK7
// memcpy(maincpu+0x1e00, flash+0x8800, 0x0a00); // BANK8 uint8_t* flash = memregion("flash")->base();
// memcpy(maincpu+0x1e00, flash+0x9200, 0x0a00); // BANK9 uint8_t* maincpu = &m_mainram[0];
memset(maincpu + 0x1e00, 0x00, 0x1000);
switch (m_bootcopy)
{
// there are a whole bunch of blocks that map at 0x5e00 (boot code jumps straight to 0x5e00)
case 0x0: memcpy(maincpu + 0x1e00, flash + 0x2000, 0x1000); break; // BANK0 - clears RAM, sets up stack etc. but then jumps to 0x9xxx where we have nothing (probably the correct initial block tho)
case 0x1: memcpy(maincpu + 0x1e00, flash + 0x4200, 0x0a00); break; // BANK1 - just set register + a jump (to function that writes to UART)
case 0x2: memcpy(maincpu + 0x1e00, flash + 0x4c00, 0x0a00); break; // BANK2
case 0x3: memcpy(maincpu + 0x1e00, flash + 0x5600, 0x0a00); break; // BANK3
case 0x4: memcpy(maincpu + 0x1e00, flash + 0x6000, 0x0a00); break; // BANK4 - ends up reting with nothing on the stack
case 0x5: memcpy(maincpu + 0x1e00, flash + 0x6a00, 0x0a00); break; // BANK5
case 0x6: memcpy(maincpu + 0x1e00, flash + 0x7400, 0x0a00); break; // BANK6
case 0x7: memcpy(maincpu + 0x1e00, flash + 0x7e00, 0x0a00); break; // BANK7
case 0x8: memcpy(maincpu + 0x1e00, flash + 0x8800, 0x0a00); break; // BANK8
case 0x9: memcpy(maincpu + 0x1e00, flash + 0x9200, 0x0a00); break; // BANK9
}
m_bootcopy++;
if (m_bootcopy == 0xa) m_bootcopy = 0x0;
/* block starting at e000 in flash is not code? (or encrypted?) /* block starting at e000 in flash is not code? (or encrypted?)
no code to map at 0x9000 in address space (possible BIOS?) no code to map at 0x9000 in address space (possible BIOS?)
@ -92,13 +113,6 @@ void monon_color_state::machine_start()
*/ */
} }
void monon_color_state::machine_reset()
{
m_maincpu->set_state_int(MCS51_PC, 0x4000);
}
void monon_color_state::video_start() void monon_color_state::video_start()
{ {
} }

View File

@ -329,6 +329,7 @@ static const dasm_table_entry dasm_table[] =
{ "asap", le, 0, []() -> util::disasm_interface * { return new asap_disassembler; } }, { "asap", le, 0, []() -> util::disasm_interface * { return new asap_disassembler; } },
{ "avr8", le, 0, []() -> util::disasm_interface * { return new avr8_disassembler; } }, { "avr8", le, 0, []() -> util::disasm_interface * { return new avr8_disassembler; } },
{ "axc51core", le, 0, []() -> util::disasm_interface * { return new axc51core_disassembler; } }, { "axc51core", le, 0, []() -> util::disasm_interface * { return new axc51core_disassembler; } },
{ "axc208", le, 0, []() -> util::disasm_interface * { return new ax208_disassembler; } },
{ "capricorn", le, 0, []() -> util::disasm_interface * { return new capricorn_disassembler; } }, { "capricorn", le, 0, []() -> util::disasm_interface * { return new capricorn_disassembler; } },
{ "ccpu", le, 0, []() -> util::disasm_interface * { return new ccpu_disassembler; } }, { "ccpu", le, 0, []() -> util::disasm_interface * { return new ccpu_disassembler; } },
{ "cdp1801", le, 0, []() -> util::disasm_interface * { return new cosmac_disassembler(cosmac_disassembler::TYPE_1801); } }, { "cdp1801", le, 0, []() -> util::disasm_interface * { return new cosmac_disassembler(cosmac_disassembler::TYPE_1801); } },