mirror of
https://github.com/holub/mame
synced 2025-04-16 05:24:54 +03:00
New machines marked as NOT_WORKING
--- IBM RT PC [Bitsavers]
This commit is contained in:
parent
2ee5ac358c
commit
89b519f58e
@ -165,6 +165,7 @@ CPUS["GTRON"] = true
|
||||
CPUS["M88000"] = true
|
||||
CPUS["XAVIX2"] = true
|
||||
CPUS["UPD78K"] = true
|
||||
CPUS["ROMP"] = true
|
||||
|
||||
--------------------------------------------------
|
||||
-- specify available sound cores; some of these are
|
||||
@ -920,6 +921,7 @@ BUSES["PSX_PARALLEL"] = true
|
||||
BUSES["QL"] = true
|
||||
BUSES["QBUS"] = true
|
||||
BUSES["RS232"] = true
|
||||
BUSES["RTPC_KBD"] = true
|
||||
BUSES["S100"] = true
|
||||
BUSES["SAMCOUPE_DRIVE_PORT"] = true
|
||||
BUSES["SAMCOUPE_EXPANSION"] = true
|
||||
@ -1334,6 +1336,7 @@ function linkProjects_mame_mess(_target, _subtarget)
|
||||
"rockwell",
|
||||
"roland",
|
||||
"rolm",
|
||||
"rtpc",
|
||||
"sage",
|
||||
"saitek",
|
||||
"samcoupe",
|
||||
@ -3432,6 +3435,15 @@ files {
|
||||
MAME_DIR .. "src/mame/drivers/aim65_40.cpp",
|
||||
}
|
||||
|
||||
createMESSProjects(_target, _subtarget, "rtpc")
|
||||
files {
|
||||
MAME_DIR .. "src/mame/drivers/rtpc.cpp",
|
||||
MAME_DIR .. "src/mame/machine/rosetta.cpp",
|
||||
MAME_DIR .. "src/mame/machine/rosetta.h",
|
||||
MAME_DIR .. "src/mame/machine/rtpc_iocc.cpp",
|
||||
MAME_DIR .. "src/mame/machine/rtpc_iocc.h",
|
||||
}
|
||||
|
||||
createMESSProjects(_target, _subtarget, "sage")
|
||||
files {
|
||||
MAME_DIR .. "src/mame/drivers/sage2.cpp",
|
||||
|
768
src/mame/drivers/rtpc.cpp
Normal file
768
src/mame/drivers/rtpc.cpp
Normal file
@ -0,0 +1,768 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Patrick Mackinlay
|
||||
|
||||
/*
|
||||
* IBM RT PC.
|
||||
*
|
||||
* Sources:
|
||||
* - http://bitsavers.org/pdf/ibm/pc/rt/75X0232_RT_PC_Technical_Reference_Volume_1_Jun87.pdf
|
||||
* - http://www.cs.cmu.edu/afs/andrew.cmu.edu/usr/shadow/www/ibmrt.html
|
||||
* - http://ps-2.kev009.com/ohlandl/6152/rt_index.html
|
||||
*
|
||||
* TODO:
|
||||
* - finish refactoring iocc
|
||||
* - additional machine variants
|
||||
* - configurable RAM size
|
||||
*/
|
||||
/*
|
||||
* https://www-01.ibm.com/common/ssi/ShowDoc.wss?docURL=/common/ssi/rep_ca/6/897/ENUS186-006/index.html
|
||||
* https://www-01.ibm.com/common/ssi/ShowDoc.wss?docURL=/common/ssi/rep_ca/1/897/ENUS187-021/index.html
|
||||
* https://www-01.ibm.com/common/ssi/ShowDoc.wss?docURL=/common/ssi/rep_ca/0/897/ENUS188-120/index.html
|
||||
*
|
||||
* Model Chassis CPU RAM HDD Release Price Notes
|
||||
* 010 6151 032 1M/4M 40M Jan 1986 $11,700
|
||||
* 015 6151 032 2M/4M 70M Nov 1986 $10,050
|
||||
* 020 6150 032 1M/4M 40M Jan 1986 $14,945
|
||||
* 025 6150 032 2M/4M 70M Jan 1986 $17,940
|
||||
* A25 6150 032 2M/4M 70M Jan 1986 $19,510 5080 attachment/no keyboard
|
||||
* 115 6151 Adv 4M/16M 70M Feb 1987 $10,600 AFPA
|
||||
* 125 6150 Adv 4M/16M 70M Feb 1987 $16,100 AFPA
|
||||
* B25 6150 Adv 4M/16M 70M Feb 1987 $17,670 AFPA, 5080 attachment/no keyboard
|
||||
* 130 6151 Enh 16M 114M Jul 1988 $23,220 EAFPA
|
||||
* 135 6150 Enh 16M 114M Jul 1988 $30,595 EAFPA
|
||||
* B35 6150 Enh 16M 114M Jul 1988 $32,165 EAFPA, 5080 attachment/no keyboard
|
||||
*
|
||||
* 032 (aka SGP), 170ns (23.5294 MHz crystal / 4 == 5.882350 MHz == 170ns), 1MB/2MB/4MB memory boards
|
||||
* Advanced, 100ns 4MB (6151) external (6150) (presume ~40MHz crystal/4), 4MB/8MB memory boards
|
||||
* Enhanced, 80ns, 16MB soldered, EAFPA standard, CMOS (49.400 MHz crystal/4 == 12.350MHz == 80.971ns)
|
||||
*
|
||||
* AFPA is M68881 @ 20MHz
|
||||
* EAFPA is AD90221-2 ADSP-3210 (multiplier) + AD90222-2 ADSP-3221 (fp alu) + AD90220-2 ADSP-1401 (program sequencer)
|
||||
*
|
||||
* system processor real memory address map
|
||||
* 0000'0000-00ff'ffff 16MB memory management unit
|
||||
* 0100'0000-efff'ffff -- not defined
|
||||
*
|
||||
* system board I/O addresses (all in segment F)
|
||||
* f000'0000-f0ff'ffff 16MB i/o channel i/o map
|
||||
* f100'0000-f3ff'ffff 48MB reserved
|
||||
* f400'0000-f4ff'ffff 16MB i/o channel memory map
|
||||
* f500'0000-f7ff'ffff reserved?
|
||||
* f800'0000-fbff'ffff reserved
|
||||
* fc00'0000-fdff'ffff mc68881
|
||||
* fe00'0000-feff'ffff fpa2
|
||||
* ff00'0000-ffff'ffff 16MB floating point accelerator
|
||||
*
|
||||
* system processor i/o address map
|
||||
* 00'0000-7f'ffff 8MB not defined
|
||||
* 80'0000-80'ffff 64KB processor channel device initialization
|
||||
* 81'0000-81'ffff 64KB memory management unit
|
||||
* 82'0000-ff'ffff 8064KB not defined
|
||||
*
|
||||
* advanced processor
|
||||
* 80'0400 i/o interface 1 i/o base
|
||||
* 80'0100 i/o interface 2 i/o base
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* WIP
|
||||
* - diagnostic disk 1 fails with code 67
|
||||
* - aix vrm disk 1 fails with alternating code a6/13
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
// cpu and memory
|
||||
#include "cpu/romp/romp.h"
|
||||
#include "cpu/mcs51/mcs51.h"
|
||||
|
||||
// various hardware
|
||||
#include "machine/rosetta.h"
|
||||
#include "machine/rtpc_iocc.h"
|
||||
#include "machine/am9517a.h"
|
||||
#include "machine/pic8259.h"
|
||||
#include "machine/i8255.h"
|
||||
#include "machine/mc146818.h"
|
||||
#include "machine/z80scc.h"
|
||||
#include "machine/timer.h"
|
||||
|
||||
// isa bus
|
||||
#include "bus/isa/isa.h"
|
||||
#include "bus/isa/isa_cards.h"
|
||||
#include "bus/isa/mda.h"
|
||||
#include "bus/isa/fdc.h"
|
||||
#include "bus/isa/ide.h"
|
||||
|
||||
// busses and connectors
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "bus/rtpc/kbd_con.h"
|
||||
#include "bus/rtpc/kbd.h"
|
||||
|
||||
#include "sound/spkrdev.h"
|
||||
#include "machine/input_merger.h"
|
||||
|
||||
#include "imagedev/floppy.h"
|
||||
#include "formats/pc_dsk.h"
|
||||
|
||||
#define LOG_GENERAL (1U << 0)
|
||||
#define LOG_KLS (1U << 1)
|
||||
|
||||
//#define VERBOSE (LOG_GENERAL)
|
||||
#include "logmacro.h"
|
||||
|
||||
#include "debugger.h"
|
||||
|
||||
#include "rtpc.lh"
|
||||
|
||||
namespace {
|
||||
|
||||
class rtpc_state : public driver_device
|
||||
{
|
||||
public:
|
||||
rtpc_state(machine_config const &mconfig, device_type type, char const *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_cpu(*this, "cpu")
|
||||
, m_mcu(*this, "mcu")
|
||||
, m_mmu(*this, "mmu")
|
||||
, m_iocc(*this, "iocc")
|
||||
, m_dma(*this, "dma%u", 0U)
|
||||
, m_pic(*this, "pic%u", 0U)
|
||||
, m_ppi(*this, "ppi")
|
||||
, m_rtc(*this, "rtc")
|
||||
, m_scc(*this, "scc")
|
||||
, m_isa(*this, "isa")
|
||||
, m_kbd_con(*this, "kbd_con")
|
||||
, m_speaker(*this, "kbd_con:kbd:speaker")
|
||||
, m_ipl(*this, "ipl")
|
||||
{
|
||||
}
|
||||
|
||||
void ibm6150(machine_config &config);
|
||||
void ibm6151(machine_config &config);
|
||||
|
||||
void init_common();
|
||||
|
||||
protected:
|
||||
// driver_device overrides
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
|
||||
template <bool SCC> void iocc_pio_map(address_map &map);
|
||||
|
||||
void common(machine_config &config);
|
||||
|
||||
DECLARE_FLOPPY_FORMATS(floppy_formats);
|
||||
|
||||
void mcu_port1_w(u8 data);
|
||||
void mcu_port2_w(u8 data);
|
||||
void mcu_port3_w(u8 data);
|
||||
void ppi_portc_w(u8 data);
|
||||
|
||||
void kls_cmd_w(offs_t offset, u16 data, u16 mem_mask);
|
||||
void crra_w(u8 data);
|
||||
void crrb_w(u8 data);
|
||||
void dia_w(u8 data);
|
||||
|
||||
void mcu_timer(timer_device &timer, void *ptr, s32 param)
|
||||
{
|
||||
m_mcu_p3 ^= 0x10;
|
||||
m_mcu->set_input_line(MCS51_T0_LINE, BIT(m_mcu_p3, 4));
|
||||
}
|
||||
|
||||
void speaker()
|
||||
{
|
||||
if (m_speaker)
|
||||
m_speaker->level_w(!BIT(m_mcu_p2, 7) ? m_mcu_p1 >> 6 : 0);
|
||||
}
|
||||
|
||||
// devices
|
||||
required_device<romp_device> m_cpu;
|
||||
required_device<i8051_device> m_mcu;
|
||||
required_device<rosetta_device> m_mmu;
|
||||
required_device<rtpc_iocc_device> m_iocc;
|
||||
|
||||
required_device_array<am9517a_device, 2> m_dma;
|
||||
required_device_array<pic8259_device, 2> m_pic;
|
||||
required_device<i8255_device> m_ppi;
|
||||
required_device<mc146818_device> m_rtc;
|
||||
optional_device<z80scc_device> m_scc;
|
||||
|
||||
required_device<isa16_device> m_isa;
|
||||
required_device<rtpc_kbd_con_device> m_kbd_con;
|
||||
optional_device<speaker_sound_device> m_speaker;
|
||||
|
||||
required_region_ptr<u32> m_ipl;
|
||||
|
||||
u8 m_mcu_p0;
|
||||
u8 m_mcu_p1;
|
||||
u8 m_mcu_p2;
|
||||
u8 m_mcu_p3;
|
||||
|
||||
u8 m_ppi_pb;
|
||||
u8 m_mcu_uart;
|
||||
|
||||
u8 m_ch8er; // dma channel 8 enable register
|
||||
u8 m_crra; // component reset register a
|
||||
u8 m_crrb; // component reset register b
|
||||
|
||||
u8 m_ext[2]; // external serial registers
|
||||
};
|
||||
|
||||
static double const speaker_levels[4] = { 0.0, 1.0 / 3.0, 2.0 / 3.0, 1.0 };
|
||||
|
||||
void rtpc_state::machine_start()
|
||||
{
|
||||
m_mcu_p0 = 0;
|
||||
m_mcu_p1 = 0;
|
||||
m_mcu_p2 = 0;
|
||||
m_mcu_p3 = 0;
|
||||
|
||||
m_ppi_pb = 0;
|
||||
|
||||
m_crra = 0xff;
|
||||
m_crrb = 0xff;
|
||||
}
|
||||
|
||||
void rtpc_state::machine_reset()
|
||||
{
|
||||
}
|
||||
|
||||
void rtpc_state::init_common()
|
||||
{
|
||||
if (m_speaker)
|
||||
m_speaker->set_levels(4, speaker_levels);
|
||||
}
|
||||
|
||||
template <bool SCC> void rtpc_state::iocc_pio_map(address_map &map)
|
||||
{
|
||||
if (SCC)
|
||||
{
|
||||
map(0x00'8000, 0x00'8003).rw(m_scc, FUNC(z80scc_device::dc_ab_r), FUNC(z80scc_device::dc_ab_w));
|
||||
map(0x00'8020, 0x00'8020).lrw8([this]() { return m_ext[0]; }, "ext_a_r", [this](u8 data) { m_ext[0] = data; }, "ext_a_w");
|
||||
map(0x00'8040, 0x00'8040).lrw8([this]() { return m_ext[1]; }, "ext_b_r", [this](u8 data) { m_ext[1] = data; }, "ext_b_w");
|
||||
map(0x00'8060, 0x00'8060).lr8([this]() { return u8(m_scc->m1_r()); }, "intack");
|
||||
}
|
||||
|
||||
// delay 1µs per byte written
|
||||
map(0x00'80e0, 0x00'80e3).lw8([this](u8 data) { m_cpu->eat_cycles(m_cpu->clock() / 1000000 + 1); }, "io_delay");
|
||||
|
||||
map(0x00'8400, 0x00'8403).mirror(0x7c).rw(m_ppi, FUNC(i8255_device::read), FUNC(i8255_device::write));
|
||||
map(0x00'8400, 0x00'8401).mirror(0x78).w(FUNC(rtpc_state::kls_cmd_w));
|
||||
|
||||
map(0x00'8800, 0x00'883f).rw(m_rtc, FUNC(mc146818_device::read_direct), FUNC(mc146818_device::write_direct));
|
||||
map(0x00'8840, 0x00'884f).mirror(0x10).rw(m_dma[0], FUNC(am9517a_device::read), FUNC(am9517a_device::write));
|
||||
map(0x00'8860, 0x00'887f).umask16(0xff00).rw(m_dma[1], FUNC(am9517a_device::read), FUNC(am9517a_device::write));
|
||||
map(0x00'8880, 0x00'8881).mirror(0x1e).rw(m_pic[0], FUNC(pic8259_device::read), FUNC(pic8259_device::write));
|
||||
map(0x00'88a0, 0x00'88a1).mirror(0x1e).rw(m_pic[1], FUNC(pic8259_device::read), FUNC(pic8259_device::write));
|
||||
map(0x00'88c0, 0x00'88c0).mirror(0x1f).rw(m_iocc, FUNC(rtpc_iocc_device::dbr_r), FUNC(rtpc_iocc_device::dbr_w));
|
||||
map(0x00'88e0, 0x00'88e0).mirror(0x1f).rw(m_iocc, FUNC(rtpc_iocc_device::dmr_r), FUNC(rtpc_iocc_device::dmr_w));
|
||||
|
||||
map(0x00'8c00, 0x00'8c00).mirror(0x03).lrw8([this]() { return m_ch8er; }, "ch8er_r", [this](u8 data) { m_ch8er = data; }, "ch8er_w");
|
||||
map(0x00'8c20, 0x00'8c20).mirror(0x03).rw(m_iocc, FUNC(rtpc_iocc_device::ccr_r), FUNC(rtpc_iocc_device::ccr_w));
|
||||
map(0x00'8c40, 0x00'8c40).mirror(0x03).lr8([this]() { return m_crra; }, "crra_r");
|
||||
map(0x00'8c40, 0x00'8c40).mirror(0x03).w(FUNC(rtpc_state::crra_w));
|
||||
map(0x00'8c60, 0x00'8c60).mirror(0x03).lr8([this]() { return m_crrb; }, "crrb_r");
|
||||
map(0x00'8c60, 0x00'8c60).mirror(0x03).w(FUNC(rtpc_state::crrb_w));
|
||||
|
||||
// memory config reg (cc=2x8M, dd=2x2M, 88=2x4M)
|
||||
map(0x00'8c80, 0x00'8c80).mirror(0x03).lr8([this]() { return 0xf8; }, "mcr");
|
||||
map(0x00'8ca0, 0x00'8ca0).mirror(0x03).w(FUNC(rtpc_state::dia_w));
|
||||
|
||||
map(0x01'0000, 0x01'07ff).rw(m_iocc, FUNC(rtpc_iocc_device::tcw_r), FUNC(rtpc_iocc_device::tcw_w));
|
||||
map(0x01'0800, 0x01'0801).mirror(0x7fc).rw(m_iocc, FUNC(rtpc_iocc_device::csr_r<1>), FUNC(rtpc_iocc_device::csr_w));
|
||||
map(0x01'0802, 0x01'0803).mirror(0x7fc).rw(m_iocc, FUNC(rtpc_iocc_device::csr_r<0>), FUNC(rtpc_iocc_device::csr_w));
|
||||
}
|
||||
|
||||
FLOPPY_FORMATS_MEMBER(rtpc_state::floppy_formats)
|
||||
FLOPPY_PC_FORMAT
|
||||
FLOPPY_FORMATS_END
|
||||
|
||||
void rtpc_state::mcu_port1_w(u8 data)
|
||||
{
|
||||
// bit function
|
||||
// 6 speaker volume 0
|
||||
// 7 speaker volume 1
|
||||
LOGMASKED(LOG_KLS, "mcu_port1_w volume %d\n", data >> 6);
|
||||
m_mcu_p1 = (m_mcu_p1 & 0x3f) | (data & 0xc0);
|
||||
|
||||
// speaker volume wraps to ppi port b.6 and b.5
|
||||
m_ppi_pb &= ~0x60;
|
||||
m_ppi_pb |= (data >> 1) & 0x60;
|
||||
|
||||
speaker();
|
||||
}
|
||||
|
||||
void rtpc_state::mcu_port2_w(u8 data)
|
||||
{
|
||||
// bit dst
|
||||
// 0 ppi port c.0 (iid0)
|
||||
// 1 ppi port c.1 (iid1)
|
||||
// 2 ppi port c.2 (iid2)
|
||||
// 3 i/o channel system reset (active low)
|
||||
// 4 ppi port c.4
|
||||
// 5 (input)
|
||||
// 6 ppi port c.6 (-ack)
|
||||
// 7 speaker frequency
|
||||
|
||||
// interrupts
|
||||
// 0 informational
|
||||
// 1 received byte from keyboard
|
||||
// 2 received byte from uart
|
||||
// 3 returning byte requested by system
|
||||
// 4 block transfer ready
|
||||
// 5 unassigned
|
||||
// 6 self-test performed
|
||||
// 7 error condition
|
||||
|
||||
if ((data ^ m_mcu_p2) & 7)
|
||||
LOGMASKED(LOG_KLS, "mcu_port2_w interrupt %d\n", data & 7);
|
||||
|
||||
if ((data ^ m_mcu_p2) & 8)
|
||||
LOGMASKED(LOG_KLS, "mcu_port2_w system reset %d\n", data & 8);
|
||||
|
||||
m_ppi->pc4_w(BIT(data, 4));
|
||||
m_ppi->pc6_w(BIT(data, 6));
|
||||
|
||||
m_mcu_p2 &= ~0xdf;
|
||||
m_mcu_p2 |= data & 0xdf;
|
||||
|
||||
// speaker frequency wraps to ppi port b.7
|
||||
m_ppi_pb &= ~0x80;
|
||||
m_ppi_pb |= ~data & 0x80;
|
||||
|
||||
speaker();
|
||||
}
|
||||
|
||||
void rtpc_state::mcu_port3_w(u8 data)
|
||||
{
|
||||
// bit i/o function
|
||||
// 0 i uart rx
|
||||
// 1 o uart tx
|
||||
// 2 i kbd clock in
|
||||
// 3 i obf/int1
|
||||
// 4 i 32 kHz
|
||||
// 5 i kbd data in
|
||||
// 6 o kbd data out
|
||||
// 7 o kbd clock out
|
||||
|
||||
LOGMASKED(LOG_KLS, "mcu_port3_w 0x%02x\n", data);
|
||||
|
||||
m_kbd_con->data_write_from_mb(BIT(data, 6));
|
||||
m_kbd_con->clock_write_from_mb(BIT(data, 7));
|
||||
|
||||
m_mcu_p3 = (m_mcu_p3 & ~0xc2) | (data & 0xc2);
|
||||
}
|
||||
|
||||
void rtpc_state::ppi_portc_w(u8 data)
|
||||
{
|
||||
LOGMASKED(LOG_KLS, "ppi_portc_w 0x%02x\n", data);
|
||||
|
||||
// bit 3 -> i/o channel (irq)
|
||||
m_pic[0]->ir5_w(BIT(data, 3));
|
||||
|
||||
// bit 5 -> mcu p2.5 (ibf)
|
||||
if (BIT(data, 5))
|
||||
m_mcu_p2 |= 0x20;
|
||||
else
|
||||
m_mcu_p2 &= ~0x20;
|
||||
|
||||
// bit 7 -> mcu p3.3(-int1) (-obf)
|
||||
if (BIT(data, 7))
|
||||
m_mcu_p3 |= 0x08;
|
||||
else
|
||||
m_mcu_p3 &= ~0x08;
|
||||
m_mcu->set_input_line(MCS51_INT1_LINE, !BIT(data, 7));
|
||||
}
|
||||
|
||||
void rtpc_state::kls_cmd_w(offs_t offset, u16 data, u16 mem_mask)
|
||||
{
|
||||
LOGMASKED(LOG_KLS, "kls_cmd_w command 0x%02x data 0x%02x mask 0x%04x\n", u8(data), data >> 8, mem_mask);
|
||||
|
||||
// 00cc cccc dddd dddd
|
||||
switch (mem_mask)
|
||||
{
|
||||
case 0xff00:
|
||||
m_ppi->write(0, data);
|
||||
break;
|
||||
case 0x00ff:
|
||||
m_ppi->write(1, data);
|
||||
break;
|
||||
case 0xffff:
|
||||
m_mcu_p1 = (m_mcu_p1 & ~0x3f) | (data & 0x3f);
|
||||
m_ppi->write(0, data >> 8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void rtpc_state::crra_w(u8 data)
|
||||
{
|
||||
LOG("crra_w 0x%02x\n", data);
|
||||
|
||||
// bit function
|
||||
// 0 i/o slot 1
|
||||
// 1 i/o slot 2
|
||||
// 2 i/o slot 3
|
||||
// 3 i/o slot 4
|
||||
// 4 i/o slot 5
|
||||
// 5 i/o slot 6
|
||||
// 6 i/o slot 7
|
||||
// 7 i/o slot 8
|
||||
|
||||
m_crra = data;
|
||||
}
|
||||
|
||||
void rtpc_state::crrb_w(u8 data)
|
||||
{
|
||||
LOG("crrb_w 0x%02x\n", data);
|
||||
|
||||
// bit function
|
||||
// 0 8530
|
||||
// 1 rs232 interface
|
||||
// 2 8051
|
||||
// 3 dmac1
|
||||
// 4 dmac2
|
||||
// 5 arbitor
|
||||
// 6 reserved
|
||||
// 7 reserved
|
||||
|
||||
if (BIT(data, 0))
|
||||
m_scc->reset();
|
||||
// TODO: rs232 if
|
||||
m_mcu->set_input_line(INPUT_LINE_RESET, !BIT(data, 2));
|
||||
// TODO: dmac !ready
|
||||
// TODO: arbitor
|
||||
|
||||
m_crrb = data;
|
||||
}
|
||||
|
||||
void rtpc_state::dia_w(u8 data)
|
||||
{
|
||||
bool const state = BIT(data, 0);
|
||||
|
||||
LOG("dia_w 0x%02x (%s)\n", data, machine().describe_context());
|
||||
|
||||
m_pic[0]->ir0_w(state);
|
||||
m_pic[0]->ir1_w(state);
|
||||
m_pic[0]->ir2_w(state);
|
||||
m_pic[0]->ir3_w(state);
|
||||
m_pic[0]->ir4_w(state);
|
||||
m_pic[0]->ir5_w(state);
|
||||
m_pic[0]->ir6_w(state);
|
||||
m_pic[0]->ir7_w(state);
|
||||
|
||||
m_pic[1]->ir0_w(state);
|
||||
m_pic[1]->ir1_w(state);
|
||||
m_pic[1]->ir2_w(state);
|
||||
m_pic[1]->ir3_w(state);
|
||||
m_pic[1]->ir4_w(state);
|
||||
m_pic[1]->ir5_w(state);
|
||||
m_pic[1]->ir6_w(state);
|
||||
m_pic[1]->ir7_w(state);
|
||||
}
|
||||
|
||||
void rtpc_state::common(machine_config &config)
|
||||
{
|
||||
ROMP(config, m_cpu, 23'529'400 / 4);
|
||||
m_cpu->set_mmu(m_mmu);
|
||||
m_cpu->set_iou(m_iocc);
|
||||
|
||||
input_merger_device &reqi2(INPUT_MERGER_ANY_LOW(config, "reqi2"));
|
||||
reqi2.output_handler().set_inputline(m_cpu, INPUT_LINE_IRQ2).invert();
|
||||
|
||||
// TODO: hole for 1M/4M memory boards
|
||||
// 2/2 rams 4M
|
||||
// 2/1 rams 4M
|
||||
// 1/1 rams 4M hole 1M
|
||||
// 4/0 rams 4M
|
||||
// 4/4 rams 16M hole 4M
|
||||
ROSETTA(config, m_mmu, m_cpu->clock(), rosetta_device::RAM_4M);
|
||||
m_mmu->set_mem(m_cpu, AS_PROGRAM);
|
||||
m_mmu->set_rom("ipl");
|
||||
m_mmu->out_pchk().set(reqi2, FUNC(input_merger_device::in_w<0>));
|
||||
m_mmu->out_mchk().set_inputline(m_cpu, INPUT_LINE_NMI);
|
||||
|
||||
// keyboard, locator, speaker adapter
|
||||
// P8051AH 2075
|
||||
// 61X6310 8811
|
||||
// (c)IBM 1986
|
||||
// (c)INTEL '80
|
||||
I8051(config, m_mcu, 9.216_MHz_XTAL);
|
||||
m_mcu->port_in_cb<0>().set([this]() { return m_ppi->pa_r(); });
|
||||
m_mcu->port_out_cb<0>().set([this](u8 data) { m_mcu_p0 = data; });
|
||||
m_mcu->port_in_cb<1>().set([this]() { return m_mcu_p1 & 0x1f; });
|
||||
m_mcu->port_out_cb<1>().set(FUNC(rtpc_state::mcu_port1_w));
|
||||
m_mcu->port_in_cb<2>().set([this]() { return m_mcu_p2; });
|
||||
m_mcu->port_out_cb<2>().set(FUNC(rtpc_state::mcu_port2_w));
|
||||
m_mcu->port_out_cb<3>().set(FUNC(rtpc_state::mcu_port3_w));
|
||||
m_mcu->port_in_cb<3>().set([this]() { return m_mcu_p3 & 0x3d; });
|
||||
m_mcu->serial_tx_cb().set(
|
||||
[this](u8 data)
|
||||
{
|
||||
if (BIT(m_mcu_p1, 5))
|
||||
{
|
||||
m_mcu_uart = data;
|
||||
m_mcu->set_input_line(MCS51_RX_LINE, 1);
|
||||
}
|
||||
else
|
||||
logerror("uart tx 0x%02x\n", data);
|
||||
});
|
||||
m_mcu->serial_rx_cb().set([this]() { return m_mcu_uart; });
|
||||
//m_mcu->out_?().set_inputline(m_cpu, INPUT_LINE_IRQ0);
|
||||
|
||||
TIMER(config, "mcu_timer").configure_periodic(FUNC(rtpc_state::mcu_timer), attotime::from_hz(32768));
|
||||
|
||||
RTPC_IOCC(config, m_iocc, 0);
|
||||
m_iocc->out_int().set(reqi2, FUNC(input_merger_device::in_w<1>));
|
||||
m_iocc->out_rst().set_inputline(m_dma[0], INPUT_LINE_RESET);
|
||||
m_iocc->out_rst().append_inputline(m_dma[1], INPUT_LINE_RESET);
|
||||
|
||||
// ISA bus
|
||||
ISA16(config, m_isa, 14'318'180 / 3);
|
||||
m_isa->set_memspace(m_iocc, AS_PROGRAM);
|
||||
m_isa->set_iospace(m_iocc, AS_IO);
|
||||
//m_isa->iochck_callback().set(FUNC(at_mb_device::iochck_w));
|
||||
|
||||
// NEC
|
||||
// D8237AC-5
|
||||
// 8903HV101
|
||||
AM9517A(config, m_dma[0], m_isa->clock());
|
||||
// chan usage
|
||||
// 0 serial port A
|
||||
// 1 serial port B
|
||||
// 2 diskette drive, serial port A
|
||||
// 3 pc network, serial port B
|
||||
m_isa->drq0_callback().set(m_dma[0], FUNC(am9517a_device::dreq_w<0>));
|
||||
m_isa->drq1_callback().set(m_dma[0], FUNC(am9517a_device::dreq_w<1>));
|
||||
m_isa->drq2_callback().set(m_dma[0], FUNC(am9517a_device::dreq_w<2>));
|
||||
m_isa->drq3_callback().set(m_dma[0], FUNC(am9517a_device::dreq_w<3>));
|
||||
m_dma[0]->out_hreq_callback().set(m_dma[0], FUNC(am9517a_device::hack_w));
|
||||
m_dma[0]->out_dack_callback<0>().set(m_iocc, FUNC(rtpc_iocc_device::dack_w<2>));
|
||||
m_dma[0]->out_dack_callback<1>().set(m_iocc, FUNC(rtpc_iocc_device::dack_w<1>));
|
||||
m_dma[0]->out_dack_callback<2>().set(m_iocc, FUNC(rtpc_iocc_device::dack_w<0>));
|
||||
m_dma[0]->out_dack_callback<3>().set(m_iocc, FUNC(rtpc_iocc_device::dack_w<3>));
|
||||
m_dma[0]->in_memr_callback().set(m_iocc, FUNC(rtpc_iocc_device::dma_b_r));
|
||||
m_dma[0]->out_memw_callback().set(m_iocc, FUNC(rtpc_iocc_device::dma_b_w));
|
||||
|
||||
// NEC
|
||||
// D8237AC-5
|
||||
// 8903HV101
|
||||
AM9517A(config, m_dma[1], m_isa->clock());
|
||||
// chan usage
|
||||
// 5 reserved
|
||||
// 6 reserved
|
||||
// 7 reserved
|
||||
// 8 286 coprocessor
|
||||
m_isa->drq5_callback().set(m_dma[1], FUNC(am9517a_device::dreq_w<1>));
|
||||
m_isa->drq6_callback().set(m_dma[1], FUNC(am9517a_device::dreq_w<2>));
|
||||
m_isa->drq7_callback().set(m_dma[1], FUNC(am9517a_device::dreq_w<3>));
|
||||
m_dma[1]->out_hreq_callback().set(m_dma[1], FUNC(am9517a_device::hack_w));
|
||||
m_dma[1]->out_dack_callback<0>().set(m_iocc, FUNC(rtpc_iocc_device::dack_w<4>));
|
||||
m_dma[1]->out_dack_callback<1>().set(m_iocc, FUNC(rtpc_iocc_device::dack_w<5>));
|
||||
m_dma[1]->out_dack_callback<2>().set(m_iocc, FUNC(rtpc_iocc_device::dack_w<6>));
|
||||
m_dma[1]->out_dack_callback<3>().set(m_iocc, FUNC(rtpc_iocc_device::dack_w<7>));
|
||||
m_dma[1]->in_memr_callback().set(m_iocc, FUNC(rtpc_iocc_device::dma_w_r));
|
||||
m_dma[1]->out_memw_callback().set(m_iocc, FUNC(rtpc_iocc_device::dma_w_w));
|
||||
|
||||
// NEC
|
||||
// D8259AC
|
||||
PIC8259(config, m_pic[0]);
|
||||
m_pic[0]->out_int_callback().set_inputline(m_cpu, INPUT_LINE_IRQ3).invert();
|
||||
// irq source
|
||||
// 0 iocc irq 0: dma tc
|
||||
// 1 iocc irq 10: (multiport async)
|
||||
// 2 iocc irq 9: pc network, (multiport async), enhanced color graphics adapter, 3278/79 emulation adapter
|
||||
// 3 iocc irq 3: serial port 2, pc network
|
||||
// 4 iocc irq 4: serial port 1
|
||||
// 5 iocc irq 1: kbd
|
||||
// 6 iocc irq 2: 8530
|
||||
// 7 iocc irq 7: parallel port 1, monochrome/printer
|
||||
m_isa->irq10_callback().set(m_pic[0], FUNC(pic8259_device::ir1_w));
|
||||
m_isa->irq2_callback().set(m_pic[0], FUNC(pic8259_device::ir2_w));
|
||||
m_isa->irq3_callback().set(m_pic[0], FUNC(pic8259_device::ir3_w));
|
||||
m_isa->irq4_callback().set(m_pic[0], FUNC(pic8259_device::ir4_w));
|
||||
m_isa->irq7_callback().set(m_pic[0], FUNC(pic8259_device::ir7_w));
|
||||
|
||||
// NEC
|
||||
// D8259AC
|
||||
PIC8259(config, m_pic[1]);
|
||||
m_pic[1]->out_int_callback().set_inputline(m_cpu, INPUT_LINE_IRQ4).invert();
|
||||
// irq source
|
||||
// 0 iocc irq 8: reserved
|
||||
// 1 iocc irq 11: (advanced monochrome graphics display) (multiport async)
|
||||
// 2 iocc irq 14: fixed disk
|
||||
// 3 iocc irq 12: (ibm rt pc streaming tape drive adapter)
|
||||
// 4 iocc irq 6: diskette drive
|
||||
// 5 iocc irq 5: parallel port 2
|
||||
// 6 iocc irq 15: (286 coprocessor)
|
||||
// 7 iocc irq 13: serial port ex ct1 irpt
|
||||
m_isa->irq11_callback().set(m_pic[1], FUNC(pic8259_device::ir1_w));
|
||||
m_isa->irq14_callback().set(m_pic[1], FUNC(pic8259_device::ir2_w));
|
||||
m_isa->irq12_callback().set(m_pic[1], FUNC(pic8259_device::ir3_w));
|
||||
m_isa->irq6_callback().set(m_pic[1], FUNC(pic8259_device::ir4_w));
|
||||
m_isa->irq5_callback().set(m_pic[1], FUNC(pic8259_device::ir5_w));
|
||||
m_isa->irq15_callback().set(m_pic[1], FUNC(pic8259_device::ir6_w));
|
||||
|
||||
// P8255A-5
|
||||
// L6430434
|
||||
// (C)INTEL '81
|
||||
I8255A(config, m_ppi);
|
||||
// port A: read/write 8051
|
||||
// port B: input
|
||||
// port C lower: input
|
||||
// port C upper: 8051 handshake
|
||||
// port C & 0x20 -> irq
|
||||
m_ppi->in_pa_callback().set([this]() { return m_mcu_p0; });
|
||||
|
||||
// TODO: bits 4-1 "non-adapter system board signals"
|
||||
// TODO: bit 0 "uart rxd signal"
|
||||
m_ppi->in_pb_callback().set([this]() { return m_ppi_pb; });
|
||||
|
||||
m_ppi->out_pc_callback().set(FUNC(rtpc_state::ppi_portc_w));
|
||||
m_ppi->in_pc_callback().set([this]() { return m_mcu_p2 & 0x57; });
|
||||
|
||||
RTPC_KBD_CON(config, m_kbd_con);
|
||||
m_kbd_con->option_add("kbd", RTPC_KBD);
|
||||
m_kbd_con->set_default_option("kbd");
|
||||
m_kbd_con->out_data_cb().set([this](int state) { if (state) m_mcu_p3 |= 0x20; else m_mcu_p3 &= ~0x20; });
|
||||
m_kbd_con->out_clock_cb().set(
|
||||
[this](int state)
|
||||
{
|
||||
if (state)
|
||||
m_mcu_p3 |= 0x04;
|
||||
else
|
||||
m_mcu_p3 &= ~0x04;
|
||||
m_mcu->set_input_line(MCS51_INT0_LINE, !state);
|
||||
});
|
||||
|
||||
// MC146818AP
|
||||
// IL 0A46D8729
|
||||
MC146818(config, m_rtc, 32.768_kHz_XTAL);
|
||||
m_rtc->sqw().set(m_cpu, FUNC(romp_device::clk_w));
|
||||
m_rtc->sqw().append(
|
||||
[this](int state)
|
||||
{
|
||||
if (state)
|
||||
m_ppi_pb |= 0x08;
|
||||
else
|
||||
m_ppi_pb &= ~0x08;
|
||||
});
|
||||
m_rtc->irq().set_inputline(m_cpu, INPUT_LINE_IRQ1).invert();
|
||||
m_rtc->irq().append(
|
||||
[this](int state)
|
||||
{
|
||||
if (!state)
|
||||
m_ppi_pb |= 0x10;
|
||||
else
|
||||
m_ppi_pb &= ~0x10;
|
||||
});
|
||||
|
||||
config.set_default_layout(layout_rtpc);
|
||||
}
|
||||
|
||||
void rtpc_isa8_cards(device_slot_interface &device)
|
||||
{
|
||||
device.option_add("mda", ISA8_MDA);
|
||||
}
|
||||
|
||||
void rtpc_isa16_cards(device_slot_interface &device)
|
||||
{
|
||||
// FIXME: need 16-bit combined hdc/fdc card
|
||||
device.option_add("hdc", ISA16_IDE);
|
||||
device.option_add("fdc", ISA8_FDC_AT);
|
||||
}
|
||||
|
||||
void rtpc_state::ibm6150(machine_config &config)
|
||||
{
|
||||
common(config);
|
||||
m_iocc->set_addrmap(2, &rtpc_state::iocc_pio_map<true>);
|
||||
|
||||
SCC8530N(config, m_scc, 3'580'000);
|
||||
m_scc->configure_channels(3'072'000, 3'072'000, 3'072'000, 3'072'000);
|
||||
m_scc->out_int_callback().set(m_pic[0], FUNC(pic8259_device::ir6_w));
|
||||
|
||||
// port: TXD, DTR, RTS, RI, RXD, DSR, CTS, DCD
|
||||
// external registers: DTR, DSR, RI
|
||||
// scc: TXD, RTS, RXD, CTS, DCD
|
||||
// scc: DTR/REQ, SYNC not connected
|
||||
|
||||
rs232_port_device &port0(RS232_PORT(config, "serial0", default_rs232_devices, nullptr));
|
||||
port0.cts_handler().set(m_scc, FUNC(z80scc_device::ctsa_w));
|
||||
port0.dcd_handler().set(m_scc, FUNC(z80scc_device::dcda_w));
|
||||
port0.rxd_handler().set(m_scc, FUNC(z80scc_device::rxa_w));
|
||||
m_scc->out_rtsa_callback().set(port0, FUNC(rs232_port_device::write_rts));
|
||||
m_scc->out_txda_callback().set(port0, FUNC(rs232_port_device::write_txd));
|
||||
|
||||
rs232_port_device &port1(RS232_PORT(config, "serial1", default_rs232_devices, nullptr));
|
||||
// TXD, DTR, RTS, RI, RXD, DSR, CTS, DCD
|
||||
port1.cts_handler().set(m_scc, FUNC(z80scc_device::ctsb_w));
|
||||
port1.dcd_handler().set(m_scc, FUNC(z80scc_device::dcdb_w));
|
||||
port1.rxd_handler().set(m_scc, FUNC(z80scc_device::rxb_w));
|
||||
m_scc->out_rtsb_callback().set(port1, FUNC(rs232_port_device::write_rts));
|
||||
m_scc->out_txdb_callback().set(port1, FUNC(rs232_port_device::write_txd));
|
||||
|
||||
// ISA slots
|
||||
ISA16_SLOT(config, "isa1", 0, m_isa, rtpc_isa16_cards, "fdc", false); // slot 1: disk/diskette adapter
|
||||
ISA16_SLOT(config, "isa2", 0, m_isa, rtpc_isa16_cards, nullptr, false); // slot 2: option
|
||||
ISA8_SLOT(config, "isa3", 0, m_isa, rtpc_isa8_cards, "mda", false); // slot 3: option
|
||||
ISA16_SLOT(config, "isa4", 0, m_isa, rtpc_isa16_cards, nullptr, false); // slot 4: option
|
||||
ISA16_SLOT(config, "isa5", 0, m_isa, rtpc_isa16_cards, nullptr, false); // slot 5: option
|
||||
ISA8_SLOT(config, "isa6", 0, m_isa, rtpc_isa8_cards, nullptr, false); // slot 6: option
|
||||
ISA16_SLOT(config, "isa7", 0, m_isa, rtpc_isa16_cards, nullptr, false); // slot 7: option
|
||||
ISA16_SLOT(config, "isa8", 0, m_isa, rtpc_isa16_cards, nullptr, false); // slot 8: coprocessor/option
|
||||
}
|
||||
|
||||
void rtpc_state::ibm6151(machine_config &config)
|
||||
{
|
||||
common(config);
|
||||
m_iocc->set_addrmap(2, &rtpc_state::iocc_pio_map<false>);
|
||||
|
||||
// ISA slots
|
||||
ISA8_SLOT(config, "isa1", 0, m_isa, rtpc_isa8_cards, "mda", false); // slot 1: option
|
||||
ISA16_SLOT(config, "isa2", 0, m_isa, rtpc_isa16_cards, nullptr, false); // slot 2: option
|
||||
ISA16_SLOT(config, "isa3", 0, m_isa, rtpc_isa16_cards, nullptr, false); // slot 2: option
|
||||
ISA16_SLOT(config, "isa4", 0, m_isa, rtpc_isa16_cards, nullptr, false); // slot 4: option
|
||||
ISA16_SLOT(config, "isa5", 0, m_isa, rtpc_isa16_cards, nullptr, false); // slot 5: coprocessor/option
|
||||
ISA16_SLOT(config, "isa6", 0, m_isa, rtpc_isa16_cards, nullptr, false); // slot 6: disk/diskette adapter
|
||||
}
|
||||
|
||||
ROM_START(ibm6150)
|
||||
ROM_REGION32_BE(0x10000, "ipl", 0)
|
||||
ROM_SYSTEM_BIOS(0, "ipl", "IPL")
|
||||
ROMX_LOAD("79x3456.bin", 0x00000, 0x4000, CRC(0a45a9ba) SHA1(02ca637c6a871c180dbfebf2ec68d8ec5a998c76), ROM_BIOS(0) | ROM_SKIP(3))
|
||||
ROMX_LOAD("79x3458.bin", 0x00001, 0x4000, CRC(7bd08ab6) SHA1(aabcfbb8fa1a5f8a08fb5cfd90ca6fe05258fde9), ROM_BIOS(0) | ROM_SKIP(3))
|
||||
ROMX_LOAD("79x3460.bin", 0x00002, 0x4000, CRC(897586e0) SHA1(528772635903f27235ebba2622b03386b84e4e17), ROM_BIOS(0) | ROM_SKIP(3))
|
||||
ROMX_LOAD("79x3462.bin", 0x00003, 0x4000, CRC(12aca906) SHA1(58f95b95768ef131d8d9d552506a9fe9c9c6077d), ROM_BIOS(0) | ROM_SKIP(3))
|
||||
|
||||
ROM_REGION(0x1000, "mcu", 0)
|
||||
ROM_LOAD("61x6310_8051.bin", 0x0000, 0x1000, CRC(296c16c1) SHA1(83858109c39d5be37e49f24d1db4e2b15f38843e))
|
||||
ROM_END
|
||||
|
||||
ROM_START(ibm6151)
|
||||
ROM_REGION32_BE(0x10000, "ipl", 0)
|
||||
ROM_SYSTEM_BIOS(0, "ipl", "IPL")
|
||||
ROMX_LOAD("79x3456.bin", 0x00000, 0x4000, CRC(0a45a9ba) SHA1(02ca637c6a871c180dbfebf2ec68d8ec5a998c76), ROM_BIOS(0) | ROM_SKIP(3))
|
||||
ROMX_LOAD("79x3458.bin", 0x00001, 0x4000, CRC(7bd08ab6) SHA1(aabcfbb8fa1a5f8a08fb5cfd90ca6fe05258fde9), ROM_BIOS(0) | ROM_SKIP(3))
|
||||
ROMX_LOAD("79x3460.bin", 0x00002, 0x4000, CRC(897586e0) SHA1(528772635903f27235ebba2622b03386b84e4e17), ROM_BIOS(0) | ROM_SKIP(3))
|
||||
ROMX_LOAD("79x3462.bin", 0x00003, 0x4000, CRC(12aca906) SHA1(58f95b95768ef131d8d9d552506a9fe9c9c6077d), ROM_BIOS(0) | ROM_SKIP(3))
|
||||
|
||||
// Version: 073
|
||||
// Date: 85 289 (16 Oct 1985)
|
||||
// Checksum: 0xc8 0xe8
|
||||
ROM_REGION(0x1000, "mcu", 0)
|
||||
ROM_LOAD("61x6310_8051.bin", 0x0000, 0x1000, CRC(296c16c1) SHA1(83858109c39d5be37e49f24d1db4e2b15f38843e))
|
||||
ROM_END
|
||||
|
||||
#define rom_rtpc010 rom_ibm6151
|
||||
#define rom_rtpc015 rom_ibm6151
|
||||
#define rom_rtpc020 rom_ibm6150
|
||||
#define rom_rtpc025 rom_ibm6150
|
||||
#define rom_rtpca25 rom_ibm6150
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
|
||||
COMP(1986, rtpc010, 0, 0, ibm6151, 0, rtpc_state, init_common, "International Business Machines", "IBM RT PC Model 010", MACHINE_NOT_WORKING)
|
||||
COMP(1986, rtpc015, 0, 0, ibm6151, 0, rtpc_state, init_common, "International Business Machines", "IBM RT PC Model 015", MACHINE_NOT_WORKING)
|
||||
COMP(1986, rtpc020, 0, 0, ibm6150, 0, rtpc_state, init_common, "International Business Machines", "IBM RT PC Model 020", MACHINE_NOT_WORKING)
|
||||
COMP(1986, rtpc025, 0, 0, ibm6150, 0, rtpc_state, init_common, "International Business Machines", "IBM RT PC Model 025", MACHINE_NOT_WORKING)
|
||||
COMP(1986, rtpca25, 0, 0, ibm6150, 0, rtpc_state, init_common, "International Business Machines", "IBM RT PC Model A25", MACHINE_NOT_WORKING)
|
69
src/mame/layout/rtpc.lay
Normal file
69
src/mame/layout/rtpc.lay
Normal file
@ -0,0 +1,69 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
license:CC0
|
||||
copyright-holders:Patrick Mackinlay
|
||||
IBM RT PC diagnostic and keyboard LEDs
|
||||
-->
|
||||
<mamelayout version="2">
|
||||
<element name="led" defstate="0">
|
||||
<led7seg>
|
||||
<color red="1.0" green="0.0" blue="0.0" />
|
||||
</led7seg>
|
||||
</element>
|
||||
|
||||
<element name="kbd_led" defstate="0">
|
||||
<disk state="1">
|
||||
<color red="0.0" green="0.75" blue="0.0" />
|
||||
</disk>
|
||||
</element>
|
||||
<element name="num_lock">
|
||||
<text string="Num Lock">
|
||||
<color red="1.0" green="1.0" blue="1.0" />
|
||||
</text>
|
||||
</element>
|
||||
<element name="caps_lock">
|
||||
<text string="Caps Lock">
|
||||
<color red="1.0" green="1.0" blue="1.0" />
|
||||
</text>
|
||||
</element>
|
||||
<element name="scroll_lock">
|
||||
<text string="Scroll Lock">
|
||||
<color red="1.0" green="1.0" blue="1.0" />
|
||||
</text>
|
||||
</element>
|
||||
|
||||
<view name="Graphics">
|
||||
<screen index="0">
|
||||
<!-- assume MDA for now -->
|
||||
<bounds x="0" y="0" width="720" height="350" />
|
||||
</screen>
|
||||
|
||||
<element name="num_text" ref="num_lock">
|
||||
<bounds x="10" y="370" width="40" height="15" />
|
||||
</element>
|
||||
<element name="kbd_led0" ref="kbd_led">
|
||||
<bounds x="25" y="385" width="10" height="10" />
|
||||
</element>
|
||||
|
||||
<element name="caps_text" ref="caps_lock">
|
||||
<bounds x="60" y="370" width="40" height="15" />
|
||||
</element>
|
||||
<element name="kbd_led1" ref="kbd_led">
|
||||
<bounds x="75" y="385" width="10" height="10" />
|
||||
</element>
|
||||
|
||||
<element name="scroll_text" ref="scroll_lock">
|
||||
<bounds x="110" y="370" width="40" height="15" />
|
||||
</element>
|
||||
<element name="kbd_led2" ref="kbd_led">
|
||||
<bounds x="125" y="385" width="10" height="10" />
|
||||
</element>
|
||||
|
||||
<element name="led0" ref="led">
|
||||
<bounds x="700" y="375" width="15" height="20" />
|
||||
</element>
|
||||
<element name="led1" ref="led">
|
||||
<bounds x="680" y="375" width="15" height="20" />
|
||||
</element>
|
||||
</view>
|
||||
</mamelayout>
|
1202
src/mame/machine/rosetta.cpp
Normal file
1202
src/mame/machine/rosetta.cpp
Normal file
File diff suppressed because it is too large
Load Diff
181
src/mame/machine/rosetta.h
Normal file
181
src/mame/machine/rosetta.h
Normal file
@ -0,0 +1,181 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Patrick Mackinlay
|
||||
|
||||
#ifndef MAME_MACHINE_ROSETTA_H
|
||||
#define MAME_MACHINE_ROSETTA_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cpu/romp/rsc.h"
|
||||
|
||||
class rosetta_device
|
||||
: public device_t
|
||||
, public rsc_cpu_interface
|
||||
{
|
||||
public:
|
||||
// ram size in doublewords
|
||||
enum ram_size : unsigned
|
||||
{
|
||||
RAM_NONE = 0,
|
||||
RAM_1M = 0x0004'0000,
|
||||
RAM_2M = 0x0008'0000,
|
||||
RAM_4M = 0x0010'0000,
|
||||
RAM_8M = 0x0020'0000,
|
||||
RAM_16M = 0x0040'0000,
|
||||
};
|
||||
|
||||
rosetta_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock, ram_size ram = RAM_NONE);
|
||||
|
||||
template <typename T> void set_mem(T &&tag, int spacenum) { m_mem_space.set_tag(std::forward<T>(tag), spacenum); }
|
||||
template <typename T> void set_rom(T &&tag) { m_rom.set_tag(std::forward<T>(tag)); }
|
||||
|
||||
auto out_pchk() { return m_out_pchk.bind(); }
|
||||
auto out_mchk() { return m_out_mchk.bind(); }
|
||||
|
||||
using rsc_mode = rsc_bus_interface::rsc_mode;
|
||||
|
||||
// rsc_cpu_interface overrides
|
||||
virtual bool fetch(u32 address, u16 &data, rsc_mode const mode) override;
|
||||
virtual bool ior(u32 address, u32 &data) override;
|
||||
virtual bool iow(u32 address, u32 data) override;
|
||||
|
||||
// rsc_bus_interface overrides
|
||||
virtual bool load(u32 address, u8 &data, rsc_mode const mode, bool sp) override { return load<u8>(address, data, mode, sp); }
|
||||
virtual bool load(u32 address, u16 &data, rsc_mode const mode, bool sp) override { return load<u16>(address, data, mode, sp); }
|
||||
virtual bool load(u32 address, u32 &data, rsc_mode const mode, bool sp) override { return load<u32>(address, data, mode, sp); }
|
||||
virtual bool store(u32 address, u8 data, rsc_mode const mode, bool sp) override { return store<u8>(address, data, mode, sp); }
|
||||
virtual bool store(u32 address, u16 data, rsc_mode const mode, bool sp) override { return store<u16>(address, data, mode, sp); }
|
||||
virtual bool store(u32 address, u32 data, rsc_mode const mode, bool sp) override { return store<u32>(address, data, mode, sp); }
|
||||
virtual bool modify(u32 address, std::function<u8(u8)> f, rsc_mode const mode) override { return modify<u8>(address, f, mode); }
|
||||
virtual bool modify(u32 address, std::function<u16(u16)> f, rsc_mode const mode) override { return modify<u16>(address, f, mode); }
|
||||
virtual bool modify(u32 address, std::function<u32(u32)> f, rsc_mode const mode) override { return modify<u32>(address, f, mode); }
|
||||
|
||||
protected:
|
||||
// device_t overrides
|
||||
virtual void device_validity_check(validity_checker &valid) const override;
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
virtual void device_post_load() override;
|
||||
|
||||
// virtual address translation
|
||||
bool translate(u32 &address, bool system_processor, bool store);
|
||||
|
||||
// rsc_bus_interface implementation
|
||||
template <typename T> bool load(u32 address, T &data, rsc_mode const mode, bool sp);
|
||||
template <typename T> bool store(u32 address, T data, rsc_mode const mode, bool sp);
|
||||
template <typename T> bool modify(u32 address, std::function<T(T)> f, rsc_mode const mode);
|
||||
|
||||
// register read handlers
|
||||
u32 segment_r(offs_t offset);
|
||||
u32 control_r(offs_t offset);
|
||||
u32 tlb_r(offs_t offset);
|
||||
|
||||
// register write handlers
|
||||
void segment_w(offs_t offset, u32 data);
|
||||
void control_w(offs_t offset, u32 data);
|
||||
void tlb_w(offs_t offset, u32 data);
|
||||
|
||||
// memory read handlers
|
||||
u32 rom_r(offs_t offset, u32 mem_mask);
|
||||
u32 ram_r(offs_t offset, u32 mem_mask);
|
||||
u32 rca_r(offs_t offset);
|
||||
|
||||
// memory write handlers
|
||||
void rom_w(offs_t offset, u32 data, u32 mem_mask);
|
||||
void ram_w(offs_t offset, u32 data, u32 mem_mask);
|
||||
void rca_w(offs_t offset, u32 data);
|
||||
|
||||
u8 compute_ecc(u32 const data) const;
|
||||
unsigned check_ecc(u32 &data, u8 const ecc) const;
|
||||
|
||||
struct tlb_entry
|
||||
{
|
||||
u32 field0 = 0; // address tag
|
||||
u32 field1 = 0; // real page, valid, key
|
||||
u32 field2 = 0; // write, transaction identifier, lockbits
|
||||
};
|
||||
tlb_entry tlb_search(u64 const virtual_address, bool const special);
|
||||
u32 tlb_reload(tlb_entry &tlb_entry, u64 const virtual_address, bool special = false);
|
||||
|
||||
void tlb_inv_all(u32 data);
|
||||
void tlb_inv_segment(u32 data);
|
||||
void tlb_inv_address(u32 data);
|
||||
void compute_address(u32 data);
|
||||
|
||||
void config_map();
|
||||
void config_tlb();
|
||||
|
||||
enum mear_state : u32
|
||||
{
|
||||
UNLOCKED,
|
||||
LOCKED,
|
||||
MEMORY,
|
||||
};
|
||||
void set_mear(u32 const address, mear_state lock);
|
||||
void set_rmdr(u8 const ecc, bool lock);
|
||||
|
||||
void set_pchk(bool state)
|
||||
{
|
||||
if (state != m_pchk_state)
|
||||
{
|
||||
m_pchk_state = state;
|
||||
|
||||
// program check line is active low
|
||||
m_out_pchk(!m_pchk_state);
|
||||
}
|
||||
}
|
||||
|
||||
void set_mchk(bool state)
|
||||
{
|
||||
// assume edge-triggered, active low
|
||||
if (state)
|
||||
{
|
||||
m_out_mchk(0);
|
||||
m_out_mchk(1);
|
||||
}
|
||||
else
|
||||
m_out_mchk(1);
|
||||
}
|
||||
|
||||
private:
|
||||
required_address_space m_mem_space;
|
||||
required_region_ptr<u32> m_rom;
|
||||
output_finder<2> m_leds;
|
||||
|
||||
devcb_write_line m_out_pchk;
|
||||
devcb_write_line m_out_mchk;
|
||||
|
||||
memory_access<24, 2, 0, ENDIANNESS_BIG>::cache m_mem;
|
||||
|
||||
// registers
|
||||
u32 m_segment[16];
|
||||
u32 m_control[9];
|
||||
|
||||
// lock and line state
|
||||
mear_state m_mear_lock;
|
||||
bool m_rmdr_lock;
|
||||
bool m_led_lock;
|
||||
bool m_pchk_state;
|
||||
|
||||
// tlb state
|
||||
tlb_entry m_tlb[16][2];
|
||||
u16 m_tlb_lru;
|
||||
|
||||
// storage
|
||||
std::unique_ptr<u32[]> m_ram;
|
||||
std::unique_ptr<u8[]> m_ecc;
|
||||
std::unique_ptr<u8[]> m_rca;
|
||||
|
||||
// address translation constants
|
||||
u32 m_atag_mask;
|
||||
u32 m_page_mask;
|
||||
unsigned m_page_shift;
|
||||
u32 m_hat_base;
|
||||
u16 m_hat_mask;
|
||||
|
||||
ram_size const m_ram_size;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(ROSETTA, rosetta_device)
|
||||
|
||||
#endif // MAME_MACHINE_ROSETTA_H
|
349
src/mame/machine/rtpc_iocc.cpp
Normal file
349
src/mame/machine/rtpc_iocc.cpp
Normal file
@ -0,0 +1,349 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Patrick Mackinlay
|
||||
|
||||
/*
|
||||
* IBM RT PC I/O Channel Converter/Controller
|
||||
*
|
||||
* Sources:
|
||||
* - http://bitsavers.org/pdf/ibm/pc/rt/75X0232_RT_PC_Technical_Reference_Volume_1_Jun87.pdf
|
||||
*
|
||||
* TODO:
|
||||
* - bus spaces should be little endian
|
||||
* - alternate controllers, region mode dma
|
||||
* - improve rsc interface
|
||||
* - state saving
|
||||
* - refactoring and cleanup
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "rtpc_iocc.h"
|
||||
|
||||
#define LOG_GENERAL (1U << 0)
|
||||
#define LOG_DMA (1U << 1)
|
||||
#define LOG_WIDEPIO (1U << 2)
|
||||
|
||||
//#define VERBOSE (LOG_GENERAL|LOG_DMA)
|
||||
#include "logmacro.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(RTPC_IOCC, rtpc_iocc_device, "rtpc_iocc", "RT PC I/O Channel Converter/Controller")
|
||||
|
||||
rtpc_iocc_device::rtpc_iocc_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
|
||||
: device_t(mconfig, RTPC_IOCC, tag, owner, clock)
|
||||
, device_memory_interface(mconfig, *this)
|
||||
, rsc_bus_interface(mconfig, *this)
|
||||
, m_mem_config("mem", ENDIANNESS_BIG, 16, 24, 0)
|
||||
, m_pio_config("pio", ENDIANNESS_BIG, 16, 24, 0)
|
||||
, m_out_int(*this)
|
||||
, m_out_rst(*this)
|
||||
, m_rsc(*this, "^mmu")
|
||||
, m_csr(0)
|
||||
, m_ccr(0)
|
||||
, m_dbr(0)
|
||||
, m_dmr(0)
|
||||
, m_tcw{}
|
||||
, m_adc(0)
|
||||
, m_out_int_state(false)
|
||||
{
|
||||
}
|
||||
|
||||
device_memory_interface::space_config_vector rtpc_iocc_device::memory_space_config() const
|
||||
{
|
||||
return space_config_vector{
|
||||
std::make_pair(AS_PROGRAM, &m_mem_config),
|
||||
std::make_pair(AS_IO, &m_pio_config)
|
||||
};
|
||||
}
|
||||
|
||||
void rtpc_iocc_device::device_start()
|
||||
{
|
||||
m_out_int.resolve_safe();
|
||||
m_out_rst.resolve_safe();
|
||||
|
||||
save_item(NAME(m_csr));
|
||||
save_item(NAME(m_ccr));
|
||||
save_item(NAME(m_dbr));
|
||||
save_item(NAME(m_dmr));
|
||||
save_item(NAME(m_tcw));
|
||||
save_item(NAME(m_adc));
|
||||
save_item(NAME(m_out_int_state));
|
||||
}
|
||||
|
||||
void rtpc_iocc_device::device_reset()
|
||||
{
|
||||
m_csr = 0;
|
||||
|
||||
set_int(false);
|
||||
}
|
||||
|
||||
u8 rtpc_iocc_device::dma_b_r(offs_t offset)
|
||||
{
|
||||
u8 data = 0;
|
||||
|
||||
if (!BIT(m_dmr, 7 - m_adc))
|
||||
{
|
||||
u16 const tcw = m_tcw[(m_adc << 6) | (offset >> 11)];
|
||||
u32 const real = ((tcw & TCW_PFX) << 11) | (offset & 0x7ff);
|
||||
|
||||
LOGMASKED(LOG_DMA, "dma0 tcw 0x%04x real 0x%08x\n", tcw, real);
|
||||
if (tcw & TCW_IOC)
|
||||
data = space(AS_PROGRAM).read_byte(real);
|
||||
else
|
||||
{
|
||||
if (!m_rsc->load(real, data, RSC_N))
|
||||
{
|
||||
// on dma exception
|
||||
// - assert interrupt (level 2)
|
||||
// - csr | DE | ~PER | INTP
|
||||
|
||||
m_csr &= ~CSR_PER;
|
||||
m_csr |= (CSR_DE0 >> m_adc) | CSR_DEXK;
|
||||
m_out_rst(1);
|
||||
set_int(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
fatalerror("rtpc_iocc_device::dma_b_r() invalid dma operation\n");
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void rtpc_iocc_device::dma_b_w(offs_t offset, u8 data)
|
||||
{
|
||||
LOGMASKED(LOG_DMA, "dma0 offset 0x%04x data 0x%02x\n", offset, data);
|
||||
|
||||
if (!BIT(m_dmr, 7 - m_adc))
|
||||
{
|
||||
u16 const tcw = m_tcw[(m_adc << 6) | (offset >> 11)];
|
||||
u32 const real = ((tcw & TCW_PFX) << 11) | (offset & 0x7ff);
|
||||
|
||||
LOGMASKED(LOG_DMA, "dma0 tcw 0x%04x real 0x%08x\n", tcw, real);
|
||||
if (tcw & TCW_IOC)
|
||||
space(AS_PROGRAM).write_byte(real, data);
|
||||
else
|
||||
m_rsc->store(real, data, RSC_N);
|
||||
}
|
||||
else
|
||||
fatalerror("rtpc_iocc_device::dma_b_w() invalid dma operation\n");
|
||||
}
|
||||
|
||||
u8 rtpc_iocc_device::dma_w_r(offs_t offset)
|
||||
{
|
||||
u16 data = 0;
|
||||
|
||||
if (!BIT(m_dmr, 7 - m_adc))
|
||||
{
|
||||
u16 const tcw = m_tcw[(m_adc << 6) | (offset >> 10)];
|
||||
u32 const real = ((tcw & TCW_PFX) << 11) | (offset & 0x7ff);
|
||||
|
||||
LOGMASKED(LOG_DMA, "dma1 tcw 0x%04x real 0x%08x\n", tcw, real);
|
||||
if (tcw & TCW_IOC)
|
||||
data = space(AS_PROGRAM).read_word(real);
|
||||
else
|
||||
m_rsc->load(real, data, RSC_N);
|
||||
}
|
||||
else
|
||||
fatalerror("rtpc_iocc_device::dma_w_r() invalid dma operation\n");
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void rtpc_iocc_device::dma_w_w(offs_t offset, u8 data)
|
||||
{
|
||||
LOGMASKED(LOG_DMA, "dma1 offset 0x%04x data 0x%02x\n", offset, data);
|
||||
|
||||
if (!BIT(m_dmr, 7 - m_adc))
|
||||
{
|
||||
u16 const tcw = m_tcw[(m_adc << 6) | (offset >> 10)];
|
||||
u32 const real = ((tcw & TCW_PFX) << 11) | ((offset & 0x7ff) << 1);
|
||||
|
||||
LOGMASKED(LOG_DMA, "dma1 tcw 0x%04x real 0x%08x\n", tcw, real);
|
||||
// FIXME: upper data bits
|
||||
if (tcw & TCW_IOC)
|
||||
space(AS_PROGRAM).write_word(real, data);
|
||||
else
|
||||
m_rsc->store(real, u16(data), RSC_N);
|
||||
}
|
||||
else
|
||||
fatalerror("rtpc_iocc_device::dma_w_w() invalid dma operation\n");
|
||||
}
|
||||
|
||||
template <typename T> bool rtpc_iocc_device::load(u32 address, T &data, rsc_mode const mode)
|
||||
{
|
||||
unsigned const s = (address >> 24) & 15 ? AS_PROGRAM : AS_IO;
|
||||
|
||||
if (s == AS_PROGRAM && (mode & RSC_U) && !(m_ccr & CCR_MMP))
|
||||
{
|
||||
LOG("load mem protection violation (%s)\n", machine().describe_context());
|
||||
m_csr |= CSR_EXR | CSR_PER | CSR_PD | CSR_PVIO;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s == AS_IO)
|
||||
{
|
||||
if ((mode & RSC_U) && (address == 0xf001'0800U || !(m_ccr & CCR_IMP)))
|
||||
{
|
||||
LOG("load pio protection violation (%s)\n", machine().describe_context());
|
||||
m_csr |= CSR_EXR | CSR_PER | CSR_PD | CSR_PVIO;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
switch (sizeof(T))
|
||||
{
|
||||
case 1: data = space(s).read_byte(address); break;
|
||||
case 2:
|
||||
if (s == 2 && target_size(address) < sizeof(T))
|
||||
{
|
||||
LOGMASKED(LOG_WIDEPIO, "load pio w<-b 0x%08x (%s)\n", address, machine().describe_context());
|
||||
data = u16(space(s).read_byte(address)) << 8;
|
||||
data |= space(s).read_byte(address);
|
||||
}
|
||||
else
|
||||
data = space(s).read_word(address);
|
||||
break;
|
||||
case 4:
|
||||
if (s == 2 && target_size(address) < sizeof(T))
|
||||
{
|
||||
if (target_size(address) == 1)
|
||||
{
|
||||
LOGMASKED(LOG_WIDEPIO, "load pio d<-b 0x%08x (%s)\n", address, machine().describe_context());
|
||||
data = u32(space(s).read_byte(address)) << 24;
|
||||
data |= u32(space(s).read_byte(address)) << 16;
|
||||
data |= u32(space(s).read_byte(address)) << 8;
|
||||
data |= space(s).read_byte(address);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGMASKED(LOG_WIDEPIO, "load pio d<-w 0x%08x (%s)\n", address, machine().describe_context());
|
||||
data = u32(space(s).read_word(address)) << 16;
|
||||
data |= space(s).read_word(address);
|
||||
}
|
||||
}
|
||||
else
|
||||
data = space(s).read_dword(address);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// avoid incorrect MSVC warnings about excessive shift sizes below
|
||||
#pragma warning(disable:4333)
|
||||
#endif
|
||||
|
||||
template <typename T> bool rtpc_iocc_device::store(u32 address, T data, rsc_mode const mode)
|
||||
{
|
||||
unsigned const spacenum = (address >> 24) & 15 ? AS_PROGRAM : AS_IO;
|
||||
|
||||
if (spacenum == AS_PROGRAM && (mode & RSC_U) && !(m_ccr & CCR_MMP))
|
||||
{
|
||||
LOG("store mem protection violation (%s)\n", machine().describe_context());
|
||||
m_csr |= CSR_PER | CSR_PD | CSR_PVIO;
|
||||
if (mode & RSC_T)
|
||||
{
|
||||
m_csr |= CSR_EXR;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
set_int(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (spacenum == AS_IO && (mode & RSC_U))
|
||||
{
|
||||
if (address == 0xf001'0800U || !(m_ccr & CCR_IMP))
|
||||
{
|
||||
LOG("store pio protection violation (%s)\n", machine().describe_context());
|
||||
m_csr |= CSR_PER | CSR_PD | CSR_PVIO;
|
||||
if (mode & RSC_T)
|
||||
{
|
||||
m_csr |= CSR_EXR;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
set_int(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
switch (sizeof(T))
|
||||
{
|
||||
case 1: space(spacenum).write_byte(address, data); break;
|
||||
case 2:
|
||||
if (spacenum == AS_IO && target_size(address) < sizeof(T))
|
||||
{
|
||||
LOGMASKED(LOG_WIDEPIO, "store pio w->b 0x%08x data 0x%04x (%s)\n", address, data, machine().describe_context());
|
||||
space(spacenum).write_byte(address, u8(data >> 8));
|
||||
space(spacenum).write_byte(address, u8(data >> 0));
|
||||
}
|
||||
else
|
||||
space(spacenum).write_word(address, data);
|
||||
break;
|
||||
case 4:
|
||||
if (spacenum == AS_IO && target_size(address) < sizeof(T))
|
||||
{
|
||||
if (target_size(address) == 1)
|
||||
{
|
||||
LOGMASKED(LOG_WIDEPIO, "store pio d->b 0x%08x data 0x%08x (%s)\n", address, data, machine().describe_context());
|
||||
space(spacenum).write_byte(address, u8(data >> 24));
|
||||
space(spacenum).write_byte(address, u8(data >> 16));
|
||||
space(spacenum).write_byte(address, u8(data >> 8));
|
||||
space(spacenum).write_byte(address, u8(data >> 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGMASKED(LOG_WIDEPIO, "store pio d->w 0x%08x data 0x%08x (%s)\n", address, data, machine().describe_context());
|
||||
space(spacenum).write_word(address, u16(data >> 16));
|
||||
space(spacenum).write_word(address, u16(data >> 0));
|
||||
}
|
||||
}
|
||||
else
|
||||
space(spacenum).write_dword(address, data);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T> bool rtpc_iocc_device::modify(u32 address, std::function<T(T)> f, rsc_mode const mode)
|
||||
{
|
||||
unsigned const spacenum = (address >> 24) & 15 ? AS_PROGRAM : AS_IO;
|
||||
|
||||
if (spacenum == AS_PROGRAM && (mode & RSC_U) && !(m_ccr & CCR_MMP))
|
||||
{
|
||||
LOG("modify mem protection violation (%s)\n", machine().describe_context());
|
||||
m_csr |= CSR_PER | CSR_PD | CSR_PVIO;
|
||||
if (mode & RSC_T)
|
||||
{
|
||||
m_csr |= CSR_EXR;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
set_int(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (spacenum == AS_IO)
|
||||
{
|
||||
LOG("modify pio space invalid operation (%s)\n", machine().describe_context());
|
||||
m_csr |= CSR_EXR | CSR_PER | CSR_PD | CSR_INVOP;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (sizeof(T))
|
||||
{
|
||||
case 1: space(spacenum).write_byte(address, f(space(spacenum).read_byte(address))); break;
|
||||
case 2: space(spacenum).write_word(address, f(space(spacenum).read_word(address))); break;
|
||||
case 4: space(spacenum).write_dword(address, f(space(spacenum).read_dword(address))); break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
170
src/mame/machine/rtpc_iocc.h
Normal file
170
src/mame/machine/rtpc_iocc.h
Normal file
@ -0,0 +1,170 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Patrick Mackinlay
|
||||
|
||||
#ifndef MAME_MACHINE_RTPC_IOCC_H
|
||||
#define MAME_MACHINE_RTPC_IOCC_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cpu/romp/rsc.h"
|
||||
|
||||
class rtpc_iocc_device
|
||||
: public device_t
|
||||
, public device_memory_interface
|
||||
, public rsc_bus_interface
|
||||
{
|
||||
public:
|
||||
rtpc_iocc_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
|
||||
|
||||
auto out_int() { return m_out_int.bind(); }
|
||||
auto out_rst() { return m_out_rst.bind(); }
|
||||
|
||||
enum ccr_mask : u8
|
||||
{
|
||||
CCR_RFE = 0x02, // refresh enable
|
||||
CCR_RFT = 0x04, // refresh period (0=14.9µs, 1=6.4µs)
|
||||
CCR_MMP = 0x08, // memory map privilege
|
||||
CCR_IMP = 0x10, // i/o map privilege
|
||||
CCR_DKA = 0x20, // dma keyboard access
|
||||
CCR_DSA = 0x40, // dma i/o subsystem access
|
||||
CCR_DCA = 0x80, // dma control register access
|
||||
};
|
||||
|
||||
enum csr_mask : u32
|
||||
{
|
||||
CSR_EXR = 0x80000000, // exception reported
|
||||
CSR_INTP = 0x40000000, // interrupt pending
|
||||
CSR_EPOW = 0x10000000, // early power off warning
|
||||
CSR_SRST = 0x08000000, // soft reset
|
||||
CSR_SAT = 0x04000000, // system attention
|
||||
CSR_PER = 0x01000000, // pio error
|
||||
CSR_DE0 = 0x00800000, // dma error channel 0
|
||||
CSR_DE1 = 0x00400000, // dma error channel 1
|
||||
CSR_DE2 = 0x00200000, // dma error channel 2
|
||||
CSR_DE3 = 0x00100000, // dma error channel 3
|
||||
CSR_DE5 = 0x00080000, // dma error channel 5
|
||||
CSR_DE6 = 0x00040000, // dma error channel 6
|
||||
CSR_DE7 = 0x00020000, // dma error channel 7
|
||||
CSR_DE8 = 0x00010000, // dma error channel 8
|
||||
CSR_PD = 0x00008000, // pio/dma
|
||||
CSR_PVIO = 0x00004000, // protection violation
|
||||
CSR_INVOP = 0x00002000, // invalid operation
|
||||
CSR_IOCK = 0x00001000, // i/o channel check
|
||||
CSR_DEXK = 0x00000800, // dma exception
|
||||
CSR_CRC = 0x00000400, // channel reset captured
|
||||
CSR_SBB = 0x00000200, // system board busy
|
||||
CSR_PRP = 0x00000100, // pio request pending
|
||||
|
||||
CSR_RSV = 0x220000ff, // reserved
|
||||
};
|
||||
|
||||
enum tcw_mask : u16
|
||||
{
|
||||
TCW_PFX = 0x1fff, // translation prefix
|
||||
TCW_IOC = 0x4000, // i/o channel destination
|
||||
TCW_VIR = 0x8000, // virtual access
|
||||
};
|
||||
|
||||
using rsc_mode = rsc_bus_interface::rsc_mode;
|
||||
|
||||
// rsc_pio_interface overrides
|
||||
virtual bool load(u32 address, u8 &data, rsc_mode const mode, bool sp) override { return load<u8>(address, data, mode); }
|
||||
virtual bool load(u32 address, u16 &data, rsc_mode const mode, bool sp) override { return load<u16>(address, data, mode); }
|
||||
virtual bool load(u32 address, u32 &data, rsc_mode const mode, bool sp) override { return load<u32>(address, data, mode); }
|
||||
virtual bool store(u32 address, u8 data, rsc_mode const mode, bool sp) override { return store<u8>(address, data, mode); }
|
||||
virtual bool store(u32 address, u16 data, rsc_mode const mode, bool sp) override { return store<u16>(address, data, mode); }
|
||||
virtual bool store(u32 address, u32 data, rsc_mode const mode, bool sp) override { return store<u32>(address, data, mode); }
|
||||
virtual bool modify(u32 address, std::function<u8(u8)> f, rsc_mode const mode) override { return modify<u8>(address, f, mode); }
|
||||
virtual bool modify(u32 address, std::function<u16(u16)> f, rsc_mode const mode) override { return modify<u16>(address, f, mode); }
|
||||
virtual bool modify(u32 address, std::function<u32(u32)> f, rsc_mode const mode) override { return modify<u32>(address, f, mode); }
|
||||
|
||||
u8 ccr_r() { return m_ccr; }
|
||||
void ccr_w(u8 data) { m_ccr = data; }
|
||||
|
||||
template <unsigned Word> u16 csr_r() { return u16((m_csr | CSR_RSV) >> (16 * Word)); }
|
||||
void csr_w(u16 data) { set_int(false); m_csr = 0; }
|
||||
|
||||
u8 dma_b_r(offs_t offset);
|
||||
u8 dma_w_r(offs_t offset);
|
||||
void dma_b_w(offs_t offset, u8 data);
|
||||
void dma_w_w(offs_t offset, u8 data);
|
||||
|
||||
u8 dmr_r() { return m_dmr; }
|
||||
u8 dbr_r() { return m_dbr; }
|
||||
void dmr_w(u8 data) { m_dmr = data; }
|
||||
void dbr_w(u8 data) { m_dbr = data; }
|
||||
|
||||
u16 tcw_r(offs_t offset) { return m_tcw[offset]; }
|
||||
void tcw_w(offs_t offset, u16 data, u16 mem_mask) { COMBINE_DATA(&m_tcw[offset]); }
|
||||
|
||||
template <unsigned Channel> void dack_w(int state) { if (!state) m_adc = Channel; }
|
||||
|
||||
protected:
|
||||
// device_t overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
// device_memory_interface overrides
|
||||
virtual space_config_vector memory_space_config() const override;
|
||||
//virtual bool memory_translate(int spacenum, int intention, offs_t &address) override;
|
||||
|
||||
template <typename T> bool load(u32 address, T &data, rsc_mode const mode);
|
||||
template <typename T> bool store(u32 address, T data, rsc_mode const mode);
|
||||
template <typename T> bool modify(u32 address, std::function<T(T)> f, rsc_mode const mode);
|
||||
|
||||
void set_int(bool state)
|
||||
{
|
||||
if (state != m_out_int_state)
|
||||
{
|
||||
if (state)
|
||||
m_csr |= CSR_INTP;
|
||||
m_out_int_state = state;
|
||||
m_out_int(!m_out_int_state);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned target_size(u32 const address) const
|
||||
{
|
||||
if (address < 0xf000'8000U)
|
||||
{
|
||||
if (address == 0xf000'0110U || address == 0xf000'0112U)
|
||||
return 2;
|
||||
else
|
||||
// FIXME: get size from isa bus
|
||||
return 1;
|
||||
}
|
||||
else if (address == 0xf000'8400U)
|
||||
// exception for kls
|
||||
return 2;
|
||||
else if (address < 0xf001'0000U)
|
||||
return 1;
|
||||
else if (address < 0xf001'0800U)
|
||||
return 2;
|
||||
else
|
||||
return 4;
|
||||
}
|
||||
|
||||
private:
|
||||
address_space_config m_mem_config;
|
||||
address_space_config m_pio_config;
|
||||
|
||||
devcb_write_line m_out_int;
|
||||
devcb_write_line m_out_rst;
|
||||
|
||||
required_device<rsc_bus_interface> m_rsc;
|
||||
|
||||
u32 m_csr; // channel status register
|
||||
u8 m_ccr; // channel control register
|
||||
|
||||
u8 m_dbr; // dma buffer register
|
||||
u8 m_dmr; // dma mode register
|
||||
u16 m_tcw[1024]; // dma translation control words
|
||||
|
||||
unsigned m_adc; // active dma channel
|
||||
|
||||
bool m_out_int_state;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(RTPC_IOCC, rtpc_iocc_device)
|
||||
|
||||
#endif // MAME_MACHINE_RTPC_IOCC_H
|
@ -35828,6 +35828,13 @@ rt1715 //
|
||||
rt1715lc // (latin/cyrillic)
|
||||
rt1715w //
|
||||
|
||||
@source:rtpc.cpp
|
||||
rtpc010 // IBM RT PC Model 010
|
||||
rtpc015 // IBM RT PC Model 015
|
||||
rtpc020 // IBM RT PC Model 020
|
||||
rtpc025 // IBM RT PC Model 025
|
||||
rtpc025 // IBM RT PC Model A25
|
||||
|
||||
@source:runaway.cpp
|
||||
qwak // (proto) (c) 1982
|
||||
runaway // (proto) (c) 1982
|
||||
|
@ -850,6 +850,7 @@ roland_tr707.cpp
|
||||
roland_tr909.cpp
|
||||
roland_u20.cpp
|
||||
rt1715.cpp
|
||||
rtpc.cpp
|
||||
rvoice.cpp
|
||||
rx78.cpp
|
||||
rz1.cpp
|
||||
|
Loading…
Reference in New Issue
Block a user