summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Patrick Mackinlay <pmackinlay@hotmail.com>2023-01-27 12:15:41 +0700
committer Patrick Mackinlay <pmackinlay@hotmail.com>2023-01-27 12:15:41 +0700
commit3ecac2e50cf727527f2022f81c1a606ee7ad4a62 (patch)
treeebbd483e5241ad936112b8bd9f668960ce5cae14 /src
parente577e83f4057cb114ed796f5f0b9a276c259511e (diff)
labtam: add serial ports
Diffstat (limited to 'src')
-rw-r--r--src/devices/bus/multibus/labtam_vducom.cpp185
-rw-r--r--src/devices/bus/multibus/labtam_vducom.h5
2 files changed, 150 insertions, 40 deletions
diff --git a/src/devices/bus/multibus/labtam_vducom.cpp b/src/devices/bus/multibus/labtam_vducom.cpp
index 98b30713c73..0aaf49d55ae 100644
--- a/src/devices/bus/multibus/labtam_vducom.cpp
+++ b/src/devices/bus/multibus/labtam_vducom.cpp
@@ -8,12 +8,16 @@
* - https://arvutimuuseum.ut.ee/index.php?m=eksponaadid&id=223
*
* TODO:
- * - skeleton only
+ * - keyboard click/bell
+ * - light pen
+ * - parallel ports
*/
#include "emu.h"
#include "labtam_vducom.h"
+#include "machine/input_merger.h"
+
#define VERBOSE 0
#include "logmacro.h"
@@ -39,6 +43,7 @@ labtam_vducom_device_base::labtam_vducom_device_base(machine_config const &mconf
, m_ctc(*this, "ctc%u", 0U)
, m_com(*this, "com%u", 0U)
, m_nvram(*this, "nvram%u", 0U)
+ , m_serial(*this, "serial%u", 0U)
, m_e4(*this, "E4")
, m_mbus(*this, "mbus")
, m_installed(false)
@@ -85,48 +90,48 @@ ROM_END
static INPUT_PORTS_START(labtam_vducom)
PORT_START("E4")
- PORT_DIPNAME(0x01, 0x01, "Keyboard Select 1") PORT_DIPLOCATION("E4:1")
+ PORT_DIPNAME(0x08, 0x08, "Keyboard Select 1") PORT_DIPLOCATION("E4:1")
PORT_DIPSETTING(0x00, DEF_STR(Yes))
- PORT_DIPSETTING(0x01, DEF_STR(No))
- PORT_DIPNAME(0x02, 0x02, "Disable Graphics") PORT_DIPLOCATION("E4:2")
+ PORT_DIPSETTING(0x08, DEF_STR(No))
+ PORT_DIPNAME(0x10, 0x10, "Disable Graphics") PORT_DIPLOCATION("E4:2")
PORT_DIPSETTING(0x00, DEF_STR(Yes))
- PORT_DIPSETTING(0x02, DEF_STR(No))
+ PORT_DIPSETTING(0x10, DEF_STR(No))
PORT_DIPNAME(0x04, 0x04, "Keyboard Select 0") PORT_DIPLOCATION("E4:3")
PORT_DIPSETTING(0x00, DEF_STR(Yes))
PORT_DIPSETTING(0x04, DEF_STR(No))
- PORT_DIPNAME(0x08, 0x08, "Killer Enable") PORT_DIPLOCATION("E4:4")
+ PORT_DIPNAME(0x20, 0x20, "Killer Enable") PORT_DIPLOCATION("E4:4")
PORT_DIPSETTING(0x00, DEF_STR(Yes))
- PORT_DIPSETTING(0x08, DEF_STR(No))
- PORT_DIPNAME(0x10, 0x10, "Init NVRAM") PORT_DIPLOCATION("E4:5")
+ PORT_DIPSETTING(0x20, DEF_STR(No))
+ PORT_DIPNAME(0x02, 0x02, "Init NVRAM") PORT_DIPLOCATION("E4:5")
PORT_DIPSETTING(0x00, DEF_STR(Yes))
- PORT_DIPSETTING(0x10, DEF_STR(No))
- PORT_DIPNAME(0x40, 0x40, "Terminal Mode") PORT_DIPLOCATION("E4:7")
+ PORT_DIPSETTING(0x02, DEF_STR(No))
+ PORT_DIPNAME(0x01, 0x01, "Terminal Mode") PORT_DIPLOCATION("E4:7")
PORT_DIPSETTING(0x00, DEF_STR(Yes))
- PORT_DIPSETTING(0x40, DEF_STR(No))
- PORT_DIPUNUSED_DIPLOC(0xa0, 0xa0, "E4:6,8")
+ PORT_DIPSETTING(0x01, DEF_STR(No))
+ PORT_DIPUNUSED_DIPLOC(0xc0, 0xc0, "E4:6,8")
INPUT_PORTS_END
static INPUT_PORTS_START(labtam_8086cpu)
PORT_START("E4")
- PORT_DIPNAME(0x01, 0x01, "Keyboard Select 1") PORT_DIPLOCATION("E4:1")
+ PORT_DIPNAME(0x08, 0x08, "Keyboard Select 1") PORT_DIPLOCATION("E4:1")
PORT_DIPSETTING(0x00, DEF_STR(Yes))
- PORT_DIPSETTING(0x01, DEF_STR(No))
- PORT_DIPNAME(0x02, 0x00, "Disable Graphics") PORT_DIPLOCATION("E4:2")
+ PORT_DIPSETTING(0x08, DEF_STR(No))
+ PORT_DIPNAME(0x10, 0x00, "Disable Graphics") PORT_DIPLOCATION("E4:2")
PORT_DIPSETTING(0x00, DEF_STR(Yes))
- PORT_DIPSETTING(0x02, DEF_STR(No))
+ PORT_DIPSETTING(0x10, DEF_STR(No))
PORT_DIPNAME(0x04, 0x04, "Keyboard Select 0") PORT_DIPLOCATION("E4:3")
PORT_DIPSETTING(0x00, DEF_STR(Yes))
PORT_DIPSETTING(0x04, DEF_STR(No))
- PORT_DIPNAME(0x08, 0x08, "Killer Enable") PORT_DIPLOCATION("E4:4")
+ PORT_DIPNAME(0x20, 0x20, "Killer Enable") PORT_DIPLOCATION("E4:4")
PORT_DIPSETTING(0x00, DEF_STR(Yes))
- PORT_DIPSETTING(0x08, DEF_STR(No))
- PORT_DIPNAME(0x10, 0x10, "Init NVRAM") PORT_DIPLOCATION("E4:5")
+ PORT_DIPSETTING(0x20, DEF_STR(No))
+ PORT_DIPNAME(0x02, 0x02, "Init NVRAM") PORT_DIPLOCATION("E4:5")
PORT_DIPSETTING(0x00, DEF_STR(Yes))
- PORT_DIPSETTING(0x10, DEF_STR(No))
- PORT_DIPNAME(0x40, 0x40, "Terminal Mode") PORT_DIPLOCATION("E4:7")
+ PORT_DIPSETTING(0x02, DEF_STR(No))
+ PORT_DIPNAME(0x01, 0x01, "Terminal Mode") PORT_DIPLOCATION("E4:7")
PORT_DIPSETTING(0x00, DEF_STR(Yes))
- PORT_DIPSETTING(0x40, DEF_STR(No))
- PORT_DIPUNUSED_DIPLOC(0xa0, 0xa0, "E4:6,8")
+ PORT_DIPSETTING(0x01, DEF_STR(No))
+ PORT_DIPUNUSED_DIPLOC(0xc0, 0xc0, "E4:6,8")
INPUT_PORTS_END
static const gfx_layout vducom_char_set_1 =
@@ -195,6 +200,21 @@ void labtam_vducom_device_base::device_reset()
m_nvram[1]->recall(1);
m_mbus.select(0);
+
+ m_ctc[0]->gate1_w(1);
+ m_ctc[0]->gate2_w(1);
+ m_ctc[0]->gate3_w(1);
+ m_ctc[0]->gate4_w(1);
+ m_ctc[0]->gate5_w(1);
+
+ m_ctc[0]->source1_w(1);
+ m_ctc[0]->source2_w(1);
+ m_ctc[0]->source3_w(1);
+ m_ctc[0]->source4_w(1);
+ m_ctc[0]->source5_w(1);
+
+ m_ctc[1]->gate4_w(1);
+ m_ctc[1]->source5_w(1);
}
void labtam_vducom_device_base::device_add_mconfig(machine_config &config)
@@ -204,28 +224,90 @@ void labtam_vducom_device_base::device_add_mconfig(machine_config &config)
m_cpu->set_addrmap(AS_IO, &labtam_vducom_device_base::cpu_pio);
m_cpu->set_irq_acknowledge_callback(m_pic, FUNC(pic8259_device::inta_cb));
- AM9513(config, m_ctc[0], 4'000'000);
- //m_ctc[0]->out1_cb().set(m_pic, FUNC(pic8259_device::ir0_w));
- m_ctc[0]->out4_cb().set(m_ctc[0], FUNC(am9513_device::gate5_w)); // ?
- m_ctc[0]->out5_cb().set(m_ctc[0], FUNC(am9513_device::source4_w)); // ?
+ AM9513(config, m_ctc[1], 16_MHz_XTAL / 4);
+ m_ctc[1]->out4_cb().set(m_ctc[1], FUNC(am9513_device::gate5_w));
+ m_ctc[1]->out5_cb().set(m_ctc[1], FUNC(am9513_device::source4_w)); // TODO: also keyboard bell
- AM9513(config, m_ctc[1], 4'000'000);
- m_ctc[1]->out1_cb().set(m_com[1], FUNC(upd7201_device::txcb_w));
- m_ctc[1]->out2_cb().set(m_com[1], FUNC(upd7201_device::rxcb_w));
- m_ctc[1]->out3_cb().set(m_com[1], FUNC(upd7201_device::rxca_w));
- m_ctc[1]->out3_cb().append(m_com[1], FUNC(upd7201_device::txca_w));
- m_ctc[1]->out4_cb().set(m_com[0], FUNC(upd7201_device::rxcb_w));
- m_ctc[1]->out5_cb().set(m_com[0], FUNC(upd7201_device::rxca_w));
- m_ctc[1]->out5_cb().append(m_com[0], FUNC(upd7201_device::txca_w));
+ AM9513(config, m_ctc[0], 16_MHz_XTAL / 4);
+ m_ctc[0]->out1_cb().set(m_com[1], FUNC(upd7201_device::txcb_w));
+ m_ctc[0]->out2_cb().set(m_com[1], FUNC(upd7201_device::rxcb_w));
+ m_ctc[0]->out3_cb().set(m_com[1], FUNC(upd7201_device::rxca_w));
+ m_ctc[0]->out3_cb().append(m_com[1], FUNC(upd7201_device::txca_w));
+ m_ctc[0]->out4_cb().set(m_com[0], FUNC(upd7201_device::rxcb_w));
+ m_ctc[0]->out4_cb().append(m_com[0], FUNC(upd7201_device::txcb_w));
+ m_ctc[0]->out5_cb().set(m_com[0], FUNC(upd7201_device::rxca_w));
+ m_ctc[0]->out5_cb().append(m_com[0], FUNC(upd7201_device::txca_w));
PIC8259(config, m_pic);
+ /*
+ * irq source
+ * 0 crtc vsync
+ * 1 light pen strobe
+ * 2 com1
+ * 3 com0
+ * 4 parallel input strobe
+ * 5 parallel printer acknowledge
+ * 6 parallel printer busy
+ * 7 not connected
+ */
m_pic->out_int_callback().set_inputline(m_cpu, INPUT_LINE_INT0);
- UPD7201(config, m_com[0], 4'000'000);
+ UPD7201(config, m_com[0], 16_MHz_XTAL / 4);
m_com[0]->out_int_callback().set(m_pic, FUNC(pic8259_device::ir3_w));
- UPD7201(config, m_com[1], 4'000'000);
+
+ RS232_PORT(config, m_serial[0], default_rs232_devices, nullptr);
+ input_merger_any_high_device &com0dcda(INPUT_MERGER_ANY_HIGH(config, "com0dcda"));
+ input_merger_any_high_device &com0ctsa(INPUT_MERGER_ANY_HIGH(config, "com0ctsa"));
+ m_serial[0]->cts_handler().set(com0ctsa, FUNC(input_merger_any_high_device::in_w<0>));
+ m_serial[0]->dsr_handler().set(com0ctsa, FUNC(input_merger_any_high_device::in_w<1>));
+ com0ctsa.output_handler().set(m_com[0], FUNC(upd7201_device::ctsa_w));
+ m_serial[0]->dcd_handler().set(com0dcda, FUNC(input_merger_any_high_device::in_w<0>));
+ m_serial[0]->dsr_handler().append(com0dcda, FUNC(input_merger_any_high_device::in_w<1>));
+ com0dcda.output_handler().set(m_com[0], FUNC(upd7201_device::dcda_w));
+ m_serial[0]->rxd_handler().set(m_com[0], FUNC(upd7201_device::rxa_w));
+ m_com[0]->out_dtra_callback().set(m_serial[0], FUNC(rs232_port_device::write_dtr));
+ m_com[0]->out_rtsa_callback().set(m_serial[0], FUNC(rs232_port_device::write_rts));
+ m_com[0]->out_txda_callback().set(m_serial[0], FUNC(rs232_port_device::write_txd));
+
+ RS232_PORT(config, m_serial[1], default_rs232_devices, nullptr);
+ input_merger_any_high_device &com0dcdb(INPUT_MERGER_ANY_HIGH(config, "com0dcdb"));
+ input_merger_any_high_device &com0ctsb(INPUT_MERGER_ANY_HIGH(config, "com0ctsb"));
+ m_serial[1]->cts_handler().set(com0ctsb, FUNC(input_merger_any_high_device::in_w<0>));
+ m_serial[1]->dsr_handler().set(com0ctsb, FUNC(input_merger_any_high_device::in_w<1>));
+ com0ctsb.output_handler().set(m_com[0], FUNC(upd7201_device::ctsb_w));
+ m_serial[1]->dcd_handler().set(com0dcdb, FUNC(input_merger_any_high_device::in_w<0>));
+ m_serial[1]->dsr_handler().append(com0dcdb, FUNC(input_merger_any_high_device::in_w<1>));
+ com0dcdb.output_handler().set(m_com[0], FUNC(upd7201_device::dcdb_w));
+ m_serial[1]->rxd_handler().set(m_com[0], FUNC(upd7201_device::rxb_w));
+ m_com[0]->out_txdb_callback().set(m_serial[1], FUNC(rs232_port_device::write_txd));
+ m_com[0]->out_rtsb_callback().set(m_serial[1], FUNC(rs232_port_device::write_rts));
+ m_com[0]->out_dtrb_callback().set(m_serial[1], FUNC(rs232_port_device::write_dtr));
+
+ UPD7201(config, m_com[1], 16_MHz_XTAL / 4);
m_com[1]->out_int_callback().set(m_pic, FUNC(pic8259_device::ir2_w));
+ RS232_PORT(config, m_serial[2], default_rs232_devices, nullptr);
+ input_merger_any_high_device &com1dcda(INPUT_MERGER_ANY_HIGH(config, "com1dcda"));
+ input_merger_any_high_device &com1ctsa(INPUT_MERGER_ANY_HIGH(config, "com1ctsa"));
+ m_serial[2]->cts_handler().set(com1ctsa, FUNC(input_merger_any_high_device::in_w<0>));
+ m_serial[2]->dsr_handler().set(com1ctsa, FUNC(input_merger_any_high_device::in_w<1>));
+ com1ctsa.output_handler().set(m_com[1], FUNC(upd7201_device::ctsa_w));
+ m_serial[2]->dcd_handler().set(com1dcda, FUNC(input_merger_any_high_device::in_w<0>));
+ m_serial[2]->dsr_handler().append(com1dcda, FUNC(input_merger_any_high_device::in_w<1>));
+ com1dcda.output_handler().set(m_com[1], FUNC(upd7201_device::dcda_w));
+ m_serial[2]->rxd_handler().set(m_com[1], FUNC(upd7201_device::rxa_w));
+ m_com[1]->out_dtra_callback().set(m_serial[2], FUNC(rs232_port_device::write_dtr));
+ m_com[1]->out_rtsa_callback().set(m_serial[2], FUNC(rs232_port_device::write_rts));
+ m_com[1]->out_txda_callback().set(m_serial[2], FUNC(rs232_port_device::write_txd));
+
+ RS232_PORT(config, m_serial[3], default_rs232_devices, type() == LABTAM_VDUCOM ? "keyboard" : nullptr);
+ m_serial[3]->dcd_handler().set(m_com[1], FUNC(upd7201_device::dcdb_w));
+ m_serial[3]->cts_handler().set(m_com[1], FUNC(upd7201_device::ctsb_w));
+ m_serial[3]->rxd_handler().set(m_com[1], FUNC(upd7201_device::rxb_w));
+ m_com[1]->out_dtrb_callback().set(m_serial[3], FUNC(rs232_port_device::write_dtr));
+ m_com[1]->out_rtsb_callback().set(m_serial[3], FUNC(rs232_port_device::write_rts));
+ m_com[1]->out_txdb_callback().set(m_serial[3], FUNC(rs232_port_device::write_txd));
+
X2212(config, m_nvram[0]);
X2212(config, m_nvram[1]);
}
@@ -234,7 +316,7 @@ void labtam_vducom_device::device_add_mconfig(machine_config &config)
{
labtam_vducom_device_base::device_add_mconfig(config);
- MC6845(config, m_crtc, 1'000'000);
+ MC6845(config, m_crtc, 16_MHz_XTAL / 16);
m_crtc->set_show_border_area(false);
m_crtc->set_hpixels_per_column(16);
m_crtc->out_vsync_callback().set("pic", FUNC(pic8259_device::ir0_w));
@@ -244,7 +326,7 @@ void labtam_vducom_device::device_add_mconfig(machine_config &config)
PALETTE(config, m_palette, FUNC(labtam_vducom_device::palette_init), 4);
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
- m_screen->set_raw(1'000'000, 62 * 16, 2 * 16, 52 * 16, 78 * 4, 3 * 4, 75 * 4);
+ m_screen->set_raw(16_MHz_XTAL / 16, 62 * 16, 2 * 16, 52 * 16, 78 * 4, 3 * 4, 75 * 4);
m_screen->set_screen_update(m_crtc, FUNC(mc6845_device::screen_update));
// gfxdecode is only to show the font data in the tile viewer
@@ -276,7 +358,10 @@ void labtam_vducom_device_base::cpu_pio(address_map &map)
map(0xf000, 0xf00f).rw(FUNC(labtam_vducom_device_base::u15_r), FUNC(labtam_vducom_device_base::u7_w)).umask16(0x00ff);
map(0xf200, 0xf200).lw8([this](u8 data) { m_start = (m_start & 0xff00) | u16(data) << 0; }, "start_lo");
map(0xf400, 0xf400).lw8([this](u8 data) { m_start = (m_start & 0x00ff) | u16(data) << 8; }, "start_hi");
- map(0xfe00, 0xfe00).lw8([this](u8 data) { m_nvram[0]->store(1); m_nvram[1]->store(1); }, "store_array");
+ //map(0xf600, 0xf600); // r:parallel data input, w:joystick start pulse
+ //map(0xf800, 0xf800); // r:parallel data acknowledge, w:parallel printer output
+ //map(0xfa00, 0xfa00); // w:parallel printer strobe
+ map(0xfe00, 0xfe00).rw(FUNC(labtam_vducom_device_base::nvram_recall), FUNC(labtam_vducom_device_base::nvram_store));
}
void labtam_vducom_device::cpu_pio(address_map &map)
@@ -345,3 +430,23 @@ u16 labtam_vducom_device_base::bus_mem_r(offs_t offset, u16 mem_mask)
return m_bus->space(AS_PROGRAM).read_word(address, mem_mask);
}
+
+u8 labtam_vducom_device_base::nvram_recall()
+{
+ m_nvram[0]->recall(1);
+ m_nvram[1]->recall(1);
+
+ m_nvram[0]->recall(0);
+ m_nvram[1]->recall(0);
+
+ return 0;
+}
+
+void labtam_vducom_device_base::nvram_store(u8 data)
+{
+ m_nvram[0]->store(1);
+ m_nvram[1]->store(1);
+
+ m_nvram[0]->store(0);
+ m_nvram[1]->store(0);
+}
diff --git a/src/devices/bus/multibus/labtam_vducom.h b/src/devices/bus/multibus/labtam_vducom.h
index 86326acc001..70f1b9b5cef 100644
--- a/src/devices/bus/multibus/labtam_vducom.h
+++ b/src/devices/bus/multibus/labtam_vducom.h
@@ -51,12 +51,17 @@ protected:
u8 u7() const { return m_u7; }
private:
+ u8 nvram_recall();
+ void nvram_store(u8 data);
+
required_device<i8086_cpu_device> m_cpu;
required_device<pic8259_device> m_pic;
required_device_array<am9513_device, 2> m_ctc;
required_device_array<z80sio_device, 2> m_com;
required_device_array<x2212_device, 2> m_nvram;
+ required_device_array<rs232_port_device, 4> m_serial;
+
required_ioport m_e4;
memory_view m_mbus;