This commit is contained in:
Scott Stone 2016-07-17 13:10:18 -04:00
commit 3cfa08fd6f
9 changed files with 941 additions and 95 deletions

View File

@ -1608,6 +1608,8 @@ if (BUSES["RS232"]~=null) then
MAME_DIR .. "src/devices/bus/rs232/pty.h",
MAME_DIR .. "src/devices/bus/rs232/ser_mouse.cpp",
MAME_DIR .. "src/devices/bus/rs232/ser_mouse.h",
MAME_DIR .. "src/devices/bus/rs232/sparckbd.cpp",
MAME_DIR .. "src/devices/bus/rs232/sparckbd.h",
MAME_DIR .. "src/devices/bus/rs232/terminal.cpp",
MAME_DIR .. "src/devices/bus/rs232/terminal.h",
MAME_DIR .. "src/devices/bus/rs232/xvd701.cpp",

View File

@ -0,0 +1,590 @@
// license:BSD-3-Clause
// copyright-holders:Vas Crabb
#include "sparckbd.h"
#include <numeric>
/*
TODO: implement keyclick
TODO: determine default keyclick state on real keyboard
TODO: use 1,200 Baud properly once we work out what's going on with the SCC
HLE SPARC serial keyboard compatible with Sun Type 4/5/6
messages from host to keyboard:
0000 0001 reset (keyboard responds with self test pass/fail)
0000 0010 bell on (480us period)
0000 0011 bell off
0000 1010 enable keyclick (5us duration 480us period on make)
0000 1011 disable keyclick
0000 1110 ---- lscn LED (1 = on, l = caps lock, s = scroll lock, c = compose, n = num lock)
0000 1111 layout request (keyboard responds with layout response)
message from keyboad to host:
0xxx xxxx key make
1xxx xxxx key break
0111 1111 all keys up
1111 1110 00dd dddd layout response (DIP switches 3 to 8 from MSB to LSB)
1111 1111 0000 0100 reset response (self test pass, always followed by all keys up or key make)
0111 1110 0000 0001 self test fal
Type 5 US PC layout:
76 1d 05 06 08 0a 0c 0e 10 11 12 07 09 0b 16 17 15 2d 02 04 30
01 03 2a 1e 1f 20 21 22 23 24 25 26 27 28 29 2b 2c 34 60 62 2e 2f 47
19 1a 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 58 42 4a 7b 44 45 46
31 33 77 4d 4e 4f 50 51 52 53 54 55 56 57 59 5b 5c 5d 7d
48 49 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 14 70 71 72
5f 61 4c 78 13 79 0d 43 7a 18 1b 1c 5e 32 5a
Type 5 US UNIX layout:
76 xx 05 06 08 0a 0c 0e 10 11 12 07 09 0b 16 17 15 2d 02 04 30
01 03 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 58 2a 2c 34 60 62 2e 2f 47
19 1a 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 2b 42 4a 7b 44 45 46
31 33 4c 4d 4e 4f 50 51 52 53 54 55 56 57 59 5b 5c 5d 7d
48 49 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 14 70 71 72
5f 61 77 78 13 79 0d 43 7a 18 1b 1c 5e 32 5a
xx is a blank key
6f is assigned to linefeed, which is present on Type 4 keyboards, but absent on Type 5
*/
namespace {
INPUT_PORTS_START( sparc_keyboard )
PORT_START("DIP")
PORT_DIPNAME( 0x3f, 0x21, "Layout" ) PORT_DIPLOCATION("DIP:!8,!7,!6,!5,!4,!3")
PORT_DIPSETTING( 0x00, "U.S.A. (US4.kt)" )
PORT_DIPSETTING( 0x01, "U.S.A. (US4.kt)" )
PORT_DIPSETTING( 0x02, "Belgium (FranceBelg4.kt)" )
PORT_DIPSETTING( 0x03, "Canada (Canada4.kt)" )
PORT_DIPSETTING( 0x04, "Denmark (Denmakr4.kt)" )
PORT_DIPSETTING( 0x05, "Germany (Germany4.kt)" )
PORT_DIPSETTING( 0x06, "Italy (Italy4.kt)" )
PORT_DIPSETTING( 0x07, "The Netherlands (Netherland4.kt)" )
PORT_DIPSETTING( 0x08, "Norway (Norway4.kt)" )
PORT_DIPSETTING( 0x09, "Portugal (Portugal4.kt)" )
PORT_DIPSETTING( 0x0a, "Latin America/Spanish (SpainLatAm4.kt)" )
PORT_DIPSETTING( 0x0b, "Sweden (SwedenFin4.kt)" )
PORT_DIPSETTING( 0x0c, "Switzerland/French (Switzer_Fr4.kt)" )
PORT_DIPSETTING( 0x0d, "Switzerland/German (Switzer_Ge4.kt)" )
PORT_DIPSETTING( 0x0e, "Great Britain (UK4.kt)" )
// 0x0f
PORT_DIPSETTING( 0x10, "Korea (Korea4.kt)" )
PORT_DIPSETTING( 0x11, "Taiwan (Taiwan4.kt)" )
// 0x12...0x20
PORT_DIPSETTING( 0x21, "U.S.A. (US5.kt)" )
PORT_DIPSETTING( 0x22, "U.S.A./UNIX (US_UNIX5.kt)" )
PORT_DIPSETTING( 0x23, "France (France5.kt)" )
PORT_DIPSETTING( 0x24, "Denmark (Denmark5.kt)" )
PORT_DIPSETTING( 0x25, "Germany (Germany5.kt)" )
PORT_DIPSETTING( 0x26, "Italy (Italy5.kt)" )
PORT_DIPSETTING( 0x27, "The Netherlands (Netherland5.kt)" )
PORT_DIPSETTING( 0x28, "Norway (Norway5.kt)" )
PORT_DIPSETTING( 0x29, "Portugal (Portugal5.kt)" )
PORT_DIPSETTING( 0x2a, "Spain (Spain5.kt)" )
PORT_DIPSETTING( 0x2b, "Sweden (Sweden5.kt)" )
PORT_DIPSETTING( 0x2c, "Switzerland/French (Switzer_Fr5.kt)" )
PORT_DIPSETTING( 0x2d, "Switzerland/German (Switzer_Ge5.kt)" )
PORT_DIPSETTING( 0x2e, "Great Britain (UK5.kt)" )
PORT_DIPSETTING( 0x2f, "Korea (Korea5.kt)" )
PORT_DIPSETTING( 0x30, "Taiwan (Taiwan5.kt)" )
PORT_DIPSETTING( 0x31, "Japan (Japan5.kt)" )
PORT_DIPSETTING( 0x32, "Canada/French (Canada_Fr5.kt)" )
PORT_DIPSETTING( 0x33, "Hungary (Hungary5.kt)" )
PORT_DIPSETTING( 0x34, "Poland (Poland5.kt)" )
PORT_DIPSETTING( 0x35, "Czech (Czech5.kt)" )
PORT_DIPSETTING( 0x36, "Russia (Russia5.kt)" )
PORT_DIPSETTING( 0x37, "Latvia (Latvia5.kt)" )
PORT_DIPSETTING( 0x38, "Turkey-Q5 (TurkeyQ5.kt)" )
PORT_DIPSETTING( 0x39, "Greece (Greece5.kt)" )
PORT_DIPSETTING( 0x3a, "Arabic (Arabic5.kt)" )
PORT_DIPSETTING( 0x3b, "Lithuania (Lithuania5.kt)" )
PORT_DIPSETTING( 0x3c, "Belgium (Belgium5.kt)" )
// 0x3d
PORT_DIPSETTING( 0x3e, "Turkey-F5 (TurkeyF5.kt)" )
PORT_DIPSETTING( 0x3f, "Canada/French (Canada_Fr5_TBITS5.kt)" )
PORT_DIPUNUSED_DIPLOC( 0x40, 0x00, "DIP:!2" )
PORT_DIPUNUSED_DIPLOC( 0x80, 0x00, "DIP:!1" )
PORT_START("ROW0")
PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Stop")
PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Vol-")
PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Again")
PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Vol+")
PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F1") PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1))
PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F2") PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2))
PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F10") PORT_CODE(KEYCODE_F10) PORT_CHAR(UCHAR_MAMEKEY(F10))
PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F3") PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3))
PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F11") PORT_CODE(KEYCODE_F11) PORT_CHAR(UCHAR_MAMEKEY(F11))
PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F4") PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4))
PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F12") PORT_CODE(KEYCODE_F12) PORT_CHAR(UCHAR_MAMEKEY(F12))
PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F5") PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5))
PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Alt Graph") PORT_CODE(KEYCODE_RALT) PORT_CHAR(UCHAR_MAMEKEY(RALT))
PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F6") PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6))
PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_START("ROW1")
PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F7") PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7))
PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F8") PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8))
PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F9") PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9))
PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Alt") PORT_CODE(KEYCODE_LALT)
PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Up") PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP))
PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Pause") PORT_CODE(KEYCODE_PAUSE)
PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Print Screen") PORT_CODE(KEYCODE_PRTSCR) PORT_CHAR(UCHAR_MAMEKEY(PRTSCR))
PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Scroll Lock") PORT_CODE(KEYCODE_SCRLOCK) PORT_CHAR(UCHAR_MAMEKEY(SCRLOCK))
PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Left") PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT))
PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Props")
PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Undo")
PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Down") PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN))
PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Right") PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT))
PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Esc") PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC))
PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@')
PORT_START("ROW2")
PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#')
PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')
PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%')
PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^')
PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&')
PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*')
PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(')
PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')')
PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_')
PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+')
PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~')
PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Backspace") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8)
PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Insert") PORT_CODE(KEYCODE_INSERT) PORT_CHAR(UCHAR_MAMEKEY(INSERT))
PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Mute")
PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("KP /") PORT_CODE(KEYCODE_SLASH_PAD)
PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("KP *") PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR(UCHAR_MAMEKEY(ASTERISK))
PORT_START("ROW3")
PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Pwr")
PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Front")
PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("KP .") PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD))
PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Copy")
PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Home") PORT_CODE(KEYCODE_HOME) PORT_CHAR(UCHAR_MAMEKEY(HOME))
PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tab") PORT_CODE(KEYCODE_TAB) PORT_CHAR(9)
PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q')
PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W')
PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E')
PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R')
PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T')
PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y')
PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U')
PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I')
PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O')
PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P')
PORT_START("ROW4")
PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{')
PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}')
PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Del") PORT_CODE(KEYCODE_DEL) PORT_CHAR(UCHAR_MAMEKEY(DEL))
PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Compose") PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_MAMEKEY(RCONTROL))
PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("KP 7") PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD))
PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("KP 8") PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD))
PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("KP 9") PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD))
PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("KP -") PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD))
PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Open")
PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Paste")
PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("End") PORT_CODE(KEYCODE_END) PORT_CHAR(UCHAR_MAMEKEY(END))
PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Control") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL))
PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A')
PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S')
PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D')
PORT_START("ROW5")
PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F')
PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G')
PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H')
PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J')
PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K')
PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L')
PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':')
PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"')
PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|')
PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)
PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Enter") PORT_CODE(KEYCODE_ENTER_PAD)
PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("KP 4") PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD))
PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("KP 5") PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD))
PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("KP 6") PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD))
PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("KP 0") PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD))
PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Find")
PORT_START("ROW6")
PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Page Up") PORT_CODE(KEYCODE_PGUP) PORT_CHAR(UCHAR_MAMEKEY(PGUP))
PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Cut")
PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Num Lock") PORT_CODE(KEYCODE_NUMLOCK) PORT_CHAR(UCHAR_MAMEKEY(NUMLOCK))
PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("L Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_MAMEKEY(LSHIFT))
PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z')
PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X')
PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('c') PORT_CHAR('C')
PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('v') PORT_CHAR('V')
PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('b') PORT_CHAR('B')
PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('n') PORT_CHAR('N')
PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('m') PORT_CHAR('M')
PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<')
PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>')
PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?')
PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("R Shift") PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_MAMEKEY(RSHIFT))
PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Line Feed") PORT_CHAR(10)
PORT_START("ROW7")
PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("KP 1") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD))
PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("KP 2") PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD))
PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("KP 3") PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD))
PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Help")
PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Caps Lock") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK))
PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("L Meta") PORT_CODE(KEYCODE_LWIN) PORT_CHAR(UCHAR_MAMEKEY(LWIN))
PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')
PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("R Meta") PORT_CODE(KEYCODE_RWIN) PORT_CHAR(UCHAR_MAMEKEY(RWIN))
PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Page Down") PORT_CODE(KEYCODE_PGDN) PORT_CHAR(UCHAR_MAMEKEY(PGDN))
PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("KP +") PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(PLUS_PAD))
PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_UNUSED )
INPUT_PORTS_END
MACHINE_CONFIG_FRAGMENT(sparc_keyboard)
MCFG_SPEAKER_STANDARD_MONO("bell")
MCFG_SOUND_ADD("beeper", BEEP, ATTOSECONDS_TO_HZ(480 * ATTOSECONDS_PER_MICROSECOND))
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "bell", 1.0)
MACHINE_CONFIG_END
} // anonymous namespace
device_type const SPARC_KEYBOARD = &device_creator<sparc_keyboard_device>;
sparc_keyboard_device::sparc_keyboard_device(
machine_config const &mconfig,
char const *tag,
device_t *owner,
UINT32 clock)
: sparc_keyboard_device(mconfig,
SPARC_KEYBOARD,
"SPARC Keyboard",
tag,
owner,
clock,
"sparc_keyboard",
__FILE__)
{
}
sparc_keyboard_device::sparc_keyboard_device(
machine_config const &mconfig,
device_type type,
char const *name,
char const *tag,
device_t *owner,
UINT32 clock,
char const *shortname,
char const *source)
: device_t(mconfig, type, name, tag, owner, clock, shortname, source)
, device_serial_interface(mconfig, *this)
, device_rs232_port_interface(mconfig, *this)
, m_scan_timer(nullptr)
, m_tx_delay_timer(nullptr)
, m_dips(*this, "DIP")
, m_key_inputs{
{ *this, "ROW0" }, { *this, "ROW1" },
{ *this, "ROW2" }, { *this, "ROW3" },
{ *this, "ROW4" }, { *this, "ROW5" },
{ *this, "ROW6" }, { *this, "ROW7" } }
, m_beeper(*this, "beeper")
, m_current_keys{ 0, 0, 0, 0, 0, 0, 0, 0 }
, m_next_row(0)
, m_fifo{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
, m_head(0)
, m_tail(0)
, m_empty(0)
, m_rx_state(RX_IDLE)
, m_beeper_state(0)
{
}
machine_config_constructor sparc_keyboard_device::device_mconfig_additions() const
{
return MACHINE_CONFIG_NAME(sparc_keyboard);
}
ioport_constructor sparc_keyboard_device::device_input_ports() const
{
return INPUT_PORTS_NAME(sparc_keyboard);
}
WRITE_LINE_MEMBER( sparc_keyboard_device::input_txd )
{
device_serial_interface::rx_w(state);
}
void sparc_keyboard_device::device_start()
{
device_serial_interface::register_save_state(machine().save(), this);
m_scan_timer = timer_alloc(SCAN_TIMER_ID);
m_tx_delay_timer = timer_alloc(TX_DELAY_TIMER_ID);
save_item(NAME(m_current_keys));
save_item(NAME(m_next_row));
save_item(NAME(m_fifo));
save_item(NAME(m_head));
save_item(NAME(m_tail));
save_item(NAME(m_empty));
save_item(NAME(m_rx_state));
save_item(NAME(m_beeper_state));
}
void sparc_keyboard_device::device_reset()
{
// initialise state
std::fill(std::begin(m_current_keys), std::end(m_current_keys), 0x0000U);
m_next_row = 0;
std::fill(std::begin(m_fifo), std::end(m_fifo), 0);
m_head = m_tail = 0;
m_empty = 1;
m_rx_state = RX_IDLE;
m_beeper_state = 0;
// configure device_serial_interface
set_data_frame(1, 8, PARITY_NONE, STOP_BITS_1);
set_rate(9'600); // FIXME: should be 1'200 but the z80scc Baud rate generator is broken
receive_register_reset();
transmit_register_reset();
// set device_rs232_port_interface lines - note that only RxD is physically present
output_rxd(1);
output_dcd(0);
output_dsr(0);
output_ri(0);
output_cts(0);
// send reset response
send_byte(0xffU);
send_byte(0x04U);
UINT16 const acc(
std::accumulate(
std::begin(m_key_inputs),
std::end(m_key_inputs),
UINT16(0),
[] (UINT16 a, auto const &b) { return a | b->read(); }));
if (!acc)
send_byte(0x7fU);
// kick the scan timer
m_scan_timer->adjust(attotime::from_hz(1'200), 0, attotime::from_hz(1'200));
m_tx_delay_timer->reset();
}
void sparc_keyboard_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
switch (id)
{
case SCAN_TIMER_ID:
scan_row();
break;
case TX_DELAY_TIMER_ID:
assert(is_transmit_register_empty());
assert(!m_empty || (m_head == m_tail));
assert(m_head < ARRAY_LENGTH(m_fifo));
assert(m_tail < ARRAY_LENGTH(m_fifo));
if (!m_empty)
{
printf("SPARC keyboard: send queued: %02x\n", m_fifo[m_head]);
fflush(stdout);
transmit_register_setup(m_fifo[m_head]);
m_head = (m_head + 1) & 0x0fU;
m_empty = (m_head == m_tail) ? 1 : 0;
}
break;
default:
device_serial_interface::device_timer(timer, id, param, ptr);
}
}
void sparc_keyboard_device::tra_callback()
{
output_rxd(transmit_register_get_data_bit());
}
void sparc_keyboard_device::tra_complete()
{
m_tx_delay_timer->reset(attotime::from_hz(1'200 / 10));
}
void sparc_keyboard_device::rcv_complete()
{
receive_register_extract();
UINT8 const code(get_received_char());
printf("SPARC keyboard: received byte: %02x\n", code);
fflush(stdout);
switch (m_rx_state)
{
case RX_LED:
printf("SPARC keyboard: LED data: %02x\n", code);
fflush(stdout);
machine().output().set_led_value(LED_NUM, BIT(code, 0));
machine().output().set_led_value(LED_COMPOSE, BIT(code, 1));
machine().output().set_led_value(LED_SCROLL, BIT(code, 2));
machine().output().set_led_value(LED_CAPS, BIT(code, 3));
m_rx_state = RX_IDLE;
break;
default:
assert(m_rx_state == RX_IDLE);
case RX_IDLE:
switch (code)
{
// Reset
case 0x01U:
printf("SPARC keyboard: reset\n");
fflush(stdout);
device_reset();
break;
// Bell on
case 0x02U:
printf("SPARC keyboard: bell on\n");
fflush(stdout);
m_beeper_state |= UINT8(BEEPER_BELL);
m_beeper->set_state(m_beeper_state ? 1 : 0);
m_rx_state = RX_IDLE;
break;
// Bell off
case 0x03U:
printf("SPARC keyboard: bell off\n");
fflush(stdout);
m_beeper_state &= ~UINT8(BEEPER_BELL);
m_beeper->set_state(m_beeper_state ? 1 : 0);
m_rx_state = RX_IDLE;
break;
// Click on
case 0x0aU:
printf("SPARC keyboard: keyclick on\n");
fflush(stdout);
logerror("Keyclick on");
m_rx_state = RX_IDLE;
break;
// Click off
case 0x0bU:
printf("SPARC keyboard: keyclick off\n");
fflush(stdout);
logerror("Keyclick off");
m_rx_state = RX_IDLE;
break;
// LED command
case 0x0eU:
printf("SPARC keyboard: LED command\n");
fflush(stdout);
m_rx_state = RX_LED;
break;
// Layout command
case 0x0fU:
printf("SPARC keyboard: layout command\n");
fflush(stdout);
send_byte(UINT8(m_dips->read() & 0x3fU));
m_rx_state = RX_IDLE;
break;
default:
logerror("Unknown command: 0x%02x", code);
m_rx_state = RX_IDLE;
}
}
}
void sparc_keyboard_device::scan_row()
{
assert(m_next_row < ARRAY_LENGTH(m_key_inputs));
assert(m_next_row < ARRAY_LENGTH(m_current_keys));
UINT16 const row(m_key_inputs[m_next_row]->read());
UINT16 &current(m_current_keys[m_next_row]);
bool keyup(false);
for (UINT8 bit = 0; (bit < 16) && (m_empty || (m_head != m_tail)); ++bit)
{
UINT16 const mask(UINT16(1) << bit);
if ((row ^ current) & mask)
{
UINT8 const make_break((row & mask) ? 0x00U : 0x80U);
keyup = keyup || bool(make_break);
current = (current & ~mask) | (row & mask);
send_byte(make_break | (m_next_row << 4) | bit);
}
}
if (keyup)
{
UINT16 const acc(
std::accumulate(
std::begin(m_current_keys),
std::end(m_current_keys),
UINT16(0),
[] (UINT16 a, UINT16 b) { return a | b; }));
if (!acc)
send_byte(0x7fU);
}
m_next_row = (m_next_row + 1) & 0x07U;
}
void sparc_keyboard_device::send_byte(UINT8 code)
{
assert(!m_empty || (m_head == m_tail));
assert(m_head < ARRAY_LENGTH(m_fifo));
assert(m_tail < ARRAY_LENGTH(m_fifo));
if (m_empty && is_transmit_register_empty() && (m_tx_delay_timer->remaining() == attotime::never))
{
printf("SPARC keyboard: send immediately: %02x\n", code);
fflush(stdout);
transmit_register_setup(code);
}
else if (m_empty || (m_head != m_tail))
{
printf("SPARC keyboard: queue to send: %02x\n", code);
fflush(stdout);
m_fifo[m_tail] = code;
m_tail = (m_tail + 1) & 0x0fU;
m_empty = 0;
}
else
{
printf("SPARC keyboard: lost to overrun: %02x\n", code);
fflush(stdout);
logerror("FIFO overrun (code = 0x%02x)", code);
}
}

View File

@ -0,0 +1,82 @@
// license:BSD-3-Clause
// copyright-holders:Vas Crabb
#ifndef MAME_DEVICES_RS232_SPARCKBD_H
#define MAME_DEVICES_RS232_SPARCKBD_H
#pragma once
#include "rs232.h"
#include "sound/beep.h"
class sparc_keyboard_device : public device_t, public device_serial_interface, public device_rs232_port_interface
{
public:
sparc_keyboard_device(machine_config const &mconfig, char const *tag, device_t *owner, UINT32 clock);
sparc_keyboard_device(machine_config const &mconfig, device_type type, char const *name, char const *tag, device_t *owner, UINT32 clock, char const *shortname, char const *source);
virtual machine_config_constructor device_mconfig_additions() const override;
virtual ioport_constructor device_input_ports() const override;
virtual DECLARE_WRITE_LINE_MEMBER( input_txd ) override;
protected:
// device 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;
// device_serial_interface overrides
virtual void tra_callback() override;
virtual void tra_complete() override;
virtual void rcv_complete() override;
private:
// device_serial_interface uses 10'000 range
enum {
SCAN_TIMER_ID = 20'000,
TX_DELAY_TIMER_ID
};
// TODO: ensure these don't clash with diagnostic LEDs on host computer
enum : int {
LED_NUM = 0,
LED_COMPOSE,
LED_SCROLL,
LED_CAPS
};
enum : UINT8 {
BEEPER_BELL = 0x01U,
BEEPER_CLICK = 0x02U
};
enum : UINT8 {
RX_IDLE,
RX_LED
};
void scan_row();
void send_byte(UINT8 code);
emu_timer *m_scan_timer;
emu_timer *m_tx_delay_timer;
required_ioport m_dips;
required_ioport m_key_inputs[8];
required_device<beep_device> m_beeper;
UINT16 m_current_keys[8];
UINT8 m_next_row;
UINT8 m_fifo[16];
UINT8 m_head, m_tail;
UINT8 m_empty;
UINT8 m_rx_state;
UINT8 m_beeper_state;
};
extern const device_type SPARC_KEYBOARD;
#endif // MAME_DEVICES_RS232_SPARCKBD_H

View File

@ -88,7 +88,7 @@ DONE (x) (p=partly) NMOS CMOS ESCC EMSCC
#ifdef _MSC_VER
#define FUNCNAME __func__
#define LLFORMAT "%I64%"
#define LLFORMAT "%I64d"
#else
#define FUNCNAME __PRETTY_FUNCTION__
#define LLFORMAT "%lld"

View File

@ -386,7 +386,7 @@ Thanks to Alex, Mr Mudkips, and Philip Burke for this info.
#define LOG_PCI
//#define LOG_BASEBOARD
//#define VERBOSE_MSG
/////////////////////////
extern const device_type JVS_MASTER;
@ -804,9 +804,11 @@ int ohci_hlean2131qc_device::handle_nonstandard_request(int endpoint, USBSetupPa
{
int sense;
#ifdef VERBOSE_MSG
printf("Control request to an2131qc: %x %x %x %x %x %x %x\n\r", endpoint, endpoints[endpoint].controldirection, setup->bmRequestType, setup->bRequest, setup->wValue, setup->wIndex, setup->wLength);
#endif
if (endpoint != 0)
return -1;
printf("Control request to an2131qc: %x %x %x %x %x %x %x\n\r", endpoint, endpoints[endpoint].controldirection, setup->bmRequestType, setup->bRequest, setup->wValue, setup->wIndex, setup->wLength);
// default valuse for data stage
for (int n = 0; n < setup->wLength; n++)
endpoints[endpoint].buffer[n] = 0x50 ^ n;
@ -857,7 +859,7 @@ int ohci_hlean2131qc_device::handle_nonstandard_request(int endpoint, USBSetupPa
// data for the packets will be transferred to the host using endpoint 4 (IN)
// the nuber of bytes to transfer is returned at bytes 4 and 5 in the data stage of this control transfer
// data transferred starts with a byte with value 0, then a byte with value the number of packets received, then a block of bytes for each packet
// the bytes for a packet start with the jvs node address, then a dummy one (must be 0), then a 16 bit number in little endian format that specifies how many bytes follow
// the bytes for a packet start with the jvs node address of the sender, then a dummy one (must be 0), then a 16 bit number in little endian format that specifies how many bytes follow
// the bytes that follow contain the body of the packet as received from the jvs bus, from the 0xa0 byte to the checksum
endpoints[endpoint].buffer[0] = 0; // 0 if not busy
endpoints[endpoint].buffer[5] = jvs.buffer_out_used >> 8; // amount to transfer with endpoint 4
@ -910,7 +912,10 @@ int ohci_hlean2131qc_device::handle_nonstandard_request(int endpoint, USBSetupPa
// data for the packets will be transferred from the host using endpoint 4 (OUT)
// data sent by the host contains first a byte with value 0 that is ignored, then a byte specifying the number of packets that follow, then the data for each packet
// the data for each packet contains first a byte with value 0, then the sync byte (0xe0) then all the other bytes of the packet ending with the checksum byte
// broadcast packets must have a destination node address of value 0xff
#ifdef VERBOSE_MSG
printf(" Jvs packets data of %d bytes\n\r", setup->wIndex);
#endif
endpoints[endpoint].buffer[0] = 0;
if (jvs.buffer_out_used == 0)
{
@ -953,7 +958,9 @@ int ohci_hlean2131qc_device::handle_nonstandard_request(int endpoint, USBSetupPa
int ohci_hlean2131qc_device::handle_bulk_pid(int endpoint, int pid, UINT8 *buffer, int size)
{
#ifdef VERBOSE_MSG
printf("Bulk request: %x %d %x\n\r", endpoint, pid, size);
#endif
if (((endpoint == 1) || (endpoint == 2)) && (pid == InPid))
{
if (size > endpoints[endpoint].remain)
@ -974,15 +981,19 @@ int ohci_hlean2131qc_device::handle_bulk_pid(int endpoint, int pid, UINT8 *buffe
{
if (size > endpoints[4].remain)
size = endpoints[4].remain;
#ifdef VERBOSE_MSG
for (int n = 0; n < size; n++)
printf(" %02x", buffer[n]);
#endif
if (size > 0) {
memcpy(endpoints[4].position, buffer, size);
endpoints[4].position = endpoints[4].position + size;
endpoints[4].remain = endpoints[4].remain - size;
if (endpoints[4].remain == 0)
{
#ifdef VERBOSE_MSG
printf("\n\r");
#endif
// extract packets
int numpk = jvs.buffer_in[1];
int p = 2;
@ -1011,6 +1022,8 @@ int ohci_hlean2131qc_device::handle_bulk_pid(int endpoint, int pid, UINT8 *buffe
// use data of this packet
jvs.master->send_packet(dest, len, jvs.buffer_in + p);
// generate response
if (dest == 0xff)
dest = 0;
int recv = jvs.master->received_packet(jvs.buffer_out + jvs.buffer_out_used + 5);
// update buffer_out
if (recv > 0)
@ -1021,7 +1034,7 @@ int ohci_hlean2131qc_device::handle_bulk_pid(int endpoint, int pid, UINT8 *buffe
jvs.buffer_out[jvs.buffer_out_used + 5 + recv] = chk & 255;
jvs.buffer_out_packets++;
// jvs node address
jvs.buffer_out[jvs.buffer_out_used] = jvs.buffer_out[jvs.buffer_out_used + 5];
jvs.buffer_out[jvs.buffer_out_used] = (UINT8)dest;
// dummy
jvs.buffer_out[jvs.buffer_out_used + 1] = 0;
// length following
@ -1085,9 +1098,11 @@ void ohci_hlean2131sc_device::initialize(running_machine &machine, ohci_usb_cont
int ohci_hlean2131sc_device::handle_nonstandard_request(int endpoint, USBSetupPacket *setup)
{
//#ifdef VERBOSE_MSG
printf("Control request to an2131sc: %x %x %x %x %x %x %x\n\r", endpoint, endpoints[endpoint].controldirection, setup->bmRequestType, setup->bRequest, setup->wValue, setup->wIndex, setup->wLength);
//#endif
if (endpoint != 0)
return -1;
printf("Control request to an2131sc: %x %x %x %x %x %x %x\n\r", endpoint, endpoints[endpoint].controldirection, setup->bmRequestType, setup->bRequest, setup->wValue, setup->wIndex, setup->wLength);
for (int n = 0; n < setup->wLength; n++)
endpoints[endpoint].buffer[n] = 0xa0 ^ n;
endpoints[endpoint].position = endpoints[endpoint].buffer;

View File

@ -28,9 +28,13 @@ Notes:
- untoucha doesn't have it either; press "test" during boot for one kind
of service menu, "analyzer" at any other time for another menu (including
dip switch settings)
Note: screen asking to press test during boot does not show if machine contains credits.
TODO:
- dips/inputs for all games
- dips/inputs for some games
- untoucha: player high scores are lost when resetting
15-July 2016 - DIPs added to untoucha [theguru]
****************************************************************************/
@ -288,9 +292,9 @@ static INPUT_PORTS_START( hnayayoi )
PORT_START("COIN") /* COIN */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME(DEF_STR( Test )) PORT_CODE(KEYCODE_F1) /* Test */
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SERVICE2 ) /* Analizer (Statistics) */
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME(DEF_STR( Test )) PORT_CODE(KEYCODE_F1) // there is also a dip switch
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SERVICE2 ) PORT_NAME("Analizer")
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) // "Non Use" in service mode
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN2 ) /* "Note" ("Paper Money") = 10 Credits */
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(2)
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE1 )
@ -378,9 +382,9 @@ static INPUT_PORTS_START( hnfubuki )
PORT_START("COIN") /* COIN */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME(DEF_STR( Test )) PORT_CODE(KEYCODE_F1) /* Test */
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SERVICE2 ) /* Analizer (Statistics) */
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME(DEF_STR( Test )) PORT_CODE(KEYCODE_F1)
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SERVICE2 ) PORT_NAME("Analizer")
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_SERVICE3 ) PORT_NAME("Memory Reset")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN2 ) /* "Note" ("Paper Money") = 10 Credits */
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(2)
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE1 )
@ -391,64 +395,61 @@ INPUT_PORTS_END
static INPUT_PORTS_START( untoucha )
PORT_START("DSW1") /* DSW1 */
PORT_DIPNAME( 0x01, 0x01, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x01, 0x01, "Double-Up Difficulty" ) PORT_DIPLOCATION("SW1:8")
PORT_DIPSETTING( 0x01, "Normal" )
PORT_DIPSETTING( 0x00, "Difficult" )
PORT_DIPNAME( 0x06, 0x06, "Stage-Up Difficulty" ) PORT_DIPLOCATION("SW1:6,7")
PORT_DIPSETTING( 0x02, DEF_STR( Easy ) )
PORT_DIPSETTING( 0x06, DEF_STR( Medium ) )
PORT_DIPSETTING( 0x04, DEF_STR( Hard ) )
PORT_DIPSETTING( 0x00, DEF_STR( Hardest ) )
PORT_DIPNAME( 0x18, 0x18, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW1:4,5")
PORT_DIPSETTING( 0x08, DEF_STR( Easy ) )
PORT_DIPSETTING( 0x18, DEF_STR( Medium ) )
PORT_DIPSETTING( 0x10, DEF_STR( Hard ) )
PORT_DIPSETTING( 0x00, DEF_STR( Hardest ) )
PORT_DIPNAME( 0x60, 0x60, "Score Limit" ) PORT_DIPLOCATION("SW1:2,3")
PORT_DIPSETTING( 0x60, "200, 1000, 10000, 70000" )
PORT_DIPSETTING( 0x40, "250, 2000, 10000, 70000" )
PORT_DIPSETTING( 0x20, "500, 5000, 10000, 70000" )
PORT_DIPSETTING( 0x00, "1000, 5000, 10000, 70000" )
PORT_DIPNAME( 0x80, 0x80, "Stages" ) PORT_DIPLOCATION("SW1:1")
PORT_DIPSETTING( 0x80, "4" )
PORT_DIPSETTING( 0x00, "3" ) /* nudity only seems to show when Stages = 3? */
PORT_START("DSW2") /* DSW2 */
PORT_DIPNAME( 0x01, 0x01, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW2:1")
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x80, DEF_STR( On ) )
PORT_DIPNAME( 0x40, 0x40, "Speech" ) PORT_DIPLOCATION("SW2:2")
PORT_DIPSETTING( 0x40, DEF_STR( On ) )
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPNAME( 0x20, 0x20, "Unknown (Aumit?)" ) PORT_DIPLOCATION("SW2:3")
PORT_DIPSETTING( 0x20, DEF_STR( Off ) ) /* DIPSW sheet says 'AUMIT CUT WHEN ON' */
PORT_DIPSETTING( 0x00, DEF_STR( On ) ) /* Maybe it is Audit, but where/what? */
PORT_DIPNAME( 0x10, 0x10, "Auto Hold" ) PORT_DIPLOCATION("SW2:4")
PORT_DIPSETTING( 0x10, DEF_STR( On ) )
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPNAME( 0x08, 0x08, "Coin 2 (Credits)" ) PORT_DIPLOCATION("SW2:5")
PORT_DIPSETTING( 0x08, "1 Coin/5 Credits" )
PORT_DIPSETTING( 0x00, "1 Coin/8 Credits" )
PORT_DIPNAME( 0x07, 0x07, "Coin 1 (Score)" ) PORT_DIPLOCATION("SW2:6,7,8")
PORT_DIPSETTING( 0x01, "1 Coin/75 Score" )
PORT_DIPSETTING( 0x02, "1 Coin/50 Score" )
PORT_DIPSETTING( 0x03, "1 Coin/20 Score" )
PORT_DIPSETTING( 0x04, "1 Coin/15 Score" )
PORT_DIPSETTING( 0x07, "1 Coin/25 Score" )
PORT_DIPSETTING( 0x05, "1 Coin/10 Score" )
PORT_DIPSETTING( 0x06, "1 Coin/5 Score" )
PORT_DIPSETTING( 0x00, "1 Coin/100 Score" )
PORT_START("COIN") /* COIN */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME(DEF_STR(Test)) PORT_CODE(KEYCODE_F1) /* Test */
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SERVICE2 ) /* Analizer (Statistics) */
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN2 ) /* "Note" ("Paper Money") = 10 Credits */
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME(DEF_STR( Test )) PORT_CODE(KEYCODE_F1)
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SERVICE2 ) PORT_NAME("Analizer")
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_SERVICE3 ) PORT_NAME("Memory Reset")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN2 ) /* "Note" ("Paper Money") = 5 or 8 Credits */
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(2)
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE1 )
@ -492,7 +493,7 @@ static INPUT_PORTS_START( untoucha )
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_D_UP )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Flip Flop") PORT_CODE(KEYCODE_F)
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Flip Flop") PORT_CODE(KEYCODE_F) /* what does this do? */
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
@ -675,4 +676,4 @@ DRIVER_INIT_MEMBER(hnayayoi_state,hnfubuki)
GAME( 1987, hnayayoi, 0, hnayayoi, hnayayoi, driver_device, 0, ROT0, "Dyna Electronics", "Hana Yayoi (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, hnfubuki, hnayayoi, hnfubuki, hnfubuki, hnayayoi_state, hnfubuki, ROT0, "Dynax", "Hana Fubuki [BET] (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, untoucha, 0, untoucha, untoucha, driver_device, 0, ROT0, "Dynax", "Untouchable (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, untoucha, 0, untoucha, untoucha, driver_device, 0, ROT0, "Dynax", "Untouchable (Ver. 2.10)", MACHINE_SUPPORTS_SAVE )

View File

@ -1,12 +1,30 @@
// license:BSD-3-Clause
// copyright-holders:Miodrag Milanovic
/***************************************************************************
// copyright-holders:Miodrag Milanovic, Robbbert
/**********************************************************************************************
Morrow Designs Micro Decision
Morrow Designs Micro Decision
2009-12-10 Skeleton driver.
2009-12-10 Skeleton driver.
****************************************************************************/
Although it looks like an ordinary CP/M computer, the monitor and keyboard are actually a
dumb terminal plugged into the base unit. Therefore the roms and details of the terminal are
needed.
Board design changes depending on bios version of base unit:
In earliest design, F7 sets up VFO and F8 selects motor on, while fdc does drive select.
Later version gets rid of these, and F7 now does motor on and drive select; also addition of
i8253 timer, a centronics port, and a diagnostic jumper. F8 is unused.
Currently (as at 2016-07-17), memory test works, rom banking works, disk does NOT boot.
Ver 1 roms say "Not found", Ver 2 roms hang after pressing enter, Ver 3 rom hangs after memory test.
ToDo:
- Make the floppy boot
- Add i8253 timer chip
- Add centronics parts
- Different hardware for different bios versions (only earliest design is coded)
***********************************************************************************************/
#include "emu.h"
#include "cpu/z80/z80.h"
@ -14,27 +32,41 @@
#include "machine/terminal.h"
#include "softlist.h"
#define TERMINAL_TAG "terminal"
class microdec_state : public driver_device
{
public:
microdec_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_terminal(*this, TERMINAL_TAG),
m_maincpu(*this, "maincpu")
: driver_device(mconfig, type, tag)
, m_terminal(*this, "terminal")
, m_maincpu(*this, "maincpu")
, m_fdc(*this, "fdc")
, m_floppy0(*this, "fdc:0")
, m_floppy(nullptr)
{
}
DECLARE_READ8_MEMBER(status_r);
DECLARE_READ8_MEMBER(keyin_r);
DECLARE_WRITE8_MEMBER(kbd_put);
DECLARE_READ8_MEMBER(portf5_r);
DECLARE_READ8_MEMBER(portf6_r);
DECLARE_WRITE8_MEMBER(portf6_w);
DECLARE_READ8_MEMBER(portf7_r);
DECLARE_WRITE8_MEMBER(portf7_w);
DECLARE_WRITE8_MEMBER(portf8_w);
DECLARE_DRIVER_INIT(microdec);
private:
UINT8 m_term_data;
UINT8 m_portf8;
bool m_fdc_rdy;
virtual void machine_reset() override;
virtual void machine_start() override;
required_device<generic_terminal_device> m_terminal;
required_device<cpu_device> m_maincpu;
required_device<upd765a_device> m_fdc;
required_device<floppy_connector> m_floppy0;
floppy_image_device *m_floppy;
};
@ -50,17 +82,74 @@ READ8_MEMBER( microdec_state::keyin_r )
return ret;
}
/*
d0-2 : motor on signals from f8
d3 : ack (cent)
d4 : ready (fdd)
d5 : diag jumper (md3 only) */
READ8_MEMBER( microdec_state::portf5_r )
{
m_fdc->set_ready_line_connected(m_fdc_rdy);
UINT8 data = m_portf8 | ioport("DIAG")->read() | 0xc0;
return data;
}
// disable eprom
READ8_MEMBER( microdec_state::portf6_r )
{
membank("bankr0")->set_entry(0); // point at ram
return 0xff;
}
// TC pin on fdc
READ8_MEMBER( microdec_state::portf7_r )
{
m_fdc->tc_w(1);
return 0xff;
}
// enable eprom
WRITE8_MEMBER( microdec_state::portf6_w )
{
membank("bankr0")->set_entry(1); // point at rom
}
// sets up VFO stuff
WRITE8_MEMBER( microdec_state::portf7_w )
{
m_fdc_rdy = BIT(data,2);
}
/*
d0-2 : motor on for drive sockets
d3 : precomp */
WRITE8_MEMBER( microdec_state::portf8_w )
{
m_portf8 = data & 7;
/* code for motor on per drive goes here */
m_floppy = m_floppy0->get_device();
m_fdc->set_floppy(m_floppy);
if (m_floppy)
m_floppy->mon_w(0);
}
static ADDRESS_MAP_START(microdec_mem, AS_PROGRAM, 8, microdec_state)
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE( 0x0000, 0x0fff ) AM_ROM
AM_RANGE( 0x0000, 0x0fff ) AM_READ_BANK("bankr0") AM_WRITE_BANK("bankw0")
AM_RANGE( 0x1000, 0xffff ) AM_RAM
ADDRESS_MAP_END
static ADDRESS_MAP_START(microdec_io, AS_IO, 8, microdec_state)
ADDRESS_MAP_UNMAP_HIGH
ADDRESS_MAP_GLOBAL_MASK(0xff)
AM_RANGE(0xfa, 0xfb) AM_DEVICE("upd765", upd765a_device, map)
AM_RANGE(0xfc, 0xfc) AM_READ(keyin_r) AM_DEVWRITE(TERMINAL_TAG, generic_terminal_device, write)
AM_RANGE(0xf5, 0xf5) AM_READ(portf5_r)
AM_RANGE(0xf6, 0xf6) AM_READWRITE(portf6_r,portf6_w)
AM_RANGE(0xf7, 0xf7) AM_READWRITE(portf7_r,portf7_w)
AM_RANGE(0xf8, 0xf8) AM_WRITE(portf8_w)
AM_RANGE(0xfa, 0xfb) AM_DEVICE("fdc", upd765a_device, map)
AM_RANGE(0xfc, 0xfc) AM_READ(keyin_r) AM_DEVWRITE("terminal", generic_terminal_device, write)
AM_RANGE(0xfd, 0xfd) AM_READ(status_r)
// AM_RANGE(0xf0, 0xf3) 8253 PIT (md3 only) used as a baud rate generator for serial ports
// AM_RANGE(0xf4, 0xf4) Centronics data
@ -68,14 +157,18 @@ static ADDRESS_MAP_START(microdec_io, AS_IO, 8, microdec_state)
// AM_RANGE(0xf5, 0xf5) Centronics status (md3) read bit 3 (ack=1); read bit 4 (busy=1); write bit 7 (stb=0)
// AM_RANGE(0xf6, 0xf6) rom enable (w=enable; r=disable)
// AM_RANGE(0xf7, 0xf7) VFO Count set
// AM_RANGE(0xf8, 0xf8) Motor and SHift control
// AM_RANGE(0xf8, 0xf8) Motor and Shift control
// AM_RANGE(0xfa, 0xfb) uPD765C fdc FA=status; FB=data
// AM_RANGE(0xfc, 0xfd) Serial Port 1 FC=data FD=status
// AM_RANGE(0xfe, 0xff) Serial Port 2 FE=data FF=status
// AM_RANGE(0xfc, 0xfd) Serial Port 1 (terminal) FC=data FD=status
// AM_RANGE(0xfe, 0xff) Serial Port 2 (printer) FE=data FF=status
ADDRESS_MAP_END
/* Input ports */
static INPUT_PORTS_START( microdec )
PORT_START("DIAG")
PORT_DIPNAME( 0x20, 0x20, "Diagnostics" )
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
INPUT_PORTS_END
void microdec_state::machine_start()
@ -84,6 +177,9 @@ void microdec_state::machine_start()
void microdec_state::machine_reset()
{
membank("bankr0")->set_entry(1); // point at rom
membank("bankw0")->set_entry(0); // always write to ram
m_maincpu->set_input_line_vector(0, 0x7f);
m_term_data = 0;
}
@ -96,6 +192,15 @@ static SLOT_INTERFACE_START( microdec_floppies )
SLOT_INTERFACE( "525hd", FLOPPY_525_HD )
SLOT_INTERFACE_END
DRIVER_INIT_MEMBER( microdec_state, microdec )
{
UINT8 *main = memregion("maincpu")->base();
membank("bankr0")->configure_entry(1, &main[0x0000]);
membank("bankr0")->configure_entry(0, &main[0x1000]);
membank("bankw0")->configure_entry(0, &main[0x1000]);
}
static MACHINE_CONFIG_START( microdec, microdec_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu",Z80, XTAL_4MHz)
@ -103,12 +208,15 @@ static MACHINE_CONFIG_START( microdec, microdec_state )
MCFG_CPU_IO_MAP(microdec_io)
/* video hardware */
MCFG_DEVICE_ADD(TERMINAL_TAG, GENERIC_TERMINAL, 0)
MCFG_DEVICE_ADD("terminal", GENERIC_TERMINAL, 0)
MCFG_GENERIC_TERMINAL_KEYBOARD_CB(WRITE8(microdec_state, kbd_put))
MCFG_UPD765A_ADD("upd765", true, true)
MCFG_FLOPPY_DRIVE_ADD("upd765:0", microdec_floppies, "525hd", floppy_image_device::default_floppy_formats)
MCFG_FLOPPY_DRIVE_ADD("upd765:1", microdec_floppies, "525hd", floppy_image_device::default_floppy_formats)
MCFG_UPD765A_ADD("fdc", true, true)
MCFG_UPD765_INTRQ_CALLBACK(INPUTLINE("maincpu", INPUT_LINE_IRQ0))
MCFG_FLOPPY_DRIVE_ADD("fdc:0", microdec_floppies, "525hd", floppy_image_device::default_floppy_formats)
MCFG_FLOPPY_DRIVE_SOUND(true)
//MCFG_FLOPPY_DRIVE_ADD("fdc:1", microdec_floppies, "525hd", floppy_image_device::default_floppy_formats)
//MCFG_FLOPPY_DRIVE_SOUND(true)
// software lists
MCFG_SOFTWARE_LIST_ADD("flop_list", "md2_flop")
@ -116,7 +224,7 @@ MACHINE_CONFIG_END
/* ROM definition */
ROM_START( md2 )
ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF )
ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASEFF )
ROM_SYSTEM_BIOS( 0, "v13", "v1.3" )
ROMX_LOAD( "md2-13.bin", 0x0000, 0x0800, CRC(43f4c9ab) SHA1(48a35cbee4f341310e9cba5178c3fd6e74ef9748), ROM_BIOS(1))
ROM_SYSTEM_BIOS( 1, "v13a", "v1.3a" )
@ -130,7 +238,7 @@ ROM_START( md2 )
ROM_END
ROM_START( md3 )
ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF )
ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASEFF )
ROM_SYSTEM_BIOS( 0, "v23a", "v2.3a" )
ROMX_LOAD( "md3-23a.bin", 0x0000, 0x1000, CRC(95d59980) SHA1(ae65a8e8e2823cf4cf6b1d74c0996248e290e9f1), ROM_BIOS(1))
ROM_SYSTEM_BIOS( 1, "v25", "v2.5" )
@ -142,5 +250,5 @@ ROM_END
/* Driver */
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
COMP( 1982, md2, 0, 0, microdec, microdec, driver_device, 0, "Morrow Designs", "Micro Decision MD-2", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
COMP( 1982, md3, md2, 0, microdec, microdec, driver_device, 0, "Morrow Designs", "Micro Decision MD-3", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
COMP( 1982, md2, 0, 0, microdec, microdec, microdec_state, microdec, "Morrow Designs", "Micro Decision MD-2", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW )
COMP( 1982, md3, md2, 0, microdec, microdec, microdec_state, microdec, "Morrow Designs", "Micro Decision MD-3", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW )

View File

@ -417,6 +417,7 @@
#include "machine/bankdev.h"
#include "machine/nvram.h"
#include "bus/rs232/rs232.h"
#include "bus/rs232/sparckbd.h"
#include "machine/timekpr.h"
#include "machine/upd765.h"
#include "formats/pc_dsk.h"
@ -431,6 +432,7 @@
#define TIMEKEEPER_TAG "timekpr"
#define SCC1_TAG "scc1"
#define SCC2_TAG "scc2"
#define KEYBOARD_TAG "keyboard"
#define RS232A_TAG "rs232a"
#define RS232B_TAG "rs232b"
#define FDC_TAG "fdc"
@ -483,6 +485,11 @@ const sparc_disassembler::asi_desc_map::value_type sun4c_asi_desc[] = {
{ 0x0d, { nullptr, "Flush Cache (Page)" } },
{ 0x0e, { nullptr, "Flush Cache (Context)" } }
};
// TODO: put this somewhere common when sun4m, sun4d, sun4u, etc. are split out
SLOT_INTERFACE_START(keyboard_devices)
SLOT_INTERFACE("keyboard", SPARC_KEYBOARD)
SLOT_INTERFACE_END
}
enum
@ -533,6 +540,9 @@ public:
DECLARE_READ8_MEMBER( fdc_r );
DECLARE_WRITE8_MEMBER( fdc_w );
DECLARE_WRITE_LINE_MEMBER( scc1_int );
DECLARE_WRITE_LINE_MEMBER( scc2_int );
DECLARE_DRIVER_INIT(sun4);
DECLARE_DRIVER_INIT(sun4c);
DECLARE_DRIVER_INIT(ss2);
@ -567,6 +577,7 @@ private:
UINT8 m_ctx_mask; // SS2 is sun4c but has 16 contexts; most have 8
UINT8 m_pmeg_mask; // SS2 is sun4c but has 16384 PTEs; most have 8192
UINT8 m_irq_reg; // IRQ control
UINT8 m_scc1_int, m_scc2_int;
UINT8 m_diag;
int m_arch;
@ -850,7 +861,7 @@ WRITE32_MEMBER( sun4_state::sun4c_mmu_w )
UINT32 tmp = (m_pagemap[entry] & 0xffff) << 10;
tmp |= (offset & 0x3ff);
printf("sun4: write translated vaddr %08x to phys %08x type %d, PTE %08x, ASI %d, PC=%x\n", offset<<2, tmp<<2, (m_pagemap[entry]>>26) & 3, m_pagemap[entry], asi, m_maincpu->pc());
//printf("sun4: write translated vaddr %08x to phys %08x type %d, PTE %08x, ASI %d, PC=%x\n", offset<<2, tmp<<2, (m_pagemap[entry]>>26) & 3, m_pagemap[entry], asi, m_maincpu->pc());
switch ((m_pagemap[entry] >> 26) & 3)
{
@ -1241,6 +1252,7 @@ void sun4_state::machine_reset()
m_context = 0;
m_system_enable = 0;
m_irq_reg = 0;
m_scc1_int = m_scc2_int = 0;
memset(m_counter, 0, sizeof(m_counter));
}
@ -1413,6 +1425,24 @@ WRITE8_MEMBER( sun4_state::irq_w )
//printf("%02x to IRQ\n", data);
m_irq_reg = data;
m_maincpu->set_input_line(SPARC_IRQ12, ((m_scc1_int || m_scc2_int) && (m_irq_reg & 0x01)) ? ASSERT_LINE : CLEAR_LINE);
}
WRITE_LINE_MEMBER( sun4_state::scc1_int )
{
printf("scc1 int: %d\n", state);
m_scc1_int = state;
m_maincpu->set_input_line(SPARC_IRQ12, ((m_scc1_int || m_scc2_int) && (m_irq_reg & 0x01)) ? ASSERT_LINE : CLEAR_LINE);
}
WRITE_LINE_MEMBER( sun4_state::scc2_int )
{
printf("scc2 int: %d\n", state);
m_scc2_int = state;
m_maincpu->set_input_line(SPARC_IRQ12, ((m_scc1_int || m_scc2_int) && (m_irq_reg & 0x01)) ? ASSERT_LINE : CLEAR_LINE);
}
void sun4_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
@ -1576,8 +1606,17 @@ static MACHINE_CONFIG_START( sun4, sun4_state )
MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32)
MCFG_ADDRESS_MAP_BANK_STRIDE(0x80000000)
// Keyboard/mouse
MCFG_SCC8530_ADD(SCC1_TAG, XTAL_4_9152MHz, 0, 0, 0, 0)
MCFG_Z80SCC_OUT_INT_CB(WRITELINE(sun4_state, scc1_int))
MCFG_Z80SCC_OUT_TXDA_CB(DEVWRITELINE(KEYBOARD_TAG, rs232_port_device, write_txd))
MCFG_RS232_PORT_ADD(KEYBOARD_TAG, keyboard_devices, "keyboard")
MCFG_RS232_RXD_HANDLER(DEVWRITELINE(SCC1_TAG, z80scc_device, rxa_w))
// RS232 serial ports
MCFG_SCC8530_ADD(SCC2_TAG, XTAL_4_9152MHz, 0, 0, 0, 0)
MCFG_Z80SCC_OUT_INT_CB(WRITELINE(sun4_state, scc2_int))
MCFG_Z80SCC_OUT_TXDA_CB(DEVWRITELINE(RS232A_TAG, rs232_port_device, write_txd))
MCFG_Z80SCC_OUT_TXDB_CB(DEVWRITELINE(RS232B_TAG, rs232_port_device, write_txd))
@ -1621,8 +1660,17 @@ static MACHINE_CONFIG_START( sun4c, sun4_state )
MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32)
MCFG_ADDRESS_MAP_BANK_STRIDE(0x80000000)
// Keyboard/mouse
MCFG_SCC8530_ADD(SCC1_TAG, XTAL_4_9152MHz, 0, 0, 0, 0)
MCFG_Z80SCC_OUT_INT_CB(WRITELINE(sun4_state, scc1_int))
MCFG_Z80SCC_OUT_TXDA_CB(DEVWRITELINE(KEYBOARD_TAG, rs232_port_device, write_txd))
MCFG_RS232_PORT_ADD(KEYBOARD_TAG, keyboard_devices, "keyboard")
MCFG_RS232_RXD_HANDLER(DEVWRITELINE(SCC1_TAG, z80scc_device, rxa_w))
// RS232 serial ports
MCFG_SCC8530_ADD(SCC2_TAG, XTAL_4_9152MHz, 0, 0, 0, 0)
MCFG_Z80SCC_OUT_INT_CB(WRITELINE(sun4_state, scc2_int))
MCFG_Z80SCC_OUT_TXDA_CB(DEVWRITELINE(RS232A_TAG, rs232_port_device, write_txd))
MCFG_Z80SCC_OUT_TXDB_CB(DEVWRITELINE(RS232B_TAG, rs232_port_device, write_txd))