dim68k: Various improvements [AJR, Bitsavers]

- Replace generic serial keyboard with dump and low level emulation of MCU-based keyboard
- Specify correct clocks and XTAL sources for CPU and various other components
- Add game control port (untested)
This commit is contained in:
AJR 2023-05-18 11:19:58 -04:00
parent d14961c7b7
commit 136538f624
3 changed files with 327 additions and 36 deletions

View File

@ -10,19 +10,18 @@
of the emulated systems, or you create any other format you wished.
TODO:
- HLE serial keyboard
- Graphics display (including colour and video_control options)
- RTC (is this a thing? the manual indicates it just uses the DUART's timers to track time)
- Centronics printer
- Video-high
- Video-reset
- Game switches, paddles and timers (which work almost identically to the Apple II)
- The plug-in boards
- Emulator trap function
DUART I/O port bits:
INPUT:
bit 0 = Centronics RDY
bit 4 = RS-232C DCD
OUTPUT:
all bits = Centronics data
@ -48,12 +47,14 @@
****************************************************************************/
#include "emu.h"
#include "dim68k_kbd.h"
#include "cpu/m68000/m68000.h"
#include "imagedev/floppy.h"
#include "machine/mc68681.h"
#include "machine/upd765.h"
#include "sound/spkrdev.h"
#include "video/mc6845.h"
#include "bus/pc_joy/pc_joy.h"
#include "bus/rs232/rs232.h"
#include "emupal.h"
#include "screen.h"
@ -73,6 +74,7 @@ public:
, m_speaker(*this, "speaker")
, m_fdc(*this, "fdc")
, m_floppy(*this, "fdc:%u", 0U)
, m_gamectrl(*this, "gamectrl")
, m_ram(*this, "ram")
, m_palette(*this, "palette")
, m_p_chargen(*this, "chargen")
@ -85,13 +87,12 @@ public:
private:
void dim68k_palette(palette_device &palette);
u16 dim68k_fdc_r();
u16 dim68k_game_switches_r();
u8 dim68k_game_switches_r(offs_t offset);
u16 dim68k_speaker_r();
u16 dim68k_banksw_r();
void dim68k_banksw_w(u16 data);
void dim68k_fdc_w(u16 data);
void dim68k_printer_strobe_w(u16 data);
void dim68k_reset_timers_w(u16 data);
void dim68k_speaker_w(u16 data);
void dim68k_video_control_w(u16 data);
void dim68k_video_high_w(u16 data);
@ -113,6 +114,7 @@ private:
required_device<speaker_sound_device> m_speaker;
required_device<upd765a_device> m_fdc;
required_device_array<floppy_connector, 2> m_floppy;
required_device<pc_joy_device> m_gamectrl;
required_shared_ptr<uint16_t> m_ram;
required_device<palette_device> m_palette;
required_region_ptr<u8> m_p_chargen;
@ -145,19 +147,22 @@ u16 dim68k_state::dim68k_fdc_r()
return 0;
}
u16 dim68k_state::dim68k_game_switches_r()
u8 dim68k_state::dim68k_game_switches_r(offs_t offset)
// Reading the game port switches
// FFCC11 = switch 0; FFCC13 = switch 1, etc to switch 3
// FFCC19 = paddle 0; FFCC1B = paddle 1, etc to paddle 3
{
return 0xffff;
return BIT(m_gamectrl->joy_port_r(), offset ^ 4) ? 0 : 0x80;
}
u16 dim68k_state::dim68k_speaker_r()
// Any read or write of this address will toggle the position of the speaker cone
{
m_speaker_bit ^= 1;
m_speaker->level_w(m_speaker_bit);
if (!machine().side_effects_disabled())
{
m_speaker_bit ^= 1;
m_speaker->level_w(m_speaker_bit);
}
return 0;
}
@ -229,11 +234,6 @@ void dim68k_state::dim68k_video_reset_w(u16 data)
{
}
void dim68k_state::dim68k_reset_timers_w(u16 data)
// reset game port timer before reading paddles
{
}
void dim68k_state::dim68k_printer_strobe_w(u16 data)
// anything sent here will trigger a one-shot for a strobe pulse
{
@ -280,7 +280,8 @@ void dim68k_state::mem_map(address_map &map)
#endif
map(0xffc400, 0xffc41f).rw(m_duart, FUNC(scn2681_device::read), FUNC(scn2681_device::write)).umask16(0x00ff);
map(0xffc800, 0xffc801).rw(FUNC(dim68k_state::dim68k_speaker_r), FUNC(dim68k_state::dim68k_speaker_w));
map(0xffcc00, 0xffcc1f).rw(FUNC(dim68k_state::dim68k_game_switches_r), FUNC(dim68k_state::dim68k_reset_timers_w));
map(0xffcc00, 0xffcc00).w(m_gamectrl, FUNC(pc_joy_device::joy_port_w));
map(0xffcc10, 0xffcc1f).r(FUNC(dim68k_state::dim68k_game_switches_r)).umask16(0x00ff);
map(0xffd000, 0xffd003).m(m_fdc, FUNC(upd765a_device::map)).umask16(0x00ff); // NEC uPD765A
map(0xffd000, 0xffd000).lr8([this]() -> u8 { return m_fdc_irq; }, "free0");
map(0xffd004, 0xffd005).rw(FUNC(dim68k_state::dim68k_fdc_r), FUNC(dim68k_state::dim68k_fdc_w));
@ -409,27 +410,16 @@ void dim68k_state::machine_start()
save_item(NAME(m_video_control));
}
static DEVICE_INPUT_DEFAULTS_START(keyboard)
DEVICE_INPUT_DEFAULTS("RS232_RXBAUD", 0xff, RS232_BAUD_300)
DEVICE_INPUT_DEFAULTS("RS232_TXBAUD", 0xff, RS232_BAUD_300)
DEVICE_INPUT_DEFAULTS("RS232_DATABITS", 0xff, RS232_DATABITS_8)
DEVICE_INPUT_DEFAULTS("RS232_PARITY", 0xff, RS232_PARITY_NONE)
DEVICE_INPUT_DEFAULTS("RS232_STOPBITS", 0xff, RS232_STOPBITS_1)
DEVICE_INPUT_DEFAULTS_END
void dim68k_state::dim68k(machine_config &config)
{
/* basic machine hardware */
M68000(config, m_maincpu, XTAL(10'000'000));
M68000(config, m_maincpu, 14.318181_MHz_XTAL / 2); // part rated for 8 MHz; clock verified from manual
m_maincpu->set_addrmap(AS_PROGRAM, &dim68k_state::mem_map);
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(50);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
screen.set_raw(14.318181_MHz_XTAL, 896, 0, 640, 279, 0, 224);
screen.set_screen_update("crtc", FUNC(mc6845_device::screen_update));
screen.set_size(640, 480);
screen.set_visarea(0, 640-1, 0, 250-1);
PALETTE(config, m_palette, FUNC(dim68k_state::dim68k_palette), 16);
GFXDECODE(config, "gfxdecode", m_palette, gfx_dim68k);
@ -438,27 +428,28 @@ void dim68k_state::dim68k(machine_config &config)
SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.50);
/* Devices */
UPD765A(config, m_fdc, 4'000'000, true, true); // these options unknown
UPD765A(config, m_fdc, 16_MHz_XTAL / 4, true, true); // clocked through FDC9229BT; options unknown
FLOPPY_CONNECTOR(config, m_floppy[0], dim68k_floppies, "525qd", floppy_image_device::default_mfm_floppy_formats);
FLOPPY_CONNECTOR(config, m_floppy[1], dim68k_floppies, "525qd", floppy_image_device::default_mfm_floppy_formats);
m_fdc->intrq_wr_callback().set(FUNC(dim68k_state::fdc_irq_w));
MC6845(config, m_crtc, 1790000);
MC6845(config, m_crtc, 14.318181_MHz_XTAL / 8);
m_crtc->set_screen("screen");
m_crtc->set_show_border_area(false);
m_crtc->set_char_width(8);
m_crtc->set_update_row_callback(FUNC(dim68k_state::crtc_update_row));
rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, nullptr));
rs232_port_device &kbdport(RS232_PORT(config, "kbdport", default_rs232_devices, "keyboard"));
kbdport.set_option_device_input_defaults("keyboard", DEVICE_INPUT_DEFAULTS_NAME(keyboard));
SCN2681(config, m_duart, 3.6864_MHz_XTAL);
m_duart->a_tx_cb().set(kbdport, FUNC(rs232_port_device::write_txd));
m_duart->b_tx_cb().set(rs232, FUNC(rs232_port_device::write_txd));
kbdport.rxd_handler().set(m_duart, FUNC(scn2681_device::rx_a_w));
DIM68K_KEYBOARD(config, "keyboard").txd_callback().set(m_duart, FUNC(scn2681_device::rx_a_w));
PC_JOY(config, m_gamectrl);
rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, nullptr));
rs232.rxd_handler().set(m_duart, FUNC(scn2681_device::rx_b_w));
rs232.dcd_handler().set(m_duart, FUNC(scn2681_device::ip4_w));
m_duart->b_tx_cb().set(rs232, FUNC(rs232_port_device::write_txd));
// software lists
SOFTWARE_LIST(config, "flop_list").set_original("dim68k");

