summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author R. Belmont <rb6502@users.noreply.github.com>2019-11-12 11:45:10 -0500
committer GitHub <noreply@github.com>2019-11-12 11:45:10 -0500
commit542997be406b48c8f5f6ec834e104eefb6cf07ee (patch)
treeee3e0b64967c5a44b37478e75260668cc28e206a
parentd093c549295c721fd0c6f507b9d17804f24fafe1 (diff)
parent97270022635f8e970ae3b478b5791cd185a88705 (diff)
Merge pull request #5881 from 68bit/qvt102-misc
qvt102: key lines, boost interleave
-rw-r--r--src/mame/drivers/qvt102.cpp91
1 files changed, 59 insertions, 32 deletions
diff --git a/src/mame/drivers/qvt102.cpp b/src/mame/drivers/qvt102.cpp
index ebb8b658c8f..5af6cd299a1 100644
--- a/src/mame/drivers/qvt102.cpp
+++ b/src/mame/drivers/qvt102.cpp
@@ -15,6 +15,13 @@
Keyboard: D8748D, 6.000MHz Crystal, Beeper
+ For the QVT102, the 'Setup' function is entered by typing F11. The 'left'
+ and 'right' arrow keys then move between entries on a line, and the 'up'
+ and 'down' arrow keys move between lines. The space bar cycles through
+ options for an entry. Shift-S saves the values to NVRAM; F11 exits without
+ saving; Shift-D resets to the default values; and Shift-R restores from
+ the saved values.
+
TODO:
- Support QVT-102A differences (bidirectional aux, different keyboard)
- Key click sounds weird
@@ -43,28 +50,28 @@
class qvt102_state : public driver_device
{
public:
- qvt102_state(const machine_config &mconfig, device_type type, const char *tag) :
- driver_device(mconfig, type, tag),
- m_maincpu(*this, "maincpu"),
- m_irqs(*this, "irqs"),
- m_kbdmcu(*this, "kbdmcu"),
- m_keys_p1(*this, "P1_%u", 0U),
- m_keys_p2(*this, "P2_%u", 0U),
- m_keys_special(*this, "SPECIAL"),
- m_jumper(*this, "JUMPER"),
- m_acia(*this, "acia"),
- m_host(*this, "host"),
- m_aux(*this, "aux"),
- m_ctc(*this, "ctc"),
- m_crtc(*this, "crtc"),
- m_screen(*this, "screen"),
- m_palette(*this, "palette"),
- m_speaker(*this, "speaker"),
- m_vram(*this, "videoram"),
- m_char_rom(*this, "chargen"),
- m_latch(0),
- m_kbd_data(0),
- m_kbd_bus(0xff), m_kbd_p1(0xff), m_kbd_p2(0xff)
+ qvt102_state(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag)
+ , m_maincpu(*this, "maincpu")
+ , m_irqs(*this, "irqs")
+ , m_kbdmcu(*this, "kbdmcu")
+ , m_keys_p1(*this, "P1_%u", 0U)
+ , m_keys_p2(*this, "P2_%u", 0U)
+ , m_keys_special(*this, "SPECIAL")
+ , m_jumper(*this, "JUMPER")
+ , m_acia(*this, "acia")
+ , m_host(*this, "host")
+ , m_aux(*this, "aux")
+ , m_ctc(*this, "ctc")
+ , m_crtc(*this, "crtc")
+ , m_screen(*this, "screen")
+ , m_palette(*this, "palette")
+ , m_speaker(*this, "speaker")
+ , m_vram(*this, "videoram")
+ , m_char_rom(*this, "chargen")
+ , m_latch(0)
+ , m_kbd_data(0)
+ , m_kbd_bus(0xff), m_kbd_p1(0xff), m_kbd_p2(0xff)
{ }
void qvt102(machine_config &config);
@@ -362,9 +369,14 @@ READ_LINE_MEMBER(qvt102_state::mcu_t0_r)
{
int state = 1;
- if (BIT(m_kbd_bus, 4) == 0) state = BIT(m_keys_special->read(), 0);
- if (BIT(m_kbd_bus, 5) == 0) state = BIT(m_keys_special->read(), 1);
- if (BIT(m_kbd_bus, 6) == 0) state = BIT(m_keys_special->read(), 2);
+ // The keyboard firmware also scans for a key at bit 3, and it appears
+ // to be a modifier key and is passed to the host in bit 3 of the
+ // second code, but the terminal firmware appears to ignore it. The
+ // schematics show no sign of a connection.
+
+ if (BIT(m_kbd_bus, 4) == 0) state &= BIT(m_keys_special->read(), 0);
+ if (BIT(m_kbd_bus, 5) == 0) state &= BIT(m_keys_special->read(), 1);
+ if (BIT(m_kbd_bus, 6) == 0) state &= BIT(m_keys_special->read(), 2);
return state;
}
@@ -376,9 +388,9 @@ READ_LINE_MEMBER(qvt102_state::mcu_t1_r)
for (int i = 0; i < 8; i++)
{
if (BIT(m_kbd_p1, i) == 0)
- state = BIT(m_keys_p1[(m_kbd_bus >> 4) & 7]->read(), i);
+ state &= BIT(m_keys_p1[(m_kbd_bus >> 4) & 7]->read(), i);
if (BIT(m_kbd_p2, i) == 0)
- state = BIT(m_keys_p2[(m_kbd_bus >> 4) & 7]->read(), i);
+ state &= BIT(m_keys_p2[(m_kbd_bus >> 4) & 7]->read(), i);
}
return state;
@@ -394,6 +406,23 @@ WRITE8_MEMBER(qvt102_state::mcu_p2_w)
m_kbd_p2 = data;
m_kbd_data = !BIT(data, 7);
+
+ // The keyboard serial data is read by the host using a bit banger in
+ // the IRQ handler and it is a tight loop requiring good
+ // synchronization between the host CPU and keyboard controller. A
+ // word starts with a raising of the line which (inverted) triggers
+ // the IRQ and the handler then waits and synchronizes to a falling
+ // edge. There is a delay of about 189us before this falling edge. The
+ // IRQ handler then reads the bits in a tight loop, reading the last
+ // after around 332 usec.
+ //
+ // The strategy here is to boost the interleave when the line is
+ // written high, and to hold this boost for 350us. This ensures that
+ // the boost lasts for the critical section of the IRQ handler.
+ //
+ if (m_kbd_data)
+ machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(350));
+
m_irqs->in_w<2>(m_kbd_data);
}
@@ -584,6 +613,9 @@ WRITE_LINE_MEMBER(qvt102_state::host_dcd_w)
void qvt102_state::machine_start()
{
+ m_kbd_data = 0;
+ m_kbd_bus = m_kbd_p1 = m_kbd_p2 = 0xff;
+
// register for save states
save_item(NAME(m_latch));
save_item(NAME(m_kbd_data));
@@ -595,8 +627,6 @@ void qvt102_state::machine_start()
void qvt102_state::machine_reset()
{
m_latch = 0;
- m_kbd_data = 0;
- m_kbd_bus = m_kbd_p1 = m_kbd_p2 = 0xff;
}
@@ -609,9 +639,6 @@ void qvt102_state::qvt102(machine_config &config)
M6800(config, m_maincpu, 16.6698_MHz_XTAL / 18);
m_maincpu->set_addrmap(AS_PROGRAM, &qvt102_state::mem_map);
- // needs a tight sync with the keyboard cpu
- config.set_perfect_quantum(m_maincpu);
-
INPUT_MERGER_ANY_HIGH(config, m_irqs).output_handler().set_inputline(m_maincpu, M6800_IRQ_LINE);
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); // 2x TC5514-APL + 3V battery