mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
Fix Heath H19 keyboard (#2066)
* Fix Heath H19 keyboard * Fix how enable/disable of 25th line is handled. * Updated to use internal ROM in MM5740.
This commit is contained in:
parent
a0aa981a6e
commit
9533352c6b
@ -1236,6 +1236,18 @@ if (MACHINES["K056230"]~=null) then
|
||||
}
|
||||
end
|
||||
|
||||
---------------------------------------------------
|
||||
--
|
||||
--@src/devices/machine/mm5740.h,MACHINES["MM5740"] = true
|
||||
---------------------------------------------------
|
||||
|
||||
if (MACHINES["MM5740"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/machine/mm5740.cpp",
|
||||
MAME_DIR .. "src/devices/machine/mm5740.h",
|
||||
}
|
||||
end
|
||||
|
||||
---------------------------------------------------
|
||||
--
|
||||
--@src/devices/machine/kb3600.h,MACHINES["KB3600"] = true
|
||||
|
@ -471,6 +471,7 @@ MACHINES["MIOT6530"] = true
|
||||
MACHINES["MM58167"] = true
|
||||
MACHINES["MM58274C"] = true
|
||||
MACHINES["MM74C922"] = true
|
||||
MACHINES["MM5740"] = true
|
||||
MACHINES["MOS6526"] = true
|
||||
MACHINES["MOS6529"] = true
|
||||
MACHINES["MOS6551"] = true
|
||||
|
173
src/devices/machine/mm5740.cpp
Normal file
173
src/devices/machine/mm5740.cpp
Normal file
@ -0,0 +1,173 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:R. Belmont, Mark Garlanger
|
||||
/**********************************************************************
|
||||
|
||||
National Semiconductor MM5740 Keyboard Encoder emulation
|
||||
(Code originally based on kb3600.cpp)
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#include "mm5740.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
// devices
|
||||
const device_type MM5740 = &device_creator<mm5740_device>;
|
||||
|
||||
//**************************************************************************
|
||||
// DEVICE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
ROM_START( mm5740 )
|
||||
ROM_REGION(0x1c2, "internal", 0)
|
||||
ROM_LOAD("mm5740aac.ic1", 0x000, 0x1c2, CRC(aed404d3) SHA1(e7b9feba5f789f388d27820b5f3fa591d41b4ab1))
|
||||
ROM_END
|
||||
|
||||
//-------------------------------------------------
|
||||
// rom_region - device-specific ROM region
|
||||
//-------------------------------------------------
|
||||
|
||||
const tiny_rom_entry *mm5740_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME( mm5740 );
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// mm5740_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
mm5740_device::mm5740_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, MM5740, "MM5740", tag, owner, clock, "mm5740", __FILE__),
|
||||
m_read_x({*this, *this, *this, *this, *this, *this, *this, *this, *this}),
|
||||
m_read_shift(*this),
|
||||
m_read_control(*this),
|
||||
m_write_data_ready(*this),
|
||||
m_rom(*this, "internal")
|
||||
{
|
||||
std::fill_n(m_x_mask, 9, 0);
|
||||
}
|
||||
|
||||
uint32_t mm5740_device::calc_effective_clock_key_debounce(uint32_t capacitance)
|
||||
{
|
||||
// calculate key debounce based on capacitance in pF
|
||||
uint32_t key_debounce_msec = capacitance / 125;
|
||||
if (key_debounce_msec == 0)
|
||||
{
|
||||
key_debounce_msec = 1;
|
||||
}
|
||||
|
||||
return 1000 / key_debounce_msec;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void mm5740_device::device_start()
|
||||
{
|
||||
// resolve callbacks
|
||||
for(int i = 0; i < 9; i++)
|
||||
{
|
||||
m_read_x[i].resolve_safe(0x3ff);
|
||||
}
|
||||
m_read_shift.resolve_safe(0);
|
||||
m_read_control.resolve_safe(0);
|
||||
m_write_data_ready.resolve_safe();
|
||||
|
||||
// allocate timers
|
||||
m_scan_timer = timer_alloc();
|
||||
m_scan_timer->adjust(attotime::from_hz(clock()), 0, attotime::from_hz(clock()));
|
||||
|
||||
// state saving
|
||||
save_item(NAME(m_b));
|
||||
save_item(NAME(m_x_mask));
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific reset
|
||||
//-------------------------------------------------
|
||||
|
||||
void mm5740_device::device_reset()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_timer - handler timer events
|
||||
//-------------------------------------------------
|
||||
|
||||
void mm5740_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
int ako = 0;
|
||||
|
||||
for (int x = 0; x < 9; x++)
|
||||
{
|
||||
uint16_t data = m_read_x[x]() ^ 0x3ff;
|
||||
|
||||
if ((data ^ m_x_mask[x]) == 0)
|
||||
{
|
||||
// bail early if nothing has changed.
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int y = 0; y < 10; y++)
|
||||
{
|
||||
|
||||
if (BIT(data, y))
|
||||
{
|
||||
uint8_t *rom = m_rom->base();
|
||||
uint16_t offset = x*10 + y;
|
||||
// Common portion
|
||||
uint16_t common = (uint16_t) rom[offset];
|
||||
|
||||
offset += (((m_read_shift() ? 1: 0) + (m_read_control() ? 2: 0)) + 1) * 90;
|
||||
|
||||
// Unique portion based on shift/ctrl keys.
|
||||
uint8_t uniq = rom[offset];
|
||||
|
||||
uint16_t b = (((common & 0x10) << 4) | ((uniq & 0x0f) << 4) | (common & 0x0f)) ^ 0x1ff;
|
||||
|
||||
ako = 1;
|
||||
|
||||
if (!BIT(m_x_mask[x], y))
|
||||
{
|
||||
m_x_mask[x] |= (1 << y);
|
||||
if (m_b != b)
|
||||
{
|
||||
m_b = b;
|
||||
m_write_data_ready(ASSERT_LINE);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // key released, unmark it from the "down" info
|
||||
{
|
||||
m_x_mask[x] &= ~(1 << y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ako)
|
||||
{
|
||||
m_write_data_ready(CLEAR_LINE);
|
||||
m_b = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// b_r -
|
||||
//-------------------------------------------------
|
||||
|
||||
uint16_t mm5740_device::b_r()
|
||||
{
|
||||
m_write_data_ready(CLEAR_LINE);
|
||||
return m_b;
|
||||
}
|
||||
|
162
src/devices/machine/mm5740.h
Normal file
162
src/devices/machine/mm5740.h
Normal file
@ -0,0 +1,162 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders: R. Belmont
|
||||
/**********************************************************************
|
||||
|
||||
MM5740 Keyboard Encoder emulation
|
||||
|
||||
**********************************************************************
|
||||
_____ _____
|
||||
B3 1 |* \_/ | 40 B4
|
||||
Vll 2 | | 39 B9
|
||||
Clock 3 | | 38 B2
|
||||
X9 4 | | 37 B1
|
||||
X8 5 | | 36 B8
|
||||
X7 6 | | 35 B7
|
||||
X6 7 | | 34 B6
|
||||
X5 8 | | 33 B5
|
||||
X4 9 | | 32 Vss
|
||||
X3 10 | MM5740 | 31 Y9
|
||||
X2 11 | | 30 Y8
|
||||
X1 12 | | 29 Y7
|
||||
Data Strobe Output 13 | | 28 Y6
|
||||
Data Strobe Control 14 | | 27 Y5
|
||||
Output Enable 15 | | 26 Y4
|
||||
Repeat 16 | | 25 Y3
|
||||
Key Bounce Mask 17 | | 24 Y2
|
||||
Vgg 18 | | 23 Y1
|
||||
Control 19 | | 22 Y0
|
||||
Shift Lock I/O 20 |_____________| 21 Shift
|
||||
|
||||
Name Pin No. Function
|
||||
----------------------------------------------------------------------
|
||||
|
||||
X1-X9 4-12 Output - Drives the key switch matrix.
|
||||
|
||||
Y1-Y10 22-31 Inputs - connect to the X drive lines with
|
||||
the key switch matrix.
|
||||
|
||||
B1-B9 1,33-40 Tri-stated data outputs.
|
||||
|
||||
Data Strobe Output 13 Output to indicate key pressed.
|
||||
|
||||
Data Strobe Control 14 Input to control data strobe output pulse width.
|
||||
|
||||
Output Enable 15 Input to control the chip's TRI-STATE output
|
||||
|
||||
Repeat 16 Each cycle of this signal will issue
|
||||
a new data strobe for the pressed key.
|
||||
|
||||
Key-Bounce Mask 17 Use capacitor on this chip to provide
|
||||
key debouncing
|
||||
|
||||
Shift 21 Shift key pressed
|
||||
|
||||
Control 19 Control key pressed
|
||||
|
||||
Shift Lock I/O 20 Togglable input to signify shift (NOT caps) lock.
|
||||
|
||||
Clock 3 A TTL compatible clock signal
|
||||
|
||||
Vss 32 +5.0V
|
||||
|
||||
Vll 2 Ground
|
||||
|
||||
Vgg 18 -12V
|
||||
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
/* TODO:
|
||||
Support Key-bounce mask
|
||||
Support Repeat function
|
||||
Support shift lock
|
||||
Support additional internal ROMs
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef MAME_DEVICE_MACHINE_MM5740_H
|
||||
#define MAME_DEVICE_MACHINE_MM5740_H
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// INTERFACE CONFIGURATION MACROS
|
||||
//**************************************************************************
|
||||
|
||||
#define MCFG_MM5740_MATRIX_X1(_cb) devcb = &mm5740_device::set_x_cb(*device, DEVCB_##_cb, 0);
|
||||
#define MCFG_MM5740_MATRIX_X2(_cb) devcb = &mm5740_device::set_x_cb(*device, DEVCB_##_cb, 1);
|
||||
#define MCFG_MM5740_MATRIX_X3(_cb) devcb = &mm5740_device::set_x_cb(*device, DEVCB_##_cb, 2);
|
||||
#define MCFG_MM5740_MATRIX_X4(_cb) devcb = &mm5740_device::set_x_cb(*device, DEVCB_##_cb, 3);
|
||||
#define MCFG_MM5740_MATRIX_X5(_cb) devcb = &mm5740_device::set_x_cb(*device, DEVCB_##_cb, 4);
|
||||
#define MCFG_MM5740_MATRIX_X6(_cb) devcb = &mm5740_device::set_x_cb(*device, DEVCB_##_cb, 5);
|
||||
#define MCFG_MM5740_MATRIX_X7(_cb) devcb = &mm5740_device::set_x_cb(*device, DEVCB_##_cb, 6);
|
||||
#define MCFG_MM5740_MATRIX_X8(_cb) devcb = &mm5740_device::set_x_cb(*device, DEVCB_##_cb, 7);
|
||||
#define MCFG_MM5740_MATRIX_X9(_cb) devcb = &mm5740_device::set_x_cb(*device, DEVCB_##_cb, 8);
|
||||
#define MCFG_MM5740_SHIFT_CB(_cb) devcb = &mm5740_device::set_shift_cb(*device, DEVCB_##_cb);
|
||||
#define MCFG_MM5740_CONTROL_CB(_cb) devcb = &mm5740_device::set_control_cb(*device, DEVCB_##_cb);
|
||||
#define MCFG_MM5740_DATA_READY_CB(_cb) devcb = &mm5740_device::set_data_ready_cb(*device, DEVCB_##_cb);
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> mm5740_device
|
||||
|
||||
class mm5740_device : public device_t
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
mm5740_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
// public interface
|
||||
uint16_t b_r();
|
||||
|
||||
template<typename Object> static devcb_base &set_x_cb(device_t &device, Object &&object, uint8_t i)
|
||||
{
|
||||
assert(i<9); return downcast<mm5740_device &>(device).m_read_x[i].set_callback(std::forward<Object>(object));
|
||||
}
|
||||
template<typename Object> static devcb_base &set_shift_cb(device_t &device, Object &&object)
|
||||
{
|
||||
return downcast<mm5740_device &>(device).m_read_shift.set_callback(std::forward<Object>(object));
|
||||
}
|
||||
template<typename Object> static devcb_base &set_control_cb(device_t &device, Object &&object)
|
||||
{
|
||||
return downcast<mm5740_device &>(device).m_read_control.set_callback(std::forward<Object>(object));
|
||||
}
|
||||
template<typename Object> static devcb_base &set_data_ready_cb(device_t &device, Object &&object)
|
||||
{
|
||||
return downcast<mm5740_device &>(device).m_write_data_ready.set_callback(std::forward<Object>(object));
|
||||
}
|
||||
static uint32_t calc_effective_clock_key_debounce(uint32_t capacitance);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
|
||||
virtual const tiny_rom_entry *device_rom_region() const override;
|
||||
|
||||
private:
|
||||
devcb_read16 m_read_x[9];
|
||||
devcb_read_line m_read_shift, m_read_control;
|
||||
devcb_write_line m_write_data_ready;
|
||||
|
||||
required_memory_region m_rom; // Internal ROM
|
||||
|
||||
int m_b; // output buffer
|
||||
|
||||
int m_x_mask[9]; // mask of what keys are down
|
||||
|
||||
// timers
|
||||
emu_timer *m_scan_timer; // keyboard scan timer
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type MM5740;
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -2,35 +2,25 @@
|
||||
// copyright-holders:Robbbert, Mark Garlanger
|
||||
/***************************************************************************
|
||||
|
||||
Heathkit H19
|
||||
Heathkit H19
|
||||
|
||||
12/05/2009 Skeleton driver.
|
||||
A smart terminal designed and manufactured by Heath Company.
|
||||
|
||||
The keyboard consists of a 9x10 matrix connected to a MM5740N
|
||||
mask-programmed keyboard controller. The output of this passes
|
||||
through a rom. The MM5740N may be custom-made, in which case it
|
||||
will need to be procured and tested. There is a "default" array;
|
||||
perhaps this is used. The presence of the rom would seem to
|
||||
indicate that the default is being used. We won't know, of
|
||||
course, until the device is emulated.
|
||||
The keyboard consists of a 9x10 matrix connected to a MM5740AAC/N
|
||||
mask-programmed keyboard controller. The output of this passes
|
||||
through a rom.
|
||||
|
||||
Keyboard input can also come from the serial port (a 8250).
|
||||
Either device will signal an interrupt to the CPU when a key
|
||||
is pressed/sent.
|
||||
Input can also come from the serial port (a 8250).
|
||||
Either device will signal an interrupt to the CPU when a key
|
||||
is pressed/data is received.
|
||||
|
||||
For the moment, the "ascii keyboard" device is used for the keyboard.
|
||||
TODO:
|
||||
- Finish connecting up the 8250
|
||||
- enable 8520 interrupts
|
||||
- speed up emulation
|
||||
|
||||
TODO:
|
||||
- Create device or HLE of MM5740N keyboard controller
|
||||
- Make sure correct mask programming is used for it
|
||||
- Use keyboard rom
|
||||
- Finish connecting up the 8250
|
||||
- Verify beep lengths
|
||||
- Verify ram size
|
||||
- When the internal keyboard works, get rid of the "ascii_keyboard".
|
||||
|
||||
Bios 1 (super19) has the videoram at D800. This is not emulated.
|
||||
However, a keyclick can be heard, to assure you it does in fact work.
|
||||
super19 version has the videoram at D800. This is not emulated.
|
||||
However, a keyclick can be heard, to assure you it does in fact work.
|
||||
|
||||
****************************************************************************/
|
||||
/***************************************************************************
|
||||
@ -48,17 +38,16 @@
|
||||
|
||||
Only address lines A5, A6, A7 are used by the U442 three-to-eight line decoder
|
||||
|
||||
1. Keyboard encoder 0x80
|
||||
2. Keyboard status 0xA0
|
||||
3. CRT controller 0x60
|
||||
4. Power-up configuration (primary) 0x00
|
||||
5. Power-up configuration (secondary) 0x20
|
||||
6. ACE (communications) 0x40
|
||||
7. Bell enable 0xE0
|
||||
8. Key click enable 0xC0
|
||||
|
||||
Decoder U442 is enabled only during an I/O read or write operation to elimnate the
|
||||
possibility of false decoding on a refresh address coming from the Z80.
|
||||
Address Description
|
||||
----------------------------------------------------
|
||||
0x00 Power-up configuration (primary - SW401)
|
||||
0x20 Power-up configuration (secondary - SW402)
|
||||
0x40 ACE (communications)
|
||||
0x60 CRT controller
|
||||
0x80 Keyboard encoder
|
||||
0xA0 Keyboard status
|
||||
0xC0 Key click enable
|
||||
0xE0 Bell enable
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
@ -67,21 +56,29 @@
|
||||
#include "video/mc6845.h"
|
||||
#include "sound/beep.h"
|
||||
#include "machine/ins8250.h"
|
||||
#include "machine/keyboard.h"
|
||||
#include "machine/mm5740.h"
|
||||
|
||||
// Standard H19 used a 2.048 MHz clock
|
||||
#define H19_CLOCK (XTAL_12_288MHz / 6)
|
||||
#define MC6845_CLOCK (XTAL_12_288MHz /8)
|
||||
#define INS8250_CLOCK (XTAL_12_288MHz /4)
|
||||
// Capacitor value in pF
|
||||
#define H19_KEY_DEBOUNCE_CAPACITOR 5000
|
||||
#define MM5740_CLOCK (mm5740_device::calc_effective_clock_key_debounce(H19_KEY_DEBOUNCE_CAPACITOR))
|
||||
|
||||
// Beep Frequency is 1 KHz
|
||||
#define H19_BEEP_FRQ (H19_CLOCK / 2048)
|
||||
|
||||
#define KBDC_TAG "mm5740"
|
||||
|
||||
|
||||
class h19_state : public driver_device
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
TIMER_BEEP_OFF
|
||||
TIMER_KEY_CLICK_OFF,
|
||||
TIMER_BELL_OFF
|
||||
};
|
||||
|
||||
h19_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
@ -93,13 +90,20 @@ public:
|
||||
, m_beep(*this, "beeper")
|
||||
, m_p_videoram(*this, "videoram")
|
||||
, m_p_chargen(*this, "chargen")
|
||||
, m_mm5740(*this, KBDC_TAG)
|
||||
, m_kbdrom(*this, "keyboard")
|
||||
, m_kbspecial(*this, "MODIFIERS")
|
||||
{
|
||||
}
|
||||
|
||||
DECLARE_READ8_MEMBER(h19_80_r);
|
||||
DECLARE_READ8_MEMBER(h19_a0_r);
|
||||
DECLARE_WRITE8_MEMBER(h19_c0_w);
|
||||
DECLARE_WRITE8_MEMBER(h19_kbd_put);
|
||||
DECLARE_WRITE8_MEMBER(h19_keyclick_w);
|
||||
DECLARE_WRITE8_MEMBER(h19_bell_w);
|
||||
DECLARE_READ8_MEMBER(kbd_key_r);
|
||||
DECLARE_READ8_MEMBER(kbd_flags_r);
|
||||
DECLARE_READ_LINE_MEMBER(mm5740_shift_r);
|
||||
DECLARE_READ_LINE_MEMBER(mm5740_control_r);
|
||||
DECLARE_WRITE_LINE_MEMBER(mm5740_data_ready_w);
|
||||
|
||||
MC6845_UPDATE_ROW(crtc_update_row);
|
||||
|
||||
private:
|
||||
@ -113,182 +117,187 @@ private:
|
||||
required_device<beep_device> m_beep;
|
||||
required_shared_ptr<uint8_t> m_p_videoram;
|
||||
required_region_ptr<u8> m_p_chargen;
|
||||
};
|
||||
required_device<mm5740_device> m_mm5740;
|
||||
required_memory_region m_kbdrom;
|
||||
required_ioport m_kbspecial;
|
||||
|
||||
uint8_t m_transchar;
|
||||
bool m_strobe;
|
||||
uint16_t translate_mm5740_b(uint16_t b);
|
||||
bool m_keyclickactive;
|
||||
bool m_bellactive;
|
||||
};
|
||||
|
||||
void h19_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case TIMER_BEEP_OFF:
|
||||
m_beep->set_state(0);
|
||||
case TIMER_KEY_CLICK_OFF:
|
||||
m_keyclickactive = false;
|
||||
break;
|
||||
case TIMER_BELL_OFF:
|
||||
m_bellactive = false;
|
||||
break;
|
||||
default:
|
||||
assert_always(false, "Unknown id in h19_state::device_timer");
|
||||
}
|
||||
|
||||
if (!m_keyclickactive && !m_bellactive)
|
||||
{
|
||||
m_beep->set_state(0);
|
||||
}
|
||||
}
|
||||
|
||||
READ8_MEMBER( h19_state::h19_80_r )
|
||||
{
|
||||
// keyboard data
|
||||
uint8_t ret = m_term_data;
|
||||
m_term_data = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
READ8_MEMBER( h19_state::h19_a0_r )
|
||||
{
|
||||
// keyboard status
|
||||
m_maincpu->set_input_line(0, CLEAR_LINE);
|
||||
return 0x7f; // says that a key is ready and no modifier keys are pressed
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( h19_state::h19_c0_w )
|
||||
{
|
||||
/* Beeper control - a 96L02 contains 2 oneshots, one for bell and one for keyclick.
|
||||
|
||||
offset 00-1F = keyclick
|
||||
offset 20-3F = terminal bell */
|
||||
|
||||
uint8_t length = (offset & 0x20) ? 200 : 6;
|
||||
m_beep->set_state(1);
|
||||
timer_set(attotime::from_msec(length), TIMER_BEEP_OFF);
|
||||
}
|
||||
|
||||
static ADDRESS_MAP_START(h19_mem, AS_PROGRAM, 8, h19_state)
|
||||
ADDRESS_MAP_UNMAP_HIGH
|
||||
AM_RANGE(0x0000, 0x1fff) AM_ROM
|
||||
AM_RANGE(0x2000, 0xf7ff) AM_RAM
|
||||
AM_RANGE(0x4000, 0x4100) AM_RAM
|
||||
AM_RANGE(0xf800, 0xffff) AM_RAM AM_SHARE("videoram")
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START( h19_io, AS_IO, 8, h19_state)
|
||||
ADDRESS_MAP_UNMAP_HIGH
|
||||
ADDRESS_MAP_GLOBAL_MASK(0xff)
|
||||
AM_RANGE(0x00, 0x1F) AM_READ_PORT("S401")
|
||||
AM_RANGE(0x20, 0x3F) AM_READ_PORT("S402")
|
||||
AM_RANGE(0x00, 0x1F) AM_READ_PORT("SW401")
|
||||
AM_RANGE(0x20, 0x3F) AM_READ_PORT("SW402")
|
||||
AM_RANGE(0x40, 0x47) AM_MIRROR(0x18) AM_DEVREADWRITE("ins8250", ins8250_device, ins8250_r, ins8250_w )
|
||||
AM_RANGE(0x60, 0x60) AM_DEVWRITE("crtc", mc6845_device, address_w)
|
||||
AM_RANGE(0x61, 0x61) AM_DEVREADWRITE("crtc", mc6845_device, register_r, register_w)
|
||||
AM_RANGE(0x80, 0x9F) AM_READ(h19_80_r)
|
||||
AM_RANGE(0xA0, 0xBF) AM_READ(h19_a0_r)
|
||||
AM_RANGE(0xC0, 0xFF) AM_WRITE(h19_c0_w)
|
||||
AM_RANGE(0x80, 0x9F) AM_READ(kbd_key_r)
|
||||
AM_RANGE(0xA0, 0xBF) AM_READ(kbd_flags_r)
|
||||
AM_RANGE(0xC0, 0xDF) AM_WRITE(h19_keyclick_w)
|
||||
AM_RANGE(0xE0, 0xFF) AM_WRITE(h19_bell_w)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
/* Input ports */
|
||||
static INPUT_PORTS_START( h19 )
|
||||
// Port codes are omitted to prevent collision with terminal keys
|
||||
|
||||
PORT_START("MODIFIERS")
|
||||
// bit 0 connects to B8 of MM5740 - purpose unknown
|
||||
// bit 0 connects to B8 of MM5740 - low if either shift key is
|
||||
// bit 7 is low if a key is pressed
|
||||
PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CapsLock")
|
||||
PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Break")
|
||||
PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("OffLine")
|
||||
PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CTRL")
|
||||
PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LeftShift")
|
||||
PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Repeat")
|
||||
PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Reset")
|
||||
PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RightShift")
|
||||
PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CapsLock") PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE
|
||||
PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Break") PORT_CODE(KEYCODE_PAUSE)
|
||||
PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("OffLine") PORT_CODE(KEYCODE_F12) PORT_TOGGLE
|
||||
PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL))
|
||||
PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LeftShift") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
|
||||
PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Repeat") PORT_CODE(KEYCODE_LALT)
|
||||
PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RightShift") PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
|
||||
PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Reset") PORT_CODE(KEYCODE_F10)
|
||||
|
||||
PORT_START("X1")
|
||||
PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("/")
|
||||
PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X2")
|
||||
PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0-pad")
|
||||
PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Dot-pad")
|
||||
PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Enter-pad")
|
||||
PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("/") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?')
|
||||
PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Unused")
|
||||
PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Unused")
|
||||
PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Unused")
|
||||
PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("k_X2")
|
||||
PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Unused")
|
||||
PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0-pad") PORT_CODE(KEYCODE_0_PAD) PORT_CHAR('0')
|
||||
PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Dot-pad") PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR('.')
|
||||
PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Enter-pad") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(13)
|
||||
PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Unused")
|
||||
|
||||
PORT_START("X2")
|
||||
PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(";")
|
||||
PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("\'")
|
||||
PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("{")
|
||||
PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Return")
|
||||
PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1-pad")
|
||||
PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2-pad")
|
||||
PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3-pad")
|
||||
PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(";") PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('.')
|
||||
PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("\'") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('\"')
|
||||
PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("{") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('{') PORT_CHAR('}')
|
||||
PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)
|
||||
PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Unused")
|
||||
PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Unused")
|
||||
PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1-pad") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR('1')
|
||||
PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2-pad") PORT_CODE(KEYCODE_2_PAD) PORT_CHAR('2')
|
||||
PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3-pad") PORT_CODE(KEYCODE_3_PAD) PORT_CHAR('3')
|
||||
PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Unused")
|
||||
|
||||
PORT_START("X3")
|
||||
PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P")
|
||||
PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("[")
|
||||
PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("\\")
|
||||
PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LF")
|
||||
PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("DEL")
|
||||
PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4-pad")
|
||||
PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5-pad")
|
||||
PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6-pad")
|
||||
PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P')
|
||||
PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("[") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR(']')
|
||||
PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("\\") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|')
|
||||
PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LF") PORT_CODE(KEYCODE_RWIN)
|
||||
PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("DEL") PORT_CODE(KEYCODE_DEL) PORT_CHAR(UCHAR_MAMEKEY(DEL))
|
||||
PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Unused")
|
||||
PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4-pad") PORT_CODE(KEYCODE_4_PAD) PORT_CHAR('4')
|
||||
PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5-pad") PORT_CODE(KEYCODE_5_PAD) PORT_CHAR('5')
|
||||
PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6-pad") PORT_CODE(KEYCODE_6_PAD) PORT_CHAR('6')
|
||||
PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Unused")
|
||||
|
||||
PORT_START("X4")
|
||||
PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0")
|
||||
PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("-")
|
||||
PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("=")
|
||||
PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("AccentAcute")
|
||||
PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("BS")
|
||||
PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X1")
|
||||
PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7-pad")
|
||||
PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8-pad")
|
||||
PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9-pad")
|
||||
PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')')
|
||||
PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("-") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_')
|
||||
PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("=") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+')
|
||||
PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("AccentAcute") PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~')
|
||||
PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("BS") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8)
|
||||
PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("k_X1")
|
||||
PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7-pad") PORT_CODE(KEYCODE_7_PAD) PORT_CHAR('7')
|
||||
PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8-pad") PORT_CODE(KEYCODE_8_PAD) PORT_CHAR('8')
|
||||
PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9-pad") PORT_CODE(KEYCODE_9_PAD) PORT_CHAR('9')
|
||||
PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Unused")
|
||||
|
||||
PORT_START("X5")
|
||||
PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F1")
|
||||
PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F2")
|
||||
PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F3")
|
||||
PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F4")
|
||||
PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F5")
|
||||
PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Erase")
|
||||
PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Blue")
|
||||
PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Red")
|
||||
PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Gray")
|
||||
PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F1") PORT_CODE(KEYCODE_F1)
|
||||
PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F2") PORT_CODE(KEYCODE_F2)
|
||||
PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F3") PORT_CODE(KEYCODE_F3)
|
||||
PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F4") PORT_CODE(KEYCODE_F4)
|
||||
PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F5") PORT_CODE(KEYCODE_F5)
|
||||
PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Erase") PORT_CODE(KEYCODE_F6)
|
||||
PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Blue") PORT_CODE(KEYCODE_F7)
|
||||
PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Red") PORT_CODE(KEYCODE_F8)
|
||||
PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Gray") PORT_CODE(KEYCODE_F9)
|
||||
PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Unused")
|
||||
|
||||
PORT_START("X6")
|
||||
PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Space")
|
||||
PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z")
|
||||
PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X")
|
||||
PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C")
|
||||
PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V")
|
||||
PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B")
|
||||
PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N")
|
||||
PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M")
|
||||
PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(",")
|
||||
PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(".")
|
||||
PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z')
|
||||
PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X')
|
||||
PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C')
|
||||
PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V')
|
||||
PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B')
|
||||
PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N')
|
||||
PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M')
|
||||
PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(",") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<')
|
||||
PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(".") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>')
|
||||
PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')
|
||||
|
||||
PORT_START("X7")
|
||||
PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Scroll")
|
||||
PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A")
|
||||
PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S")
|
||||
PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D")
|
||||
PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F")
|
||||
PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G")
|
||||
PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H")
|
||||
PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J")
|
||||
PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K")
|
||||
PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L")
|
||||
PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A')
|
||||
PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S')
|
||||
PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D')
|
||||
PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F')
|
||||
PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G')
|
||||
PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H')
|
||||
PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J')
|
||||
PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K')
|
||||
PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L')
|
||||
PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Scroll") PORT_CODE(KEYCODE_LWIN)
|
||||
|
||||
|
||||
PORT_START("X8")
|
||||
PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Tab")
|
||||
PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q")
|
||||
PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W")
|
||||
PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E")
|
||||
PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R")
|
||||
PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T")
|
||||
PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y")
|
||||
PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U")
|
||||
PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I")
|
||||
PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O")
|
||||
PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q')
|
||||
PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W')
|
||||
PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E')
|
||||
PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R')
|
||||
PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T')
|
||||
PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y')
|
||||
PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U')
|
||||
PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I')
|
||||
PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O')
|
||||
PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Tab") PORT_CODE(KEYCODE_TAB) PORT_CHAR(9)
|
||||
|
||||
|
||||
PORT_START("X9")
|
||||
PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Esc")
|
||||
PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1")
|
||||
PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2")
|
||||
PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3")
|
||||
PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4")
|
||||
PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5")
|
||||
PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6")
|
||||
PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7")
|
||||
PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8")
|
||||
PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9")
|
||||
PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
|
||||
PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@')
|
||||
PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#')
|
||||
PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')
|
||||
PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%')
|
||||
PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^')
|
||||
PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&')
|
||||
PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*')
|
||||
PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(')
|
||||
PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Esc") PORT_CODE(KEYCODE_ESC) PORT_CHAR(27)
|
||||
|
||||
PORT_START("S401")
|
||||
PORT_DIPNAME( 0x0f, 0x03, "Baud Rate")
|
||||
PORT_START("SW401")
|
||||
PORT_DIPNAME( 0x0f, 0x0c, "Baud Rate")
|
||||
PORT_DIPSETTING( 0x01, "110")
|
||||
PORT_DIPSETTING( 0x02, "150")
|
||||
PORT_DIPSETTING( 0x03, "300")
|
||||
@ -309,21 +318,21 @@ static INPUT_PORTS_START( h19 )
|
||||
PORT_DIPNAME( 0x40, 0x00, "Parity Type")
|
||||
PORT_DIPSETTING( 0x00, DEF_STR(Normal))
|
||||
PORT_DIPSETTING( 0x40, "Stick")
|
||||
PORT_DIPNAME( 0x80, 0x00, "Duplex")
|
||||
PORT_DIPNAME( 0x80, 0x80, "Duplex")
|
||||
PORT_DIPSETTING( 0x00, "Half")
|
||||
PORT_DIPSETTING( 0x80, "Full")
|
||||
|
||||
PORT_START("S402") // stored at 40C8
|
||||
PORT_START("SW402") // stored at 40C8
|
||||
PORT_DIPNAME( 0x01, 0x00, "Cursor")
|
||||
PORT_DIPSETTING( 0x00, "Underline")
|
||||
PORT_DIPSETTING( 0x01, "Block")
|
||||
PORT_DIPNAME( 0x02, 0x00, "Keyclick")
|
||||
PORT_DIPSETTING( 0x02, DEF_STR(No))
|
||||
PORT_DIPSETTING( 0x00, DEF_STR(Yes))
|
||||
PORT_DIPNAME( 0x04, 0x04, "Wrap at EOL")
|
||||
PORT_DIPNAME( 0x04, 0x00, "Wrap at EOL")
|
||||
PORT_DIPSETTING( 0x00, DEF_STR(No))
|
||||
PORT_DIPSETTING( 0x04, DEF_STR(Yes))
|
||||
PORT_DIPNAME( 0x08, 0x08, "Auto LF on CR")
|
||||
PORT_DIPNAME( 0x08, 0x00, "Auto LF on CR")
|
||||
PORT_DIPSETTING( 0x00, DEF_STR(No))
|
||||
PORT_DIPSETTING( 0x08, DEF_STR(Yes))
|
||||
PORT_DIPNAME( 0x10, 0x00, "Auto CR on LF")
|
||||
@ -340,11 +349,120 @@ static INPUT_PORTS_START( h19 )
|
||||
PORT_DIPSETTING( 0x80, "60Hz")
|
||||
INPUT_PORTS_END
|
||||
|
||||
// Keyboard encoder masks
|
||||
#define KB_ENCODER_KEY_VALUE_MASK 0x7F
|
||||
#define KB_ENCODER_CONTROL_KEY_MASK 0x80
|
||||
|
||||
// Keyboard flag masks
|
||||
#define KB_STATUS_SHIFT_KEYS_MASK 0x01
|
||||
#define KB_STATUS_CAPS_LOCK_MASK 0x02
|
||||
#define KB_STATUS_BREAK_KEY_MASK 0x04
|
||||
#define KB_STATUS_ONLINE_KEY_MASK 0x08
|
||||
#define KB_STATUS_REPEAT_KEYS_MASK 0x40
|
||||
#define KB_STATUS_KEYBOARD_STROBE_MASK 0x80
|
||||
|
||||
|
||||
void h19_state::machine_reset()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER( h19_state::h19_keyclick_w )
|
||||
{
|
||||
/* Keyclick - 6 mSec */
|
||||
|
||||
m_beep->set_state(1);
|
||||
m_keyclickactive = true;
|
||||
timer_set(attotime::from_msec(6), TIMER_KEY_CLICK_OFF);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( h19_state::h19_bell_w )
|
||||
{
|
||||
/* Bell (^G) - 200 mSec */
|
||||
|
||||
m_beep->set_state(1);
|
||||
m_bellactive = true;
|
||||
timer_set(attotime::from_msec(200), TIMER_BELL_OFF);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
MM5740 B Mapping to the ROM address
|
||||
|
||||
B1 -> A0 A10 = 0
|
||||
B2 -> A1 A9 = 0
|
||||
B3 -> A2 A8 = B8
|
||||
B4 -> A3 A7 = B7
|
||||
B5 -> A4 A6 = B9
|
||||
B6 -> A5 A5 = B6
|
||||
B7 -> A7 A4 = B5
|
||||
B8 -> A8 A3 = B4
|
||||
B9 -> A6 A2 = B3
|
||||
ground -> A9 A1 = B2
|
||||
ground -> A10 A0 = B1
|
||||
|
||||
****************************************************************************/
|
||||
uint16_t h19_state::translate_mm5740_b(uint16_t b)
|
||||
{
|
||||
return ((b & 0x100) >> 2) | ((b & 0x0c0) << 1) | (b & 0x03f);
|
||||
}
|
||||
|
||||
READ8_MEMBER(h19_state::kbd_key_r)
|
||||
{
|
||||
m_maincpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE);
|
||||
m_strobe = false;
|
||||
|
||||
// high bit is for control key pressed, this is handled in the ROM, no processing needed.
|
||||
return m_transchar;
|
||||
}
|
||||
|
||||
READ8_MEMBER(h19_state::kbd_flags_r)
|
||||
{
|
||||
uint8_t rv = 0;
|
||||
uint16_t modifiers = m_kbspecial->read();
|
||||
|
||||
rv = modifiers & 0xff;
|
||||
|
||||
// check both shifts
|
||||
if (((modifiers & 0x020) == 0) || ((modifiers & 0x100) == 0))
|
||||
{
|
||||
rv |= 0x1;
|
||||
}
|
||||
|
||||
// invert offline switch
|
||||
rv ^= KB_STATUS_ONLINE_KEY_MASK;
|
||||
|
||||
if (!m_strobe)
|
||||
{
|
||||
rv |= KB_STATUS_KEYBOARD_STROBE_MASK;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
READ_LINE_MEMBER(h19_state::mm5740_shift_r)
|
||||
{
|
||||
return ((m_kbspecial->read() ^ 0x120) & 0x120) ? ASSERT_LINE : CLEAR_LINE;
|
||||
}
|
||||
|
||||
READ_LINE_MEMBER(h19_state::mm5740_control_r)
|
||||
{
|
||||
return ((m_kbspecial->read() ^ 0x10) & 0x10) ? ASSERT_LINE: CLEAR_LINE;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(h19_state::mm5740_data_ready_w)
|
||||
{
|
||||
if (state == ASSERT_LINE)
|
||||
{
|
||||
uint8_t *decode = m_kbdrom->base();
|
||||
|
||||
m_transchar = decode[translate_mm5740_b(m_mm5740->b_r())];
|
||||
m_strobe = true;
|
||||
m_maincpu->set_input_line(INPUT_LINE_IRQ0, ASSERT_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MC6845_UPDATE_ROW( h19_state::crtc_update_row )
|
||||
{
|
||||
const rgb_t *palette = m_palette->palette()->entry_list_raw();
|
||||
@ -399,40 +517,45 @@ static GFXDECODE_START( h19 )
|
||||
GFXDECODE_ENTRY( "chargen", 0x0000, h19_charlayout, 0, 1 )
|
||||
GFXDECODE_END
|
||||
|
||||
WRITE8_MEMBER( h19_state::h19_kbd_put )
|
||||
{
|
||||
m_term_data = data;
|
||||
m_maincpu->set_input_line(0, HOLD_LINE);
|
||||
}
|
||||
|
||||
static MACHINE_CONFIG_START( h19, h19_state )
|
||||
/* basic machine hardware */
|
||||
MCFG_CPU_ADD("maincpu",Z80, H19_CLOCK) // From schematics
|
||||
MCFG_CPU_PROGRAM_MAP(h19_mem)
|
||||
MCFG_CPU_IO_MAP(h19_io)
|
||||
//MCFG_DEVICE_PERIODIC_INT_DRIVER(h19_state, irq0_line_hold, 50) // for testing, causes a keyboard scan
|
||||
|
||||
/* video hardware */
|
||||
MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::green())
|
||||
MCFG_SCREEN_REFRESH_RATE(60)
|
||||
MCFG_SCREEN_REFRESH_RATE(60) // TODO- this is adjustable by dipswitch.
|
||||
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
|
||||
MCFG_SCREEN_UPDATE_DEVICE("crtc", mc6845_device, screen_update)
|
||||
|
||||
MCFG_SCREEN_SIZE(640, 250)
|
||||
MCFG_SCREEN_VISIBLE_AREA(0, 640 - 1, 0, 250 - 1)
|
||||
MCFG_GFXDECODE_ADD("gfxdecode", "palette", h19)
|
||||
MCFG_PALETTE_ADD_MONOCHROME("palette")
|
||||
|
||||
MCFG_MC6845_ADD("crtc", MC6845, "screen", XTAL_12_288MHz / 8) // clk taken from schematics
|
||||
MCFG_MC6845_SHOW_BORDER_AREA(false)
|
||||
MCFG_MC6845_CHAR_WIDTH(8) /*?*/
|
||||
MCFG_MC6845_ADD("crtc", MC6845, "screen", MC6845_CLOCK)
|
||||
MCFG_MC6845_SHOW_BORDER_AREA(true)
|
||||
MCFG_MC6845_CHAR_WIDTH(8)
|
||||
MCFG_MC6845_UPDATE_ROW_CB(h19_state, crtc_update_row)
|
||||
MCFG_MC6845_OUT_VSYNC_CB(INPUTLINE("maincpu", INPUT_LINE_NMI)) // frame pulse
|
||||
|
||||
MCFG_DEVICE_ADD("ins8250", INS8250, XTAL_12_288MHz / 4) // 3.072mhz clock which gets divided down for the various baud rates
|
||||
MCFG_DEVICE_ADD("ins8250", INS8250, INS8250_CLOCK)
|
||||
MCFG_INS8250_OUT_INT_CB(INPUTLINE("maincpu", 0)) // interrupt
|
||||
|
||||
MCFG_DEVICE_ADD("keyboard", GENERIC_KEYBOARD, 0)
|
||||
MCFG_GENERIC_KEYBOARD_CB(WRITE8(h19_state, h19_kbd_put))
|
||||
MCFG_DEVICE_ADD(KBDC_TAG, MM5740, MM5740_CLOCK)
|
||||
MCFG_MM5740_MATRIX_X1(IOPORT("X1"))
|
||||
MCFG_MM5740_MATRIX_X2(IOPORT("X2"))
|
||||
MCFG_MM5740_MATRIX_X3(IOPORT("X3"))
|
||||
MCFG_MM5740_MATRIX_X4(IOPORT("X4"))
|
||||
MCFG_MM5740_MATRIX_X5(IOPORT("X5"))
|
||||
MCFG_MM5740_MATRIX_X6(IOPORT("X6"))
|
||||
MCFG_MM5740_MATRIX_X7(IOPORT("X7"))
|
||||
MCFG_MM5740_MATRIX_X8(IOPORT("X8"))
|
||||
MCFG_MM5740_MATRIX_X9(IOPORT("X9"))
|
||||
MCFG_MM5740_SHIFT_CB(READLINE(h19_state, mm5740_shift_r))
|
||||
MCFG_MM5740_CONTROL_CB(READLINE(h19_state, mm5740_control_r))
|
||||
MCFG_MM5740_DATA_READY_CB(WRITELINE(h19_state, mm5740_data_ready_w))
|
||||
|
||||
/* sound hardware */
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
@ -483,7 +606,7 @@ ROM_START( watz19 )
|
||||
ROM_END
|
||||
|
||||
/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */
|
||||
COMP( 1979, h19, 0, 0, h19, h19, driver_device, 0, "Heath Inc", "Heathkit H-19", MACHINE_NOT_WORKING )
|
||||
COMP( 1979, h19, 0, 0, h19, h19, driver_device, 0, "Heath Inc", "Heathkit H-19", 0 )
|
||||
/* TODO - verify the years for these third-party replacement ROMs. */
|
||||
COMP( 1982, super19, h19, 0, h19, h19, driver_device, 0, "Heath Inc", "Heathkit H-19 w/ Super-19 ROM", MACHINE_NOT_WORKING )
|
||||
COMP( 1982, watz19, h19, 0, h19, h19, driver_device, 0, "Heath Inc", "Heathkit H-19 w/ Watzman ROM", MACHINE_NOT_WORKING )
|
||||
|
Loading…
Reference in New Issue
Block a user