View File

@ -0,0 +1,233 @@
// license:BSD-3-Clause
// copyright-holders:AJR
/**********************************************************************
Micro Craft Dimension 68000 84-key keyboard
This keyboard mimics the layout of early IBM PC keyboards. The
main differences are that \ is to the left of the left Shift key,
the "Retrn" key (thus labeled here) is horizontal rather than
vertical in orientation, and the keypad has an "Enter" key. The
communication is unidirectional asynchronous TTL-level serial at
300 baud, using ASCII codes only for printable characters. LEDs
are provided for the Caps Lock and Num Lock keys, but not for
Scroll Lock.
Mysteries:
Why does the 8048 have to be slightly overclocked to yield the
correct baud rate?
Keycodes are transmitted with even parity, despite the DUART
configuration and documentation specifying no parity. Framing
errors frequently result, but these might be harmless.
There are actually two serial outputs generated by the 8048,
one being the complement of the other.
Due to an apparent bug in CP/M, 2 on the numeric keypad may not
work correctly in numeric mode (likely since the code it sends
is coincidentally the ASCII CR code).
**********************************************************************/
#include "emu.h"
#include "dim68k_kbd.h"
DEFINE_DEVICE_TYPE(DIM68K_KEYBOARD, dim68k_keyboard_device, "dim68k_kbd", "Dimension 68000 keyboard")
dim68k_keyboard_device::dim68k_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, DIM68K_KEYBOARD, tag, owner, clock)
, m_mcu(*this, "mcu")
, m_eprom(*this, "eprom")
, m_keys(*this, "KEYS%d", 0U)
, m_capslock_led(*this, "capslock")
, m_numlock_led(*this, "numlock")
, m_txd_callback(*this)
, m_p1_in(0xff)
{
}
void dim68k_keyboard_device::device_resolve_objects()
{
m_capslock_led.resolve();
m_numlock_led.resolve();
m_txd_callback.resolve_safe();
}
void dim68k_keyboard_device::device_start()
{
save_item(NAME(m_p1_in));
}
u8 dim68k_keyboard_device::p1_r()
{
return m_p1_in;
}
void dim68k_keyboard_device::p2_w(u8 data)
{
m_txd_callback(BIT(data, 5));
// Bit 4 is complementary output
m_capslock_led = !BIT(data, 7);
m_numlock_led = !BIT(data, 6);
}
WRITE_LINE_MEMBER(dim68k_keyboard_device::prog_w)
{
if (state)
{
u8 j = m_mcu->p1_r() & 0x0f;
if (j < 11)
m_p1_in = m_keys[j]->read();
else
m_p1_in = 0xff;
}
}
u8 dim68k_keyboard_device::eprom_r()
{
return m_eprom[u16(m_mcu->p2_r() & 1) << 8 | m_mcu->p1_r()];
}
void dim68k_keyboard_device::ext_map(address_map &map)
{
map(0x00, 0x00).mirror(0xff).r(FUNC(dim68k_keyboard_device::eprom_r));
}
static INPUT_PORTS_START(dim68k_keyboard)
PORT_START("KEYS0")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(NUMLOCK)) PORT_CODE(KEYCODE_NUMLOCK)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Right Shift") PORT_CHAR(UCHAR_MAMEKEY(RSHIFT)) PORT_CODE(KEYCODE_RSHIFT)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Alt") PORT_CHAR(UCHAR_MAMEKEY(LALT)) PORT_CODE(KEYCODE_LALT)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ctrl") PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) PORT_CODE(KEYCODE_LCONTROL)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) PORT_CODE(KEYCODE_RALT)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Left Shift") PORT_CHAR(UCHAR_MAMEKEY(LSHIFT), UCHAR_SHIFT_1) PORT_CODE(KEYCODE_LSHIFT)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_START("KEYS1")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Scroll Lock Break") PORT_CHAR(UCHAR_MAMEKEY(SCRLOCK)) PORT_CODE(KEYCODE_SLASH_PAD)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 9 Pg Up") PORT_CHAR(UCHAR_MAMEKEY(PGUP)) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) PORT_CODE(KEYCODE_9_PAD)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(PLUS_PAD)) PORT_CODE(KEYCODE_PLUS_PAD)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(u8"Keypad 6 \u2192") PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) PORT_CODE(KEYCODE_6_PAD)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) PORT_CODE(KEYCODE_ENTER_PAD)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad . Del") PORT_CHAR(UCHAR_MAMEKEY(DEL)) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD)) PORT_CODE(KEYCODE_DEL_PAD)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 3 Pg Dn") PORT_CHAR(UCHAR_MAMEKEY(PGDN)) PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) PORT_CODE(KEYCODE_3_PAD)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) PORT_CODE(KEYCODE_MINUS_PAD)
PORT_START("KEYS2")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Back Space") PORT_CHAR(0x08) PORT_CODE(KEYCODE_BACKSPACE)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 7 Home") PORT_CHAR(UCHAR_MAMEKEY(HOME)) PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) PORT_CODE(KEYCODE_7_PAD)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) PORT_CODE(KEYCODE_5_PAD)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(u8"Keypad 4 \u2190") PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) PORT_CODE(KEYCODE_4_PAD)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(u8"Keypad 2 \u2193") PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) PORT_CODE(KEYCODE_2_PAD)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 0 Ins") PORT_CHAR(UCHAR_MAMEKEY(INSERT)) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) PORT_CODE(KEYCODE_0_PAD)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 1 End") PORT_CHAR(UCHAR_MAMEKEY(END)) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) PORT_CODE(KEYCODE_1_PAD)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(u8"Keypad 8 \u2191") PORT_CHAR(UCHAR_MAMEKEY(UP)) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) PORT_CODE(KEYCODE_8_PAD)
PORT_START("KEYS3")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('=') PORT_CHAR('+') PORT_CODE(KEYCODE_EQUALS)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(']') PORT_CHAR('}') PORT_CODE(KEYCODE_CLOSEBRACE)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Retrn") PORT_CHAR(0x0d) PORT_CODE(KEYCODE_ENTER)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_UNUSED) // duplicate of `/~ key?
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("* PrtSc") PORT_CHAR(UCHAR_MAMEKEY(ASTERISK)) PORT_CODE(KEYCODE_ASTERISK)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) // generates 0xDC code
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F10)) PORT_CODE(KEYCODE_F10)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('`') PORT_CHAR('~') PORT_CODE(KEYCODE_BACKSLASH)
PORT_START("KEYS4")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('0') PORT_CHAR(')') PORT_CODE(KEYCODE_0)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P") PORT_CHAR('p') PORT_CHAR('P') PORT_CODE(KEYCODE_P)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('\'') PORT_CHAR('"') PORT_CODE(KEYCODE_QUOTE)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(';') PORT_CHAR(':') PORT_CODE(KEYCODE_COLON)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Space") PORT_CHAR(' ') PORT_CODE(KEYCODE_SPACE)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('-') PORT_CHAR('_') PORT_CODE(KEYCODE_MINUS)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('.') PORT_CHAR('>') PORT_CODE(KEYCODE_STOP)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('[') PORT_CHAR('{') PORT_CODE(KEYCODE_OPENBRACE)
PORT_START("KEYS5")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('8') PORT_CHAR('*') PORT_CODE(KEYCODE_8)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I") PORT_CHAR('i') PORT_CHAR('I') PORT_CODE(KEYCODE_I)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L") PORT_CHAR('l') PORT_CHAR('L') PORT_CODE(KEYCODE_L)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K") PORT_CHAR('k') PORT_CHAR('K') PORT_CODE(KEYCODE_K)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(',') PORT_CHAR('<') PORT_CODE(KEYCODE_COMMA)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('9') PORT_CHAR('(') PORT_CODE(KEYCODE_9)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M") PORT_CHAR('m') PORT_CHAR('M') PORT_CODE(KEYCODE_M)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O") PORT_CHAR('o') PORT_CHAR('O') PORT_CODE(KEYCODE_O)
PORT_START("KEYS6")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('6') PORT_CHAR('^') PORT_CODE(KEYCODE_6)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y") PORT_CHAR('y') PORT_CHAR('Y') PORT_CODE(KEYCODE_Y)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J") PORT_CHAR('j') PORT_CHAR('J') PORT_CODE(KEYCODE_J)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H") PORT_CHAR('h') PORT_CHAR('H') PORT_CODE(KEYCODE_H)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N") PORT_CHAR('n') PORT_CHAR('N') PORT_CODE(KEYCODE_N)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('7') PORT_CHAR('&') PORT_CODE(KEYCODE_7)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F9)) PORT_CODE(KEYCODE_F9)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U") PORT_CHAR('u') PORT_CHAR('U') PORT_CODE(KEYCODE_U)
PORT_START("KEYS7")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('4') PORT_CHAR('$') PORT_CODE(KEYCODE_4)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R") PORT_CHAR('r') PORT_CHAR('R') PORT_CODE(KEYCODE_R)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G") PORT_CHAR('g') PORT_CHAR('G') PORT_CODE(KEYCODE_G)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F") PORT_CHAR('f') PORT_CHAR('F') PORT_CODE(KEYCODE_F)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V") PORT_CHAR('v') PORT_CHAR('V') PORT_CODE(KEYCODE_V)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('3') PORT_CHAR('#') PORT_CODE(KEYCODE_3)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CHAR('c') PORT_CHAR('C') PORT_CODE(KEYCODE_C)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T") PORT_CHAR('t') PORT_CHAR('T') PORT_CODE(KEYCODE_T)
PORT_START("KEYS8")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('2') PORT_CHAR('@') PORT_CODE(KEYCODE_2)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W") PORT_CHAR('w') PORT_CHAR('W') PORT_CODE(KEYCODE_W)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CHAR('d') PORT_CHAR('D') PORT_CODE(KEYCODE_D)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S") PORT_CHAR('s') PORT_CHAR('S') PORT_CODE(KEYCODE_S)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X") PORT_CHAR('x') PORT_CHAR('X') PORT_CODE(KEYCODE_X)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('1') PORT_CHAR('!') PORT_CODE(KEYCODE_1)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z") PORT_CHAR('z') PORT_CHAR('Z') PORT_CODE(KEYCODE_Z)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q") PORT_CHAR('q') PORT_CHAR('Q') PORT_CODE(KEYCODE_Q)
PORT_START("KEYS9")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Esc") PORT_CHAR(0x1b) PORT_CODE(KEYCODE_TILDE)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Tab") PORT_CHAR(0x09) PORT_CODE(KEYCODE_TAB)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A") PORT_CHAR('a') PORT_CHAR('A') PORT_CODE(KEYCODE_A)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F8)) PORT_CODE(KEYCODE_F8)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('\\') PORT_CHAR('|') PORT_CODE(KEYCODE_BACKSLASH2)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_CODE(KEYCODE_F2)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F7)) PORT_CODE(KEYCODE_F7)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F4)) PORT_CODE(KEYCODE_F4)
PORT_START("KEYS10")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F1)) PORT_CODE(KEYCODE_F1)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_CODE(KEYCODE_F3)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F6)) PORT_CODE(KEYCODE_F6)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F5)) PORT_CODE(KEYCODE_F5)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('/') PORT_CHAR('?') PORT_CODE(KEYCODE_SLASH)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('5') PORT_CHAR('%') PORT_CODE(KEYCODE_5)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CHAR('b') PORT_CHAR('B') PORT_CODE(KEYCODE_B)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CHAR('e') PORT_CHAR('E') PORT_CODE(KEYCODE_E)
INPUT_PORTS_END
ioport_constructor dim68k_keyboard_device::device_input_ports() const
{
return INPUT_PORTS_NAME(dim68k_keyboard);
}
void dim68k_keyboard_device::device_add_mconfig(machine_config &config)
{
I8048(config, m_mcu, 4'752'000 /* 4.608_MHz_XTAL */); // NEC 20-08048-399 + 300-107 XTAL
m_mcu->set_addrmap(AS_IO, &dim68k_keyboard_device::ext_map);
m_mcu->p1_in_cb().set(FUNC(dim68k_keyboard_device::p1_r));
m_mcu->p2_in_cb().set_constant(0xf7);
m_mcu->p2_out_cb().set(FUNC(dim68k_keyboard_device::p2_w));
m_mcu->prog_out_cb().set(FUNC(dim68k_keyboard_device::prog_w));
}
ROM_START(dim68k_keyboard)
ROM_REGION(0x400, "mcu", 0)
ROM_LOAD("20-08048-399.bin", 0x000, 0x400, CRC(558ad86a) SHA1(a0a356e355b4df6c9565d186e2c878a6302de1b8))
ROM_REGION(0x1000, "eprom", 0)
ROM_LOAD("mc114_rev-a.bin", 0x0000, 0x1000, CRC(950542e3) SHA1(d1e87c8ccd17e4e2249fe89f13111ec881b7ebae)) // mirrored every 512 bytes
ROM_END
const tiny_rom_entry *dim68k_keyboard_device::device_rom_region() const
{
return ROM_NAME(dim68k_keyboard);
}

