From fa45a71bce71e953feeb0a356f5537422301009a Mon Sep 17 00:00:00 2001 From: Patrick Mackinlay Date: Mon, 23 Oct 2017 18:17:19 +0700 Subject: interpro: expansion bus/slots and keyboard * added basic support for the system bus variously referred to as SR, SR bus, SRX and CBUS * added an initial GT graphics card implementation, only supports the video ram and ramdac for now, but sufficient to boot the diagnostic monitor in graphics mode * added a high-level emulation of the InterPro keyboard --- scripts/src/bus.lua | 30 ++ scripts/target/mame/mess.lua | 2 + src/devices/bus/interpro/keyboard/hle.cpp | 461 +++++++++++++++++++++++++ src/devices/bus/interpro/keyboard/hle.h | 113 ++++++ src/devices/bus/interpro/keyboard/keyboard.cpp | 67 ++++ src/devices/bus/interpro/keyboard/keyboard.h | 71 ++++ src/devices/bus/interpro/sr/gt.cpp | 199 +++++++++++ src/devices/bus/interpro/sr/gt.h | 110 ++++++ src/devices/bus/interpro/sr/sr.cpp | 379 ++++++++++++++++++++ src/devices/bus/interpro/sr/sr.h | 139 ++++++++ src/devices/bus/interpro/sr/sr_cards.cpp | 24 ++ src/devices/bus/interpro/sr/sr_cards.h | 12 + 12 files changed, 1607 insertions(+) create mode 100644 src/devices/bus/interpro/keyboard/hle.cpp create mode 100644 src/devices/bus/interpro/keyboard/hle.h create mode 100644 src/devices/bus/interpro/keyboard/keyboard.cpp create mode 100644 src/devices/bus/interpro/keyboard/keyboard.h create mode 100644 src/devices/bus/interpro/sr/gt.cpp create mode 100644 src/devices/bus/interpro/sr/gt.h create mode 100644 src/devices/bus/interpro/sr/sr.cpp create mode 100644 src/devices/bus/interpro/sr/sr.h create mode 100644 src/devices/bus/interpro/sr/sr_cards.cpp create mode 100644 src/devices/bus/interpro/sr/sr_cards.h diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 29605ec7213..ad79fd7d66c 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -3238,3 +3238,33 @@ if (BUSES["PSI_KEYBOARD"]~=null) then MAME_DIR .. "src/devices/bus/psi_kbd/hle.h", } end + +--------------------------------------------------- +-- +--@src/devices/bus/interpro/sr/sr.h,BUSES["INTERPRO_SR"] = true +--------------------------------------------------- + +if (BUSES["INTERPRO_SR"]~=null) then + files { + MAME_DIR .. "src/devices/bus/interpro/sr/sr.cpp", + MAME_DIR .. "src/devices/bus/interpro/sr/sr.h", + MAME_DIR .. "src/devices/bus/interpro/sr/sr_cards.cpp", + MAME_DIR .. "src/devices/bus/interpro/sr/sr_cards.h", + MAME_DIR .. "src/devices/bus/interpro/sr/gt.cpp", + MAME_DIR .. "src/devices/bus/interpro/sr/gt.h", + } +end + +--------------------------------------------------- +-- +--@src/devices/bus/interpro/keyboard/keyboard.h,BUSES["INTERPRO_KEYBOARD"] = true +--------------------------------------------------- + +if (BUSES["INTERPRO_KEYBOARD"]~=null) then + files { + MAME_DIR .. "src/devices/bus/interpro/keyboard/keyboard.cpp", + MAME_DIR .. "src/devices/bus/interpro/keyboard/keyboard.h", + MAME_DIR .. "src/devices/bus/interpro/keyboard/hle.cpp", + MAME_DIR .. "src/devices/bus/interpro/keyboard/hle.h" + } +end diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 916c4be6903..12b5978dcbf 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -675,6 +675,8 @@ BUSES["HPDIO"] = true BUSES["IEEE488"] = true BUSES["IMI7000"] = true BUSES["INTELLEC4"] = true +BUSES["INTERPRO_SR"] = true +BUSES["INTERPRO_KEYBOARD"] = true BUSES["INTV"] = true BUSES["INTV_CTRL"] = true BUSES["IQ151"] = true diff --git a/src/devices/bus/interpro/keyboard/hle.cpp b/src/devices/bus/interpro/keyboard/hle.cpp new file mode 100644 index 00000000000..a455f9227e3 --- /dev/null +++ b/src/devices/bus/interpro/keyboard/hle.cpp @@ -0,0 +1,461 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +/* + * A high level emulation implementation of the Intergraph InterPro keyboard, + * largely copied from the sunkbd and psi hle implementations. + * + * These keyboards have two primary banks of keys. The lower bank consists of + * a total of 67 regular keyboard keyswitches plus a numeric keypad with a + * further 18 keys. The upper bank consists of 57 membrane-style programmable + * function keys in groups of 9, 36 and 12 from left to right. + * + * The following describes the key labels and positions according to the + * standard US English keyboard layout. It's unknown what other variations + * existed at this point. + * + * Upper bank keys indicated here with asterisks are printed in white, as are + * all the A*, B* and C* keys; all the others are printed in brown. + * + * Setup* Home* 2nd A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15 2nd + * Help Clear F* F* + * Screen + * + * Find Insert Print B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 + * Here Screen* + * Remove + * + * Select Prev Next C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15 C16 + * Screen Screen + * + * + * In between the banks on the right hand side, there is a row of LEDs, the + * first three are pictures, rather than the descriptions given here). + * + * Disk Lock ----- L1 L2 L3 L4 + * + * Lower bank keys have up to 3 labels, in shifted and unshifted positions, and + * in red on the front face of the key-cap. + * + * Esc ~ ! @ # $ % ^ & * ( ) _ + Back Delete PF1 PF2 PF3 PF4 + * ` 1 2 3 4 5 6 7 8 9 0 - = Space ± ÷ × + + * Esc Num Lk ScrlLk Sys + * + * Alt Tab Q W E R T Y U I O P { } 7 8 9 _ + * Mode [ ] + * Home ↑ Pg Up Prt Sc + * + * Ctrl Caps A S D F G H J K L : " | Return 4 5 6 , + * Lock + * ← → − + * + * Shift > Z X C V B N M , . ? Shift ▲ 1 2 3 = + * < ■ + * End ↓ Pg Dn + * + * Hold Super- Line Repeat ◄ ■ ► 0 ◦ + * Screen impose Feed ▼ . Enter + * Ins Del + + * + * Alt Mode and Caps Lock keys have locking switches, capturing the key in the + * depressed position, as well as physical leds visible on the keycaps + * themselves. The keyboard also has two physical buttons on the back face of + * the keyboard, circular button labelled Boot, and a square one labelled Reset. + * + * The keyboard uses a 1200bps serial protocol to communicate with the host, + * with 1 start bit, 8 data bits, 1 stop bit, and even parity. The protocol + * as far as is known consists of the following sequences: + * + * From Host Purpose Expected Response + * --------- ------- ----------------- + * D Diagnostic 0xff , where status bits are set to + * indicate diagnostic failure source: 0x8=EPROM + * checksum, 0x10=RAM error, 0x20=ROM checksum + * + * B ( Bell On None + * + * B ) Bell Off None + * + * B Unknown None + * + * The keyboard has a keyboard click function, and the LED indicators described + * earlier, meaning that there are additional commands to enable and disable + * these functions. + * + * The keyboard transmits ASCII codes corresponding to the keycap labels for + * keys which map to the ASCII character set. Modifiers are applied by the + * keyboard itself, and do not generate make/break codes of their own. + * + * The following non-ASCII sequences are recognised in the system software, + * and likely correspond to specific keyboard keys or buttons: + * + * Sequence Function + * -------- -------- + * ^L Reboot, possibly maps to Reboot button + * ^M Unknown + * ^N Unknown, but operates as a toggle + * ^U Unknown + * + * TODO + * - unmapped keys + * - auto-repeat + * - key click and LED commands + * - alternative layouts + * + */ +#include "emu.h" +#include "hle.h" + +#include "machine/keyboard.ipp" +#include "speaker.h" + +#define VERBOSE 0 +#include "logmacro.h" + +DEFINE_DEVICE_TYPE_NS(INTERPRO_HLE_EN_US_KEYBOARD, bus::interpro::keyboard, hle_en_us_device, "kbd_hle_en_us", "InterPro Keyboard (HLE, US English)") + +namespace bus { namespace interpro { namespace keyboard { + +namespace { + + u8 const TRANSLATION_TABLE[4][5][16] = + { + // unshifted + { + { 0x1b, 0x60, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x2d, 0x3d, 0x08, 0x7f }, // 0 + { 0x00, 0x09, 0x71, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69, 0x6f, 0x70, 0x5b, 0x5d, 0x00, 0x00 }, // 1 + { 0x00, 0x00, 0x61, 0x73, 0x64, 0x66, 0x67, 0x68, 0x6a, 0x6b, 0x6c, 0x3b, 0x27, 0x5c, 0x0d, 0x00 }, // 2 + { 0x00, 0x3c, 0x7a, 0x78, 0x63, 0x76, 0x62, 0x6e, 0x6d, 0x2c, 0x2e, 0x2f, 0x00, 0x00, 0x00, 0x00 }, // 3 + { 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 4 + }, + // shifted + { + { 0x1b, 0x7e, 0x21, 0x40, 0x23, 0x24, 0x25, 0x5e, 0x26, 0x2a, 0x28, 0x29, 0x5f, 0x2b, 0x08, 0x7f }, // 0 + { 0x00, 0x09, 0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49, 0x4f, 0x50, 0x7b, 0x7d, 0x00, 0x00 }, // 1 + { 0x00, 0x00, 0x41, 0x53, 0x44, 0x46, 0x47, 0x48, 0x4a, 0x4b, 0x4c, 0x3a, 0x22, 0x7c, 0x0d, 0x00 }, // 2 + { 0x00, 0x3e, 0x5a, 0x58, 0x43, 0x56, 0x42, 0x4e, 0x4d, 0x2c, 0x2e, 0x3f, 0x00, 0x00, 0x00, 0x00 }, // 3 + { 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 4 + }, + // unshifted-control + { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0 + { 0x00, 0x00, 0x11, 0x17, 0x05, 0x12, 0x14, 0x19, 0x15, 0x09, 0x0f, 0x10, 0x1b, 0x1d, 0x00, 0x00 }, // 1 + { 0x00, 0x00, 0x01, 0x13, 0x04, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0c, 0x00, 0x00, 0x1c, 0x00, 0x00 }, // 2 + { 0x00, 0x00, 0x1a, 0x18, 0x03, 0x16, 0x02, 0x0e, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 3 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 4 + }, + // shifted-control + { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0 + { 0x00, 0x00, 0x11, 0x17, 0x05, 0x12, 0x14, 0x19, 0x15, 0x09, 0x0f, 0x10, 0x1b, 0x1d, 0x00, 0x00 }, // 1 + { 0x00, 0x00, 0x01, 0x13, 0x04, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0c, 0x00, 0x00, 0x1c, 0x00, 0x00 }, // 2 + { 0x00, 0x00, 0x1a, 0x18, 0x03, 0x16, 0x02, 0x0e, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 3 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 4 + } + }; + +INPUT_PORTS_START(interpro_en_us) + + PORT_START("modifiers") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_NAME("Control") PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_NAME("Shift") PORT_CHAR(UCHAR_SHIFT_1) + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_CAPSLOCK) PORT_NAME("Caps Lock") PORT_TOGGLE PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) + + PORT_START("row_0") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC) PORT_NAME("Esc") PORT_CHAR(UCHAR_MAMEKEY(ESC)) + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') + PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') + PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') + PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_NAME("Backspace") PORT_CHAR(8) + PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL) PORT_NAME("Delete") PORT_CHAR(UCHAR_MAMEKEY(DEL)) + + PORT_START("row_1") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_UNUSED) // "Alt Mode" + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TAB) PORT_NAME("Tab") PORT_CHAR(9) + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') + PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') + PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') + + PORT_START("row_2") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_UNUSED) // CTRL + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_UNUSED) // LOCK + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') + PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') + PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"') + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') + PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) PORT_NAME("Return") PORT_CHAR(13) + + PORT_START("row_3") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_UNUSED) // LSHIFT + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSLASH2) PORT_CHAR('<') PORT_CHAR('>') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') + PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') + PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_UNUSED) // RSHIFT + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_NAME("Up") PORT_CHAR(UCHAR_MAMEKEY(UP)) + + PORT_START("row_4") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_UNUSED) // "Hold Screen" + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_UNUSED) // "Superimpose" + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_UNUSED) // "Line Feed" + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_NAME("Space") PORT_CHAR(UCHAR_MAMEKEY(SPACE)) + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_UNUSED) // "Repeat" + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_NAME("Left") PORT_CHAR(UCHAR_MAMEKEY(LEFT)) + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_NAME("Down") PORT_CHAR(UCHAR_MAMEKEY(DOWN)) + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_NAME("Right") PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) + +INPUT_PORTS_END + +INPUT_PORTS_START(hle_en_us_device) + PORT_INCLUDE(interpro_en_us) +INPUT_PORTS_END + +} // anonymous namespace + +hle_device_base::hle_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock) + : device_t(mconfig, type, tag, owner, clock) + , device_buffered_serial_interface(mconfig, *this) + , device_interpro_keyboard_port_interface(mconfig, *this) + , device_matrix_keyboard_interface(mconfig, *this, "row_0", "row_1", "row_2", "row_3", "row_4") + , m_click_timer(nullptr) + , m_beeper(*this, "beeper") + , m_make_count(0U) + , m_rx_state(RX_IDLE) + , m_keyclick(0U) + , m_beeper_state(0U) +{ +} + +hle_device_base::~hle_device_base() +{ +} + +WRITE_LINE_MEMBER(hle_device_base::input_txd) +{ + device_buffered_serial_interface::rx_w(state); +} + +MACHINE_CONFIG_MEMBER(hle_device_base::device_add_mconfig) + 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 + +void hle_device_base::device_start() +{ + m_click_timer = timer_alloc(CLICK_TIMER_ID); + + save_item(NAME(m_make_count)); + save_item(NAME(m_rx_state)); + save_item(NAME(m_keyclick)); + save_item(NAME(m_beeper_state)); +} + +void hle_device_base::device_reset() +{ + // initialise state + clear_fifo(); + m_make_count = 0U; + m_rx_state = RX_IDLE; + m_keyclick = 0U; + m_beeper_state = 0x00U; + + // configure device_buffered_serial_interface + set_data_frame(START_BIT_COUNT, DATA_BIT_COUNT, PARITY, STOP_BITS); + set_rate(BAUD); + receive_register_reset(); + transmit_register_reset(); + + // start with keyboard LEDs off + machine().output().set_led_value(LED_DISK, 0); + machine().output().set_led_value(LED_LOCK, 0); + machine().output().set_led_value(LED_UNKNOWN, 0); + machine().output().set_led_value(LED_L1, 0); + machine().output().set_led_value(LED_L2, 0); + machine().output().set_led_value(LED_L3, 0); + machine().output().set_led_value(LED_L4, 0); + + // no beep + m_click_timer->reset(); + + // kick the base + reset_key_state(); + start_processing(attotime::from_hz(1'200)); +} + +void hle_device_base::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + switch (id) + { + case CLICK_TIMER_ID: + m_beeper_state &= ~u8(BEEPER_CLICK); + m_beeper->set_state(m_beeper_state ? 1 : 0); + break; + + default: + break; + } +} + +void hle_device_base::tra_callback() +{ + output_rxd(transmit_register_get_data_bit()); +} + +void hle_device_base::tra_complete() +{ + if (fifo_full()) + start_processing(attotime::from_hz(1'200)); + + device_buffered_serial_interface::tra_complete(); +} + +void hle_device_base::key_make(u8 row, u8 column) +{ + // we should have stopped processing if we filled the FIFO + assert(!fifo_full()); + + // send the make code, click if desired + transmit_byte(translate(row, column)); + if (m_keyclick) + { + m_beeper_state |= u8(BEEPER_CLICK); + m_beeper->set_state(m_beeper_state ? 1 : 0); + m_click_timer->reset(attotime::from_msec(5)); + } + + // count keys + ++m_make_count; + assert(m_make_count); +} + +void hle_device_base::key_break(u8 row, u8 column) +{ + // we should have stopped processing if we filled the FIFO + assert(!fifo_full()); + assert(m_make_count); + + --m_make_count; + + // check our counting + assert(are_all_keys_up() == !bool(m_make_count)); +} + +void hle_device_base::transmit_byte(u8 byte) +{ + LOG("transmit_byte 0x%02x\n", byte); + device_buffered_serial_interface::transmit_byte(byte); + if (fifo_full()) + stop_processing(); +} + +void hle_device_base::received_byte(u8 byte) +{ + LOG("received_byte 0x%02x\n", byte); + + switch (m_rx_state) + { + case RX_ESC: + switch (byte) + { + case 'B': // bell + m_rx_state = RX_BELL; + break; + + case 'D': // diagnostic + transmit_byte(0xff); + transmit_byte(0x00); + + m_rx_state = RX_IDLE; + break; + } + break; + + case RX_BELL: + switch (byte) + { + case '(': + LOG("bell on\n"); + m_beeper_state |= u8(BEEPER_BELL); + m_beeper->set_state(m_beeper_state ? 1 : 0); + break; + + case ')': + LOG("bell off\n"); + m_beeper_state &= ~u8(BEEPER_BELL); + m_beeper->set_state(m_beeper_state ? 1 : 0); + break; + + default: + // FIXME: boot code sends 0x8, unknown meaning + break; + } + m_rx_state = RX_IDLE; + break; + + case RX_IDLE: + if (byte == 0x1b) + m_rx_state = RX_ESC; + break; + } +} + +hle_en_us_device::hle_en_us_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : hle_device_base(mconfig, INTERPRO_HLE_EN_US_KEYBOARD, tag, owner, clock), + m_modifiers(*this, "modifiers") +{ +} + +ioport_constructor hle_en_us_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(hle_en_us_device); +} + +u8 hle_en_us_device::translate(u8 row, u8 column) +{ + u8 const modifiers(m_modifiers->read()); + + bool const ctrl(modifiers & 0x01); + bool const shift(bool(modifiers & 0x02) || (bool(modifiers & 0x04))); + bool const ctrl_shift(ctrl && shift); + + unsigned const map(ctrl_shift ? 3 : ctrl ? 2 : shift ? 1 : 0); + + return TRANSLATION_TABLE[map][row][column]; +} + +} } } // namespace bus::interpro::keyboard diff --git a/src/devices/bus/interpro/keyboard/hle.h b/src/devices/bus/interpro/keyboard/hle.h new file mode 100644 index 00000000000..fac0b48d3be --- /dev/null +++ b/src/devices/bus/interpro/keyboard/hle.h @@ -0,0 +1,113 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay +#ifndef MAME_DEVICES_INTERPRO_KEYBOARD_HLE_H +#define MAME_DEVICES_INTERPRO_KEYBOARD_HLE_H + +#pragma once + +#include "keyboard.h" +#include "machine/keyboard.h" +#include "sound/beep.h" + +namespace bus { namespace interpro { namespace keyboard { + +class hle_device_base + : public device_t + , public device_buffered_serial_interface<16U> + , public device_interpro_keyboard_port_interface + , protected device_matrix_keyboard_interface<5U> +{ +public: + virtual ~hle_device_base() override; + + virtual DECLARE_WRITE_LINE_MEMBER(input_txd) override; + +protected: + // constructor/destructor + hle_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock); + + // device overrides + virtual void device_add_mconfig(machine_config &config) override; + 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_buffered_serial_interface overrides + virtual void tra_callback() override; + virtual void tra_complete() override; + + // device_matrix_keyboard_interface overrides + virtual void key_make(u8 row, u8 column) override; + virtual void key_break(u8 row, u8 column) override; + + // customised transmit_byte method + void transmit_byte(u8 byte); + virtual u8 translate(u8 row, u8 column) = 0; + +private: + enum { + CLICK_TIMER_ID = 30'000 + }; + + enum : int { + LED_DISK = 0, + LED_LOCK, + LED_UNKNOWN, + LED_L1, + LED_L2, + LED_L3, + LED_L4 + }; + + enum : u8 { + BEEPER_BELL = 0x01U, + BEEPER_CLICK = 0x02U + }; + + enum : u8 { + RX_IDLE, + RX_ESC, + RX_BELL + }; + + enum : u8 { + COMMAND_RESET = 0x01U, + COMMAND_BELL_ON = 0x02U, + COMMAND_BELL_OFF = 0x03U, + COMMAND_CLICK_ON = 0x0aU, + COMMAND_CLICK_OFF = 0x0bU, + COMMAND_LED = 0x0eU, + COMMAND_LAYOUT = 0x0fU + }; + + // device_buffered_serial_interface overrides + virtual void received_byte(u8 byte) override; + + emu_timer *m_click_timer; + required_device m_beeper; + + u8 m_make_count; + u8 m_rx_state; + + u8 m_keyclick; + u8 m_beeper_state; +}; + + +class hle_en_us_device : public hle_device_base +{ +public: + hle_en_us_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); + + virtual ioport_constructor device_input_ports() const override; + + virtual u8 translate(u8 row, u8 column) override; + + required_ioport m_modifiers; +}; + +} } } // namespace bus::interpro::keyboard + +DECLARE_DEVICE_TYPE_NS(INTERPRO_HLE_EN_US_KEYBOARD, bus::interpro::keyboard, hle_en_us_device) + +#endif // MAME_DEVICES_INTERPRO_KEYBOARD_HLE_H diff --git a/src/devices/bus/interpro/keyboard/keyboard.cpp b/src/devices/bus/interpro/keyboard/keyboard.cpp new file mode 100644 index 00000000000..210b509277c --- /dev/null +++ b/src/devices/bus/interpro/keyboard/keyboard.cpp @@ -0,0 +1,67 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +#include "emu.h" +#include "keyboard.h" + +#define VERBOSE 0 +#include "logmacro.h" + +DEFINE_DEVICE_TYPE(INTERPRO_KEYBOARD_PORT, interpro_keyboard_port_device, "interpro_keyboard_port", "InterPro Keyboard Port") + +int const device_interpro_keyboard_port_interface::START_BIT_COUNT; +int const device_interpro_keyboard_port_interface::DATA_BIT_COUNT; +device_serial_interface::parity_t const device_interpro_keyboard_port_interface::PARITY; +device_serial_interface::stop_bits_t const device_interpro_keyboard_port_interface::STOP_BITS; +int const device_interpro_keyboard_port_interface::BAUD; + +interpro_keyboard_port_device::interpro_keyboard_port_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock) + : interpro_keyboard_port_device(mconfig, INTERPRO_KEYBOARD_PORT, tag, owner, clock) +{ +} + +interpro_keyboard_port_device::interpro_keyboard_port_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, type, tag, owner, clock) + , device_slot_interface(mconfig, *this) + , m_rxd_handler(*this) + , m_dev(nullptr) +{ +} + +interpro_keyboard_port_device::~interpro_keyboard_port_device() +{ +} + +void interpro_keyboard_port_device::device_config_complete() +{ + m_dev = dynamic_cast(get_card_device()); +} + +void interpro_keyboard_port_device::device_start() +{ + m_rxd_handler.resolve_safe(); + + save_item(NAME(m_rxd)); +} + +WRITE_LINE_MEMBER(interpro_keyboard_port_device::write_txd) +{ + if (m_dev) + m_dev->input_txd(state); +} + +device_interpro_keyboard_port_interface::device_interpro_keyboard_port_interface(machine_config const &mconfig, device_t &device) + : device_slot_card_interface(mconfig, device) + , m_port(dynamic_cast(device.owner())) +{ +} + +device_interpro_keyboard_port_interface::~device_interpro_keyboard_port_interface() +{ +} + +#include "hle.h" + +SLOT_INTERFACE_START(interpro_keyboard_devices) + SLOT_INTERFACE("hle_en_us", INTERPRO_HLE_EN_US_KEYBOARD) +SLOT_INTERFACE_END diff --git a/src/devices/bus/interpro/keyboard/keyboard.h b/src/devices/bus/interpro/keyboard/keyboard.h new file mode 100644 index 00000000000..ca3b1a2eb82 --- /dev/null +++ b/src/devices/bus/interpro/keyboard/keyboard.h @@ -0,0 +1,71 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay +#ifndef MAME_BUS_INTERPRO_KEYBOARD_KEYBOARD_H +#define MAME_BUS_INTERPRO_KEYBOARD_KEYBOARD_H + +#pragma once + +#define MCFG_INTERPRO_KEYBOARD_PORT_ADD(tag, slot_intf, def_slot) \ + MCFG_DEVICE_ADD(tag, INTERPRO_KEYBOARD_PORT, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(slot_intf, def_slot, false) + +#define MCFG_INTERPRO_KEYBOARD_RXD_HANDLER(cb) \ + devcb = &interpro_keyboard_port_device::set_rxd_handler(*device, DEVCB_##cb); + +class device_interpro_keyboard_port_interface; + +class interpro_keyboard_port_device : public device_t, public device_slot_interface +{ + friend class device_interpro_keyboard_port_interface; + +public: + interpro_keyboard_port_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock); + virtual ~interpro_keyboard_port_device(); + + // static configuration helpers + template static devcb_base &set_rxd_handler(device_t &device, Object &&cb) { return downcast(device).m_rxd_handler.set_callback(std::forward(cb)); } + + DECLARE_WRITE_LINE_MEMBER(write_txd); + +protected: + interpro_keyboard_port_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, uint32_t clock); + + virtual void device_start() override; + virtual void device_config_complete() override; + + int m_rxd; + + devcb_write_line m_rxd_handler; + +private: + device_interpro_keyboard_port_interface *m_dev; +}; + +class device_interpro_keyboard_port_interface : public device_slot_card_interface +{ + friend class interpro_keyboard_port_device; + +public: + virtual ~device_interpro_keyboard_port_interface() override; + + virtual DECLARE_WRITE_LINE_MEMBER(input_txd) { } + + DECLARE_WRITE_LINE_MEMBER(output_rxd) { m_port->m_rxd = state; m_port->m_rxd_handler(state); } + +protected: + device_interpro_keyboard_port_interface(machine_config const &mconfig, device_t &device); + + interpro_keyboard_port_device *m_port; + + static constexpr int START_BIT_COUNT = 1; + static constexpr int DATA_BIT_COUNT = 8; + static constexpr device_serial_interface::parity_t PARITY = device_serial_interface::PARITY_EVEN; + static constexpr device_serial_interface::stop_bits_t STOP_BITS = device_serial_interface::STOP_BITS_1; + static constexpr int BAUD = 1'200; +}; + +DECLARE_DEVICE_TYPE(INTERPRO_KEYBOARD_PORT, interpro_keyboard_port_device) + +SLOT_INTERFACE_EXTERN(interpro_keyboard_devices); + +#endif // MAME_BUS_INTERPRO_KEYBOARD_KEYBOARD_H diff --git a/src/devices/bus/interpro/sr/gt.cpp b/src/devices/bus/interpro/sr/gt.cpp new file mode 100644 index 00000000000..4725b5850b8 --- /dev/null +++ b/src/devices/bus/interpro/sr/gt.cpp @@ -0,0 +1,199 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +/* + * An emulation of GT graphics for Intergraph InterPro. + * + * TODO + * - control register (including primary/secondary buffer selection) + * - DP8510V BITBLT unit + * - custom Bresenham line drawing ASIC + * - support GT+, GTII, GTII+ + * + */ + +#include "emu.h" +#include "screen.h" + +#include "gt.h" + +#define VERBOSE 0 +#include "logmacro.h" + +DEVICE_ADDRESS_MAP_START(map, 32, mpcb963_device) + AM_RANGE(0x00000000, 0x0000007f) AM_READ(idprom_r) + AM_RANGE(0x00000080, 0x0000008f) AM_DEVICE8("ramdac0", bt459_device, map, 0xff) + AM_RANGE(0x000000b0, 0x000000b3) AM_READWRITE16(control_r, control_w, 0xffff) + //AM_RANGE(0x000000d4, 0x000000d7) AM_READWRITE8(, 0xff) // currently unknown + //AM_RANGE(0x000000a0, 0x000000a0) AM_READWRITE8(, 0xff) // currently unknown + AM_RANGE(0x00400000, 0x005fffff) AM_READWRITE(vram_r, vram_w) +ADDRESS_MAP_END + +DEVICE_ADDRESS_MAP_START(map, 32, mpcba79_device) + AM_RANGE(0x00000000, 0x0000007f) AM_READ(idprom_r) + AM_RANGE(0x00000080, 0x0000008f) AM_DEVICE8("ramdac0", bt459_device, map, 0xff) + AM_RANGE(0x00000090, 0x0000009f) AM_DEVICE8("ramdac1", bt459_device, map, 0xff) + AM_RANGE(0x000000b0, 0x000000b3) AM_READWRITE16(control_r, control_w, 0xffff) + //AM_RANGE(0x000000d4, 0x000000d7) AM_READWRITE8(, 0xff) // currently unknown + //AM_RANGE(0x000000a0, 0x000000a0) AM_READWRITE8(, 0xff) // currently unknown + AM_RANGE(0x00400000, 0x007fffff) AM_READWRITE(vram_r, vram_w) +ADDRESS_MAP_END + +ROM_START(mpcb963) + ROM_REGION(0x80, "idprom", 0) + ROM_LOAD32_BYTE("mpcb963a.bin", 0x0, 0x20, CRC(4cf4562d) SHA1(58bcc2afb66168f1d44a0366b6a5ccc4c22e0f32)) +ROM_END + +ROM_START(mpcba79) + ROM_REGION(0x80, "idprom", 0) + ROM_LOAD32_BYTE("mpcba79a.bin", 0x0, 0x20, CRC(b3b98324) SHA1(77b4ed0bbc6ed19646c4536d9976563f78961408)) +ROM_END + +DEFINE_DEVICE_TYPE(MPCB963, mpcb963_device, "mpcb963", "2000 Graphics f/1 1Mp Monitor") +DEFINE_DEVICE_TYPE(MPCBA79, mpcba79_device, "mpcba79", "2000 Graphics f/2 1Mp Monitors") + +/* + * The screen data here is just a guess for now. Real values will need to be + * determined to ensure the cursor positions generated by the Bt459 are + * aligned properly on the screen. + */ +MACHINE_CONFIG_MEMBER(mpcb963_device::device_add_mconfig) + MCFG_SCREEN_ADD("screen0", RASTER) + MCFG_SCREEN_RAW_PARAMS(80'000'000, XRES, 0, XRES, YRES, 0, YRES) + MCFG_SCREEN_UPDATE_DEVICE("", mpcb963_device, screen_update0) + MCFG_DEVICE_ADD("ramdac0", BT459, 0) +MACHINE_CONFIG_END + +MACHINE_CONFIG_MEMBER(mpcba79_device::device_add_mconfig) + MCFG_SCREEN_ADD("screen0", RASTER) + MCFG_SCREEN_RAW_PARAMS(80'000'000, XRES, 0, XRES, YRES, 0, YRES) + MCFG_SCREEN_UPDATE_DEVICE("", mpcba79_device, screen_update0) + MCFG_DEVICE_ADD("ramdac0", BT459, 0) + + MCFG_SCREEN_ADD("screen1", RASTER) + MCFG_SCREEN_RAW_PARAMS(80'000'000, XRES, 0, XRES, YRES, 0, YRES) + MCFG_SCREEN_UPDATE_DEVICE("", mpcba79_device, screen_update1) + MCFG_DEVICE_ADD("ramdac1", BT459, 0) +MACHINE_CONFIG_END + +gt_device_base::gt_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : + sr_card_device_base(mconfig, type, tag, owner, clock) +{ +} + +mpcb963_device::mpcb963_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + gt_device_base(mconfig, MPCB963, tag, owner, clock), + m_screen + { + { { *this, "ramdac0" }, {}, true } + } +{ +} + +const tiny_rom_entry *mpcb963_device::device_rom_region() const +{ + return ROM_NAME(mpcb963); +} + +void mpcb963_device::device_start() +{ + gt_device_base::device_start(); + + m_screen[0].vram.reset(new u8[VRAM_SIZE]); + + save_item(NAME(m_control)); + save_pointer(NAME(m_screen[0].vram.get()), VRAM_SIZE); +} + + +WRITE16_MEMBER(mpcb963_device::control_w) +{ + LOG("control_w 0x%04x\n", data); + + m_control = data; +} + +READ32_MEMBER(mpcb963_device::vram_r) const +{ + return ((u32 *)m_screen[(offset >> 19) & 1].vram.get())[offset & 0x7ffff]; +} + +WRITE32_MEMBER(mpcb963_device::vram_w) +{ + gt_screen_t >_screen = m_screen[(offset >> 19) & 1]; + + ((u32 *)gt_screen.vram.get())[offset & 0x7ffff] = (((u32 *)gt_screen.vram.get())[offset & 0x7ffff] & ~mem_mask) | (data & mem_mask); +} + +u32 mpcb963_device::screen_update0(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + gt_screen_t >_screen = m_screen[0]; + + gt_screen.ramdac->screen_update(screen, bitmap, cliprect, >_screen.vram[gt_screen.primary ? 0x000000 : 0x100000]); + + return 0; +} + +mpcba79_device::mpcba79_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + gt_device_base(mconfig, MPCBA79, tag, owner, clock), + m_screen +{ + { { *this, "ramdac0" },{}, true }, + { { *this, "ramdac1" },{}, true } +} +{ +} + +const tiny_rom_entry *mpcba79_device::device_rom_region() const +{ + return ROM_NAME(mpcba79); +} + +void mpcba79_device::device_start() +{ + gt_device_base::device_start(); + + m_screen[0].vram.reset(new u8[VRAM_SIZE]); + m_screen[1].vram.reset(new u8[VRAM_SIZE]); + + save_item(NAME(m_control)); + save_pointer(NAME(m_screen[0].vram.get()), VRAM_SIZE); + save_pointer(NAME(m_screen[1].vram.get()), VRAM_SIZE); +} + +WRITE16_MEMBER(mpcba79_device::control_w) +{ + LOG("control_w 0x%04x\n", data); + + m_control = data; +} + +READ32_MEMBER(mpcba79_device::vram_r) const +{ + return ((u32 *)m_screen[(offset >> 19) & 1].vram.get())[offset & 0x7ffff]; +} + +WRITE32_MEMBER(mpcba79_device::vram_w) +{ + gt_screen_t >_screen = m_screen[(offset >> 19) & 1]; + + ((u32 *)gt_screen.vram.get())[offset & 0x7ffff] = (((u32 *)gt_screen.vram.get())[offset & 0x7ffff] & ~mem_mask) | (data & mem_mask); +} + +u32 mpcba79_device::screen_update0(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + gt_screen_t >_screen = m_screen[0]; + + gt_screen.ramdac->screen_update(screen, bitmap, cliprect, >_screen.vram[gt_screen.primary ? 0x000000 : 0x100000]); + + return 0; +} + +u32 mpcba79_device::screen_update1(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + gt_screen_t >_screen = m_screen[1]; + + gt_screen.ramdac->screen_update(screen, bitmap, cliprect, >_screen.vram[gt_screen.primary ? 0x000000 : 0x100000]); + + return 0; +} diff --git a/src/devices/bus/interpro/sr/gt.h b/src/devices/bus/interpro/sr/gt.h new file mode 100644 index 00000000000..8c507871e53 --- /dev/null +++ b/src/devices/bus/interpro/sr/gt.h @@ -0,0 +1,110 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay +#ifndef MAME_BUS_INTERPRO_SR_GT_H +#define MAME_BUS_INTERPRO_SR_GT_H + +#pragma once + +#include "sr.h" +#include "video/bt459.h" + +class gt_device_base : public sr_card_device_base +{ +protected: + gt_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + +public: + const int XRES = 1184; + const int YRES = 884; + const int VRAM_SIZE = 0x200000; // 1 megabyte double buffered + + enum control_mask + { + CONTROL_SCREEN = 0x1000, // possibly selects screen 0 or 1? + CONTROL_BUSY = 0x8000 + }; + + typedef struct + { + required_device ramdac; + std::unique_ptr vram; + + bool primary; + } gt_screen_t; + + virtual DECLARE_READ16_MEMBER(control_r) const = 0; + virtual DECLARE_WRITE16_MEMBER(control_w) = 0; + + //virtual DECLARE_READ8_MEMBER(dac_r) const = 0; + //virtual DECLARE_WRITE8_MEMBER(dac_w) = 0; + + virtual DECLARE_READ32_MEMBER(vram_r) const = 0; + virtual DECLARE_WRITE32_MEMBER(vram_w) = 0; + + // BSGA XLeft 0x104 (write) + // BSGA XLeft 0x10c (read) +}; + +class mpcb963_device : public gt_device_base +{ +public: + mpcb963_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + virtual DECLARE_ADDRESS_MAP(map, 32) override; + + virtual DECLARE_READ16_MEMBER(control_r) const override { return m_control; } + virtual DECLARE_WRITE16_MEMBER(control_w) override; + + //virtual DECLARE_READ8_MEMBER(dac_r) const override { return m_screen[0].ramdac->read(space, offset, mem_mask); } + //virtual DECLARE_WRITE8_MEMBER(dac_w) override { m_screen[0].ramdac->write(space, offset, data, mem_mask); } + + virtual DECLARE_READ32_MEMBER(vram_r) const override; + virtual DECLARE_WRITE32_MEMBER(vram_w) override; + + u32 screen_update0(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + +protected: + virtual const tiny_rom_entry *device_rom_region() const override; + virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override; + +private: + u16 m_control; + + gt_screen_t m_screen[1]; +}; + +class mpcba79_device : public gt_device_base +{ +public: + mpcba79_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + virtual DECLARE_ADDRESS_MAP(map, 32) override; + + virtual DECLARE_READ16_MEMBER(control_r) const override { return m_control; } + virtual DECLARE_WRITE16_MEMBER(control_w) override; + + //virtual DECLARE_READ8_MEMBER(dac_r) const override { return m_screen[offset >> 2].ramdac->read(space, offset & 0x3, mem_mask); } + //virtual DECLARE_WRITE8_MEMBER(dac_w) override { m_screen[offset >> 2].ramdac->write(space, offset & 0x3, data, mem_mask); } + + virtual DECLARE_READ32_MEMBER(vram_r) const override; + virtual DECLARE_WRITE32_MEMBER(vram_w) override; + + u32 screen_update0(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + u32 screen_update1(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + +protected: + virtual const tiny_rom_entry *device_rom_region() const override; + virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override; + +private: + u16 m_control; + gt_screen_t m_screen[2]; +}; + +// device type definition +DECLARE_DEVICE_TYPE(MPCB963, mpcb963_device) +DECLARE_DEVICE_TYPE(MPCBA79, mpcba79_device) + +#endif // MAME_BUS_INTERPRO_SR_GT_H diff --git a/src/devices/bus/interpro/sr/sr.cpp b/src/devices/bus/interpro/sr/sr.cpp new file mode 100644 index 00000000000..765e3573dff --- /dev/null +++ b/src/devices/bus/interpro/sr/sr.cpp @@ -0,0 +1,379 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +/* + * An initial very primitive emulation of the SR bus for the Intergraph + * InterPro. + * + * The bus is referred to by several different names at different places + * in the system code, such as SR, SR bus, SRX, SRX/C bus, CBUS and some + * variations on those. It's likely that SRX is an enhanced version of the + * original SR bus implementation, and that CBUS is an alternate name. + * + * SR bus devices are mapped into the host memory map at a fixed address + * range per slot, starting at 0x87000000 and incrementing by 0x08000000. + * Within this address range, the first 32 double words provide access to + * a 32 byte board signature area, with a format as follows. + * + * u8 board[8] first four bytes typically zero, next three bytes + * contain a board number (in ASCII) from the list + * below, last byte contains a revision character + * u8 eco[8] engineering change order bits; these are initially + * all set, and are cleared starting from the least + * significant bit of the first byte onward to indicate + * board level changes + * u8 feature[8] used for different purposes by different boards + * u8 reserved[2] always set to 0xff + * u16 family indicate the board type from the list below + * u8 footprint[4] the first three bytes contain the magic number 0x55 + * 0xaa 0x55, the last byte contains the ones-complement + * of the sum of the other bytes as a checksum + * + * The following are the board families taken from the system boot ROM. + * + * Family Description + * ------ ----------- + * 0x0000 I/O processor + * 0x0001 CLIX engine + * 0x0002 expansion memory + * 0x0003 floating-point engine + * 0x0004 pipe-starter + * 0x0005 integrated frame buffer + * 0x0006 32/CGX + * 0x0007 GRE integrated frame buffer + * 0x0008 hardcopy/digitizer + * 0x0009 plotter DMA I/F + * 0x000a A/V mux + * 0x000b image subsystem I/F + * 0x000c VME adapter + * 0x000d I/O processor + * 0x000e CLIX engine + * 0x000f frame grabber + * 0x0010 screen generator subsystem + * 0x0011 scanner I/F + * 0x0012 convolution filter + * 0x0013 non-linear filter + * 0x0014 run-length encoder + * 0x0015 color setter data board + * 0x0016 EDGE I + * 0x0017 6000-series system board + * 0x0018 32-channel async I/F + * 0x0019 SR QUAD SCSI I/F + * 0x001a FDDI I/F + * 0x001b EDGE II processor + * 0x001c EDGE II frame buffer + * 0x001d IOI + * 0x001e IOI Clix Engine + * 0x001f MAYA bus I/F unit + * 0x0020 comp/decomp group 4 + * 0x0021 QWIC/SRX I/F + * 0x0022 SRX test board + * 0x0023 QWIC bus CPU + * 0x0024 2000-series system board + * 0x0025 2000-series graphics board + * 0x0026 E100/SRX device I/F + * 0x0027 IKOS H/W simulator I/F + * 0x0028 enhanced VME adapter + * 0x0029 QWIC expansion memory + * 0x002a image comp/decomp + * 0x002b teleconferencing controller + * 0x002c Sky 8115-I interface + * 0x002d C-bus token ring + * 0x002e Screen IV PressFax Subsystem + * 0x002f C400E CPU + * 0x0030 C-bus exp Ethernet + * 0x0031 2400-series CPU + * 0x0032 6400-series CPU + * 0x0033 6000-series GT Graphics + * 0x0034 C4K QWIC bus processor + * 0x0038 Visualization Processor + * 0x0039 2700-series CPU + * 0x0040 6700-series CPU + * 0x0041 2800-series CPU + * 0x0042 6700-series CPU + * + * The following are the board names taken from the showconfig.dat file + * shipped with the operating system. + * + * # Description + * --- ----------- + * 004 EDGE-2 Processor f/2 2Mp-FB's + * 008 Image Memory VRAM Board + * 009 EDGE II Frame Buffer for ImageStation + * 010 VI50 Image Processor + * 014 SRX Quad-SCSI Controller + * 019 C4E CPU Assembly + * 030 EDGE-2 Processor f/1 or 2 1Mp-FB's + * 031 EDGE-2 Processor f/1 2Mp-FB + * 032 CBUS Token Ring + * 034 256MB QWIC Bus Expansion Memory + * 046 6400 36-MHz Series System Board + * 047 2400 Series System Board + * 068 2400 Graphics f/1 1Mp Monitor (V-60) + * 069 2400 Graphics f/2 1Mp Monitors (V-60) + * 070 2400 Graphics f/1 1Mp Monitor (V-76) + * 071 2400 Graphics f/2 1Mp Monitors (V-76) + * 081 2400 Graphics f/1 2Mp Monitor (V-60/76) + * 083 SRX Hard PC Option / 8 Mb + * 093 EDGE-2 Plus Processor f/1 or 2 1Mp-FB's + * 094 EDGE-2 Plus Processor f/1 2Mp-FB + * 095 EDGE-2 Plus Processor f/2 2Mp-FB's + * 096 EDGE-2 Plus Frame Buffer f/1Mp Monitor + * 098 6400 32-MHz Sapphire System Board + * 101 2400 Graphics f/1 1Mp Monitor (V-76) + * 100 2500 Series System Board + * 102 2400 Graphics f/2 1Mp Monitors (V-76) + * 106 C-Bus Series Hard PC Option / 8 Mb + * 112 SRX Fast Quad-SCSI Controller + * 115 Edge III Processor + * 116 Edge III-C Single Ramdac + * 126 SRX Enhanced VME Adapter + * 127 6700 Series System Board + * 128 2700 Series System Board + * 129 6800 Series System Board + * 135 GT II Graphics f/1 2Mp Monitor (V-60/76) + * 136 GT II Graphics f/2 2Mp Monitor (V-60/76) + * 144 6800 Series System Board + * 145 2800 Series System Board + * 217 C-Bus Hard PC Option / 16 Mb + * 218 SRX Hard PC Option / 16 Mb + * 512 32C Clix Engine w/6MB + * 543 Floating Point Engine + * 548 80386 I/O Processor + * 577 Analog Video Mux/Summer + * 588 80186 I/O Processor + * 595 Pipe Starter + * 604 Digitizer/HardCopy Controller + * 605 300 Series Clix Engine w/16MB + * 617 300 Series SR VME-Adapter + * 633 32MB Expansion Memory + * 636 80186 I/O Processor w/CoProcessor + * 641 Image Subsystem Interface + * 643 8Mb Integrated Frame Buffer f/1Mp + * 650 2Mb Integrated Frame Buffer f/1Mp + * 652 2Mb Integrated Frame Buffer f/1Mp + * 657 32C Clix Engine w/8MB + * 663 200 Series SR VME-Adapter + * 664 32C Clix Engine w/16MB + * 675 SR Plotter-DMA-Interface + * 677 32C Clix Engine w/6MB + * 686 8Mb Integrated Frame Buffer f/2Mp + * 693 Clix Engine w/8MB + * 694 Clix Engine w/16MB + * 722 SR Frame Grabber NTSC + * 730 300/400 Series Clix Engine w/8MB + * 732 Clix Engine w/16MB + * 739 16MB Expansion Memory + * 765 6000 System Board w/16MB + * 776 Runlength Encoder + * 777 Scanner Interface + * 778 Nonlinear Filter + * 779 SIP Convolution Filter + * 789 32C Clix Engine w/6MB + * 792 Digitizer/HardCopy Controller Plus + * 796 2Mb Integrated Frame Buffer f/1Mp -T + * 799 80386 I/O Processor -T + * 801 Clix Engine w/8MB + * 819 QWIC Bus Clix Engine w/256K CB CACHE + * 820 QWIC System Interface w/64MB ECC + * 821 SRX 32 Channel RS232 Controller + * 822 300 Series Clix Engine w/16MB ECC + * 823 300/400 Series Clix Engine w/8MB ECC + * 825 32C Clix Engine w/12MB + * 826 FDDI Communications Processor + * 828 EDGE-1 Graphics f/1 1Mp Monitor (55K/60) + * 837 Analog Video Mux/Summer -T + * 838 Floating Point Engine -T + * 844 32MB Expansion Memory -T + * 849 EDGE-1 Graphics f/1 2Mp Monitor (55K/60) + * 851 Clix Engine w/16MB ECC -T + * 852 Digitizer/HardCopy Controller Plus -T + * 853 Clix Engine w/16MB ECC -T + * 883 6000 System Board w/8MB + * 887 SR Frame Grabber PAL + * 894 Clix Engine w/16MB ECC + * 896 EDGE-2/Plus Frame Buffer f/2Mp Monitor (V-60) + * 897 EDGE-2 Processor f/1 2Mp-FB + * 904 EDGE-1 Graphics f/2 1Mp Monitors (55K/60) + * 905 SRX Frame Grabber NTSC + * 906 SRX Frame Grabber PAL + * 915 64MB QWIC Bus Expansion Memory + * 917 Input Output Interface + * 932 IOI Clix Engine w/16MB ECC + * 956 SRX Enhanced VME-Adapter + * 958 VME-Controller f/SRX Interface + * 962 2000 System Board + * 963 2000 Graphics f/1 1Mp Monitor + * 965 EDGE-1 Graphics f/1 1Mp Monitor (66K/72) + * 966 EDGE-1 Graphics f/2 1Mp Monitors (66K/72) + * 977 6000 System Board w/32MB parity + * 978 6000 System Board w/48MB parity + * 979 6000 System Board w/64MB parity + * 980 6200 System Board w/8MB parity + * 981 6200 System Board w/16MB parity + * 982 6200 System Board w/32MB parity + * 983 6200 System Board w/48MB parity + * 984 6200 System Board w/64MB parity + * 31275 Raster Data Board + * 31277 Screener III A Board + * 31277/8 Screener III A+B Board + * A59 200 Series Clix Engine w/16MB parity + * A61 200 Series Clix Engine w/8MB parity + * A63 EDGE-2 Frame Buffer f/1Mp Monitor (55K/60) + * A77 200 Series Clix Engine w/16MB + * A79 2000 Graphics f/2 1Mp Monitors + * A80 QWIC System Interface w/16MB ECC + * A81 300 Series Clix Engine w/16MB ECC + * A86 SRX Teleconferencing Controller + * A95 IOI Clix Engine w/32MB ECC + * A96 IOI Clix Engine w/64MB ECC + * B13 System Board w/16MB parity -T + * B14 System Board w/48MB parity -T + * B15 EDGE-1 Graphics f/1 1Mp Monitor (55K/60) -T + * B16 EDGE-1 Graphics f/2 1Mp Monitors (55K/60) -T + * B17 IOI Clix Engine w/16MB ECC -T + * B18 Input Output Interface -T + * B20 SRX 32 Channel RS232 Controller -T + * B21 FDDI Communications Processor -T + * B22 SRX Quad-SCSI Controller -T + * b23 JPEG Compression/Decompression I/F + * B50 Application-Specific Acceleration Proc. II + * B63 IOI Clix Engine w/64MB ECC -T + * B67 GT Plus Graphics f/1 1Mp Monitor (V-76) + * B68 GT II Graphics f/1 1Mp Monitor (V-76) + * B70 GT II Graphics f/2 1Mp Monitors (V-76) + * B92 GT II Graphics f/1 2Mp Monitor (V-60/76) + * B93 GT II Graphics f/2 2Mp Monitors (V-60/76) + * B99 NTSC Frame Grabber for 3000 Series + * C01 PAL Frame Grabber for 3000 series + * C02 NTSC Frame Grabber for 6000 series + * C03 PAL Frame Grabber for 6000 series + * c05 25Mhz GTII Graphics f/1 1Mp Monitor + * c06 25Mhz GTII Graphics f/2 1Mp Monitors + * C41 GTII 60/76Hz Graphics f/1 2Mp Monitor + * C42 GTII 60/76Hz Graphics f/2 2Mp Monitor + * + * TODO + * - general refactoring and rework to improve implementation + */ + +#include "emu.h" +#include "sr.h" + +#define VERBOSE 1 +#include "logmacro.h" + +DEFINE_DEVICE_TYPE(SR_SLOT, sr_slot_device, "sr_slot", "InterPro SR bus slot") + +sr_slot_device::sr_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, SR_SLOT, tag, owner, clock) + , device_slot_interface(mconfig, *this) + , m_sr_tag(nullptr) + , m_sr_slottag(nullptr) +{ +} + +void sr_slot_device::static_set_sr_slot(device_t &device, const char *tag, const char *slottag) +{ + sr_slot_device &sr_card = dynamic_cast(device); + + sr_card.m_sr_tag = tag; + sr_card.m_sr_slottag = slottag; +} + +void sr_slot_device::device_start() +{ + device_sr_card_interface *dev = dynamic_cast(get_card_device()); + + if (dev) + device_sr_card_interface::static_set_sr_tag(*dev, m_sr_tag, m_sr_slottag); +} + +DEFINE_DEVICE_TYPE(SR, sr_device, "sr", "InterPro SR bus") + +sr_device::sr_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, SR, tag, owner, clock), + m_data_space(nullptr), + m_io_space(nullptr), + m_out_irq0_cb(*this), + m_out_irq1_cb(*this), + m_out_irq2_cb(*this) +{ +} + +void sr_device::device_start() +{ + // grab the main memory space from the mmu + device_memory_interface *mmu; + siblingdevice("mmu")->interface(mmu); + m_data_space = &mmu->space(0); + m_io_space = &mmu->space(1); + + // resolve callbacks + m_out_irq0_cb.resolve_safe(); + m_out_irq1_cb.resolve_safe(); + m_out_irq2_cb.resolve_safe(); + + // empty the slots + m_slot_count = 0; + for (auto &slot : m_slot) + slot = nullptr; +} + +void sr_device::device_reset() +{ +} + +void sr_device::install_idprom(device_t *dev, const char *tag, const char *region) +{ + // compute slot base address + offs_t base = 0x87000000; + + // map the idprom + m_data_space->install_read_bank(base, base + 0x7f, 0, tag); + m_data_space->unmap_write(base, base + 0x7f); + + // assign the region + machine().root_device().membank(m_data_space->device().siblingtag(tag).c_str())->set_base(machine().root_device().memregion(dev->subtag(region).c_str())->base()); +} + +device_sr_card_interface::device_sr_card_interface(const machine_config &mconfig, device_t &device) + : device_slot_card_interface(mconfig, device) + , m_sr(nullptr) + , m_sr_tag(nullptr) + , m_sr_slottag(nullptr) +{ +} + +device_sr_card_interface::~device_sr_card_interface() +{ +} + +void device_sr_card_interface::static_set_sr_tag(device_t &device, const char *tag, const char *slottag) +{ + device_sr_card_interface &sr_card = dynamic_cast(device); + + sr_card.m_sr_tag = tag; + sr_card.m_sr_slottag = slottag; +} + +void device_sr_card_interface::set_sr_device() +{ + // get a reference to the bus + m_sr = dynamic_cast(device().machine().device(m_sr_tag)); + + // install the card in the next available slot + m_sr->install_card(*this, &device_sr_card_interface::map); +} + +sr_card_device_base::sr_card_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const char *idprom_region) + : device_t(mconfig, type, tag, owner, clock) + , device_sr_card_interface(mconfig, *this) + , m_idprom_region(idprom_region) +{ +} + +void sr_card_device_base::device_start() +{ + set_sr_device(); +} diff --git a/src/devices/bus/interpro/sr/sr.h b/src/devices/bus/interpro/sr/sr.h new file mode 100644 index 00000000000..5cc36b6bd2b --- /dev/null +++ b/src/devices/bus/interpro/sr/sr.h @@ -0,0 +1,139 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +#ifndef MAME_BUS_INTERPRO_SR_SR_H +#define MAME_BUS_INTERPRO_SR_SR_H + +#pragma once + +#define MCFG_SR_OUT_IRQ0_CB(_devcb) \ + devcb = &sr_device::set_out_irq0_callback(*device, DEVCB_##_devcb); + +#define MCFG_SR_OUT_IRQ1_CB(_devcb) \ + devcb = &sr_device::set_out_irq1_callback(*device, DEVCB_##_devcb); + +#define MCFG_SR_OUT_IRQ2_CB(_devcb) \ + devcb = &sr_device::set_out_irq2_callback(*device, DEVCB_##_devcb); + +#define MCFG_SR_SLOT_ADD(_srtag, _tag, _slot_intf, _def_slot, _fixed) \ + MCFG_DEVICE_ADD(_tag, SR_SLOT, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _fixed) \ + sr_slot_device::static_set_sr_slot(*device, _srtag, _tag); + +#define MCFG_SR_SLOT_REMOVE(_tag) \ + MCFG_DEVICE_REMOVE(_tag) + +class sr_slot_device : public device_t, public device_slot_interface +{ +public: + // construction/destruction + sr_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // inline configuration + static void static_set_sr_slot(device_t &device, const char *tag, const char *slottag); +protected: + sr_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + // device-level overrides + virtual void device_start() override; + + // configuration + const char *m_sr_tag, *m_sr_slottag; +}; + +class device_sr_card_interface; + +class sr_device : public device_t +{ +public: + // construction/destruction + sr_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // inline configuration + template static devcb_base &set_out_irq0_callback(device_t &device, Object &&cb) { return downcast(device).m_out_irq0_cb.set_callback(std::forward(cb)); } + template static devcb_base &set_out_irq1_callback(device_t &device, Object &&cb) { return downcast(device).m_out_irq1_cb.set_callback(std::forward(cb)); } + template static devcb_base &set_out_irq2_callback(device_t &device, Object &&cb) { return downcast(device).m_out_irq2_cb.set_callback(std::forward(cb)); } + + DECLARE_WRITE_LINE_MEMBER(irq0_w) { m_out_irq0_cb(state); } + DECLARE_WRITE_LINE_MEMBER(irq1_w) { m_out_irq1_cb(state); } + DECLARE_WRITE_LINE_MEMBER(irq2_w) { m_out_irq2_cb(state); } + + // helper functions for card devices + template void install_card(T &device, void (T::*map)(address_map &map)) + { + // record the device in the next free slot + m_slot[m_slot_count] = &device; + + // compute slot base address + offs_t start = 0x87000000 + m_slot_count * 0x8000000; + offs_t end = start + 0x7ffffff; + + // install the device address map + m_data_space->install_device(start, end, device, map, 32); + m_io_space->install_device(start, end, device, map, 32); + + m_slot_count++; + } + + void install_idprom(device_t *dev, const char *tag, const char *region); + +protected: + sr_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // internal state + address_space *m_data_space; + address_space *m_io_space; + + devcb_write_line m_out_irq0_cb; + devcb_write_line m_out_irq1_cb; + devcb_write_line m_out_irq2_cb; + +private: + device_sr_card_interface *m_slot[16]; + int m_slot_count; +}; + +class device_sr_card_interface : public device_slot_card_interface +{ +public: + // construction/destruction + virtual ~device_sr_card_interface(); + + virtual DECLARE_ADDRESS_MAP(map, 32) = 0; + + void set_sr_device(); + + // inline configuration + static void static_set_sr_tag(device_t &device, const char *tag, const char *slottag); + +protected: + device_sr_card_interface(const machine_config &mconfig, device_t &device); + + sr_device *m_sr; + const char *m_sr_tag, *m_sr_slottag; +}; + +class sr_card_device_base : public device_t, public device_sr_card_interface +{ +protected: + sr_card_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const char *idprom_region = "idprom"); + +public: + READ32_MEMBER(idprom_r) { return device().memregion(m_idprom_region)->as_u32(offset); } + +protected: + // device-level overrides + virtual void device_start() override; + +private: + const char *const m_idprom_region; +}; + +DECLARE_DEVICE_TYPE(SR, sr_device) +DECLARE_DEVICE_TYPE(SR_SLOT, sr_slot_device) + +#endif // MAME_BUS_INTERPRO_SR_SR_H diff --git a/src/devices/bus/interpro/sr/sr_cards.cpp b/src/devices/bus/interpro/sr/sr_cards.cpp new file mode 100644 index 00000000000..9a626b04a6e --- /dev/null +++ b/src/devices/bus/interpro/sr/sr_cards.cpp @@ -0,0 +1,24 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +#include "emu.h" +#include "sr_cards.h" + +// video +#include "gt.h" + +// storage + +// sound + +// network + +// communication ports + +// other + + +SLOT_INTERFACE_START(sr_cards) + SLOT_INTERFACE("mpcb963", MPCB963) + SLOT_INTERFACE("mpcba79", MPCBA79) +SLOT_INTERFACE_END diff --git a/src/devices/bus/interpro/sr/sr_cards.h b/src/devices/bus/interpro/sr/sr_cards.h new file mode 100644 index 00000000000..b7f552173d4 --- /dev/null +++ b/src/devices/bus/interpro/sr/sr_cards.h @@ -0,0 +1,12 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +#ifndef MAME_BUS_INTERPRO_SR_SR_CARDS_H +#define MAME_BUS_INTERPRO_SR_SR_CARDS_H + +#pragma once + +// supported devices +SLOT_INTERFACE_EXTERN(sr_cards); + +#endif // MAME_BUS_INTERPRO_SR_SR_CARDS_H -- cgit v1.2.3 From 65e84a2ea1cebf1356342ca1492137ff80348fb3 Mon Sep 17 00:00:00 2001 From: Patrick Mackinlay Date: Mon, 23 Oct 2017 18:42:03 +0700 Subject: bus: tidy and formatting (nw) --- src/devices/bus/interpro/sr/gt.cpp | 42 ++++++++++++++++---------------------- src/devices/bus/interpro/sr/gt.h | 18 +++------------- src/devices/bus/interpro/sr/sr.cpp | 38 ++++++++++------------------------ src/devices/bus/interpro/sr/sr.h | 24 ++++++++++++---------- 4 files changed, 45 insertions(+), 77 deletions(-) diff --git a/src/devices/bus/interpro/sr/gt.cpp b/src/devices/bus/interpro/sr/gt.cpp index 4725b5850b8..aa1305e726a 100644 --- a/src/devices/bus/interpro/sr/gt.cpp +++ b/src/devices/bus/interpro/sr/gt.cpp @@ -9,7 +9,7 @@ * - DP8510V BITBLT unit * - custom Bresenham line drawing ASIC * - support GT+, GTII, GTII+ - * + * - reset behaviour */ #include "emu.h" @@ -59,34 +59,31 @@ DEFINE_DEVICE_TYPE(MPCBA79, mpcba79_device, "mpcba79", "2000 Graphics f/2 1Mp Mo */ MACHINE_CONFIG_MEMBER(mpcb963_device::device_add_mconfig) MCFG_SCREEN_ADD("screen0", RASTER) - MCFG_SCREEN_RAW_PARAMS(80'000'000, XRES, 0, XRES, YRES, 0, YRES) + MCFG_SCREEN_RAW_PARAMS(80'000'000, GT_XRES, 0, GT_XRES, GT_YRES, 0, GT_YRES) MCFG_SCREEN_UPDATE_DEVICE("", mpcb963_device, screen_update0) MCFG_DEVICE_ADD("ramdac0", BT459, 0) MACHINE_CONFIG_END MACHINE_CONFIG_MEMBER(mpcba79_device::device_add_mconfig) MCFG_SCREEN_ADD("screen0", RASTER) - MCFG_SCREEN_RAW_PARAMS(80'000'000, XRES, 0, XRES, YRES, 0, YRES) + MCFG_SCREEN_RAW_PARAMS(80'000'000, GT_XRES, 0, GT_XRES, GT_YRES, 0, GT_YRES) MCFG_SCREEN_UPDATE_DEVICE("", mpcba79_device, screen_update0) MCFG_DEVICE_ADD("ramdac0", BT459, 0) MCFG_SCREEN_ADD("screen1", RASTER) - MCFG_SCREEN_RAW_PARAMS(80'000'000, XRES, 0, XRES, YRES, 0, YRES) + MCFG_SCREEN_RAW_PARAMS(80'000'000, GT_XRES, 0, GT_XRES, GT_YRES, 0, GT_YRES) MCFG_SCREEN_UPDATE_DEVICE("", mpcba79_device, screen_update1) MCFG_DEVICE_ADD("ramdac1", BT459, 0) MACHINE_CONFIG_END -gt_device_base::gt_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : - sr_card_device_base(mconfig, type, tag, owner, clock) +gt_device_base::gt_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : sr_card_device_base(mconfig, type, tag, owner, clock) { } -mpcb963_device::mpcb963_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - gt_device_base(mconfig, MPCB963, tag, owner, clock), - m_screen - { - { { *this, "ramdac0" }, {}, true } - } +mpcb963_device::mpcb963_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : gt_device_base(mconfig, MPCB963, tag, owner, clock) + , m_screen{ { { *this, "ramdac0" }, {}, true } } { } @@ -99,10 +96,11 @@ void mpcb963_device::device_start() { gt_device_base::device_start(); - m_screen[0].vram.reset(new u8[VRAM_SIZE]); + // allocate double-buffered vram + m_screen[0].vram.reset(new u8[GT_VRAM * 2]); save_item(NAME(m_control)); - save_pointer(NAME(m_screen[0].vram.get()), VRAM_SIZE); + save_pointer(NAME(m_screen[0].vram.get()), GT_VRAM * 2); } @@ -129,18 +127,14 @@ u32 mpcb963_device::screen_update0(screen_device &screen, bitmap_rgb32 &bitmap, { gt_screen_t >_screen = m_screen[0]; - gt_screen.ramdac->screen_update(screen, bitmap, cliprect, >_screen.vram[gt_screen.primary ? 0x000000 : 0x100000]); + gt_screen.ramdac->screen_update(screen, bitmap, cliprect, >_screen.vram[gt_screen.primary ? 0x000000 : GT_VRAM]); return 0; } -mpcba79_device::mpcba79_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - gt_device_base(mconfig, MPCBA79, tag, owner, clock), - m_screen -{ - { { *this, "ramdac0" },{}, true }, - { { *this, "ramdac1" },{}, true } -} +mpcba79_device::mpcba79_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : gt_device_base(mconfig, MPCBA79, tag, owner, clock) + , m_screen { { { *this, "ramdac0" }, {}, true }, { { *this, "ramdac1" }, {}, true } } { } @@ -184,7 +178,7 @@ u32 mpcba79_device::screen_update0(screen_device &screen, bitmap_rgb32 &bitmap, { gt_screen_t >_screen = m_screen[0]; - gt_screen.ramdac->screen_update(screen, bitmap, cliprect, >_screen.vram[gt_screen.primary ? 0x000000 : 0x100000]); + gt_screen.ramdac->screen_update(screen, bitmap, cliprect, >_screen.vram[gt_screen.primary ? 0x000000 : GT_VRAM]); return 0; } @@ -193,7 +187,7 @@ u32 mpcba79_device::screen_update1(screen_device &screen, bitmap_rgb32 &bitmap, { gt_screen_t >_screen = m_screen[1]; - gt_screen.ramdac->screen_update(screen, bitmap, cliprect, >_screen.vram[gt_screen.primary ? 0x000000 : 0x100000]); + gt_screen.ramdac->screen_update(screen, bitmap, cliprect, >_screen.vram[gt_screen.primary ? 0x000000 : GT_VRAM]); return 0; } diff --git a/src/devices/bus/interpro/sr/gt.h b/src/devices/bus/interpro/sr/gt.h index 8c507871e53..a151657f79f 100644 --- a/src/devices/bus/interpro/sr/gt.h +++ b/src/devices/bus/interpro/sr/gt.h @@ -14,9 +14,9 @@ protected: gt_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); public: - const int XRES = 1184; - const int YRES = 884; - const int VRAM_SIZE = 0x200000; // 1 megabyte double buffered + const int GT_XRES = 1184; + const int GT_YRES = 884; + const int GT_VRAM = 0x100000; // 1 megabyte enum control_mask { @@ -35,14 +35,8 @@ public: virtual DECLARE_READ16_MEMBER(control_r) const = 0; virtual DECLARE_WRITE16_MEMBER(control_w) = 0; - //virtual DECLARE_READ8_MEMBER(dac_r) const = 0; - //virtual DECLARE_WRITE8_MEMBER(dac_w) = 0; - virtual DECLARE_READ32_MEMBER(vram_r) const = 0; virtual DECLARE_WRITE32_MEMBER(vram_w) = 0; - - // BSGA XLeft 0x104 (write) - // BSGA XLeft 0x10c (read) }; class mpcb963_device : public gt_device_base @@ -55,9 +49,6 @@ public: virtual DECLARE_READ16_MEMBER(control_r) const override { return m_control; } virtual DECLARE_WRITE16_MEMBER(control_w) override; - //virtual DECLARE_READ8_MEMBER(dac_r) const override { return m_screen[0].ramdac->read(space, offset, mem_mask); } - //virtual DECLARE_WRITE8_MEMBER(dac_w) override { m_screen[0].ramdac->write(space, offset, data, mem_mask); } - virtual DECLARE_READ32_MEMBER(vram_r) const override; virtual DECLARE_WRITE32_MEMBER(vram_w) override; @@ -84,9 +75,6 @@ public: virtual DECLARE_READ16_MEMBER(control_r) const override { return m_control; } virtual DECLARE_WRITE16_MEMBER(control_w) override; - //virtual DECLARE_READ8_MEMBER(dac_r) const override { return m_screen[offset >> 2].ramdac->read(space, offset & 0x3, mem_mask); } - //virtual DECLARE_WRITE8_MEMBER(dac_w) override { m_screen[offset >> 2].ramdac->write(space, offset & 0x3, data, mem_mask); } - virtual DECLARE_READ32_MEMBER(vram_r) const override; virtual DECLARE_WRITE32_MEMBER(vram_w) override; diff --git a/src/devices/bus/interpro/sr/sr.cpp b/src/devices/bus/interpro/sr/sr.cpp index 765e3573dff..d27609d117d 100644 --- a/src/devices/bus/interpro/sr/sr.cpp +++ b/src/devices/bus/interpro/sr/sr.cpp @@ -252,20 +252,17 @@ * c06 25Mhz GTII Graphics f/2 1Mp Monitors * C41 GTII 60/76Hz Graphics f/1 2Mp Monitor * C42 GTII 60/76Hz Graphics f/2 2Mp Monitor - * - * TODO - * - general refactoring and rework to improve implementation */ #include "emu.h" #include "sr.h" -#define VERBOSE 1 +#define VERBOSE 0 #include "logmacro.h" DEFINE_DEVICE_TYPE(SR_SLOT, sr_slot_device, "sr_slot", "InterPro SR bus slot") -sr_slot_device::sr_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +sr_slot_device::sr_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, SR_SLOT, tag, owner, clock) , device_slot_interface(mconfig, *this) , m_sr_tag(nullptr) @@ -291,13 +288,13 @@ void sr_slot_device::device_start() DEFINE_DEVICE_TYPE(SR, sr_device, "sr", "InterPro SR bus") -sr_device::sr_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - device_t(mconfig, SR, tag, owner, clock), - m_data_space(nullptr), - m_io_space(nullptr), - m_out_irq0_cb(*this), - m_out_irq1_cb(*this), - m_out_irq2_cb(*this) +sr_device::sr_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, SR, tag, owner, clock) + , m_data_space(nullptr) + , m_io_space(nullptr) + , m_out_irq0_cb(*this) + , m_out_irq1_cb(*this) + , m_out_irq2_cb(*this) { } @@ -316,7 +313,7 @@ void sr_device::device_start() // empty the slots m_slot_count = 0; - for (auto &slot : m_slot) + for (device_sr_card_interface *slot : m_slot) slot = nullptr; } @@ -324,19 +321,6 @@ void sr_device::device_reset() { } -void sr_device::install_idprom(device_t *dev, const char *tag, const char *region) -{ - // compute slot base address - offs_t base = 0x87000000; - - // map the idprom - m_data_space->install_read_bank(base, base + 0x7f, 0, tag); - m_data_space->unmap_write(base, base + 0x7f); - - // assign the region - machine().root_device().membank(m_data_space->device().siblingtag(tag).c_str())->set_base(machine().root_device().memregion(dev->subtag(region).c_str())->base()); -} - device_sr_card_interface::device_sr_card_interface(const machine_config &mconfig, device_t &device) : device_slot_card_interface(mconfig, device) , m_sr(nullptr) @@ -366,7 +350,7 @@ void device_sr_card_interface::set_sr_device() m_sr->install_card(*this, &device_sr_card_interface::map); } -sr_card_device_base::sr_card_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const char *idprom_region) +sr_card_device_base::sr_card_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, const char *idprom_region) : device_t(mconfig, type, tag, owner, clock) , device_sr_card_interface(mconfig, *this) , m_idprom_region(idprom_region) diff --git a/src/devices/bus/interpro/sr/sr.h b/src/devices/bus/interpro/sr/sr.h index 5cc36b6bd2b..236b4ea674b 100644 --- a/src/devices/bus/interpro/sr/sr.h +++ b/src/devices/bus/interpro/sr/sr.h @@ -27,12 +27,12 @@ class sr_slot_device : public device_t, public device_slot_interface { public: // construction/destruction - sr_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + sr_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); // inline configuration static void static_set_sr_slot(device_t &device, const char *tag, const char *slottag); protected: - sr_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + sr_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); // device-level overrides virtual void device_start() override; @@ -47,26 +47,30 @@ class sr_device : public device_t { public: // construction/destruction - sr_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + sr_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); // inline configuration template static devcb_base &set_out_irq0_callback(device_t &device, Object &&cb) { return downcast(device).m_out_irq0_cb.set_callback(std::forward(cb)); } template static devcb_base &set_out_irq1_callback(device_t &device, Object &&cb) { return downcast(device).m_out_irq1_cb.set_callback(std::forward(cb)); } template static devcb_base &set_out_irq2_callback(device_t &device, Object &&cb) { return downcast(device).m_out_irq2_cb.set_callback(std::forward(cb)); } + static const u32 SR_BASE = 0x87000000; + static const u32 SR_SIZE = 0x08000000; + static const int SR_COUNT = 16; + DECLARE_WRITE_LINE_MEMBER(irq0_w) { m_out_irq0_cb(state); } DECLARE_WRITE_LINE_MEMBER(irq1_w) { m_out_irq1_cb(state); } DECLARE_WRITE_LINE_MEMBER(irq2_w) { m_out_irq2_cb(state); } - // helper functions for card devices + // installation function for card devices template void install_card(T &device, void (T::*map)(address_map &map)) { // record the device in the next free slot m_slot[m_slot_count] = &device; // compute slot base address - offs_t start = 0x87000000 + m_slot_count * 0x8000000; - offs_t end = start + 0x7ffffff; + offs_t start = SR_BASE + m_slot_count * SR_SIZE; + offs_t end = start + (SR_SIZE - 1); // install the device address map m_data_space->install_device(start, end, device, map, 32); @@ -75,10 +79,8 @@ public: m_slot_count++; } - void install_idprom(device_t *dev, const char *tag, const char *region); - protected: - sr_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + sr_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); // device-level overrides virtual void device_start() override; @@ -93,7 +95,7 @@ protected: devcb_write_line m_out_irq2_cb; private: - device_sr_card_interface *m_slot[16]; + device_sr_card_interface *m_slot[SR_COUNT]; int m_slot_count; }; @@ -120,7 +122,7 @@ protected: class sr_card_device_base : public device_t, public device_sr_card_interface { protected: - sr_card_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const char *idprom_region = "idprom"); + sr_card_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, const char *idprom_region = "idprom"); public: READ32_MEMBER(idprom_r) { return device().memregion(m_idprom_region)->as_u32(offset); } -- cgit v1.2.3 From a020b82a7da8e35fef03af376b0f0b8448c64537 Mon Sep 17 00:00:00 2001 From: Patrick Mackinlay Date: Mon, 23 Oct 2017 19:40:40 +0700 Subject: gt: minor cleaning (nw) --- src/devices/bus/interpro/sr/gt.cpp | 38 ++++++++++++++++++------------------ src/devices/bus/interpro/sr/gt.h | 40 +++++++++++++++++++++----------------- 2 files changed, 41 insertions(+), 37 deletions(-) diff --git a/src/devices/bus/interpro/sr/gt.cpp b/src/devices/bus/interpro/sr/gt.cpp index aa1305e726a..c4ed9109792 100644 --- a/src/devices/bus/interpro/sr/gt.cpp +++ b/src/devices/bus/interpro/sr/gt.cpp @@ -53,25 +53,25 @@ DEFINE_DEVICE_TYPE(MPCB963, mpcb963_device, "mpcb963", "2000 Graphics f/1 1Mp Mo DEFINE_DEVICE_TYPE(MPCBA79, mpcba79_device, "mpcba79", "2000 Graphics f/2 1Mp Monitors") /* - * The screen data here is just a guess for now. Real values will need to be - * determined to ensure the cursor positions generated by the Bt459 are + * The raw screen data here is just a guess for now. Real values will need to + * be determined to ensure the cursor positions generated by the Bt459 are * aligned properly on the screen. */ MACHINE_CONFIG_MEMBER(mpcb963_device::device_add_mconfig) MCFG_SCREEN_ADD("screen0", RASTER) - MCFG_SCREEN_RAW_PARAMS(80'000'000, GT_XRES, 0, GT_XRES, GT_YRES, 0, GT_YRES) + MCFG_SCREEN_RAW_PARAMS(GT_PIXCLOCK, GT_XPIXELS, 0, GT_XPIXELS, GT_YPIXELS, 0, GT_YPIXELS) MCFG_SCREEN_UPDATE_DEVICE("", mpcb963_device, screen_update0) MCFG_DEVICE_ADD("ramdac0", BT459, 0) MACHINE_CONFIG_END MACHINE_CONFIG_MEMBER(mpcba79_device::device_add_mconfig) MCFG_SCREEN_ADD("screen0", RASTER) - MCFG_SCREEN_RAW_PARAMS(80'000'000, GT_XRES, 0, GT_XRES, GT_YRES, 0, GT_YRES) + MCFG_SCREEN_RAW_PARAMS(GT_PIXCLOCK, GT_XPIXELS, 0, GT_XPIXELS, GT_YPIXELS, 0, GT_YPIXELS) MCFG_SCREEN_UPDATE_DEVICE("", mpcba79_device, screen_update0) MCFG_DEVICE_ADD("ramdac0", BT459, 0) MCFG_SCREEN_ADD("screen1", RASTER) - MCFG_SCREEN_RAW_PARAMS(80'000'000, GT_XRES, 0, GT_XRES, GT_YRES, 0, GT_YRES) + MCFG_SCREEN_RAW_PARAMS(GT_PIXCLOCK, GT_XPIXELS, 0, GT_XPIXELS, GT_YPIXELS, 0, GT_YPIXELS) MCFG_SCREEN_UPDATE_DEVICE("", mpcba79_device, screen_update1) MCFG_DEVICE_ADD("ramdac1", BT459, 0) MACHINE_CONFIG_END @@ -97,10 +97,10 @@ void mpcb963_device::device_start() gt_device_base::device_start(); // allocate double-buffered vram - m_screen[0].vram.reset(new u8[GT_VRAM * 2]); + m_screen[0].vram.reset(new u8[GT_VRAM_SIZE]); save_item(NAME(m_control)); - save_pointer(NAME(m_screen[0].vram.get()), GT_VRAM * 2); + save_pointer(NAME(m_screen[0].vram.get()), GT_VRAM_SIZE); } @@ -118,16 +118,16 @@ READ32_MEMBER(mpcb963_device::vram_r) const WRITE32_MEMBER(mpcb963_device::vram_w) { - gt_screen_t >_screen = m_screen[(offset >> 19) & 1]; + const gt_screen_t >_screen = m_screen[(offset >> 19) & 1]; ((u32 *)gt_screen.vram.get())[offset & 0x7ffff] = (((u32 *)gt_screen.vram.get())[offset & 0x7ffff] & ~mem_mask) | (data & mem_mask); } u32 mpcb963_device::screen_update0(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - gt_screen_t >_screen = m_screen[0]; + const gt_screen_t >_screen = m_screen[0]; - gt_screen.ramdac->screen_update(screen, bitmap, cliprect, >_screen.vram[gt_screen.primary ? 0x000000 : GT_VRAM]); + gt_screen.ramdac->screen_update(screen, bitmap, cliprect, >_screen.vram[gt_screen.primary ? 0x000000 : GT_BUFFER_SIZE]); return 0; } @@ -147,12 +147,12 @@ void mpcba79_device::device_start() { gt_device_base::device_start(); - m_screen[0].vram.reset(new u8[VRAM_SIZE]); - m_screen[1].vram.reset(new u8[VRAM_SIZE]); + m_screen[0].vram.reset(new u8[GT_VRAM_SIZE]); + m_screen[1].vram.reset(new u8[GT_VRAM_SIZE]); save_item(NAME(m_control)); - save_pointer(NAME(m_screen[0].vram.get()), VRAM_SIZE); - save_pointer(NAME(m_screen[1].vram.get()), VRAM_SIZE); + save_pointer(NAME(m_screen[0].vram.get()), GT_VRAM_SIZE); + save_pointer(NAME(m_screen[1].vram.get()), GT_VRAM_SIZE); } WRITE16_MEMBER(mpcba79_device::control_w) @@ -169,25 +169,25 @@ READ32_MEMBER(mpcba79_device::vram_r) const WRITE32_MEMBER(mpcba79_device::vram_w) { - gt_screen_t >_screen = m_screen[(offset >> 19) & 1]; + const gt_screen_t >_screen = m_screen[(offset >> 19) & 1]; ((u32 *)gt_screen.vram.get())[offset & 0x7ffff] = (((u32 *)gt_screen.vram.get())[offset & 0x7ffff] & ~mem_mask) | (data & mem_mask); } u32 mpcba79_device::screen_update0(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - gt_screen_t >_screen = m_screen[0]; + const gt_screen_t >_screen = m_screen[0]; - gt_screen.ramdac->screen_update(screen, bitmap, cliprect, >_screen.vram[gt_screen.primary ? 0x000000 : GT_VRAM]); + gt_screen.ramdac->screen_update(screen, bitmap, cliprect, >_screen.vram[gt_screen.primary ? 0x000000 : GT_BUFFER_SIZE]); return 0; } u32 mpcba79_device::screen_update1(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - gt_screen_t >_screen = m_screen[1]; + const gt_screen_t >_screen = m_screen[1]; - gt_screen.ramdac->screen_update(screen, bitmap, cliprect, >_screen.vram[gt_screen.primary ? 0x000000 : GT_VRAM]); + gt_screen.ramdac->screen_update(screen, bitmap, cliprect, >_screen.vram[gt_screen.primary ? 0x000000 : GT_BUFFER_SIZE]); return 0; } diff --git a/src/devices/bus/interpro/sr/gt.h b/src/devices/bus/interpro/sr/gt.h index a151657f79f..c572772ccda 100644 --- a/src/devices/bus/interpro/sr/gt.h +++ b/src/devices/bus/interpro/sr/gt.h @@ -14,9 +14,11 @@ protected: gt_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); public: - const int GT_XRES = 1184; - const int GT_YRES = 884; - const int GT_VRAM = 0x100000; // 1 megabyte + static const u32 GT_PIXCLOCK = 80'000'000; // just a guess + static const int GT_XPIXELS = 1184; + static const int GT_YPIXELS = 884; + static const int GT_BUFFER_SIZE = 0x100000; // 1 megabyte + static const int GT_VRAM_SIZE = 0x200000; // 1 megabyte double buffered enum control_mask { @@ -24,6 +26,12 @@ public: CONTROL_BUSY = 0x8000 }; + virtual DECLARE_READ16_MEMBER(control_r) const = 0; + virtual DECLARE_WRITE16_MEMBER(control_w) = 0; + virtual DECLARE_READ32_MEMBER(vram_r) const = 0; + virtual DECLARE_WRITE32_MEMBER(vram_w) = 0; + +protected: typedef struct { required_device ramdac; @@ -31,12 +39,6 @@ public: bool primary; } gt_screen_t; - - virtual DECLARE_READ16_MEMBER(control_r) const = 0; - virtual DECLARE_WRITE16_MEMBER(control_w) = 0; - - virtual DECLARE_READ32_MEMBER(vram_r) const = 0; - virtual DECLARE_WRITE32_MEMBER(vram_w) = 0; }; class mpcb963_device : public gt_device_base @@ -44,25 +46,26 @@ class mpcb963_device : public gt_device_base public: mpcb963_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + static const int GT_SCREEN_COUNT = 1; + virtual DECLARE_ADDRESS_MAP(map, 32) override; virtual DECLARE_READ16_MEMBER(control_r) const override { return m_control; } virtual DECLARE_WRITE16_MEMBER(control_w) override; - virtual DECLARE_READ32_MEMBER(vram_r) const override; virtual DECLARE_WRITE32_MEMBER(vram_w) override; - u32 screen_update0(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - protected: virtual const tiny_rom_entry *device_rom_region() const override; virtual void device_add_mconfig(machine_config &config) override; virtual void device_start() override; + u32 screen_update0(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + private: u16 m_control; - gt_screen_t m_screen[1]; + gt_screen_t m_screen[GT_SCREEN_COUNT]; }; class mpcba79_device : public gt_device_base @@ -70,25 +73,26 @@ class mpcba79_device : public gt_device_base public: mpcba79_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + static const int GT_SCREEN_COUNT = 2; + virtual DECLARE_ADDRESS_MAP(map, 32) override; virtual DECLARE_READ16_MEMBER(control_r) const override { return m_control; } virtual DECLARE_WRITE16_MEMBER(control_w) override; - virtual DECLARE_READ32_MEMBER(vram_r) const override; virtual DECLARE_WRITE32_MEMBER(vram_w) override; - u32 screen_update0(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - u32 screen_update1(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - protected: virtual const tiny_rom_entry *device_rom_region() const override; virtual void device_add_mconfig(machine_config &config) override; virtual void device_start() override; + u32 screen_update0(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + u32 screen_update1(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + private: u16 m_control; - gt_screen_t m_screen[2]; + gt_screen_t m_screen[GT_SCREEN_COUNT]; }; // device type definition -- cgit v1.2.3