abc1600: MAC cleanup. [Curt Coder]

This commit is contained in:
Curt Coder 2022-02-07 09:28:01 +02:00
parent 5f3ec335f3
commit a40130f681
4 changed files with 151 additions and 96 deletions

View File

@ -478,7 +478,7 @@ void abc1600_state::spec_contr_reg_w(uint8_t data)
void abc1600_state::abc1600_mem(address_map &map)
{
map(0x00000, 0xfffff).m(ABC1600_MAC_TAG, FUNC(abc1600_mac_device::map));
map(0x00000, 0xfffff).rw(ABC1600_MAC_TAG, FUNC(abc1600_mac_device::read), FUNC(abc1600_mac_device::write));
}
@ -805,6 +805,13 @@ WRITE_LINE_MEMBER( abc1600_state::nmi_w )
}
}
void abc1600_state::buserr_w(offs_t offset, uint8_t data)
{
m_maincpu->set_buserror_details(offset, data, m_maincpu->get_fc());
m_maincpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE);
m_maincpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE);
}
//**************************************************************************
@ -830,6 +837,7 @@ void abc1600_state::machine_start()
save_item(NAME(m_bus0));
save_item(NAME(m_csb));
save_item(NAME(m_atce));
save_item(NAME(m_btce));
save_item(NAME(m_sccrq_a));
save_item(NAME(m_sccrq_b));
save_item(NAME(m_scc_irq));
@ -877,7 +885,7 @@ void abc1600_state::abc1600(machine_config &config)
ABC1600_MAC(config, m_mac, 0);
m_mac->set_addrmap(AS_PROGRAM, &abc1600_state::mac_mem);
m_mac->fc_cb().set(m_maincpu, FUNC(m68000_base_device::get_fc));
m_mac->buserr_cb().set_inputline(m_maincpu, M68K_LINE_BUSERROR);
m_mac->buserr_cb().set(FUNC(abc1600_state::buserr_w));
Z80DMA(config, m_dma0, 64_MHz_XTAL / 16);
m_dma0->out_busreq_callback().set(FUNC(abc1600_state::dbrq_w));

View File

@ -133,6 +133,7 @@ public:
void cio_pc_w(uint8_t data);
void nmi_w(int state);
void buserr_w(offs_t offset, uint8_t data);
void cpu_space_map(address_map &map);
@ -149,7 +150,6 @@ public:
int m_dmadis;
int m_sysscc;
int m_sysfs;
uint8_t m_cause;
int m_partst; // parity test
void abc1600(machine_config &config);
@ -164,8 +164,8 @@ public:
int m_btce; // V.24 channel B external clock enable
bool m_sccrq_a;
bool m_sccrq_b;
int m_dart_irq;
int m_scc_irq;
int m_dart_irq;
};

View File