View File

@ -0,0 +1,67 @@
// license:BSD-3-Clause
// copyright-holders:AJR
/**********************************************************************
Micro Craft Dimension 68000 84-key keyboard
**********************************************************************/
#ifndef MAME_SKELETON_DIM68K_KBD_H
#define MAME_SKELETON_DIM68K_KBD_H
#pragma once
#include "cpu/mcs48/mcs48.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> dim68k_keyboard_device
class dim68k_keyboard_device : public device_t
{
public:
// device type constructor
dim68k_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
// callback configuration
auto txd_callback() { return m_txd_callback.bind(); }
protected:
// device-level overrides
virtual void device_resolve_objects() override;
virtual void device_start() override;
virtual ioport_constructor device_input_ports() const override;
virtual void device_add_mconfig(machine_config &config) override;
virtual const tiny_rom_entry *device_rom_region() const override;
private:
// MCU handlers
u8 p1_r();
void p2_w(u8 data);
DECLARE_WRITE_LINE_MEMBER(prog_w);
u8 eprom_r();
// address map
void ext_map(address_map &map);
// object finders
required_device<mcs48_cpu_device> m_mcu;
required_region_ptr<u8> m_eprom;
required_ioport_array<11> m_keys;
output_finder<> m_capslock_led;
output_finder<> m_numlock_led;
// output callback
devcb_write_line m_txd_callback;
// internal state
u8 m_p1_in;
};
// device type declarations
DECLARE_DEVICE_TYPE(DIM68K_KEYBOARD, dim68k_keyboard_device)
#endif // MAME_SKELETON_DIM68K_KBD_H