/*************************************************************************** Heathkit H19 12/05/2009 Skeleton driver. 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. 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. For the moment, the "ascii keyboard" device is used for the keyboard. 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. ****************************************************************************/ #include "emu.h" #include "cpu/z80/z80.h" #include "video/mc6845.h" #include "sound/beep.h" #include "machine/ins8250.h" #include "machine/keyboard.h" #define KEYBOARD_TAG "keyboard" #define H19_CLOCK (XTAL_12_288MHz / 6) #define H19_BEEP_FRQ (H19_CLOCK / 1024) class h19_state : public driver_device { public: enum { TIMER_BEEP_OFF }; h19_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), m_crtc(*this, "crtc"), m_ace(*this, "ins8250"), m_beep(*this, "beeper"), m_p_videoram(*this, "videoram"), m_palette(*this, "palette") { } required_device m_maincpu; required_device m_crtc; required_device m_ace; required_device m_beep; DECLARE_READ8_MEMBER(h19_80_r); DECLARE_READ8_MEMBER(h19_a0_r); DECLARE_WRITE8_MEMBER(h19_c0_w); DECLARE_WRITE8_MEMBER(h19_kbd_put); MC6845_UPDATE_ROW(crtc_update_row); required_shared_ptr m_p_videoram; required_device m_palette; UINT8 *m_p_chargen; UINT8 m_term_data; virtual void machine_reset(); virtual void video_start(); DECLARE_WRITE_LINE_MEMBER(h19_ace_irq); protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); }; 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); break; default: assert_always(FALSE, "Unknown id in h19_state::device_timer"); } } READ8_MEMBER( h19_state::h19_80_r ) { // keyboard data UINT8 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. - lengths need verifying offset 00-1F = keyclick offset 20-3F = terminal bell */ UINT8 length = (offset & 0x20) ? 200 : 4; 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(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(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) 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 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_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_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_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_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_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_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_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_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_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_START("S401") PORT_DIPNAME( 0x0f, 0x03, "Baud Rate") PORT_DIPSETTING( 0x01, "110") PORT_DIPSETTING( 0x02, "150") PORT_DIPSETTING( 0x03, "300") PORT_DIPSETTING( 0x04, "600") PORT_DIPSETTING( 0x05, "1200") PORT_DIPSETTING( 0x06, "1800") PORT_DIPSETTING( 0x07, "2000") PORT_DIPSETTING( 0x08, "2400") PORT_DIPSETTING( 0x09, "3600") PORT_DIPSETTING( 0x0a, "4800") PORT_DIPSETTING( 0x0b, "7200") PORT_DIPSETTING( 0x0c, "9600") PORT_DIPSETTING( 0x0d, "19200") PORT_DIPNAME( 0x30, 0x00, "Parity") PORT_DIPSETTING( 0x00, DEF_STR(None)) PORT_DIPSETTING( 0x10, "Odd") PORT_DIPSETTING( 0x30, "Even") PORT_DIPNAME( 0x40, 0x00, "Parity Type") PORT_DIPSETTING( 0x00, DEF_STR(Normal)) PORT_DIPSETTING( 0x40, "Stick") PORT_DIPNAME( 0x80, 0x00, "Duplex") PORT_DIPSETTING( 0x00, "Half") PORT_DIPSETTING( 0x80, "Full") PORT_START("S402") // 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_DIPSETTING( 0x00, DEF_STR(No)) PORT_DIPSETTING( 0x04, DEF_STR(Yes)) PORT_DIPNAME( 0x08, 0x08, "Auto LF on CR") PORT_DIPSETTING( 0x00, DEF_STR(No)) PORT_DIPSETTING( 0x08, DEF_STR(Yes)) PORT_DIPNAME( 0x10, 0x00, "Auto CR on LF") PORT_DIPSETTING( 0x00, DEF_STR(No)) PORT_DIPSETTING( 0x10, DEF_STR(Yes)) PORT_DIPNAME( 0x20, 0x00, "Mode") PORT_DIPSETTING( 0x00, "VT52") PORT_DIPSETTING( 0x20, "ANSI") PORT_DIPNAME( 0x40, 0x00, "Keypad Shifted") PORT_DIPSETTING( 0x00, DEF_STR(No)) PORT_DIPSETTING( 0x40, DEF_STR(Yes)) PORT_DIPNAME( 0x80, 0x00, "Refresh") PORT_DIPSETTING( 0x00, "50Hz") PORT_DIPSETTING( 0x80, "60Hz") INPUT_PORTS_END void h19_state::machine_reset() { m_beep->set_frequency(H19_BEEP_FRQ); } void h19_state::video_start() { m_p_chargen = memregion("chargen")->base(); } MC6845_UPDATE_ROW( h19_state::crtc_update_row ) { const rgb_t *palette = m_palette->palette()->entry_list_raw(); UINT8 chr,gfx; UINT16 mem,x; UINT32 *p = &bitmap.pix32(y); for (x = 0; x < x_count; x++) { UINT8 inv=0; if (x == cursor_x) inv=0xff; mem = (ma + x) & 0x7ff; chr = m_p_videoram[mem]; if (chr & 0x80) { inv ^= 0xff; chr &= 0x7f; } /* get pattern of pixels for that character scanline */ gfx = m_p_chargen[(chr<<4) | ra] ^ inv; /* Display a scanline of a character (8 pixels) */ *p++ = palette[BIT(gfx, 7)]; *p++ = palette[BIT(gfx, 6)]; *p++ = palette[BIT(gfx, 5)]; *p++ = palette[BIT(gfx, 4)]; *p++ = palette[BIT(gfx, 3)]; *p++ = palette[BIT(gfx, 2)]; *p++ = palette[BIT(gfx, 1)]; *p++ = palette[BIT(gfx, 0)]; } } WRITE_LINE_MEMBER(h19_state::h19_ace_irq) { m_maincpu->set_input_line(0, (state ? HOLD_LINE : CLEAR_LINE)); } /* F4 Character Displayer */ static const gfx_layout h19_charlayout = { 8, 10, /* 8 x 10 characters */ 128, /* 128 characters */ 1, /* 1 bits per pixel */ { 0 }, /* no bitplanes */ /* x offsets */ { 0, 1, 2, 3, 4, 5, 6, 7 }, /* y offsets */ { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8 }, 8*16 /* every char takes 16 bytes */ }; 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("screen", RASTER) MCFG_SCREEN_REFRESH_RATE(60) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ MCFG_SCREEN_UPDATE_DEVICE("crtc", mc6845_device, screen_update) MCFG_SCREEN_SIZE(640, 200) MCFG_SCREEN_VISIBLE_AREA(0, 640 - 1, 0, 200 - 1) MCFG_GFXDECODE_ADD("gfxdecode", "palette", h19) MCFG_PALETTE_ADD_MONOCHROME_GREEN("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_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_INS8250_OUT_INT_CB(WRITELINE(h19_state, h19_ace_irq)) // interrupt MCFG_DEVICE_ADD(KEYBOARD_TAG, GENERIC_KEYBOARD, 0) MCFG_GENERIC_KEYBOARD_CB(WRITE8(h19_state, h19_kbd_put)) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_SOUND_ADD("beeper", BEEP, 0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) MACHINE_CONFIG_END /* ROM definition */ ROM_START( h19 ) ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) // Original ROM_SYSTEM_BIOS(0, "orig", "Original") ROMX_LOAD( "2732_444-46_h19code.bin", 0x0000, 0x1000, CRC(F4447DA0) SHA1(fb4093d5b763be21a9580a0defebed664b1f7a7b), ROM_BIOS(1)) // Super H19 ROM ( ROM_SYSTEM_BIOS(1, "super", "Super 19") ROMX_LOAD( "2732_super19_h447.bin", 0x0000, 0x1000, CRC(6c51aaa6) SHA1(5e368b39fe2f1af44a905dc474663198ab630117), ROM_BIOS(2)) // Watzman ROM ROM_SYSTEM_BIOS(2, "watzman", "Watzman") ROMX_LOAD( "watzman.bin", 0x0000, 0x1000, CRC(8168b6dc) SHA1(bfaebb9d766edbe545d24bc2b6630be4f3aa0ce9), ROM_BIOS(3)) ROM_REGION( 0x0800, "chargen", 0 ) // Original font dump ROM_LOAD( "2716_444-29_h19font.bin", 0x0000, 0x0800, CRC(d595ac1d) SHA1(130fb4ea8754106340c318592eec2d8a0deaf3d0)) ROM_REGION( 0x1000, "keyboard", 0 ) // Original dump ROM_LOAD( "2716_444-37_h19keyb.bin", 0x0000, 0x0800, CRC(5c3e6972) SHA1(df49ce64ae48652346a91648c58178a34fb37d3c)) // Watzman keyboard ROM_LOAD( "keybd.bin", 0x0800, 0x0800, CRC(58dc8217) SHA1(1b23705290bdf9fc6342065c6a528c04bff67b13)) ROM_END /* Driver (year is either 1978 or 1979) */ /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ COMP( 1978, h19, 0, 0, h19, h19, driver_device, 0, "Heath Inc", "Heathkit H-19", GAME_NOT_WORKING )