@ -18,28 +18,9 @@
#define LOG 0
#define LOG_MAC 0
#define LOG_DMA 0
#define LOG_IO 0
#define A0 BIT(offset, 0)
#define A1 BIT(offset, 1)
#define A2 BIT(offset, 2)
#define A4 BIT(offset, 4)
#define A7 BIT(offset, 7)
#define A8 BIT(offset, 8)
#define X11 BIT(offset, 11)
#define X12 BIT(offset, 12)
#define A17 BIT(offset, 17)
#define A18 BIT(offset, 18)
#define A19 BIT(offset, 19)
#define A10_A9_A8 ((offset >> 8) & 0x07)
#define A2_A1_A0 (offset & 0x07)
#define A1_A2 ((A1 << 1) | A2)
#define A2_A1 ((offset >> 1) & 0x03)
#define FC0 BIT(fc, 0)
#define FC1 BIT(fc, 1)
#define FC2 BIT(fc, 2)
#define PAGE_WP BIT(page_data, 14)
@ -54,13 +35,12 @@
DEFINE_DEVICE_TYPE(ABC1600_MAC, abc1600_mac_device, "abc1600mac", "ABC 1600 MAC")
void abc1600_mac_device::map(address_map &map)
void abc1600_mac_device::program_map(address_map &map)
{
map(0x00000, 0xfffff).rw(FUNC(abc1600_mac_device::read), FUNC(abc1600_mac_device::write));
// populated in drivers/abc1600.cpp
}
void abc1600_mac_device::program_map(address_map &map)
void abc1600_mac_device::mac_map(address_map &map)
{
map(0x80000, 0x80000).mirror(0x006f8).select(0x7f900).rw(FUNC(abc1600_mac_device::page_hi_r), FUNC(abc1600_mac_device::page_hi_w));
map(0x80001, 0x80001).mirror(0x006f8).select(0x7f900).rw(FUNC(abc1600_mac_device::page_lo_r), FUNC(abc1600_mac_device::page_lo_w));
@ -115,13 +95,13 @@ abc1600_mac_device::abc1600_mac_device(const machine_config &mconfig, const char
device_t(mconfig, ABC1600_MAC, tag, owner, clock),
device_memory_interface(mconfig, *this),
m_program_config("program", ENDIANNESS_BIG, 8, 21, 0, address_map_constructor(FUNC(abc1600_mac_device::program_map), this)),
m_mac_config("mac", ENDIANNESS_BIG, 8, 20, 0, address_map_constructor(FUNC(abc1600_mac_device::mac_map), this)),
m_rom(*this, "boot"),
m_segment_ram(*this, "segment_ram", 0x400, ENDIANNESS_LITTLE),
m_page_ram(*this, "page_ram", 0x800, ENDIANNESS_LITTLE),
m_watchdog(*this, "watchdog"),
m_read_fc(*this),
m_write_buserr(*this),
m_ifc2(0),
m_boote(0),
m_magic(0),
m_task(0),
@ -140,15 +120,16 @@ void abc1600_mac_device::device_start()
m_read_fc.resolve_safe(0);
m_write_buserr.resolve_safe();
// HACK fill segment RAM or abcenix won't boot
memset(m_segment_ram, 0xcd, 0x400);
//memset(m_page_ram, 0xcd, 0x400);
// state saving
save_item(NAME(m_ifc2));
save_item(NAME(m_boote));
save_item(NAME(m_magic));
save_item(NAME(m_task));
save_item(NAME(m_dmamap));
save_item(NAME(m_cause));
// HACK fill segment RAM or abcenix won't boot
memset(m_segment_ram, 0xcd, 0x200);
memset(m_page_ram, 0xcd, 0x800);
}
@ -173,23 +154,20 @@ void abc1600_mac_device::device_reset()
device_memory_interface::space_config_vector abc1600_mac_device::memory_space_config() const
{
return space_config_vector {
std::make_pair(AS_PROGRAM, &m_program_config)
std::make_pair(AS_PROGRAM, &m_program_config),
std::make_pair(AS_MAC, &m_mac_config)
};
}
//-------------------------------------------------
// translate_address -
// get_physical_offset -
//-------------------------------------------------
offs_t abc1600_mac_device::translate_address(offs_t offset, int &nonx, int &wp)
inline offs_t abc1600_mac_device::get_physical_offset(offs_t offset, int task, bool &nonx, bool &wp)
{
// segment
int force_task0 = !(m_ifc2 || A19);
int task = force_task0 ? 0 : m_task;
int sega19 = !(!(A8 || m_ifc2) || !A19);
offs_t sega = (task << 5) | (sega19 << 4) | ((offset >> 15) & 0x0f);
offs_t sega = (task << 5) | ((offset >> 15) & 0x1f);
uint8_t segd = m_segment_ram[sega];
// page
@ -198,17 +176,11 @@ offs_t abc1600_mac_device::translate_address(offs_t offset, int &nonx, int &wp)
offs_t virtual_offset = ((page_data & 0x3ff) << 11) | (offset & 0x7ff);
if (PAGE_NONX)
{
logerror("Bus error %06x : %06x\n", offset, virtual_offset);
m_write_buserr(ASSERT_LINE);
m_write_buserr(CLEAR_LINE);
}
nonx = PAGE_NONX;
wp = PAGE_WP;
if (LOG_MAC && offset != virtual_offset) logerror("%s MAC %05x:%06x (SEGA %03x SEGD %02x PGA %03x PGD %04x NONX %u WP %u TASK %u FC %u)\n", machine().describe_context(), offset, virtual_offset, sega, segd, pga, m_page_ram[pga], nonx, wp, task, m_read_fc());
if (LOG && (offset != virtual_offset)) logerror("%s MAC %05x:%06x (SEGA %03x SEGD %02x PGA %03x PGD %04x NONX %u WP %u TASK %u FC %u MAGIC %u)\n",
machine().describe_context(), offset, virtual_offset, sega, segd, pga, page_data, nonx, wp, task, m_read_fc(), m_magic);
return virtual_offset;
}
@ -220,31 +192,48 @@ offs_t abc1600_mac_device::translate_address(offs_t offset, int &nonx, int &wp)
uint8_t abc1600_mac_device::read(offs_t offset)
{
uint16_t fc = m_read_fc();
m_ifc2 = !(!(m_magic || FC0) || FC2);
uint8_t data = 0;
if (!m_boote && (offset < 0x20000))
{
// _BOOTCE
data = m_rom->base()[offset & 0x3fff];
return m_rom->base()[offset & 0x3fff];
}
else if ((offset & 0x80000) && !m_ifc2 && !FC1)
{
data = space(AS_PROGRAM).read_byte(offset);
}
else
{
int nonx = 0, wp = 0;
offs_t virtual_offset = translate_address(offset, nonx, wp);
data = space().read_byte(virtual_offset);
uint8_t fc = m_read_fc();
int task = m_task;
if (LOG_IO && virtual_offset >= 0x1fe000) logerror("%s user read %06x:%02x\n", machine().describe_context(), virtual_offset, data);
if (FC2)
{
if (offset & 0x80000)
{
if (LOG_MAC && (offset != 0x80007)) logerror("%s MAC R %05x\n",
machine().describe_context(), offset);
return space(AS_MAC).read_byte(offset);
}
else
{
task = 0;
}
}
return data;
if (!m_magic && (fc == M68K_FC_USER_PROGRAM))
{
task = 0;
}
bool nonx, wp;
offs_t virtual_offset = get_physical_offset(offset, task, nonx, wp);
if (!machine().side_effects_disabled())
{
if (nonx)
{
logerror("NONX\n");
dump();
m_write_buserr(offset, 1);
}
}
return space().read_byte(virtual_offset);
}
@ -254,24 +243,45 @@ uint8_t abc1600_mac_device::read(offs_t offset)
void abc1600_mac_device::write(offs_t offset, uint8_t data)
{
uint16_t fc = m_read_fc();
m_ifc2 = !(!(m_magic || FC0) || FC2);
uint8_t fc = m_read_fc();
int task = m_task;
if ((offset & 0x80000) && !m_ifc2 && !FC1)
if (FC2)
{
space(AS_PROGRAM).write_byte(offset, data);
if (offset & 0x80000)
{
if (LOG_MAC) logerror("%s MAC W %05x:%02x\n",
machine().describe_context(), offset, data);
space(AS_MAC).write_byte(offset, data);
return;
}
else
{
task = 0;
}
}
else
bool nonx, wp;
offs_t virtual_offset = get_physical_offset(offset, task, nonx, wp);
if (!machine().side_effects_disabled())
{
int nonx = 0, wp = 0;
offs_t virtual_offset = translate_address(offset, nonx, wp);
if (nonx || !wp) return;
if (LOG_IO && virtual_offset >= 0x1fe000) logerror("%s user write %06x:%02x\n", machine().describe_context(), virtual_offset, data);
space().write_byte(virtual_offset, data);
if (nonx)
{
logerror("NONX\n");
dump();
m_write_buserr(offset, 0);
}
if (!wp)
{
logerror("WP\n");
dump();
m_write_buserr(offset, 0);
}
}
space().write_byte(virtual_offset, data);
}
@ -332,8 +342,8 @@ void abc1600_mac_device::task_w(offs_t offset, uint8_t data)
m_boote = !BIT(data, 6);
m_magic = !BIT(data, 7);
if (LOG) logerror("%s TASK %05x:%02x (TASK %u BOOTE %u MAGIC %u)\n", machine().describe_context(), offset, data,
m_task, m_boote, m_magic);
if (LOG_MAC) logerror("%s TASK W %02x (TASK %u BOOTE %u MAGIC %u)\n",
machine().describe_context(), data, m_task, m_boote, m_magic);
}
@ -389,8 +399,9 @@ void abc1600_mac_device::segment_w(offs_t offset, uint8_t data)
offs_t sega = (m_task << 5) | A8 << 4 | ((offset >> 15) & 0xf);
m_segment_ram[sega] = data & 0x7f;
if (LOG) logerror("%s %05x:%02x TASK %u SEGMENT %u MEM %05x-%05x\n", machine().describe_context(), offset, data,
m_task, sega & 0x1f, (sega & 0x1f) * 0x8000, ((sega & 0x1f) * 0x8000) + 0x7fff);
if (LOG_MAC) logerror("%s SEG W %05x:%02x SEGA %03x SEGD %02x TASK %u\n",
machine().describe_context(), offset, data,
sega, m_segment_ram[sega], m_task);
}
@ -491,9 +502,9 @@ void abc1600_mac_device::page_lo_w(offs_t offset, uint8_t data)
offs_t pga = ((segd & 0x3f) << 4) | ((offset >> 11) & 0xf);
m_page_ram[pga] = (m_page_ram[pga] & 0xff00) | data;
if (LOG) logerror("%s %05x:%02x TASK %u SEGMENT %u PAGE %u MEM %05x-%05x %06x\n", machine().describe_context(), offset, data,
m_task, sega & 0x1f, ((offset >> 11) & 0x0f), ((sega & 0x1f) * 0x8000) + ((offset >> 11) & 0x0f) * 0x800,
((sega & 0x1f) * 0x8000) + (((offset >> 11) & 0x0f) * 0x800) + 0x7ff, (m_page_ram[pga] & 0x3ff) << 11);
if (LOG_MAC) logerror("%s PAGE W %05x:%02x (SEGA %03x SEGD %02x PGA %03x PGD %04x TASK %u)\n",
machine().describe_context(), offset, data,
sega, segd, pga, m_page_ram[pga], m_task);
}
@ -625,3 +636,32 @@ void abc1600_mac_device::dmamap_w(offs_t offset, uint8_t data)
m_dmamap[offset & 7] = data;
}
//-------------------------------------------------
// dump - dump MAC mappings
//-------------------------------------------------
void abc1600_mac_device::dump()
{
for (int task = 0; task < 16; task++) {
for (int seg = 0; seg < 32; seg++) {
for (int page = 0; page < 16; page++) {
offs_t logical = (seg * 0x8000) | (page * 0x800);
offs_t sega = (task << 5) | seg;
uint8_t segd = m_segment_ram[sega];
offs_t pga = ((segd & 0x3f) << 4) | page;
uint16_t page_data = m_page_ram[pga];
offs_t physical = (page_data & 0x3ff) << 11;
bool nonx = PAGE_NONX;
bool wp = PAGE_WP;
logerror("TASK %.2u SEGMENT %.2u PAGE %.2u MEM %05x-%05x %06x-%06x %c %c\n",
task, seg, page, logical, logical + 0x7ff, physical, physical + 0x7ff, nonx ? 'X' : ' ', wp ? ' ' : 'W');
}
}
}
}

