added support to display dividers in the debugger state view

i8089: improved debugger view
This commit is contained in:
Dirk Best 2013-08-25 12:23:20 +00:00
parent 2f8875a792
commit 273fe7960e
5 changed files with 149 additions and 71 deletions

View File

@ -37,10 +37,10 @@ i8089_device::i8089_device(const machine_config &mconfig, const char *tag, devic
m_ch2(*this, "2"),
m_write_sintr1(*this),
m_write_sintr2(*this),
m_16bit_system(false),
m_16bit_remote(false),
m_sysbus(0),
m_scb(0),
m_soc(0),
m_master(false),
m_request_grant(false),
m_current_tp(0),
m_ca(0),
m_sel(0)
@ -61,37 +61,40 @@ void i8089_device::device_start()
m_write_sintr2.resolve_safe();
// register debugger states
state_add(i8089_channel::GA, "CH1 GA", m_ch1->m_r[i8089_channel::GA].w).mask(0xfffff);
state_add(i8089_channel::GB, "CH1 GB", m_ch1->m_r[i8089_channel::GB].w).mask(0xfffff);
state_add(i8089_channel::GC, "CH1 GC", m_ch1->m_r[i8089_channel::GC].w).mask(0xfffff);
state_add(i8089_channel::TP, "CH1 TP", m_ch1->m_r[i8089_channel::TP].w).mask(0xfffff);
state_add(i8089_channel::BC, "CH1 BC", m_ch1->m_r[i8089_channel::BC].w).mask(0xffff);
state_add(i8089_channel::IX, "CH1 IX", m_ch1->m_r[i8089_channel::IX].w).mask(0xffff);
state_add(i8089_channel::CC, "CH1 CC", m_ch1->m_r[i8089_channel::CC].w).mask(0xffff);
state_add(i8089_channel::MC, "CH1 MC", m_ch1->m_r[i8089_channel::MC].w).mask(0xffff);
state_add(i8089_channel::CP, "CH1 CP", m_ch1->m_r[i8089_channel::CP].w).mask(0xfffff);
state_add(i8089_channel::PP, "CH1 PP", m_ch1->m_r[i8089_channel::PP].w).mask(0xfffff);
state_add(i8089_channel::PSW, "CH1 PSW", m_ch1->m_r[i8089_channel::PSW].w).callimport().callexport().formatstr("%12s");
state_add(i8089_channel::GA + i8089_channel::NUM_REGS, "CH2 GA", m_ch2->m_r[i8089_channel::GA].w).mask(0xfffff);
state_add(i8089_channel::GB + i8089_channel::NUM_REGS, "CH2 GB", m_ch2->m_r[i8089_channel::GB].w).mask(0xfffff);
state_add(i8089_channel::GC + i8089_channel::NUM_REGS, "CH2 GC", m_ch2->m_r[i8089_channel::GC].w).mask(0xfffff);
state_add(i8089_channel::TP + i8089_channel::NUM_REGS, "CH2 TP", m_ch2->m_r[i8089_channel::TP].w).mask(0xfffff);
state_add(i8089_channel::BC + i8089_channel::NUM_REGS, "CH2 BC", m_ch2->m_r[i8089_channel::BC].w).mask(0xffff);
state_add(i8089_channel::IX + i8089_channel::NUM_REGS, "CH2 IX", m_ch2->m_r[i8089_channel::IX].w).mask(0xffff);
state_add(i8089_channel::CC + i8089_channel::NUM_REGS, "CH2 CC", m_ch2->m_r[i8089_channel::CC].w).mask(0xffff);
state_add(i8089_channel::MC + i8089_channel::NUM_REGS, "CH2 MC", m_ch2->m_r[i8089_channel::MC].w).mask(0xffff);
state_add(i8089_channel::CP + i8089_channel::NUM_REGS, "CH2 CP", m_ch2->m_r[i8089_channel::CP].w).mask(0xfffff);
state_add(i8089_channel::PP + i8089_channel::NUM_REGS, "CH2 PP", m_ch2->m_r[i8089_channel::PP].w).mask(0xfffff);
state_add(i8089_channel::PSW + i8089_channel::NUM_REGS, "CH2 PSW", m_ch2->m_r[i8089_channel::PSW].w).callimport().callexport().formatstr("%12s");
state_add(SYSBUS, "SYSBUS", m_sysbus).mask(0x01).formatstr("%1s");
state_add(SCB, "SCB", m_scb).mask(0xfffff);
state_add(SOC, "SOC", m_soc).mask(0x03).formatstr("%2s");
state_add_divider(DIVIDER1);
state_add(CH1_GA, "CH1 GA", m_ch1->m_r[i8089_channel::GA].w).mask(0xfffff).formatstr("%8s");
state_add(CH1_GB, "CH1 GB", m_ch1->m_r[i8089_channel::GB].w).mask(0xfffff).formatstr("%8s");
state_add(CH1_GC, "CH1 GC", m_ch1->m_r[i8089_channel::GC].w).mask(0xfffff).formatstr("%8s");
state_add(CH1_TP, "CH1 TP", m_ch1->m_r[i8089_channel::TP].w).mask(0xfffff).formatstr("%8s");
state_add(CH1_BC, "CH1 BC", m_ch1->m_r[i8089_channel::BC].w).mask(0xffff);
state_add(CH1_IX, "CH1 IX", m_ch1->m_r[i8089_channel::IX].w).mask(0xffff);
state_add(CH1_CC, "CH1 CC", m_ch1->m_r[i8089_channel::CC].w).mask(0xffff);
state_add(CH1_MC, "CH1 MC", m_ch1->m_r[i8089_channel::MC].w).mask(0xffff);
state_add(CH1_CP, "CH1 CP", m_ch1->m_r[i8089_channel::CP].w).mask(0xfffff);
state_add(CH1_PP, "CH1 PP", m_ch1->m_r[i8089_channel::PP].w).mask(0xfffff);
state_add(CH1_PSW, "CH1 PSW", m_ch1->m_r[i8089_channel::PSW].w).callimport().callexport().formatstr("%12s");
state_add_divider(DIVIDER2);
state_add(CH2_GA, "CH2 GA", m_ch2->m_r[i8089_channel::GA].w).mask(0xfffff).formatstr("%8s");
state_add(CH2_GB, "CH2 GB", m_ch2->m_r[i8089_channel::GB].w).mask(0xfffff).formatstr("%8s");
state_add(CH2_GC, "CH2 GC", m_ch2->m_r[i8089_channel::GC].w).mask(0xfffff).formatstr("%8s");
state_add(CH2_TP, "CH2 TP", m_ch2->m_r[i8089_channel::TP].w).mask(0xfffff).formatstr("%8s");
state_add(CH2_BC, "CH2 BC", m_ch2->m_r[i8089_channel::BC].w).mask(0xffff);
state_add(CH2_IX, "CH2 IX", m_ch2->m_r[i8089_channel::IX].w).mask(0xffff);
state_add(CH2_CC, "CH2 CC", m_ch2->m_r[i8089_channel::CC].w).mask(0xffff);
state_add(CH2_MC, "CH2 MC", m_ch2->m_r[i8089_channel::MC].w).mask(0xffff);
state_add(CH2_CP, "CH2 CP", m_ch2->m_r[i8089_channel::CP].w).mask(0xfffff);
state_add(CH2_PP, "CH2 PP", m_ch2->m_r[i8089_channel::PP].w).mask(0xfffff);
state_add(CH2_PSW, "CH2 PSW", m_ch2->m_r[i8089_channel::PSW].w).callimport().callexport().formatstr("%12s");
state_add(STATE_GENPC, "GENPC", m_current_tp).mask(0xfffff).noshow();
// register for save states
save_item(NAME(m_16bit_system));
save_item(NAME(m_16bit_remote));
save_item(NAME(m_sysbus));
save_item(NAME(m_scb));
save_item(NAME(m_soc));
save_item(NAME(m_master));
save_item(NAME(m_request_grant));
save_item(NAME(m_ca));
save_item(NAME(m_sel));
@ -153,31 +156,47 @@ offs_t i8089_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *op
void i8089_device::state_string_export(const device_state_entry &entry, astring &string)
{
i8089_channel *ch = m_ch1;
if (entry.index() >= CH2_GA && entry.index() <= CH2_PSW)
ch = m_ch2;
switch (entry.index())
{
case i8089_channel::PSW:
string.printf("%c%s%c%s%s%s%c%c",
BIT(m_ch1->m_r[i8089_channel::PSW].w, 7) ? 'P':'.',
BIT(m_ch1->m_r[i8089_channel::PSW].w, 6) ? "XF":"..",
BIT(m_ch1->m_r[i8089_channel::PSW].w, 5) ? 'B':'.',
BIT(m_ch1->m_r[i8089_channel::PSW].w, 4) ? "IS":"..",
BIT(m_ch1->m_r[i8089_channel::PSW].w, 3) ? "IC":"..",
BIT(m_ch1->m_r[i8089_channel::PSW].w, 2) ? "TB":"..",
BIT(m_ch1->m_r[i8089_channel::PSW].w, 1) ? 'S':'.',
BIT(m_ch1->m_r[i8089_channel::PSW].w, 0) ? 'D':'.');
break;
case i8089_channel::PSW + i8089_channel::NUM_REGS:
string.printf("%c%s%c%s%s%s%c%c",
BIT(m_ch2->m_r[i8089_channel::PSW].w, 7) ? 'P':'.',
BIT(m_ch2->m_r[i8089_channel::PSW].w, 6) ? "XF":"..",
BIT(m_ch2->m_r[i8089_channel::PSW].w, 5) ? 'B':'.',
BIT(m_ch2->m_r[i8089_channel::PSW].w, 4) ? "IS":"..",
BIT(m_ch2->m_r[i8089_channel::PSW].w, 3) ? "IC":"..",
BIT(m_ch2->m_r[i8089_channel::PSW].w, 2) ? "TB":"..",
BIT(m_ch2->m_r[i8089_channel::PSW].w, 1) ? 'S':'.',
BIT(m_ch2->m_r[i8089_channel::PSW].w, 0) ? 'D':'.');
break;
case SYSBUS:
string.printf("%c", sysbus_width() ? 'W' : '.');
break;
case SOC:
string.printf("%c%c", remotebus_width() ? 'I' : '.', request_grant() ? 'R' : '.');
break;
case CH1_GA:
case CH2_GA:
string.printf("%d %05X", ch->m_r[i8089_channel::GA].t & 1, ch->m_r[i8089_channel::GA].w);
break;
case CH1_GB:
case CH2_GB:
string.printf("%d %05X", ch->m_r[i8089_channel::GB].t & 1, ch->m_r[i8089_channel::GB].w);
break;
case CH1_GC:
case CH2_GC:
string.printf("%d %05X", ch->m_r[i8089_channel::GC].t & 1, ch->m_r[i8089_channel::GC].w);
break;
case CH1_TP:
case CH2_TP:
string.printf("%d %05X", ch->m_r[i8089_channel::TP].t & 1, ch->m_r[i8089_channel::TP].w);
break;
case CH1_PSW:
case CH2_PSW:
string.printf("%c%s%c%s%s%s%c%c",
BIT(ch->m_r[i8089_channel::PSW].w, 7) ? 'P':'.',
BIT(ch->m_r[i8089_channel::PSW].w, 6) ? "XF":"..",
BIT(ch->m_r[i8089_channel::PSW].w, 5) ? 'B':'.',
BIT(ch->m_r[i8089_channel::PSW].w, 4) ? "IS":"..",
BIT(ch->m_r[i8089_channel::PSW].w, 3) ? "IC":"..",
BIT(ch->m_r[i8089_channel::PSW].w, 2) ? "TB":"..",
BIT(ch->m_r[i8089_channel::PSW].w, 1) ? 'S':'.',
BIT(ch->m_r[i8089_channel::PSW].w, 0) ? 'D':'.');
break;
}
}
@ -216,23 +235,20 @@ void i8089_device::initialize()
assert(!m_initialized);
// get system bus width
UINT8 sys_bus = m_mem->read_byte(0xffff6);
m_16bit_system = BIT(sys_bus, 0);
m_sysbus = m_mem->read_byte(0xffff6);
// get system configuration block address
UINT16 scb_offset = read_word(0xffff8);
UINT16 scb_segment = read_word(0xffffa);
offs_t scb_address = ((scb_segment << 4) + scb_offset) & 0x0fffff;
m_scb = ((scb_segment << 4) + scb_offset) & 0x0fffff;
// get system operation command
UINT16 soc = read_word(scb_address);
m_16bit_remote = BIT(soc, 0);
m_request_grant = BIT(soc, 1);
m_soc = read_byte(m_scb);
m_master = !m_sel;
// get control block address
UINT16 cb_offset = read_word(scb_address + 2);
UINT16 cb_segment = read_word(scb_address + 4);
UINT16 cb_offset = read_word(m_scb + 2);
UINT16 cb_segment = read_word(m_scb + 4);
offs_t cb_address = ((cb_segment << 4) + cb_offset) & 0x0fffff;
// initialize channels
@ -250,10 +266,10 @@ void i8089_device::initialize()
if (VERBOSE)
{
logerror("%s('%s'): ---- initializing ----\n", shortname(), basetag());
logerror("%s('%s'): %s system bus\n", shortname(), basetag(), m_16bit_system ? "16-bit" : "8-bit");
logerror("%s('%s'): system configuration block location: %06x\n", shortname(), basetag(), scb_address);
logerror("%s('%s'): %s remote bus\n", shortname(), basetag(), m_16bit_remote ? "16-bit" : "8-bit");
logerror("%s('%s'): request/grant: %d\n", shortname(), basetag(), m_request_grant);
logerror("%s('%s'): %s system bus\n", shortname(), basetag(), sysbus_width() ? "16-bit" : "8-bit");
logerror("%s('%s'): system configuration block location: %06x\n", shortname(), basetag(), m_scb);
logerror("%s('%s'): %s remote bus\n", shortname(), basetag(), remotebus_width() ? "16-bit" : "8-bit");
logerror("%s('%s'): request/grant: %d\n", shortname(), basetag(), request_grant());
logerror("%s('%s'): is %s\n", shortname(), basetag(), m_master ? "master" : "slave");
logerror("%s('%s'): channel control block location: %06x\n", shortname(), basetag(), cb_address);
}
@ -271,7 +287,7 @@ UINT16 i8089_device::read_word(offs_t address)
UINT16 data = 0xffff;
if (m_16bit_system && !(address & 1))
if (sysbus_width() && !(address & 1))
{
data = m_mem->read_word(address);
}
@ -294,7 +310,7 @@ void i8089_device::write_word(offs_t address, UINT16 data)
{
assert(m_initialized);
if (m_16bit_system && !(address & 1))
if (sysbus_width() && !(address & 1))
{
m_mem->write_word(address, data);
}

View File

@ -91,6 +91,10 @@ protected:
virtual machine_config_constructor device_mconfig_additions() const;
private:
bool sysbus_width() { return BIT(m_sysbus, 0); }
bool remotebus_width() { return BIT(m_soc, 0); }
bool request_grant() { return BIT(m_soc, 1); }
UINT8 read_byte(offs_t address);
UINT16 read_word(offs_t address);
void write_byte(offs_t address, UINT8 data);
@ -108,12 +112,31 @@ private:
address_space *m_mem;
address_space *m_io;
// register indexes for the debugger state
enum
{
SYSBUS,
SCB,
SOC,
DIVIDER1,
CH1_GA, CH1_GB, CH1_GC,
CH1_TP, CH1_BC, CH1_IX,
CH1_CC, CH1_MC, CH1_CP,
CH1_PP, CH1_PSW,
DIVIDER2,
CH2_GA, CH2_GB, CH2_GC,
CH2_TP, CH2_BC, CH2_IX,
CH2_CC, CH2_MC, CH2_CP,
CH2_PP, CH2_PSW
};
// system configuration
UINT8 m_sysbus;
offs_t m_scb;
UINT8 m_soc;
bool m_initialized;
bool m_16bit_system;
bool m_16bit_remote;
bool m_master;
bool m_request_grant;
// task pointer for the currently executing channel
offs_t m_current_tp;

View File

@ -171,7 +171,12 @@ void debug_view_state::recompute()
// add all registers into it
for (const device_state_entry *entry = source.m_stateintf->state_first(); entry != NULL; entry = entry->next())
if (entry->visible())
if (entry->divider())
{
*tailptr = auto_alloc(machine(), state_item(REG_DIVIDER, "", 0));
tailptr = &(*tailptr)->m_next;
}
else if (entry->visible())
{
*tailptr = auto_alloc(machine(), state_item(entry->index(), entry->symbol(), source.m_stateintf->state_string_max_length(entry->index())));
tailptr = &(*tailptr)->m_next;

View File

@ -115,6 +115,19 @@ device_state_entry::device_state_entry(int index, const char *symbol, void *data
m_symbol.cpy("CURFLAGS");
}
device_state_entry::device_state_entry(int index)
: m_next(NULL),
m_index(index),
m_dataptr(NULL),
m_datamask(0),
m_datasize(0),
m_flags(DSF_DIVIDER),
m_symbol(),
m_default_format(true),
m_sizemask(0)
{
}
//-------------------------------------------------
// formatstr - specify a format string
@ -526,6 +539,21 @@ device_state_entry &device_state_interface::state_add(int index, const char *sym
return *entry;
}
//-------------------------------------------------
// state_add_divider - add a simple divider
// entry
//-------------------------------------------------
device_state_entry &device_state_interface::state_add_divider(int index)
{
// allocate new entry
device_state_entry *entry = global_alloc(device_state_entry(index));
// append to the end of the list
m_state_list.append(*entry);
return *entry;
}
//-------------------------------------------------
// state_import - called after new state is

View File

@ -78,6 +78,7 @@ class device_state_entry
private:
// construction/destruction
device_state_entry(int index, const char *symbol, void *dataptr, UINT8 size);
device_state_entry(int index);
public:
// post-construction modifiers
@ -96,6 +97,7 @@ public:
void *dataptr() const { return m_dataptr.v; }
const char *symbol() const { return m_symbol; }
bool visible() const { return ((m_flags & DSF_NOSHOW) == 0); }
bool divider() const { return m_flags & DSF_DIVIDER; }
protected:
// device state flags
@ -104,6 +106,7 @@ protected:
static const UINT8 DSF_IMPORT_SEXT = 0x04; // sign-extend the data when writing new data
static const UINT8 DSF_EXPORT = 0x08; // call the export function prior to fetching the data
static const UINT8 DSF_CUSTOM_STRING = 0x10; // set if the format has a custom string
static const UINT8 DSF_DIVIDER = 0x20; // set if this is a divider entry
// helpers
bool needs_custom_string() const { return ((m_flags & DSF_CUSTOM_STRING) != 0); }
@ -179,6 +182,9 @@ public: // protected eventually
}
device_state_entry &state_add(int index, const char *symbol, void *data, UINT8 size);
// add a new divider entry
device_state_entry &state_add_divider(int index);
protected:
// derived class overrides
virtual void state_import(const device_state_entry &entry);