summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame
diff options
context:
space:
mode:
author 68bit <info@68bit.org>2019-11-09 13:33:08 +1100
committer 68bit <info@68bit.org>2019-11-09 13:58:49 +1100
commit97270022635f8e970ae3b478b5791cd185a88705 (patch)
tree19aa976f4a3f57fe767d31e6cd56902b8e4a6453 /src/mame
parent88f702b416ba9eb930e6c1e932124d5f24b1a24c (diff)
qvt102: key lines, boost interleave,
Key lines need to be logical 'anded' together, for the modifiers and the other keys - if one is pulled low the line is pulled low. Replace the use of set_perfect_quantum with a temporary boost_interleave to meet the timing synchronisation between the keyboard MPU and the main CPU. Move the resetting of the keyboard state from the reset method to the start method. The keyboad MPU pushes values for these on reset anyway so it was redundant.
Diffstat (limited to 'src/mame')
-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