View File

@ -38,7 +38,8 @@ public:
auto fc_cb() { return m_read_fc.bind(); }
auto buserr_cb() { return m_write_buserr.bind(); }
virtual void map(address_map &map);
uint8_t read(offs_t offset);
void write(offs_t offset, uint8_t data);
uint8_t cause_r();
void task_w(offs_t offset, uint8_t data);
@ -62,6 +63,8 @@ public:
void dma2_mreq_w(offs_t offset, uint8_t data) { dma_mreq_w(DMAMAP_R2_LO, offset, data); }
uint8_t dma2_iorq_r(offs_t offset) { return dma_iorq_r(DMAMAP_R2_LO, offset); }
void dma2_iorq_w(offs_t offset, uint8_t data) { dma_iorq_w(DMAMAP_R2_LO, offset, data); }
void dump();
protected:
// device-level overrides
@ -85,11 +88,9 @@ private:
DMAMAP_R0_LO,
DMAMAP_R0_HI
};
offs_t get_physical_offset(offs_t offset, int task, bool &nonx, bool &wp);
uint8_t read(offs_t offset);
void write(offs_t offset, uint8_t data);
offs_t translate_address(offs_t offset, int &nonx, int &wp);
offs_t get_dma_address(int index, uint16_t offset);
uint8_t dma_mreq_r(int index, uint16_t offset);
void dma_mreq_w(int index, uint16_t offset, uint8_t data);
@ -97,7 +98,9 @@ private:
void dma_iorq_w(int index, uint16_t offset, uint8_t data);
void program_map(address_map &map);
void mac_map(address_map &map);
const address_space_config m_program_config;
const address_space_config m_mac_config;
required_memory_region m_rom;
memory_share_creator<uint8_t> m_segment_ram;
@ -106,17 +109,21 @@ private:
required_device<watchdog_timer_device> m_watchdog;
devcb_read8 m_read_fc;
devcb_write_line m_write_buserr;
devcb_write8 m_write_buserr;
bool m_ifc2;
bool m_boote;
bool m_magic;
bool m_task;
int m_task;
uint8_t m_dmamap[8];
uint8_t m_cause;
};
constexpr int AS_MAC = 1;
// device type definition
DECLARE_DEVICE_TYPE(ABC1600_MAC, abc1600_mac_device)