mirror of
https://github.com/holub/mame
synced 2025-04-22 08:22:15 +03:00
Merge pull request #2154 from shattered/_b85368c
hp_ipc: de-skeletonize.
This commit is contained in:
commit
1265aae040
@ -715,6 +715,23 @@ if (BUSES["EP64"]~=null) then
|
||||
end
|
||||
|
||||
|
||||
---------------------------------------------------
|
||||
--
|
||||
--@src/devices/bus/hp_hil/hp_hil.h,BUSES["HPHIL"] = true
|
||||
---------------------------------------------------
|
||||
|
||||
if (BUSES["HPHIL"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/bus/hp_hil/hp_hil.cpp",
|
||||
MAME_DIR .. "src/devices/bus/hp_hil/hp_hil.h",
|
||||
MAME_DIR .. "src/devices/bus/hp_hil/hil_devices.cpp",
|
||||
MAME_DIR .. "src/devices/bus/hp_hil/hil_devices.h",
|
||||
MAME_DIR .. "src/devices/bus/hp_hil/hlekbd.cpp",
|
||||
MAME_DIR .. "src/devices/bus/hp_hil/hlekbd.h",
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
---------------------------------------------------
|
||||
--
|
||||
--@src/devices/bus/generic/slot.h,BUSES["GENERIC"] = true
|
||||
|
@ -893,6 +893,18 @@ if (FORMATS["HECT_TAP"]~=null or _OPTIONS["with-tools"]) then
|
||||
}
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
--
|
||||
--@src/lib/formats/hp_ipc_dsk.h,FORMATS["HP_IPC_DSK"] = true
|
||||
--------------------------------------------------
|
||||
|
||||
if (FORMATS["HP_IPC_DSK"]~=null or _OPTIONS["with-tools"]) then
|
||||
files {
|
||||
MAME_DIR.. "src/lib/formats/hp_ipc_dsk.cpp",
|
||||
MAME_DIR.. "src/lib/formats/hp_ipc_dsk.h",
|
||||
}
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
--
|
||||
--@src/lib/formats/iq151_dsk.h,FORMATS["IQ151_DSK"] = true
|
||||
|
@ -364,6 +364,18 @@ if (VIDEOS["HLCD0538"]~=null) then
|
||||
}
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
--
|
||||
--@src/devices/video/hp1ll3.h,VIDEOS["HP1LL3"] = true
|
||||
--------------------------------------------------
|
||||
|
||||
if (VIDEOS["HP1LL3"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/video/hp1ll3.cpp",
|
||||
MAME_DIR .. "src/devices/video/hp1ll3.h",
|
||||
}
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
--
|
||||
--@src/devices/video/huc6202.h,VIDEOS["HUC6202"] = true
|
||||
|
@ -301,6 +301,7 @@ VIDEOS["HD61830"] = true
|
||||
VIDEOS["HD66421"] = true
|
||||
VIDEOS["HLCD0515"] = true
|
||||
VIDEOS["HLCD0538"] = true
|
||||
VIDEOS["HP1LL3"] = true
|
||||
VIDEOS["HUC6202"] = true
|
||||
VIDEOS["HUC6260"] = true
|
||||
VIDEOS["HUC6261"] = true
|
||||
@ -652,6 +653,7 @@ BUSES["GAMEBOY"] = true
|
||||
BUSES["GAMEGEAR"] = true
|
||||
BUSES["GBA"] = true
|
||||
BUSES["GENERIC"] = true
|
||||
BUSES["HPHIL"] = true
|
||||
BUSES["IEEE488"] = true
|
||||
BUSES["IMI7000"] = true
|
||||
BUSES["INTV"] = true
|
||||
@ -797,6 +799,7 @@ FORMATS["GTP_CAS"] = true
|
||||
FORMATS["HECTOR_MINIDISC"] = true
|
||||
FORMATS["HECT_DSK"] = true
|
||||
FORMATS["HECT_TAP"] = true
|
||||
FORMATS["HP_IPC_DSK"] = true
|
||||
FORMATS["IQ151_DSK"] = true
|
||||
FORMATS["ITT3030_DSK"] = true
|
||||
FORMATS["JVC_DSK"] = true
|
||||
|
11
src/devices/bus/hp_hil/hil_devices.cpp
Normal file
11
src/devices/bus/hp_hil/hil_devices.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sergey Svishchev
|
||||
|
||||
#include "emu.h"
|
||||
#include "hil_devices.h"
|
||||
|
||||
#include "hlekbd.h"
|
||||
|
||||
SLOT_INTERFACE_START(hp_hil_devices)
|
||||
SLOT_INTERFACE(STR_KBD_HP_INTEGRAL, HP_IPC_HLE_KEYBOARD)
|
||||
SLOT_INTERFACE_END
|
25
src/devices/bus/hp_hil/hil_devices.h
Normal file
25
src/devices/bus/hp_hil/hil_devices.h
Normal file
@ -0,0 +1,25 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sergey Svishchev
|
||||
/***************************************************************************
|
||||
|
||||
HP-HIL devices
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __HP_HIL_DEVICES_H__
|
||||
#define __HP_HIL_DEVICES_H__
|
||||
|
||||
|
||||
#define STR_KBD_HP_46020A "hp_46020a" // ITF Keyboard
|
||||
#define STR_KBD_HP_46021A "hp_46021a" // ITF Keyboard
|
||||
#define STR_KBD_HP_46030A "hp_46030a" // Vectra Keyboard
|
||||
#define STR_KBD_HP_INTEGRAL "hp_ipc_kbd" // Integral Keyboard
|
||||
|
||||
#define STR_MOUSE_HP_46060A "hp_46060a" // 2-button mouse
|
||||
#define STR_MOUSE_HP_46060B "hp_46060b" // 3-button mouse
|
||||
|
||||
|
||||
SLOT_INTERFACE_EXTERN(hp_hil_devices);
|
||||
|
||||
|
||||
#endif /* __HP_HIL_DEVICES_H__ */
|
412
src/devices/bus/hp_hil/hlekbd.cpp
Normal file
412
src/devices/bus/hp_hil/hlekbd.cpp
Normal file
@ -0,0 +1,412 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sergey Svishchev
|
||||
#include "hlekbd.h"
|
||||
|
||||
#include "machine/keyboard.ipp"
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
DEVICE TYPE GLOBALS
|
||||
***************************************************************************/
|
||||
|
||||
device_type const HP_IPC_HLE_KEYBOARD = device_creator<bus::hp_hil::hle_hp_ipc_device>;
|
||||
|
||||
|
||||
namespace bus { namespace hp_hil {
|
||||
namespace {
|
||||
/***************************************************************************
|
||||
INPUT PORT DEFINITIONS
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
// ID codes: A0h..BFh (HP-HIL reference, p. B-4) + (IPC Service Manual, p. 10-2)
|
||||
INPUT_PORTS_START( id )
|
||||
PORT_START("COL0")
|
||||
PORT_DIPNAME( 0xff, 0xb7, "Layout" )
|
||||
PORT_DIPSETTING( 0xBF, "US" )
|
||||
PORT_DIPSETTING( 0xAF, "German" )
|
||||
PORT_DIPSETTING( 0xB7, "UK" )
|
||||
PORT_DIPSETTING( 0xBB, "French" )
|
||||
PORT_DIPSETTING( 0xBD, "Katakana" )
|
||||
PORT_DIPSETTING( 0xBE, "Latin Spanish" )
|
||||
PORT_DIPSETTING( 0xA7, "Canadian English" )
|
||||
PORT_DIPSETTING( 0xAB, "Italian" )
|
||||
PORT_DIPSETTING( 0xAD, "Dutch" )
|
||||
PORT_DIPSETTING( 0xAE, "Swedish" )
|
||||
PORT_DIPSETTING( 0xB3, "European Spanish" )
|
||||
PORT_DIPSETTING( 0xB5, "Belgian (Flemish)" )
|
||||
PORT_DIPSETTING( 0xB6, "Finnish" )
|
||||
PORT_DIPSETTING( 0xB4, "Swiss German" )
|
||||
PORT_DIPSETTING( 0xBA, "Norwegian" )
|
||||
PORT_DIPSETTING( 0xBC, "Danish" )
|
||||
PORT_DIPSETTING( 0xB2, "Swiss French" )
|
||||
INPUT_PORTS_END
|
||||
|
||||
INPUT_PORTS_START( basic )
|
||||
// keycodes 90..9f
|
||||
PORT_START("COL1")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Menu") PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9))
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F4") PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4))
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F3") PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3))
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F2") PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2))
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F1") PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1))
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("KP 8") PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD))
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Stop")
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Print/Enter")
|
||||
|
||||
// keycodes a0..af
|
||||
PORT_START("COL2")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("User/System") PORT_CODE(KEYCODE_F10) PORT_CHAR(UCHAR_MAMEKEY(F10))
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F5") PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5))
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F6") PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6))
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F7") PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7))
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F8") PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8))
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("KP 9") PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD))
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Clear Line")
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Clear Display")
|
||||
|
||||
// keycodes b0..bf
|
||||
PORT_START("COL3")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(')
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')')
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+')
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?')
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Backspace") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8)
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
|
||||
// keycodes c0..cf
|
||||
PORT_START("COL4")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') PORT_CHAR(0x09) PORT_CHAR(0x09)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') PORT_CHAR(0x0f) PORT_CHAR(0x0f)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') PORT_CHAR(0x10) PORT_CHAR(0x10)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{')
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}')
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("< >")
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
|
||||
// keycodes d0..df
|
||||
PORT_START("COL5")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') PORT_CHAR(0x0a) PORT_CHAR(0x0a)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') PORT_CHAR(0x0b) PORT_CHAR(0x0b)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') PORT_CHAR(0x0c) PORT_CHAR(0x0c)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"')
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|')
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Home") PORT_CODE(KEYCODE_HOME) PORT_CHAR(UCHAR_MAMEKEY(HOME))
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
|
||||
// keycodes e0..ef
|
||||
PORT_START("COL6")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') PORT_CHAR(0x0d) PORT_CHAR(0x0d)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<')
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>')
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_')
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Select") PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(PLUS_PAD))
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
|
||||
// keycodes f0..ff
|
||||
PORT_START("COL7")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') PORT_CHAR(0x0e) PORT_CHAR(0x0e)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("KP .") PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD))
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Left") PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT))
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Down") PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN))
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Up") PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP))
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Right") PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT))
|
||||
|
||||
// keycodes 00..0f
|
||||
PORT_START("COL8")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("KP 5") PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD))
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Extend Char R")PORT_CODE(KEYCODE_RALT) PORT_CHAR(UCHAR_SHIFT_2)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Extend Char L")PORT_CODE(KEYCODE_LALT) PORT_CHAR(UCHAR_SHIFT_2)
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("R Shift") PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_MAMEKEY(RSHIFT))
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("L Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Control") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL))
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Break/Reset")
|
||||
|
||||
// keycodes 10..1f
|
||||
PORT_START("COL9")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("KP 4") PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD))
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("KP 7") PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD))
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
|
||||
// keycodes 20..2f
|
||||
PORT_START("COL10")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("KP 1") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD))
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("KP 2") PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD))
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("KP 0") PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD))
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
|
||||
// keycodes 30..3f
|
||||
PORT_START("COL11")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') PORT_CHAR(0x02) PORT_CHAR(0x02)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') PORT_CHAR(0x16) PORT_CHAR(0x16)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') PORT_CHAR(0x03) PORT_CHAR(0x03)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') PORT_CHAR(0x18) PORT_CHAR(0x18)
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') PORT_CHAR(0x1a) PORT_CHAR(0x1a)
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("DEL/Esc") PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC))
|
||||
|
||||
// keycodes 40..4f
|
||||
PORT_START("COL12")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("KP 6") PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD))
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("KP 3") PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD))
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
|
||||
// keycodes 50..5f
|
||||
PORT_START("COL13")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') PORT_CHAR(0x08) PORT_CHAR(0x08)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') PORT_CHAR(0x07) PORT_CHAR(0x07)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') PORT_CHAR(0x06) PORT_CHAR(0x06)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') PORT_CHAR(0x04) PORT_CHAR(0x04)
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') PORT_CHAR(0x13) PORT_CHAR(0x13)
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') PORT_CHAR(0x01) PORT_CHAR(0x01)
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED )
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Caps Lock") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK))
|
||||
|
||||
// keycodes 60..6f
|
||||
PORT_START("COL14")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') PORT_CHAR(0x15) PORT_CHAR(0x15)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') PORT_CHAR(0x19) PORT_CHAR(0x19)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') PORT_CHAR(0x14) PORT_CHAR(0x14)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') PORT_CHAR(0x12) PORT_CHAR(0x12)
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') PORT_CHAR(0x05) PORT_CHAR(0x05)
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') PORT_CHAR(0x17) PORT_CHAR(0x17)
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') PORT_CHAR(0x11) PORT_CHAR(0x11)
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tab") PORT_CODE(KEYCODE_TAB) PORT_CHAR(9)
|
||||
|
||||
// keycodes 70..7f
|
||||
PORT_START("COL15")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&')
|
||||
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^')
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%')
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')
|
||||
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#')
|
||||
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@')
|
||||
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~')
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
INPUT_PORTS_START( hle_hp_ipc_device )
|
||||
PORT_INCLUDE( basic )
|
||||
PORT_INCLUDE( id )
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
BASE HLE KEYBOARD DEVICE
|
||||
***************************************************************************/
|
||||
|
||||
/*--------------------------------------------------
|
||||
hle_device_base::hle_device_base
|
||||
designated device constructor
|
||||
--------------------------------------------------*/
|
||||
|
||||
hle_device_base::hle_device_base(machine_config const &mconfig, device_type type, char const *name, char const *tag, device_t *owner, uint32_t clock, char const *shortname, char const *source)
|
||||
: device_t(mconfig, type, name, tag, owner, clock, shortname, source)
|
||||
, device_hp_hil_interface(mconfig, *this)
|
||||
, device_matrix_keyboard_interface(mconfig, *this, "COL1", "COL2", "COL3", "COL4", "COL5", "COL6", "COL7", "COL8", "COL9", "COL10", "COL11", "COL12", "COL13", "COL14", "COL15")
|
||||
{ }
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
hle_device_base::~hle_device_base
|
||||
destructor
|
||||
--------------------------------------------------*/
|
||||
|
||||
hle_device_base::~hle_device_base()
|
||||
{ }
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
hle_device_base::device_start
|
||||
perform expensive initialisations, allocate
|
||||
resources, register for save state
|
||||
--------------------------------------------------*/
|
||||
|
||||
void hle_device_base::device_start()
|
||||
{
|
||||
set_hp_hil_mlc_device();
|
||||
|
||||
m_powerup = true;
|
||||
m_passthru = false;
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
hle_device_base::device_reset
|
||||
perform startup tasks, also used for host
|
||||
requested reset
|
||||
--------------------------------------------------*/
|
||||
|
||||
void hle_device_base::device_reset()
|
||||
{
|
||||
m_fifo.clear();
|
||||
|
||||
// kick the base
|
||||
reset_key_state();
|
||||
start_processing(attotime::from_hz(1'200));
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
hle_device_base::device_timer
|
||||
handle timed events
|
||||
--------------------------------------------------*/
|
||||
|
||||
void hle_device_base::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
device_matrix_keyboard_interface::device_timer(timer, id, param, ptr);
|
||||
}
|
||||
|
||||
void hle_device_base::hil_write(uint16_t data)
|
||||
{
|
||||
int frames = 0;
|
||||
// printf("rx from mlc %04X (%s %02X)\n", data, BIT(data, 11) ? "command" : "data", data & 255);
|
||||
|
||||
if (BIT(data, 11)) switch (data & 255)
|
||||
{
|
||||
case HPHIL_IFC:
|
||||
m_powerup = false;
|
||||
break;
|
||||
|
||||
case HPHIL_EPT:
|
||||
m_passthru = true;
|
||||
break;
|
||||
|
||||
case HPHIL_ELB:
|
||||
m_passthru = false;
|
||||
break;
|
||||
|
||||
case HPHIL_ACF+1:
|
||||
m_device_id = data & 7;
|
||||
m_device_id16 = m_device_id << 8;
|
||||
m_hp_hil_mlc->hil_write((data & ~7) | ((data + 1) & 7));
|
||||
return;
|
||||
break;
|
||||
|
||||
case HPHIL_POL:
|
||||
if (!m_fifo.empty())
|
||||
{
|
||||
m_hp_hil_mlc->hil_write(m_device_id16 | 0x40); // Keycode Set 1, no coordinate data
|
||||
frames = 1;
|
||||
while (!m_fifo.empty())
|
||||
{
|
||||
m_hp_hil_mlc->hil_write(m_device_id16 | m_fifo.dequeue());
|
||||
frames++;
|
||||
}
|
||||
}
|
||||
m_hp_hil_mlc->hil_write(HPMLC_W1_C | m_device_id16 | HPHIL_POL | ((data + frames) & 7));
|
||||
return;
|
||||
break;
|
||||
|
||||
case HPHIL_DSR:
|
||||
m_device_id = m_device_id16 = 0;
|
||||
m_powerup = true;
|
||||
break;
|
||||
|
||||
case HPHIL_IDD:
|
||||
m_hp_hil_mlc->hil_write(m_device_id16 | ioport("COL0")->read());
|
||||
m_hp_hil_mlc->hil_write(m_device_id16 | 0);
|
||||
break;
|
||||
|
||||
case HPHIL_DHR:
|
||||
device_reset();
|
||||
return;
|
||||
break;
|
||||
|
||||
default:
|
||||
logerror("command %02X unknown\n", data & 255);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!m_passthru)
|
||||
m_hp_hil_mlc->hil_write(data);
|
||||
// else
|
||||
// m_next->hil_write(data);
|
||||
}
|
||||
|
||||
void hle_device_base::transmit_byte(uint8_t byte)
|
||||
{
|
||||
if (!m_fifo.full()) {
|
||||
// printf("queuing %02X\n", byte);
|
||||
m_fifo.enqueue(byte);
|
||||
}
|
||||
// else
|
||||
// printf("queuing fail (fifo full)\n");
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
hle_device_base::key_make
|
||||
handle a key being pressed
|
||||
--------------------------------------------------*/
|
||||
|
||||
void hle_device_base::key_make(uint8_t row, uint8_t column)
|
||||
{
|
||||
transmit_byte((((row + 1) ^ 8) << 4) + (column << 1));
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
hle_device_base::key_break
|
||||
handle a key being released
|
||||
--------------------------------------------------*/
|
||||
|
||||
void hle_device_base::key_break(uint8_t row, uint8_t column)
|
||||
{
|
||||
transmit_byte((((row + 1) ^ 8) << 4) + (column << 1) + 1);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
HP INTEGRAL HLE KEYBOARD DEVICE
|
||||
***************************************************************************/
|
||||
|
||||
/*--------------------------------------------------
|
||||
hle_hp_ipc_device::hle_hp_ipc_device
|
||||
abbreviated constructor
|
||||
--------------------------------------------------*/
|
||||
|
||||
hle_hp_ipc_device::hle_hp_ipc_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock)
|
||||
: hle_device_base(mconfig, HP_IPC_HLE_KEYBOARD, "HP Integral Keyboard (HLE)", tag, owner, clock, "hp_ipc_hle_kbd", __FILE__)
|
||||
{ }
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
hle_hp_ipc_device::device_input_ports
|
||||
get input ports for this device
|
||||
--------------------------------------------------*/
|
||||
|
||||
ioport_constructor hle_hp_ipc_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME(hle_hp_ipc_device);
|
||||
}
|
||||
|
||||
|
||||
} } // namespace bus::hp_hil
|
60
src/devices/bus/hp_hil/hlekbd.h
Normal file
60
src/devices/bus/hp_hil/hlekbd.h
Normal file
@ -0,0 +1,60 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sergey Svishchev
|
||||
#ifndef MAME_DEVICES_HP_HIL_HLEKBD_H
|
||||
#define MAME_DEVICES_HP_HIL_HLEKBD_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hp_hil.h"
|
||||
#include "machine/keyboard.h"
|
||||
|
||||
|
||||
extern device_type const HP_IPC_HLE_KEYBOARD;
|
||||
|
||||
|
||||
namespace bus { namespace hp_hil {
|
||||
class hle_device_base
|
||||
: public device_t
|
||||
, public device_hp_hil_interface
|
||||
, protected device_matrix_keyboard_interface<15U>
|
||||
{
|
||||
public:
|
||||
|
||||
protected:
|
||||
// constructor/destructor
|
||||
hle_device_base(machine_config const &mconfig, device_type type, char const *name, char const *tag, device_t *owner, uint32_t clock, char const *shortname, char const *source);
|
||||
virtual ~hle_device_base() override;
|
||||
|
||||
// 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_matrix_keyboard_interface overrides
|
||||
virtual void key_make(uint8_t row, uint8_t column) override;
|
||||
virtual void key_break(uint8_t row, uint8_t column) override;
|
||||
|
||||
// device_hp_hil_interface overrides
|
||||
virtual void hil_write(uint16_t data) override;
|
||||
|
||||
private:
|
||||
// device_serial_interface uses 10'000 range
|
||||
// device_matrix_keyboard_interface uses 20'000 range
|
||||
|
||||
void transmit_byte(uint8_t byte);
|
||||
|
||||
util::fifo<uint8_t, 8> m_fifo;
|
||||
};
|
||||
|
||||
|
||||
class hle_hp_ipc_device : public hle_device_base
|
||||
{
|
||||
public:
|
||||
hle_hp_ipc_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
virtual ioport_constructor device_input_ports() const override;
|
||||
};
|
||||
|
||||
} } // namespace bus::hp_hil
|
||||
|
||||
#endif // MAME_DEVICES_HP_HIL_HLEKBD_H
|
282
src/devices/bus/hp_hil/hp_hil.cpp
Normal file
282
src/devices/bus/hp_hil/hp_hil.cpp
Normal file
@ -0,0 +1,282 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sergey Svishchev
|
||||
/***************************************************************************
|
||||
|
||||
HP-HIL Keyboard connector interface
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "hp_hil.h"
|
||||
|
||||
|
||||
#define VERBOSE_DBG 0
|
||||
|
||||
#define DBG_LOG(N,M,A) \
|
||||
do { \
|
||||
if(VERBOSE_DBG>=N) \
|
||||
{ \
|
||||
if( M ) \
|
||||
logerror("%11.6f at %s: %-10s",machine().time().as_double(),machine().describe_context(),(char*)M ); \
|
||||
logerror A; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
const device_type HP_HIL_SLOT = device_creator<hp_hil_slot_device>;
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// hp_hil_slot_device - constructor
|
||||
//-------------------------------------------------
|
||||
hp_hil_slot_device::hp_hil_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, HP_HIL_SLOT, "HP_HIL_SLOT", tag, owner, clock, "hp_hil_slot", __FILE__)
|
||||
, device_slot_interface(mconfig, *this)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void hp_hil_slot_device::static_set_hp_hil_slot(device_t &device, device_t *owner, const char *mlc_tag)
|
||||
{
|
||||
hp_hil_slot_device &hp_hil = dynamic_cast<hp_hil_slot_device &>(device);
|
||||
hp_hil.m_owner = owner;
|
||||
hp_hil.m_mlc_tag = mlc_tag;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void hp_hil_slot_device::device_start()
|
||||
{
|
||||
device_hp_hil_interface *dev = dynamic_cast<device_hp_hil_interface *>(get_card_device());
|
||||
|
||||
if (dev) device_hp_hil_interface::static_set_hp_hil_mlc(*dev,m_owner->subdevice(m_mlc_tag));
|
||||
}
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
const device_type HP_HIL_MLC = device_creator<hp_hil_mlc_device>;
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// hp_hil_mlc_device - constructor
|
||||
//-------------------------------------------------
|
||||
hp_hil_mlc_device::hp_hil_mlc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, HP_HIL_MLC, "HP-HIL Master Link Controller", tag, owner, clock, "hp_hil", __FILE__)
|
||||
, int_cb(*this)
|
||||
, nmi_cb(*this)
|
||||
{
|
||||
}
|
||||
|
||||
void hp_hil_mlc_device::add_hp_hil_device( device_hp_hil_interface *device )
|
||||
{
|
||||
m_device_list.append(*device);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
void hp_hil_mlc_device::device_start()
|
||||
{
|
||||
// resolve callbacks
|
||||
int_cb.resolve_safe();
|
||||
nmi_cb.resolve_safe();
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific reset
|
||||
//-------------------------------------------------
|
||||
void hp_hil_mlc_device::device_reset()
|
||||
{
|
||||
// FIFO contents are not initialized at powerup or reset
|
||||
|
||||
m_r2 = 0;
|
||||
m_r3 = 0; // HPMLC_R3_NMI;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER(hp_hil_mlc_device::write)
|
||||
{
|
||||
device_hp_hil_interface *entry = m_device_list.first();
|
||||
|
||||
DBG_LOG(2,"Write", ("%d <- %02x\n", offset, data));
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0:
|
||||
DBG_LOG(1,"Transmit", ("%scommand 0x%02x to device %d\n", !m_loop?"loopback ":"", data, m_w1 & 7));
|
||||
if (m_loop & 2) // no devices on 2nd link loop
|
||||
return;
|
||||
if (m_loop == 0)
|
||||
{
|
||||
if (!m_fifo.full()) {
|
||||
m_fifo.enqueue(data | (m_w1 << 8));
|
||||
m_r3 |= HPMLC_R3_INT;
|
||||
int_cb(ASSERT_LINE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ((m_w1 & 7) == 0) // broadcast
|
||||
{
|
||||
while (entry)
|
||||
{
|
||||
entry->hil_write(data | (m_w1 << 8));
|
||||
entry = entry->next();
|
||||
}
|
||||
} else
|
||||
{
|
||||
while (entry)
|
||||
{
|
||||
if (entry->device_id() == (m_w1 & 7))
|
||||
entry->hil_write(data | (m_w1 << 8));
|
||||
entry = entry->next();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
m_w1 = data & 0xf;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
m_w2 = data;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
m_w3 = data;
|
||||
break;
|
||||
|
||||
case 32: // loopback switch: bit 0 = loop0, bit 1 = loop1
|
||||
m_loop = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
READ8_MEMBER(hp_hil_mlc_device::read)
|
||||
{
|
||||
uint8_t data = 0;
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0:
|
||||
if (!m_fifo.empty())
|
||||
data = m_fifo.dequeue() & 255;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (!m_fifo.empty())
|
||||
data = m_fifo.peek() >> 8;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
data = m_r2;
|
||||
m_r2 &= ~(HPMLC_R2_PERR|HPMLC_R2_FERR|HPMLC_R2_FOF);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
data = m_r3;
|
||||
m_r3 &= ~(HPMLC_R3_INT|HPMLC_R3_NMI|HPMLC_R3_LERR);
|
||||
int_cb(CLEAR_LINE);
|
||||
break;
|
||||
}
|
||||
|
||||
DBG_LOG(2,"Read", ("%d == %02x\n", offset, data));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void hp_hil_mlc_device::hil_write(uint16_t data)
|
||||
{
|
||||
DBG_LOG(1,"Receive", ("%s %04X fifo %s\n",
|
||||
BIT(data, 11)?"command":"data", data, m_fifo.full()?"full":(m_fifo.empty()?"empty":"ok")));
|
||||
|
||||
if (!m_fifo.full())
|
||||
{
|
||||
if (!BIT(data, 11))
|
||||
{
|
||||
m_fifo.enqueue(data);
|
||||
}
|
||||
else if (!m_fifo.empty() || !(m_w2 & HPMLC_W2_IPF))
|
||||
{
|
||||
m_fifo.enqueue(data);
|
||||
m_r3 |= HPMLC_R3_INT;
|
||||
m_w3 &= ~HPMLC_W3_APE;
|
||||
int_cb(ASSERT_LINE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_r2 |= HPMLC_R2_FOF;
|
||||
m_r3 |= HPMLC_R3_INT;
|
||||
int_cb(ASSERT_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(hp_hil_mlc_device::ap_w)
|
||||
{
|
||||
if (state && (m_w3 & HPMLC_W3_APE))
|
||||
{
|
||||
device_hp_hil_interface *entry = m_device_list.first();
|
||||
|
||||
while (entry)
|
||||
{
|
||||
entry->hil_write(HPMLC_W1_C | HPHIL_POL);
|
||||
entry = entry->next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// DEVICE PC KBD INTERFACE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_hp_hil_interface - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
device_hp_hil_interface::device_hp_hil_interface(const machine_config &mconfig, device_t &device)
|
||||
: device_slot_card_interface(mconfig, device)
|
||||
, m_hp_hil_mlc(nullptr)
|
||||
, m_hp_hil_mlc_dev(nullptr)
|
||||
, m_next(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// ~device_hp_hil_interface - destructor
|
||||
//-------------------------------------------------
|
||||
|
||||
device_hp_hil_interface::~device_hp_hil_interface()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void device_hp_hil_interface::static_set_hp_hil_mlc(device_t &device, device_t *mlc_device)
|
||||
{
|
||||
device_hp_hil_interface &hp_hil = dynamic_cast<device_hp_hil_interface &>(device);
|
||||
hp_hil.m_hp_hil_mlc_dev = mlc_device;
|
||||
}
|
||||
|
||||
|
||||
void device_hp_hil_interface::set_hp_hil_mlc_device()
|
||||
{
|
||||
m_hp_hil_mlc = dynamic_cast<hp_hil_mlc_device *>(m_hp_hil_mlc_dev);
|
||||
m_hp_hil_mlc->add_hp_hil_device(this);
|
||||
}
|
||||
|
200
src/devices/bus/hp_hil/hp_hil.h
Normal file
200
src/devices/bus/hp_hil/hp_hil.h
Normal file
@ -0,0 +1,200 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sergey Svishchev
|
||||
/***************************************************************************
|
||||
|
||||
HP-HIL Keyboard connector interface
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __HP_HIL_H__
|
||||
#define __HP_HIL_H__
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
|
||||
#define HPMLC_R1_OB 0x10
|
||||
|
||||
#define HPMLC_W1_C 0x0800
|
||||
|
||||
#define HPMLC_R2_PERR 0x01
|
||||
#define HPMLC_R2_FERR 0x02
|
||||
#define HPMLC_R2_FOF 0x04
|
||||
|
||||
#define HPMLC_W2_TEST 0x01
|
||||
#define HPMLC_W2_IPF 0x04
|
||||
|
||||
#define HPMLC_R3_INT 0x01
|
||||
#define HPMLC_R3_NMI 0x02
|
||||
#define HPMLC_R3_LERR 0x04
|
||||
|
||||
#define HPMLC_W3_APE 0x02
|
||||
|
||||
// commands
|
||||
#define HPHIL_IFC 0x00 // Interface Clear
|
||||
#define HPHIL_EPT 0x01 // Enter Pass-Thru Mode
|
||||
#define HPHIL_ELB 0x02 // Enter Loop-Back Mode
|
||||
#define HPHIL_IDD 0x03 // Identify and Describe
|
||||
#define HPHIL_DSR 0x04 // Device Soft Reset
|
||||
#define HPHIL_PST 0x05 // Perform Self Test
|
||||
#define HPHIL_RRG 0x06 // Read Register
|
||||
#define HPHIL_WRG 0x07 // Write Register
|
||||
#define HPHIL_ACF 0x08 // Auto Configure [08..0f]
|
||||
#define HPHIL_POL 0x10 // Poll [10..1f]
|
||||
#define HPHIL_RPL 0x20 // RePoll [20..2f]
|
||||
#define HPHIL_RNM 0x30 // Report Name
|
||||
#define HPHIL_RST 0x31 // Report Status
|
||||
#define HPHIL_EXD 0x32 // Extended Describe
|
||||
#define HPHIL_RSC 0x33 // Report Security Code
|
||||
#define HPHIL_DKA 0x3D // Disable Keyswitch AutoRepeat
|
||||
#define HPHIL_EK1 0x3E // Enable Keyswitch AutoRepeat 30cps
|
||||
#define HPHIL_EK2 0x3F // Enable Keyswitch AutoRepeat 60cps
|
||||
#define HPHIL_PR1 0x40 // Prompt 1..7 [40..46]
|
||||
#define HPHIL_PRM 0x47 // Prompt (General Purpose)
|
||||
#define HPHIL_AK1 0x48 // Acknowledge 1..7 [40..46]
|
||||
#define HPHIL_ACK 0x4F // Acknowledge (General Purpose)
|
||||
#define HPHIL_RIO 0xFA // Register I/O Error
|
||||
#define HPHIL_SHR 0xFB // System Hard Reset
|
||||
#define HPHIL_TER 0xFC // Transmission Error
|
||||
#define HPHIL_CAE 0xFD // Configuration Address Error
|
||||
#define HPHIL_DHR 0xFE // Device Hard Reset
|
||||
|
||||
/*
|
||||
* init sequnce (p. 4-13)
|
||||
*
|
||||
* DHR
|
||||
* IFC
|
||||
* ACF
|
||||
* IDD
|
||||
* EXD
|
||||
* EPT
|
||||
* ELB
|
||||
* RPL
|
||||
* POL
|
||||
* EPT
|
||||
* ELB
|
||||
*
|
||||
*/
|
||||
|
||||
//**************************************************************************
|
||||
// INTERFACE CONFIGURATION MACROS
|
||||
//**************************************************************************
|
||||
|
||||
#define MCFG_HP_HIL_INT_CALLBACK(_devcb) \
|
||||
devcb = &hp_hil_mlc_device::set_int_callback(*device, DEVCB_##_devcb);
|
||||
|
||||
#define MCFG_HP_HIL_NMI_CALLBACK(_devcb) \
|
||||
devcb = &hp_hil_mlc_device::set_nmi_callback(*device, DEVCB_##_devcb);
|
||||
|
||||
#define MCFG_HP_HIL_SLOT_ADD(_mlc_tag, _tag, _slot_intf, _def_slot) \
|
||||
MCFG_DEVICE_ADD(_tag, HP_HIL_SLOT, 0) \
|
||||
MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) \
|
||||
hp_hil_slot_device::static_set_hp_hil_slot(*device, owner, _mlc_tag);
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
|
||||
class hp_hil_slot_device : public device_t,
|
||||
public device_slot_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
hp_hil_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
|
||||
// inline configuration
|
||||
static void static_set_hp_hil_slot(device_t &device, device_t *owner, const char *mlc_tag);
|
||||
|
||||
protected:
|
||||
// configuration
|
||||
device_t *m_owner;
|
||||
const char *m_mlc_tag;
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type HP_HIL_SLOT;
|
||||
|
||||
|
||||
class device_hp_hil_interface;
|
||||
|
||||
class hp_hil_mlc_device : public device_t
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
hp_hil_mlc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
~hp_hil_mlc_device() { m_device_list.detach_all(); }
|
||||
|
||||
template<class _Object> static devcb_base &set_int_callback(device_t &device, _Object object) { return downcast<hp_hil_mlc_device &>(device).int_cb.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_nmi_callback(device_t &device, _Object object) { return downcast<hp_hil_mlc_device &>(device).nmi_cb.set_callback(object); }
|
||||
|
||||
void add_hp_hil_device(device_hp_hil_interface *device);
|
||||
|
||||
DECLARE_READ8_MEMBER(read);
|
||||
DECLARE_WRITE8_MEMBER(write);
|
||||
DECLARE_WRITE_LINE_MEMBER(ap_w);
|
||||
|
||||
void hil_write(uint16_t data);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
simple_list<device_hp_hil_interface> m_device_list;
|
||||
|
||||
util::fifo<uint16_t, 16> m_fifo;
|
||||
uint8_t m_r2, m_r3, m_w1, m_w2, m_w3, m_loop;
|
||||
|
||||
private:
|
||||
devcb_write_line int_cb, nmi_cb;
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type HP_HIL_MLC;
|
||||
|
||||
|
||||
// ======================> device_hp_hil_interface
|
||||
|
||||
class device_hp_hil_interface : public device_slot_card_interface
|
||||
{
|
||||
friend class hp_hil_mlc_device;
|
||||
|
||||
public:
|
||||
// construction/destruction
|
||||
device_hp_hil_interface(const machine_config &mconfig, device_t &device);
|
||||
virtual ~device_hp_hil_interface();
|
||||
|
||||
device_hp_hil_interface *next() const { return m_next; }
|
||||
|
||||
void set_hp_hil_mlc_device();
|
||||
|
||||
// inline configuration
|
||||
static void static_set_hp_hil_mlc(device_t &device, device_t *mlc_device);
|
||||
|
||||
virtual void hil_write(uint16_t data) { };
|
||||
int device_id() { return m_device_id; };
|
||||
|
||||
hp_hil_mlc_device *m_hp_hil_mlc;
|
||||
device_t *m_hp_hil_mlc_dev;
|
||||
device_hp_hil_interface *m_next;
|
||||
|
||||
protected:
|
||||
virtual void device_reset() { }
|
||||
|
||||
hp_hil_slot_device *m_slot;
|
||||
|
||||
int m_device_id;
|
||||
uint16_t m_device_id16;
|
||||
bool m_powerup;
|
||||
bool m_passthru;
|
||||
};
|
||||
|
||||
|
||||
#endif /* __HP_HIL_H__ */
|
713
src/devices/video/hp1ll3.cpp
Normal file
713
src/devices/video/hp1ll3.cpp
Normal file
@ -0,0 +1,713 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sergey Svishchev
|
||||
/*
|
||||
HP 1LL3-0005 GPU emulation.
|
||||
|
||||
Used by HP Integral PC, possibly other HP products.
|
||||
|
||||
On IPC, memory is 4 16Kx4bit DRAM chips = 32KB total (16K words),
|
||||
but firmware probes memory size and can work with 128KB memory.
|
||||
Undocumented "_desktop" mode requires this.
|
||||
|
||||
Capabilities:
|
||||
- up to 1024x1024 px on screen
|
||||
- lines
|
||||
- rectangles
|
||||
- area fill with user-defined pattern
|
||||
- 16x16 user-defined proportional font, with automatic cursor
|
||||
- 16x16 user-defined sprite for mouse cursor (not a sprite layer)
|
||||
- windows with blitter (copy, fill and scroll) and clipping
|
||||
|
||||
To do:
|
||||
. proper cursor and mouse pointers [cursor can be offset from the pen location]
|
||||
+ variable width fonts [?? placed relative to current window]
|
||||
+ basic lines
|
||||
- patterned lines
|
||||
. bit blits & scroll
|
||||
. meaning of WRRR bits
|
||||
. meaning of CONF data [+ autoconfiguration]
|
||||
- interrupt generation
|
||||
- realistic timing?
|
||||
- &c.
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "hp1ll3.h"
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// MACROS / CONSTANTS
|
||||
//**************************************************************************
|
||||
|
||||
#define VERBOSE_DBG 2 /* general debug messages */
|
||||
|
||||
#define DBG_LOG(N,M,A) \
|
||||
do { \
|
||||
if(VERBOSE_DBG>=N) \
|
||||
{ \
|
||||
if( M ) \
|
||||
logerror("%11.6f at %s: %-16s",machine().time().as_double(),machine().describe_context(),(char*)M ); \
|
||||
logerror A; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define HPGPU_VRAM_SIZE 16384 // *4 // experiment
|
||||
#define HPGPU_HORZ_TOTAL 512
|
||||
#define HPGPU_VERT_TOTAL 256
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
// devices
|
||||
const device_type HP1LL3 = device_creator<hp1ll3_device>;
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// hp1ll3_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
hp1ll3_device::hp1ll3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, HP1LL3, "Hewlett-Package 1LL3-0005 GPU", tag, owner, clock, "hp1ll3", __FILE__)
|
||||
, device_video_interface(mconfig, *this)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void hp1ll3_device::device_start()
|
||||
{
|
||||
// register for state saving
|
||||
save_item(NAME(m_conf));
|
||||
|
||||
machine().first_screen()->register_screen_bitmap(m_bitmap);
|
||||
|
||||
m_cursor.allocate(16, 16);
|
||||
m_sprite.allocate(16, 16);
|
||||
|
||||
m_videoram = std::make_unique<uint16_t[]>(HPGPU_VRAM_SIZE*2); // x2 size to make WRWIN/RDWIN easier
|
||||
}
|
||||
|
||||
void hp1ll3_device::device_reset()
|
||||
{
|
||||
m_input_ptr = m_command = 0;
|
||||
m_sad = m_fad = m_dad = m_org = m_rr = m_udl = 0;
|
||||
m_enable_video = m_enable_cursor = m_enable_sprite = m_busy = false;
|
||||
}
|
||||
|
||||
|
||||
inline void hp1ll3_device::point(int x, int y, int px)
|
||||
{
|
||||
uint16_t offset = m_sad;
|
||||
|
||||
offset += y*(HPGPU_HORZ_TOTAL/16) + (x >> 4);
|
||||
|
||||
if (px)
|
||||
m_videoram[offset] |= (1 << (15-(x%16)));
|
||||
else
|
||||
m_videoram[offset] &= ~(1 << (15-(x%16)));
|
||||
}
|
||||
|
||||
// Bresenham algorithm -- from ef9365.cpp
|
||||
void hp1ll3_device::line(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
int dx;
|
||||
int dy,t;
|
||||
int e;
|
||||
int x,y;
|
||||
int incy;
|
||||
int diago,horiz;
|
||||
unsigned char c1;
|
||||
|
||||
c1=0;
|
||||
incy=1;
|
||||
|
||||
if(x2>x1)
|
||||
dx = x2 - x1;
|
||||
else
|
||||
dx = x1 - x2;
|
||||
|
||||
if(y2>y1)
|
||||
dy = y2 - y1;
|
||||
else
|
||||
dy = y1 - y2;
|
||||
|
||||
if( dy > dx )
|
||||
{
|
||||
t = y2;
|
||||
y2 = x2;
|
||||
x2 = t;
|
||||
|
||||
t = y1;
|
||||
y1 = x1;
|
||||
x1 = t;
|
||||
|
||||
t = dx;
|
||||
dx = dy;
|
||||
dy = t;
|
||||
|
||||
c1 = 1;
|
||||
}
|
||||
|
||||
if( x1 > x2 )
|
||||
{
|
||||
t = y2;
|
||||
y2 = y1;
|
||||
y1 = t;
|
||||
|
||||
t = x1;
|
||||
x1 = x2;
|
||||
x2 = t;
|
||||
}
|
||||
|
||||
horiz = dy<<1;
|
||||
diago = ( dy - dx )<<1;
|
||||
e = ( dy<<1 ) - dx;
|
||||
|
||||
if( y1 <= y2 )
|
||||
incy = 1;
|
||||
else
|
||||
incy = -1;
|
||||
|
||||
x = x1;
|
||||
y = y1;
|
||||
|
||||
if(c1)
|
||||
{
|
||||
do
|
||||
{
|
||||
point(y,x,m_udl);
|
||||
|
||||
if( e > 0 )
|
||||
{
|
||||
y = y + incy;
|
||||
e = e + diago;
|
||||
}
|
||||
else
|
||||
{
|
||||
e = e + horiz;
|
||||
}
|
||||
|
||||
x++;
|
||||
|
||||
} while( x <= x2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
point(x,y,m_udl);
|
||||
|
||||
if( e > 0 )
|
||||
{
|
||||
y = y + incy;
|
||||
e = e + diago;
|
||||
}
|
||||
else
|
||||
{
|
||||
e = e + horiz;
|
||||
}
|
||||
|
||||
x++;
|
||||
|
||||
} while( x <= x2 );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void hp1ll3_device::fill(int org_x, int org_y, int w, int h, int arg)
|
||||
{
|
||||
uint16_t gfx, offset, mask, max_x = org_x + w;
|
||||
|
||||
if (m_enable_cursor) bitblt(m_cursor_x, m_cursor_y, m_dad, 16, 16, RR_XOR);
|
||||
if (m_enable_sprite) bitblt(m_sprite_x, m_sprite_y, m_dad + 16, 16, 16, RR_XOR);
|
||||
|
||||
for (int y = org_y; y < org_y + h; y++) {
|
||||
gfx = m_videoram[m_dad + (0x10 * arg) + y%16];
|
||||
if (m_rr == RR_COPYINVERTED) gfx ^= 0xffff;
|
||||
for (int x = org_x; x < max_x;) {
|
||||
mask = 0xffff;
|
||||
offset = m_sad + m_org + y * (HPGPU_HORZ_TOTAL/16) + (x >> 4);
|
||||
|
||||
if (offset >= m_sad + (HPGPU_VERT_TOTAL * HPGPU_HORZ_TOTAL/WS))
|
||||
DBG_LOG(0,"HPGPU",("buffer overflow in FILL: %04x (%d, %d)\n", offset, 16*x, y));
|
||||
|
||||
// clipping
|
||||
if (x == org_x) {
|
||||
mask >>= (org_x % WS);
|
||||
x += (WS - (org_x % WS));
|
||||
} else {
|
||||
if ((max_x - x) < WS) {
|
||||
mask &= ~((1 << (WS - (max_x % WS))) - 1);
|
||||
}
|
||||
x += WS;
|
||||
}
|
||||
m_videoram[offset] &= ~mask;
|
||||
m_videoram[offset] |= gfx & mask;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_enable_cursor) bitblt(m_cursor_x, m_cursor_y, m_dad, 16, 16, RR_XOR);
|
||||
if (m_enable_sprite) bitblt(m_sprite_x, m_sprite_y, m_dad + 16, 16, 16, RR_XOR);
|
||||
}
|
||||
|
||||
// sprite drawing -- source is 16x16 px max, no window clipping
|
||||
void hp1ll3_device::bitblt(int dstx, int dsty, uint16_t srcaddr, int width, int height, int op)
|
||||
{
|
||||
uint16_t gfx, offset, mask;
|
||||
int max_x, max_y;
|
||||
|
||||
max_x = dstx + width;
|
||||
if (max_x >= HPGPU_HORZ_TOTAL)
|
||||
max_x = HPGPU_HORZ_TOTAL;
|
||||
|
||||
max_y = dsty + height;
|
||||
if (max_y >= HPGPU_VERT_TOTAL)
|
||||
max_y = HPGPU_VERT_TOTAL;
|
||||
|
||||
for (int y = dsty; y < max_y; y++) {
|
||||
mask = 0xffff;
|
||||
gfx = m_videoram[srcaddr + y - dsty] & mask;
|
||||
offset = m_sad + y * (HPGPU_HORZ_TOTAL/16) + (dstx >> 4);
|
||||
|
||||
if (offset >= m_sad + (HPGPU_VERT_TOTAL * HPGPU_HORZ_TOTAL/16))
|
||||
DBG_LOG(0,"HPGPU",("buffer overflow in bitblt: %04x (%d, %d)\n", offset, 16*dstx, y));
|
||||
|
||||
// are we crossing word boundary?
|
||||
if (dstx % 16) {
|
||||
if (op == RR_XOR)
|
||||
{
|
||||
m_videoram[offset ] ^= gfx >> (dstx % 16);
|
||||
m_videoram[offset + 1] ^= gfx << (16 - (dstx % 16));
|
||||
}
|
||||
} else {
|
||||
if (op == RR_XOR)
|
||||
{
|
||||
m_videoram[offset] ^= (gfx & mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void hp1ll3_device::label(uint8_t chr, int width)
|
||||
{
|
||||
uint16_t x, gfx, bg = 0x3f, offset, font = m_fontdata + chr * 16;
|
||||
int max_y = m_cursor_y + m_fontheight;
|
||||
|
||||
if (max_y >= m_window.org_y + m_window.height)
|
||||
max_y = m_window.org_y + m_window.height - 1 - m_cursor_y;
|
||||
else
|
||||
max_y -= m_cursor_y;
|
||||
|
||||
if (m_enable_cursor) bitblt(m_cursor_x, m_cursor_y, m_dad, 16, 16, RR_XOR);
|
||||
if (m_enable_sprite) bitblt(m_sprite_x, m_sprite_y, m_dad + 16, 16, 16, RR_XOR);
|
||||
|
||||
for (int y = 0; y < max_y; y++) {
|
||||
x = m_cursor_x;
|
||||
offset = m_sad + (m_cursor_y + y) * (HPGPU_HORZ_TOTAL/16) + (x >> 4);
|
||||
gfx = m_videoram[font + y] >> (16 - width);
|
||||
|
||||
if (offset >= m_sad + (HPGPU_VERT_TOTAL * HPGPU_HORZ_TOTAL/16))
|
||||
DBG_LOG(0,"HPGPU",("buffer overflow in LABEL: %04x (%d, %d)\n", offset, 16*x, y));
|
||||
|
||||
// are we crossing word boundary?
|
||||
if ((x % 16) > (16 - width)) {
|
||||
if (m_rr == RR_COPYINVERTED) {
|
||||
m_videoram[offset ] |= bg >> ((x % 16) - (16 - width));
|
||||
m_videoram[offset + 1] |= bg << (16 - ((x + width) % 16));
|
||||
} else {
|
||||
m_videoram[offset ] &= ~(bg>> ((x % 16) - (16 - width)));
|
||||
m_videoram[offset + 1] &= ~(bg<< (16 - ((x + width) % 16)));
|
||||
}
|
||||
m_videoram[offset ] ^= gfx >> ((x % 16) - (16 - width));
|
||||
m_videoram[offset + 1] ^= gfx << (16 - ((x + width) % 16));
|
||||
} else {
|
||||
if (m_rr == RR_COPYINVERTED) {
|
||||
m_videoram[offset ] |= bg << ((16 - width) - (x % 16));
|
||||
} else {
|
||||
m_videoram[offset ] &= ~(bg<< ((16 - width) - (x % 16)));
|
||||
}
|
||||
m_videoram[offset ] ^= gfx << ((16 - width) - (x % 16));
|
||||
}
|
||||
}
|
||||
|
||||
m_cursor_x += width;
|
||||
if (m_enable_cursor) bitblt(m_cursor_x, m_cursor_y, m_dad, 16, 16, RR_XOR);
|
||||
if (m_enable_sprite) bitblt(m_sprite_x, m_sprite_y, m_dad + 16, 16, 16, RR_XOR);
|
||||
}
|
||||
|
||||
|
||||
uint32_t hp1ll3_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
int x, y, offset;
|
||||
uint16_t gfx, *p;
|
||||
|
||||
if (!m_enable_video) {
|
||||
bitmap.fill(rgb_t::black());
|
||||
return 0;
|
||||
}
|
||||
|
||||
// XXX last line is not actually drawn on real hw
|
||||
for (y = 0; y < HPGPU_VERT_TOTAL-1; y++) {
|
||||
offset = m_sad + y*(HPGPU_HORZ_TOTAL/16);
|
||||
p = &m_bitmap.pix16(y);
|
||||
|
||||
for (x = offset; x < offset + HPGPU_HORZ_TOTAL/16; x++)
|
||||
{
|
||||
gfx = m_videoram[x];
|
||||
|
||||
*p++ = BIT(gfx, 15);
|
||||
*p++ = BIT(gfx, 14);
|
||||
*p++ = BIT(gfx, 13);
|
||||
*p++ = BIT(gfx, 12);
|
||||
*p++ = BIT(gfx, 11);
|
||||
*p++ = BIT(gfx, 10);
|
||||
*p++ = BIT(gfx, 9);
|
||||
*p++ = BIT(gfx, 8);
|
||||
*p++ = BIT(gfx, 7);
|
||||
*p++ = BIT(gfx, 6);
|
||||
*p++ = BIT(gfx, 5);
|
||||
*p++ = BIT(gfx, 4);
|
||||
*p++ = BIT(gfx, 3);
|
||||
*p++ = BIT(gfx, 2);
|
||||
*p++ = BIT(gfx, 1);
|
||||
*p++ = BIT(gfx, 0);
|
||||
}
|
||||
}
|
||||
|
||||
copybitmap(bitmap, m_bitmap, 0, 0, 0, 0, cliprect);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// read - register read
|
||||
//-------------------------------------------------
|
||||
|
||||
/*
|
||||
* offset 0: CSR
|
||||
*
|
||||
* bit 0 gpu is busy
|
||||
* bit 1 data is ready
|
||||
* bit 3 vert blank time
|
||||
* bit 7 out of window
|
||||
*
|
||||
* offset 2: data
|
||||
*/
|
||||
|
||||
READ8_MEMBER( hp1ll3_device::read )
|
||||
{
|
||||
uint8_t data = 0;
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0:
|
||||
data = m_busy ? 1 : 0;
|
||||
data |= 2;
|
||||
data |= (m_screen->vblank() ? 8 : 0);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
switch (m_command)
|
||||
{
|
||||
case RDMEM:
|
||||
if (m_memory_ptr < HPGPU_VRAM_SIZE*2) {
|
||||
if (m_memory_ptr & 1) {
|
||||
data = m_videoram[m_memory_ptr >> 1] & 0xff;
|
||||
} else {
|
||||
data = m_videoram[m_memory_ptr >> 1] >> 8;
|
||||
}
|
||||
m_memory_ptr++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DBG_LOG(1,"HPGPU", ("R @ %d == %02x\n", offset, data));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// write - register write
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE8_MEMBER( hp1ll3_device::write )
|
||||
{
|
||||
DBG_LOG(1,"HPGPU", ("W @ %d <- %02x\n", offset, data));
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0:
|
||||
command(data);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
switch (m_command)
|
||||
{
|
||||
case CONF:
|
||||
if (m_conf_ptr & 1) {
|
||||
m_conf[m_conf_ptr >> 1] |= data;
|
||||
} else {
|
||||
m_conf[m_conf_ptr >> 1] = data << 8;
|
||||
}
|
||||
if (m_conf_ptr++ == 22) {
|
||||
DBG_LOG(2,"HPGPU",("CONF data received: %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X\n",
|
||||
m_conf[0], m_conf[1], m_conf[2], m_conf[3],
|
||||
m_conf[4], m_conf[5], m_conf[6], m_conf[7],
|
||||
m_conf[8], m_conf[9], m_conf[10]));
|
||||
}
|
||||
break;
|
||||
|
||||
case WRMEM:
|
||||
if (m_memory_ptr < HPGPU_VRAM_SIZE*2) {
|
||||
if (m_memory_ptr & 1) {
|
||||
m_videoram[m_memory_ptr >> 1] |= data;
|
||||
} else {
|
||||
m_videoram[m_memory_ptr >> 1] = data << 8;
|
||||
}
|
||||
m_memory_ptr++;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
switch (m_input_ptr)
|
||||
{
|
||||
case 0:
|
||||
m_input[0] = data << 8;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
m_input[0] |= data;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
m_input[1] = data << 8;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
m_input[1] |= data;
|
||||
break;
|
||||
}
|
||||
DBG_LOG(2,"HPGPU",("wrote %02x at %d, input buffer is %04X %04X\n", data, m_input_ptr, m_input[0], m_input[1]));
|
||||
m_input_ptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void hp1ll3_device::command(int command)
|
||||
{
|
||||
int c, w;
|
||||
|
||||
switch (command)
|
||||
{
|
||||
|
||||
// type 0 commands -- no data
|
||||
|
||||
case NOP:
|
||||
DBG_LOG(2,"HPGPU",("command: NOP [%d, 0x%x]\n", command, command));
|
||||
switch (m_command)
|
||||
{
|
||||
case RDMEM:
|
||||
DBG_LOG(1,"HPGPU",("RDMEM of %d words at %04X complete\n", (m_memory_ptr >> 1) - m_input[0], m_input[0]));
|
||||
break;
|
||||
|
||||
case WRMEM:
|
||||
DBG_LOG(1,"HPGPU",("WRMEM of %d words to %04X complete\n", (m_memory_ptr >> 1) - m_input[0], m_input[0]));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case DISVID:
|
||||
DBG_LOG(2,"HPGPU",("command: DISVID [%d, 0x%x]\n", command, command));
|
||||
m_enable_video = false;
|
||||
break;
|
||||
|
||||
case ENVID:
|
||||
DBG_LOG(2,"HPGPU",("command: ENVID [%d, 0x%x]\n", command, command));
|
||||
DBG_LOG(1,"HPGPU",("enable video; SAD %04x FAD %04x DAD %04x ORG %04x UDL %04x RR %04x\n",
|
||||
m_sad, m_fad, m_dad, m_org, m_udl, m_rr));
|
||||
m_enable_video = true;
|
||||
break;
|
||||
|
||||
case DISSP:
|
||||
DBG_LOG(2,"HPGPU",("command: DISSP [%d, 0x%x]\n", command, command));
|
||||
if (m_enable_sprite) {
|
||||
bitblt(m_sprite_x, m_sprite_y, m_dad + 16, 16, 16, RR_XOR);
|
||||
m_enable_sprite = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case ENSP:
|
||||
DBG_LOG(2,"HPGPU",("command: ENSP [%d, 0x%x]\n", command, command));
|
||||
if (m_enable_sprite) {
|
||||
bitblt(m_sprite_x, m_sprite_y, m_dad + 16, 16, 16, RR_XOR);
|
||||
}
|
||||
bitblt(m_sprite_x, m_sprite_y, m_dad + 16, 16, 16, RR_XOR);
|
||||
m_enable_sprite = true;
|
||||
DBG_LOG(1,"HPGPU",("enable sprite; cursor %d,%d sprite %d,%d\n", m_cursor_x, m_cursor_y, m_sprite_x, m_sprite_y));
|
||||
break;
|
||||
|
||||
case DISCURS:
|
||||
DBG_LOG(2,"HPGPU",("command: DISCURS [%d, 0x%x]\n", command, command));
|
||||
if (m_enable_cursor) {
|
||||
bitblt(m_cursor_x, m_cursor_y, m_dad, 16, 16, RR_XOR);
|
||||
m_enable_cursor = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case ENCURS:
|
||||
DBG_LOG(2,"HPGPU",("command: ENCURS [%d, 0x%x]\n", command, command));
|
||||
if (m_enable_cursor) {
|
||||
bitblt(m_cursor_x, m_cursor_y, m_dad, 16, 16, RR_XOR);
|
||||
}
|
||||
bitblt(m_cursor_x, m_cursor_y, m_dad, 16, 16, RR_XOR);
|
||||
m_enable_cursor = true;
|
||||
DBG_LOG(1,"HPGPU",("enable cursor; cursor %d,%d sprite %d,%d\n", m_cursor_x, m_cursor_y, m_sprite_x, m_sprite_y));
|
||||
break;
|
||||
|
||||
// type 1 commands -- 1 word of data expected in the buffer
|
||||
|
||||
// start of screen memory
|
||||
case WRSAD:
|
||||
DBG_LOG(2,"HPGPU",("command: WRSAD [%d, 0x%x] (0x%04x)\n", command, command, m_input[0]));
|
||||
m_sad = m_input[0];
|
||||
break;
|
||||
|
||||
// start of font memory
|
||||
case WRFAD:
|
||||
DBG_LOG(2,"HPGPU",("command: WRFAD [%d, 0x%x] (0x%04x)\n", command, command, m_input[0]));
|
||||
m_fad = m_input[0];
|
||||
m_fontheight = m_videoram[m_fad];
|
||||
m_fontdata = m_fad + m_videoram[m_fad + 1] + 2;
|
||||
DBG_LOG(1,"HPGPU",("font data set: FAD %04X header %d bitmaps %04X height %d\n",
|
||||
m_fad, m_videoram[m_fad + 1], m_fontdata, m_fontheight));
|
||||
break;
|
||||
|
||||
// start of data area
|
||||
case WRDAD:
|
||||
DBG_LOG(2,"HPGPU",("command: WRDAD [%d, 0x%x] (0x%04x)\n", command, command, m_input[0]));
|
||||
m_dad = m_input[0];
|
||||
break;
|
||||
|
||||
// ??
|
||||
case WRORG:
|
||||
DBG_LOG(2,"HPGPU",("command: WRORG [%d, 0x%x] (0x%04x)\n", command, command, m_input[0]));
|
||||
m_org = m_input[0];
|
||||
break;
|
||||
|
||||
// set replacement rule (raster op)
|
||||
case WRRR:
|
||||
DBG_LOG(2,"HPGPU",("command: WRRR [%d, 0x%x] (0x%04x)\n", command, command, m_input[0]));
|
||||
m_rr = m_input[0];
|
||||
break;
|
||||
|
||||
// set user-defined line pattern
|
||||
case WRUDL:
|
||||
DBG_LOG(2,"HPGPU",("command: WRUDL [%d, 0x%x] (0x%04x)\n", command, command, m_input[0]));
|
||||
m_udl = m_input[0];
|
||||
break;
|
||||
|
||||
// area fill
|
||||
case FILL:
|
||||
DBG_LOG(2,"HPGPU",("command: FILL [%d, 0x%x] (0x%04x) from (%d,%d) size (%d,%d) rop 0x%x\n",
|
||||
command, command, m_input[0],
|
||||
m_window.org_x, m_window.org_y, m_window.width, m_window.height, m_rr));
|
||||
fill(m_window.org_x, m_window.org_y, m_window.width, m_window.height, m_input[0]);
|
||||
break;
|
||||
|
||||
case LABEL:
|
||||
DBG_LOG(2,"HPGPU",("command: LABEL [%d, 0x%x] (0x%04x, '%c') at %d,%d\n", command, command, m_input[0],
|
||||
(m_input[0]<32||m_input[0]>127) ? ' ' : m_input[0], m_cursor_x, m_cursor_y));
|
||||
c = m_input[0] & 255;
|
||||
w = (c & 1) ?
|
||||
(m_videoram[m_fad + 2 + (c>>1)] & 255) :
|
||||
(m_videoram[m_fad + 2 + (c>>1)] >> 8);
|
||||
label(c, w);
|
||||
break;
|
||||
|
||||
// type 2 commands -- 2 words of data expected in the buffer
|
||||
|
||||
case DRAWPX:
|
||||
DBG_LOG(2,"HPGPU",("command: DRAWPX [%d, 0x%x] (%d, %d)\n", command, command, m_input[0], m_input[1]));
|
||||
point(m_input[0], m_input[1],(m_rr != RR_COPYINVERTED));
|
||||
break;
|
||||
|
||||
// set window size
|
||||
case WRWINSIZ:
|
||||
DBG_LOG(2,"HPGPU",("command: WRWINSIZ [%d, 0x%x] (%d, %d)\n", command, command, m_input[0], m_input[1]));
|
||||
m_window.width = m_input[0];
|
||||
m_window.height = m_input[1];
|
||||
break;
|
||||
|
||||
// set window origin
|
||||
case WRWINORG:
|
||||
DBG_LOG(2,"HPGPU",("command: WRWINORG [%d, 0x%x] (%d, %d)\n", command, command, m_input[0], m_input[1]));
|
||||
m_window.org_x = m_input[0];
|
||||
m_window.org_y = m_input[1];
|
||||
break;
|
||||
|
||||
// move pointer absolute
|
||||
case MOVEP:
|
||||
DBG_LOG(2,"HPGPU",("command: MOVEP [%d, 0x%x] (%d, %d)\n", command, command, m_input[0], m_input[1]));
|
||||
if (m_enable_cursor) bitblt(m_cursor_x, m_cursor_y, m_dad, 16, 16, RR_XOR);
|
||||
if (m_enable_sprite) bitblt(m_sprite_x, m_sprite_y, m_dad + 16, 16, 16, RR_XOR);
|
||||
m_cursor_x = m_input[0];
|
||||
m_cursor_y = m_input[1];
|
||||
if (m_enable_cursor) bitblt(m_cursor_x, m_cursor_y, m_dad, 16, 16, RR_XOR);
|
||||
if (m_enable_sprite) bitblt(m_sprite_x, m_sprite_y, m_dad + 16, 16, 16, RR_XOR);
|
||||
break;
|
||||
|
||||
// move sprite absolute
|
||||
case MOVESP:
|
||||
DBG_LOG(2,"HPGPU",("command: MOVESP [%d, 0x%x] (%d, %d)\n", command, command, m_input[0], m_input[1]));
|
||||
m_sprite_x = m_input[0];
|
||||
m_sprite_y = m_input[1];
|
||||
break;
|
||||
|
||||
// draw to ...
|
||||
case DRAWP:
|
||||
DBG_LOG(2,"HPGPU",("command: DRAWP [%d, 0x%x] (%d, %d) to (%d, %d)\n",
|
||||
command, command, m_cursor_x, m_cursor_y, m_input[0], m_input[1]));
|
||||
line(m_cursor_x, m_cursor_y, m_input[0], m_input[1]);
|
||||
m_cursor_x = m_input[0];
|
||||
m_cursor_y = m_input[1];
|
||||
break;
|
||||
|
||||
// type 3 command -- CONF -- accept configuration parameters (11 words)
|
||||
|
||||
case CONF:
|
||||
m_conf_ptr = 0;
|
||||
break;
|
||||
|
||||
// type 4 commands -- like type 1 plus data is read or written after command, terminated by NOP
|
||||
|
||||
case RDMEM:
|
||||
case WRMEM:
|
||||
DBG_LOG(2,"HPGPU",("command: %s [%d, 0x%x] (0x%04x)\n",
|
||||
command == RDMEM?"RDMEM":"WRMEM", command, command, m_input[0]));
|
||||
m_memory_ptr = m_input[0] << 1; // memory is word-addressable
|
||||
break;
|
||||
|
||||
default:
|
||||
DBG_LOG(1,"HPGPU",("command: UNKNOWN [%d, 0x%x]\n", command, command));
|
||||
break;
|
||||
}
|
||||
|
||||
m_input_ptr = 0;
|
||||
m_command = command;
|
||||
}
|
176
src/devices/video/hp1ll3.h
Normal file
176
src/devices/video/hp1ll3.h
Normal file
@ -0,0 +1,176 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sergey Svishchev
|
||||
/***************************************************************************
|
||||
|
||||
HP 1LL3-0005 GPU emulation.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __HP1LL3_H__
|
||||
#define __HP1LL3_H__
|
||||
|
||||
///*************************************************************************
|
||||
// MACROS / CONSTANTS
|
||||
///*************************************************************************
|
||||
|
||||
/*
|
||||
* command types (send)
|
||||
*
|
||||
* 0 -- no data
|
||||
* 1 -- write 1 word of data, then command
|
||||
* 2 -- write 2 words of data, then command
|
||||
* 3 -- write command, then 11 words of data (= CONF only?)
|
||||
* 4 -- write 1 word of data, then command, then write X words of data, then write NOP
|
||||
*
|
||||
* (read)
|
||||
*
|
||||
* 3 -- ???
|
||||
* 4 -- write 1 word of data, then command, then read X words of data, then write NOP
|
||||
*/
|
||||
#define NOP 0 // type 0
|
||||
#define CONF 2 // type 3, configure GPU (screen size, timings...). 11 words of data.
|
||||
#define DISVID 3 // type 0, disable video
|
||||
#define ENVID 4 // type 0, enable video
|
||||
#define WRMEM 7 // type 4, write GPU memory at offset, terminate by NOP
|
||||
#define RDMEM 8 // type 4, read GPU memory from offset, terminate by NOP
|
||||
#define WRSAD 9 // type 1, set screen area start address
|
||||
#define WRORG 10 // type 1, set ???
|
||||
#define WRDAD 11 // type 1, set data area start address (16x16 area fill, sprite and cursor)
|
||||
#define WRRR 12 // type 1, set replacement rule (rasterop)
|
||||
#define MOVEP 13 // type 2, move pointer
|
||||
#define IMOVEP 14
|
||||
#define DRAWP 15 // type 2, draw line
|
||||
#define IDRAWP 16
|
||||
#define RDP 17
|
||||
#define WRUDL 18 // type 1, set user-defined line pattern (16-bit)
|
||||
#define WRWINSIZ 19 // type 2, set ???
|
||||
#define WRWINORG 20 // type 2, set ???
|
||||
#define COPY 21 // type 2
|
||||
#define FILL 22 // type 1, fill area
|
||||
#define FRAME 23 // type _, draw rectangle
|
||||
#define SCROLUP 24 // type 2
|
||||
#define SCROLDN 25 // type 2
|
||||
#define SCROLLF 26 // type 2
|
||||
#define SCROLRT 27 // type 2
|
||||
#define RDWIN 28 // type 1
|
||||
#define WRWIN 29 // type 1
|
||||
#define RDWINPARM 30
|
||||
#define CR 31
|
||||
#define CRLFx 32
|
||||
#define LABEL 36 // type 1, draw text
|
||||
#define ENSP 38 // type 0, enable sprite
|
||||
#define DISSP 39 // type 0, disable sprite
|
||||
#define MOVESP 40 // type 2, move sprite
|
||||
#define IMOVESP 41
|
||||
#define RDSP 42
|
||||
#define DRAWPX 43 // type _, draw single pixel
|
||||
#define WRFAD 44 // type 1, set font area start address
|
||||
#define ENCURS 45 // type 0
|
||||
#define DISCURS 46 // type 0
|
||||
#define ID 63
|
||||
|
||||
|
||||
/*
|
||||
* Replacement Rules (rops). sources:
|
||||
*
|
||||
* - NetBSD's diofbvar.h (definitions for Topcat chip)
|
||||
* - pdf/hp/9000_300/specs/A-5958-4362-9_Series_300_Display_Color_Card_Theory_of_Operation_Oct85.pdf
|
||||
* refers to TOPCAT documentation p/n A-1FH2-2001-7 (not online)
|
||||
*/
|
||||
#define RR_FORCE_ZERO 0x0
|
||||
#define RR_CLEAR RR_FORCE_ZERO
|
||||
#define RR_AND 0x1
|
||||
#define RR_AND_NOT_OLD 0x2
|
||||
#define RR_NEW 0x3
|
||||
#define RR_COPY RR_NEW
|
||||
#define RR_AND_NOT_NEW 0x4
|
||||
#define RR_OLD 0x5
|
||||
#define RR_XOR 0x6
|
||||
#define RR_OR 0x7
|
||||
#define RR_NOR 0x8
|
||||
#define RR_XNOR 0x9
|
||||
#define RR_NOT_OLD 0xa
|
||||
#define RR_INVERT RR_NOT_OLD
|
||||
#define RR_OR_NOT_OLD 0xb
|
||||
#define RR_NOT_NEW 0xc
|
||||
#define RR_COPYINVERTED RR_NOT_NEW
|
||||
#define RR_OR_NOT_NEW 0xd
|
||||
#define RR_NAND 0xe
|
||||
#define RR_FORCE_ONE 0xf
|
||||
|
||||
#define WS 16 // bits in a word
|
||||
|
||||
|
||||
///*************************************************************************
|
||||
// INTERFACE CONFIGURATION MACROS
|
||||
///*************************************************************************
|
||||
|
||||
#define MCFG_HP1LL3_ADD(_tag) \
|
||||
MCFG_DEVICE_ADD(_tag, HP1LL3, 0)
|
||||
|
||||
///*************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
///*************************************************************************
|
||||
|
||||
|
||||
// ======================> hp1ll3_device
|
||||
|
||||
class hp1ll3_device : public device_t,
|
||||
public device_video_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
hp1ll3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
DECLARE_READ8_MEMBER(read);
|
||||
DECLARE_WRITE8_MEMBER(write);
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
private:
|
||||
void command(int command);
|
||||
|
||||
inline void point(int x, int y, int px);
|
||||
void label(uint8_t chr, int width);
|
||||
void fill(int x, int y, int w, int h, int arg);
|
||||
void line(int x_from, int y_from, int x_to, int y_to);
|
||||
void bitblt(int dstx, int dsty, uint16_t srcaddr, int width, int height, int op);
|
||||
|
||||
uint16_t m_conf[11], m_input[2];
|
||||
int m_input_ptr, m_memory_ptr, m_conf_ptr;
|
||||
int m_command;
|
||||
|
||||
uint16_t m_sad;
|
||||
uint16_t m_org;
|
||||
uint16_t m_dad;
|
||||
uint16_t m_rr;
|
||||
uint16_t m_fad, m_fontdata, m_fontheight;
|
||||
uint16_t m_udl;
|
||||
|
||||
bool m_enable_video, m_enable_cursor, m_enable_sprite;
|
||||
uint16_t m_cursor_x, m_cursor_y;
|
||||
uint16_t m_sprite_x, m_sprite_y;
|
||||
struct {
|
||||
uint16_t width, height, org_x, org_y, width_w;
|
||||
} m_window;
|
||||
std::unique_ptr<uint16_t[]> m_videoram;
|
||||
|
||||
bool m_busy;
|
||||
|
||||
bitmap_ind16 m_bitmap, m_cursor, m_sprite;
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type HP1LL3;
|
||||
|
||||
|
||||
#endif
|
@ -152,6 +152,7 @@ enum
|
||||
XTAL_15_4MHz = 15400000, /* DVK KSM */
|
||||
XTAL_15_468MHz = 15468480, /* Bank Panic h/w, Sega G80 */
|
||||
XTAL_15_8976MHz = 15897600, /* IAI Swyft */
|
||||
XTAL_15_92MHz = 15920000, /* HP Integral PC */
|
||||
XTAL_16MHz = 16000000, /* Extremely common, used on 100's of PCBs */
|
||||
XTAL_16_384MHz = 16384000,
|
||||
XTAL_16_5888MHz = 16588800, /* SM 7238 */
|
||||
|
42
src/lib/formats/hp_ipc_dsk.cpp
Normal file
42
src/lib/formats/hp_ipc_dsk.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sergey Svishchev
|
||||
/*********************************************************************
|
||||
|
||||
formats/hp_ipc_dsk.c
|
||||
|
||||
HP Integral PC format
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "formats/hp_ipc_dsk.h"
|
||||
|
||||
hp_ipc_format::hp_ipc_format() : wd177x_format(formats)
|
||||
{
|
||||
}
|
||||
|
||||
const char *hp_ipc_format::name() const
|
||||
{
|
||||
return "hp_ipc";
|
||||
}
|
||||
|
||||
const char *hp_ipc_format::description() const
|
||||
{
|
||||
return "HP Integral PC disk image";
|
||||
}
|
||||
|
||||
const char *hp_ipc_format::extensions() const
|
||||
{
|
||||
return "img";
|
||||
}
|
||||
|
||||
const hp_ipc_format::format hp_ipc_format::formats[] = {
|
||||
// images from coho.org. gaps unverified.
|
||||
{ floppy_image::FF_35, floppy_image::DSDD, floppy_image::MFM,
|
||||
2000, 9, 77, 2, 512, {}, 1, {}, 60, 22, 43 },
|
||||
{}
|
||||
};
|
||||
|
||||
const floppy_format_type FLOPPY_HP_IPC_FORMAT = &floppy_image_format_creator<hp_ipc_format>;
|
||||
|
30
src/lib/formats/hp_ipc_dsk.h
Normal file
30
src/lib/formats/hp_ipc_dsk.h
Normal file
@ -0,0 +1,30 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Sergey Svishchev
|
||||
/*********************************************************************
|
||||
|
||||
formats/hp_ipc_dsk.h
|
||||
|
||||
hp_ipc format
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef HP_IPC_DSK_H_
|
||||
#define HP_IPC_DSK_H_
|
||||
|
||||
#include "wd177x_dsk.h"
|
||||
|
||||
class hp_ipc_format : public wd177x_format {
|
||||
public:
|
||||
hp_ipc_format();
|
||||
|
||||
virtual const char *name() const override;
|
||||
virtual const char *description() const override;
|
||||
virtual const char *extensions() const override;
|
||||
|
||||
private:
|
||||
static const format formats[];
|
||||
};
|
||||
|
||||
extern const floppy_format_type FLOPPY_HP_IPC_FORMAT;
|
||||
|
||||
#endif
|
@ -2,10 +2,51 @@
|
||||
// copyright-holders:
|
||||
/******************************************************************************
|
||||
|
||||
|
||||
Integral Personal Computer (HP9807A)
|
||||
Hewlett-Packard, 1985
|
||||
|
||||
Driver to-do list
|
||||
=================
|
||||
|
||||
- softlist: merge dumps from coho.org and classiccmp.org
|
||||
- keyboard: NMI generation, autorepeat
|
||||
- HP-HIL mouse
|
||||
- RTC chip: proper month, day
|
||||
- switchable graphics resolution ("_desktop" mode uses 640x400)
|
||||
- HP-IB chip
|
||||
- CS/80, SS/80 storage protocol(s) and drives
|
||||
- HP-IL printer
|
||||
- sound (needs dump of COP452)
|
||||
|
||||
QA
|
||||
- diagnstc.td0: display test [cannot execute]
|
||||
- diagnstc.td0: complete keyboard test [keyboard stops responding]
|
||||
- diagnstc.td0: speaker test
|
||||
- diagnstc.td0: printer test
|
||||
+ diagnstc.td0: auto: floppy disc test
|
||||
+ diagnstc.td0: auto: ram test
|
||||
- diagnstc.td0: auto: rtc test [cannot execute]
|
||||
- diagnstc.td0: auto: short keyboard test [cannot execute + keyboard stops responding]
|
||||
|
||||
maybe
|
||||
- drive AP line of MLC from a timer
|
||||
- RTC standby interrupt?
|
||||
- what does _desktop do except setting 640x400 mode?
|
||||
- non-HLE keyboard and mouse? (need dumps of COP4xx)
|
||||
|
||||
slot devices
|
||||
- 82915A -- 300/1200 bps modem; http://www.hpmuseum.net/display_item.php?hw=920
|
||||
- 82919A -- serial; http://www.hpmuseum.net/display_item.php?hw=445
|
||||
- 82920A -- current loop; http://www.hpmuseum.net/display_item.php?hw=975
|
||||
- 82922A -- BCD interface; http://www.hpmuseum.net/display_item.php?hw=921
|
||||
- 82923A -- GPIO; http://www.hpmuseum.net/display_item.php?hw=976
|
||||
- 82924A -- HP-IL; http://www.hpmuseum.net/display_item.php?hw=922
|
||||
- 82968A -- up to 256 KB of ROM on top of operating system PCA
|
||||
- 82971A -- up to 1 MB of EPROM or 2 MB or masked ROM
|
||||
- 82998A -- HP-IB; http://www.hpmuseum.net/display_item.php?hw=933
|
||||
- 98071A -- 640x400 composite Video + Serial; http://www.hpmuseum.net/display_item.php?hw=935
|
||||
|
||||
|
||||
This is a portable mains-powered UNIX workstation computer system produced by Hewlett-Packard and launched in 1985
|
||||
Basic hardware specs are....
|
||||
- 68000 CPU at 7.96MHz
|
||||
@ -74,7 +115,7 @@ Notes:
|
||||
LS74 - 74LS74 at U2 provides system clock dividers /4 /2
|
||||
MB81256 - Fujitsu MB81256 256Kx1 DRAM. Total RAM 512Kx8/256Kx16. HP part# 1818-3308. U20-U35 (DIP16)
|
||||
TMS4500 - Texas Instruments TMS4500A DRAM Controller at U4. Clock input 3.98MHz [15.92/4] (DIP40)
|
||||
U58 - HP-HIL Keyboard Interface 'Cerberus'. Clock input on pin 24 is unknown (DIP24)
|
||||
U58 - 1RD2-6001, HP-HIL Master Link Controller 'Cerberus'. Clock input on pin 24 is unknown (DIP24)
|
||||
U60 - Unknown IC used as an interrupt encoder. Possibly a logic chip? (DIP20)
|
||||
555 - 555 Timer
|
||||
J1/J2 - Connectors joining to LOGIC B PCA (logic A to logic B bus)
|
||||
@ -121,13 +162,13 @@ HP Part# 00095-60952
|
||||
| J14 J6 J5 J4 J3 J7 J1 J8 J9 J12 |
|
||||
|------------------------------------------------------------------------------------------------------|
|
||||
Notes:
|
||||
GPU - GPU (Graphics Processor) at U1. Clock input 3MHz [24/8]. VSync on pin 45, HSync on pin 46 (DIP48)
|
||||
GPU - 1LL3-0005 GPU (Graphics Processor) at U1. Clock input 3MHz [24/8]. VSync on pin 45, HSync on pin 46 (DIP48)
|
||||
16Kx4 - 16Kx4 DRAM, organised as 32Kx8bit/16Kx16bit at U3, U4, U5 & U6. Chip type unknown, likely Fujitsu MB81416 (DIP18)
|
||||
WD2797 - Western Digital WD2797 Floppy Disk Controller at U18. Clock input 2MHz [24/2/3/2] (DIP40)
|
||||
HP-IL(1) - HP-IL 1LJ7-0015 'Saturn' Thinkjet Printer Controller IC at U28. Clock input 3MHz on pin 9 [24/8] (DIP48)
|
||||
HP-IL(2) - HP-IL Interface IC at U31. Clock input 2MHz on pin 22 [24/2/3/2] (DIP28)
|
||||
HP-IL(2) - HP-IL 1LB3 Interface IC at U31. Clock input 2MHz on pin 22 [24/2/3/2] (DIP28)
|
||||
1Kb - 1Kb RAM at U27 for printer buffer (DIP28, type unknown, very old, with only DATA0,1,2,3, C/D and DIN,DOUT)
|
||||
ROM - 16Kb (2Kx8?) Some kind of very early DIP28 PROM/ROM? Same pinout as 1Kb RAM above. Holds the character font table for the printer
|
||||
ROM - 16Kb (32Kx4) Some kind of very early DIP28 PROM/ROM? Same pinout as 1Kb RAM above. Holds the character font table for the printer
|
||||
Four versions of this ROM exist, one each for Japan/Arabic/Hebrew and one for all other regions
|
||||
NS58167A - National Semiconductor NS58167A Clock Controller RTC at U44. Clock input 32.768kHz (DIP24)
|
||||
LM358 - National Semiconductor LM358 Operational Amplifier at U40 (DIP8)
|
||||
@ -246,7 +287,7 @@ F80000-FFFFFF - Reserved 512Kb
|
||||
Access to 800000-FFFFFF can be remapped by the MMU registers.
|
||||
|
||||
|
||||
Interrupts
|
||||
Interrupts (all autovectored)
|
||||
----------
|
||||
High Priority 7 - Soft reset from keyboard (NMI)
|
||||
/\ 6 - RTC or NBIR3 (external I/O)
|
||||
@ -259,10 +300,81 @@ Low Priority 1 - RTC
|
||||
Note external interrupt lines NBIR0 to NBIR3 can be asserted by an interface connected to the external I/O port
|
||||
|
||||
|
||||
Useful links etc.
|
||||
-----------------
|
||||
|
||||
bitsavers://pdf/hp/integral/00095-90126_Integral_Personal_Computer_Service_Jan86.pdf
|
||||
|
||||
bitsavers://pdf/hp/hp-hil/45918A-90001_HP-HIL_Technical_Reference_Manual_Jan86.pdf
|
||||
HP-HIL MLC, SLC datasheets
|
||||
|
||||
bitsavers://pdf/sony/floppy/Sony_OA-D32_Microfloppy_Service_Nov83.pdf
|
||||
OA-D32W
|
||||
|
||||
http://www.hpl.hp.com/hpjournal/pdfs/IssuePDFs/1983-01.pdf
|
||||
HP-IL issue
|
||||
|
||||
http://www.hpl.hp.com/hpjournal/pdfs/IssuePDFs/1985-10.pdf
|
||||
IPC issue
|
||||
|
||||
http://www.hpl.hp.com/hpjournal/pdfs/IssuePDFs/1987-06.pdf
|
||||
HP-HIL article
|
||||
|
||||
http://www.hpmuseum.net/pdf/ComputerNews_1985_Jan15_37pages_OCR.pdf
|
||||
introducing the IPC
|
||||
|
||||
http://www.hpmuseum.net/pdf/ComputerFocus_1985_Nov_25pages_OCR.pdf
|
||||
SysV upgrade
|
||||
|
||||
http://www.hpmuseum.net/pdf/InformationSystemsAndManufacturingNews_81pages_Jun1-86_OCR.pdf
|
||||
EPROM/ROM modules
|
||||
|
||||
http://www.hpmuseum.net/pdf/HPChannels_1986_11_37pages_Nov86_OCR.pdf
|
||||
SW Eng ROM and serial option for it
|
||||
|
||||
http://www.coho.org/~pete/downloads/IPC/burst/Freeware/IPC_Driver_Writers_Disc/hp-ux.5.0.0
|
||||
kernel namelist
|
||||
|
||||
http://www.hpmuseum.net/display_item.php?hw=122
|
||||
overview, manuals, software
|
||||
|
||||
http://www.ambry.com/hp-computer-model/9807A.html
|
||||
replacement parts
|
||||
|
||||
http://www.brouhaha.com/~eric/hpcalc/chips/
|
||||
chip part numbers
|
||||
|
||||
|
||||
Software to look for
|
||||
--------------------
|
||||
|
||||
00095-60978 "Service ROM - Used in trobleshooting the integral PC" via ambry
|
||||
00095-60925 "Service ROM" via service manual
|
||||
00095-60969 "Service Diagnostic Disc" via service manual
|
||||
00095-60950 "I/O Component-Level Diagnostic Disc" via serial interface service manual
|
||||
|
||||
00095-60006 (original System III-based HP-UX 1.0 ROM)
|
||||
82995A (same bits as 82991A; the latter is an upgrade kit, former was pre-installed)
|
||||
82989J Technical Basic ROM (Jan'1986)
|
||||
82987A Software Engineering ROM (Nov'1986) (possibly can be rebuilt from floppy images on coho?)
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "bus/hp_hil/hp_hil.h"
|
||||
#include "bus/hp_hil/hil_devices.h"
|
||||
#include "cpu/m68000/m68000.h"
|
||||
#include "formats/hp_ipc_dsk.h"
|
||||
#include "machine/bankdev.h"
|
||||
#include "machine/mm58167.h"
|
||||
#include "machine/ram.h"
|
||||
#include "machine/wd_fdc.h"
|
||||
#include "video/hp1ll3.h"
|
||||
|
||||
#include "rendlay.h"
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
|
||||
class hp_ipc_state : public driver_device
|
||||
@ -271,81 +383,381 @@ public:
|
||||
hp_ipc_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_bankdev(*this, "bankdev")
|
||||
, m_fdc(*this, "fdc")
|
||||
, m_ram(*this, RAM_TAG)
|
||||
, m_screen(*this, "screen")
|
||||
{ }
|
||||
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
|
||||
DECLARE_READ16_MEMBER(mem_r);
|
||||
DECLARE_WRITE16_MEMBER(mem_w);
|
||||
DECLARE_READ16_MEMBER(mmu_r);
|
||||
DECLARE_WRITE16_MEMBER(mmu_w);
|
||||
DECLARE_READ16_MEMBER(ram_r);
|
||||
DECLARE_WRITE16_MEMBER(ram_w);
|
||||
DECLARE_READ16_MEMBER(trap_r);
|
||||
DECLARE_WRITE16_MEMBER(trap_w);
|
||||
|
||||
DECLARE_READ8_MEMBER(floppy_id_r);
|
||||
DECLARE_WRITE8_MEMBER(floppy_id_w);
|
||||
DECLARE_FLOPPY_FORMATS(floppy_formats);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(irq_1);
|
||||
DECLARE_WRITE_LINE_MEMBER(irq_2);
|
||||
DECLARE_WRITE_LINE_MEMBER(irq_3);
|
||||
DECLARE_WRITE_LINE_MEMBER(irq_4);
|
||||
DECLARE_WRITE_LINE_MEMBER(irq_5);
|
||||
DECLARE_WRITE_LINE_MEMBER(irq_6);
|
||||
DECLARE_WRITE_LINE_MEMBER(irq_7);
|
||||
|
||||
emu_timer *m_bus_error_timer;
|
||||
|
||||
private:
|
||||
required_device<m68000_device> m_maincpu;
|
||||
required_device<address_map_bank_device> m_bankdev;
|
||||
required_device<wd2797_t> m_fdc;
|
||||
required_device<ram_device> m_ram;
|
||||
required_device<screen_device> m_screen;
|
||||
|
||||
uint32_t m_mmu[4];
|
||||
uint16_t m_internal_ram[0x40000];
|
||||
uint32_t m_mmu[4], m_lowest_ram_addr;
|
||||
uint16_t *m_internal_ram;
|
||||
int m_fc;
|
||||
|
||||
inline uint32_t get_ram_address(offs_t offset) { return (m_mmu[(m_maincpu->get_fc() >> 1) & 3] + offset) & 0x3FFFFF; }
|
||||
floppy_image_device *m_floppy;
|
||||
|
||||
inline uint32_t get_ram_address(offs_t offset)
|
||||
{
|
||||
return (m_mmu[(m_maincpu->get_fc() >> 1) & 3] + offset) & 0x3FFFFF;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
void set_bus_error(uint32_t address, bool write, uint16_t mem_mask);
|
||||
bool m_bus_error;
|
||||
};
|
||||
|
||||
|
||||
static ADDRESS_MAP_START(hp_ipc_mem, AS_PROGRAM, 16, hp_ipc_state)
|
||||
AM_RANGE(0x000000, 0x07FFFF) AM_ROM
|
||||
AM_RANGE(0x600000, 0x60FFFF) AM_WRITE(mmu_w)
|
||||
AM_RANGE(0x800000, 0xFFFFFF) AM_READWRITE(ram_r, ram_w)
|
||||
void hp_ipc_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
m_bus_error = false;
|
||||
}
|
||||
|
||||
void hp_ipc_state::set_bus_error(uint32_t address, bool write, uint16_t mem_mask)
|
||||
{
|
||||
if (m_bus_error)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!ACCESSING_BITS_8_15)
|
||||
{
|
||||
address++;
|
||||
}
|
||||
m_bus_error = true;
|
||||
m_maincpu->set_buserror_details(address, write, m_maincpu->get_fc());
|
||||
m_maincpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE);
|
||||
m_bus_error_timer->adjust(m_maincpu->cycles_to_attotime(16)); // let rmw cycles complete
|
||||
}
|
||||
|
||||
static ADDRESS_MAP_START(hp_ipc_mem_outer, AS_PROGRAM, 16, hp_ipc_state)
|
||||
AM_RANGE(0x000000, 0xFFFFFF) AM_READWRITE(mem_r, mem_w)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START(hp_ipc_mem_inner, AS_PROGRAM, 16, hp_ipc_state)
|
||||
// user mode
|
||||
AM_RANGE(0x1000000, 0x17FFFFF) AM_READWRITE(ram_r, ram_w)
|
||||
AM_RANGE(0x1800000, 0x187FFFF) AM_ROM AM_REGION("maincpu", 0)
|
||||
AM_RANGE(0x1E20000, 0x1E2000F) AM_DEVREADWRITE8("gpu", hp1ll3_device, read, write, 0x00ff)
|
||||
AM_RANGE(0x1E40000, 0x1E4002F) AM_DEVREADWRITE8("rtc", mm58167_device, read, write, 0x00ff)
|
||||
|
||||
// supervisor mode
|
||||
AM_RANGE(0x0000000, 0x007FFFF) AM_ROM AM_REGION("maincpu", 0) // Internal ROM (operating system PCA)
|
||||
AM_RANGE(0x0080000, 0x00FFFFF) AM_UNMAP // Internal ROM (option ROM PCA)
|
||||
AM_RANGE(0x0100000, 0x04FFFFF) AM_UNMAP // External ROM modules
|
||||
AM_RANGE(0x0600000, 0x060FFFF) AM_READWRITE(mmu_r, mmu_w)
|
||||
AM_RANGE(0x0610000, 0x0610007) AM_READWRITE8(floppy_id_r, floppy_id_w, 0x00ff)
|
||||
AM_RANGE(0x0610008, 0x061000F) AM_DEVREADWRITE8("fdc", wd2797_t, read, write, 0x00ff)
|
||||
AM_RANGE(0x0620000, 0x062000F) AM_DEVREADWRITE8("gpu", hp1ll3_device, read, write, 0x00ff)
|
||||
AM_RANGE(0x0630000, 0x063FFFF) AM_NOP // AM_DEVREADWRITE8(TMS9914_TAG, tms9914_device, read, write, 0x00ff)
|
||||
AM_RANGE(0x0640000, 0x064002F) AM_DEVREADWRITE8("rtc", mm58167_device, read, write, 0x00ff)
|
||||
AM_RANGE(0x0650000, 0x065FFFF) AM_NOP // HP-IL Printer (optional; ROM sets _desktop to 0 if not mapped) -- sys/lpint.h
|
||||
AM_RANGE(0x0660000, 0x06600FF) AM_DEVREADWRITE8("mlc", hp_hil_mlc_device, read, write, 0x00ff) // 'caravan', scrn/caravan.h
|
||||
AM_RANGE(0x0670000, 0x067FFFF) AM_NOP // Speaker (NatSemi COP 452)
|
||||
AM_RANGE(0x0680000, 0x068FFFF) AM_NOP // 'SIMON (98628) fast HP-IB card' -- sys/simon.h
|
||||
AM_RANGE(0x0700000, 0x07FFFFF) AM_UNMAP // External I/O
|
||||
AM_RANGE(0x0800000, 0x0FFFFFF) AM_READWRITE(ram_r, ram_w)
|
||||
|
||||
// bus error handler
|
||||
AM_RANGE(0x0000000, 0x1FFFFFF) AM_READWRITE(trap_r, trap_w)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static INPUT_PORTS_START(hp_ipc)
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
READ16_MEMBER(hp_ipc_state::mmu_r)
|
||||
{
|
||||
uint16_t data = (m_mmu[offset & 3] >> 10);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(hp_ipc_state::mmu_w)
|
||||
{
|
||||
logerror("mmu_w: offset = %08x, data = %04x, register = %d, data_to_add = %08x\n", offset, data, offset & 3, (data & 0xFFF) << 10);
|
||||
m_mmu[offset & 3] = (data & 0xFFF) << 10;
|
||||
}
|
||||
|
||||
READ16_MEMBER(hp_ipc_state::mem_r)
|
||||
{
|
||||
int fc = m_maincpu->get_fc() & 4;
|
||||
|
||||
if (fc != m_fc)
|
||||
{
|
||||
m_fc = fc;
|
||||
m_bankdev->set_bank(m_fc ? 0 : 1);
|
||||
}
|
||||
|
||||
return m_bankdev->read16(space, offset, mem_mask);
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(hp_ipc_state::mem_w)
|
||||
{
|
||||
int fc = m_maincpu->get_fc() & 4;
|
||||
|
||||
if (fc != m_fc)
|
||||
{
|
||||
m_fc = fc;
|
||||
m_bankdev->set_bank(m_fc ? 0 : 1);
|
||||
}
|
||||
|
||||
m_bankdev->write16(space, offset, data, mem_mask);
|
||||
}
|
||||
|
||||
READ16_MEMBER(hp_ipc_state::trap_r)
|
||||
{
|
||||
if (!machine().side_effect_disabled()) set_bus_error((offset << 1) & 0xFFFFFF, 0, mem_mask);
|
||||
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(hp_ipc_state::trap_w)
|
||||
{
|
||||
if (!machine().side_effect_disabled()) set_bus_error((offset << 1) & 0xFFFFFF, 1, mem_mask);
|
||||
}
|
||||
|
||||
|
||||
READ16_MEMBER(hp_ipc_state::ram_r)
|
||||
{
|
||||
uint32_t ram_address = get_ram_address(offset);
|
||||
uint16_t data = 0xffff;
|
||||
|
||||
//logerror("RAM read, offset = %08x, ram address = %08X\n", offset, ram_address);
|
||||
|
||||
if (ram_address < 0x380000)
|
||||
if (ram_address < m_lowest_ram_addr)
|
||||
{
|
||||
// External RAM modules
|
||||
if (!machine().side_effect_disabled()) set_bus_error((offset << 1) + 0x800000, 0, mem_mask);
|
||||
}
|
||||
else if (ram_address < 0x3c0000)
|
||||
{
|
||||
// Internal RAM
|
||||
return m_internal_ram[offset & 0x3ffff];
|
||||
data = m_internal_ram[ram_address - m_lowest_ram_addr];
|
||||
}
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(hp_ipc_state::ram_w)
|
||||
{
|
||||
uint32_t ram_address = get_ram_address(offset);
|
||||
|
||||
//logerror("RAM write, offset = %08x, ram address = %08X, data = %04x\n", offset, ram_address, data);
|
||||
|
||||
if (ram_address < 0x380000)
|
||||
if (ram_address < m_lowest_ram_addr)
|
||||
{
|
||||
// External RAM modules
|
||||
if (!machine().side_effect_disabled()) set_bus_error((offset << 1) + 0x800000, 1, mem_mask);
|
||||
}
|
||||
else if (ram_address < 0x3c0000)
|
||||
{
|
||||
// Internal RAM
|
||||
m_internal_ram[offset & 0x3ffff] = data;
|
||||
COMBINE_DATA(&m_internal_ram[ram_address - m_lowest_ram_addr]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* bit 6 -- INTRQ
|
||||
* bit 1 -- disk changed (from drive)
|
||||
* bit 0 -- write protect (from drive)
|
||||
*/
|
||||
READ8_MEMBER(hp_ipc_state::floppy_id_r)
|
||||
{
|
||||
uint8_t data = 0;
|
||||
|
||||
data = (m_fdc->intrq_r() << 6);
|
||||
|
||||
if (m_floppy)
|
||||
{
|
||||
data |= (m_fdc->intrq_r() << 6) | (m_floppy->dskchg_r() << 1) | m_floppy->wpt_r();
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/*
|
||||
* bit 7 -- 1: motor on (via inverter to drive's /MTorOn)
|
||||
* bit 3 -- 1: head 0, 0: head 1 (via inverter to drive's /SSO)
|
||||
* bit 1 -- 1: drive select (via inverter to drive's /DRIVE SEL 1)
|
||||
* bit 0 -- 1: reset disc_changed (via inverter to drive's /DSKRST)
|
||||
*/
|
||||
WRITE8_MEMBER(hp_ipc_state::floppy_id_w)
|
||||
{
|
||||
floppy_image_device *floppy0 = m_fdc->subdevice<floppy_connector>("0")->get_device();
|
||||
|
||||
if (!BIT(data, 1))
|
||||
{
|
||||
if (m_floppy == nullptr)
|
||||
{
|
||||
m_floppy = floppy0;
|
||||
m_fdc->set_floppy(m_floppy);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_floppy = nullptr;
|
||||
}
|
||||
|
||||
if (m_floppy)
|
||||
{
|
||||
m_floppy->ss_w(BIT(data, 3));
|
||||
m_floppy->mon_w(!BIT(data, 7));
|
||||
if (BIT(data, 0))
|
||||
m_floppy->dskchg_w(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
floppy0->mon_w(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WRITE_LINE_MEMBER(hp_ipc_state::irq_1)
|
||||
{
|
||||
m_maincpu->set_input_line_and_vector(M68K_IRQ_1, state, M68K_INT_ACK_AUTOVECTOR);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(hp_ipc_state::irq_2)
|
||||
{
|
||||
m_maincpu->set_input_line_and_vector(M68K_IRQ_2, state, M68K_INT_ACK_AUTOVECTOR);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(hp_ipc_state::irq_3)
|
||||
{
|
||||
m_maincpu->set_input_line_and_vector(M68K_IRQ_3, state, M68K_INT_ACK_AUTOVECTOR);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(hp_ipc_state::irq_4)
|
||||
{
|
||||
m_maincpu->set_input_line_and_vector(M68K_IRQ_4, state, M68K_INT_ACK_AUTOVECTOR);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(hp_ipc_state::irq_5)
|
||||
{
|
||||
m_maincpu->set_input_line_and_vector(M68K_IRQ_5, state, M68K_INT_ACK_AUTOVECTOR);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(hp_ipc_state::irq_6)
|
||||
{
|
||||
m_maincpu->set_input_line_and_vector(M68K_IRQ_6, state, M68K_INT_ACK_AUTOVECTOR);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(hp_ipc_state::irq_7)
|
||||
{
|
||||
m_maincpu->set_input_line_and_vector(M68K_IRQ_7, state, M68K_INT_ACK_AUTOVECTOR);
|
||||
}
|
||||
|
||||
|
||||
void hp_ipc_state::machine_start()
|
||||
{
|
||||
m_bus_error_timer = timer_alloc(0);
|
||||
|
||||
m_bankdev->set_bank(1);
|
||||
|
||||
m_lowest_ram_addr = 0x3c0000 - (m_ram->size() >> 1);
|
||||
m_internal_ram = (uint16_t *) m_ram->pointer();
|
||||
}
|
||||
|
||||
void hp_ipc_state::machine_reset()
|
||||
{
|
||||
m_floppy = nullptr;
|
||||
}
|
||||
|
||||
|
||||
FLOPPY_FORMATS_MEMBER( hp_ipc_state::floppy_formats )
|
||||
FLOPPY_HP_IPC_FORMAT
|
||||
FLOPPY_FORMATS_END
|
||||
|
||||
static SLOT_INTERFACE_START( hp_ipc_floppies )
|
||||
SLOT_INTERFACE( "35dd", SONY_OA_D32W )
|
||||
SLOT_INTERFACE_END
|
||||
|
||||
/*
|
||||
* IRQ levels (page 5-4)
|
||||
*
|
||||
* 7 Soft reset from keyboard, non-maskable
|
||||
* 6 Real-time clock or NBIR3 (ext. I/O)
|
||||
* 5 Disc Drive or NBIR2
|
||||
* 4 GPU or NBIR1
|
||||
* 3 HP-IB, printer, or NBIR0
|
||||
* 2 HP-HIL devices (keyboard, mouse)
|
||||
* 1 Real-time clock
|
||||
*/
|
||||
static MACHINE_CONFIG_START(hp_ipc, hp_ipc_state)
|
||||
/* basic machine hardware */
|
||||
MCFG_CPU_ADD("maincpu", M68000, 15920000 / 2)
|
||||
MCFG_CPU_PROGRAM_MAP(hp_ipc_mem)
|
||||
MCFG_CPU_ADD("maincpu", M68000, XTAL_15_92MHz / 2)
|
||||
MCFG_CPU_PROGRAM_MAP(hp_ipc_mem_outer)
|
||||
|
||||
MCFG_DEVICE_ADD("bankdev", ADDRESS_MAP_BANK, 0)
|
||||
MCFG_DEVICE_PROGRAM_MAP(hp_ipc_mem_inner)
|
||||
MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG)
|
||||
MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(25)
|
||||
MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16)
|
||||
MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000000)
|
||||
|
||||
// horizontal time = 60 us (min)
|
||||
// ver.refresh period = ~300 us
|
||||
// ver.period = 16.7ms (~60 hz)
|
||||
MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::amber())
|
||||
MCFG_SCREEN_UPDATE_DEVICE("gpu", hp1ll3_device, screen_update)
|
||||
MCFG_SCREEN_RAW_PARAMS(XTAL_6MHz * 2, 720, 0, 512, 278, 0, 256)
|
||||
// when _desktop == 0:
|
||||
// MCFG_SCREEN_RAW_PARAMS(XTAL_6MHz * 2, 720, 0, 640, 480, 0, 400)
|
||||
MCFG_SCREEN_VBLANK_CALLBACK(DEVWRITELINE("mlc", hp_hil_mlc_device, ap_w)) // XXX actually it's driven by 555 (U59)
|
||||
MCFG_DEFAULT_LAYOUT(layout_lcd)
|
||||
|
||||
MCFG_SCREEN_PALETTE("palette")
|
||||
MCFG_PALETTE_ADD_MONOCHROME("palette")
|
||||
|
||||
MCFG_HP1LL3_ADD("gpu")
|
||||
// MCFG_HP1LL3_IRQ_CALLBACK(WRITELINE(hp_ipc_state, irq_4))
|
||||
MCFG_VIDEO_SET_SCREEN("screen")
|
||||
|
||||
// XXX actual clock is 1MHz; remove this workaround (and change 2000 to 100 in hp_ipc_dsk.cpp)
|
||||
// XXX when floppy code correctly handles 600 rpm drives.
|
||||
MCFG_WD2797_ADD("fdc", XTAL_2MHz)
|
||||
MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(hp_ipc_state, irq_5))
|
||||
MCFG_FLOPPY_DRIVE_ADD("fdc:0", hp_ipc_floppies, "35dd", hp_ipc_state::floppy_formats)
|
||||
|
||||
MCFG_SOFTWARE_LIST_ADD("flop_list","hp_ipc")
|
||||
|
||||
MCFG_DEVICE_ADD("rtc", MM58167, XTAL_32_768kHz)
|
||||
MCFG_MM58167_IRQ_CALLBACK(WRITELINE(hp_ipc_state, irq_1))
|
||||
// MCFG_MM58167_STANDBY_IRQ_CALLBACK(WRITELINE(hp_ipc_state, irq_6))
|
||||
|
||||
MCFG_DEVICE_ADD("mlc", HP_HIL_MLC, XTAL_15_92MHz/2)
|
||||
MCFG_HP_HIL_INT_CALLBACK(WRITELINE(hp_ipc_state, irq_2))
|
||||
MCFG_HP_HIL_NMI_CALLBACK(WRITELINE(hp_ipc_state, irq_7))
|
||||
MCFG_HP_HIL_SLOT_ADD("mlc", "hil1", hp_hil_devices, "hp_ipc_kbd")
|
||||
|
||||
MCFG_RAM_ADD(RAM_TAG)
|
||||
MCFG_RAM_DEFAULT_SIZE("512K")
|
||||
MCFG_RAM_EXTRA_OPTIONS("768K,1M,1576K,2M,3M,4M,5M,6M,7M,7680K")
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
@ -355,4 +767,4 @@ ROM_START(hp_ipc)
|
||||
ROM_END
|
||||
|
||||
|
||||
COMP(1985, hp_ipc, 0, 0, hp_ipc, hp_ipc, driver_device, 0, "HP", "Integral Personal Computer", MACHINE_IS_SKELETON)
|
||||
COMP(1985, hp_ipc, 0, 0, hp_ipc, hp_ipc, driver_device, 0, "HP", "Integral Personal Computer", MACHINE_NO_SOUND|MACHINE_IMPERFECT_GRAPHICS|MACHINE_IMPERFECT_KEYBOARD)
|
||||
|
Loading…
Reference in New Issue
Block a user