emulate ie15 keyboard & use RS232 port [shattered]

This commit is contained in:
smf- 2014-04-14 14:15:14 +00:00
parent 64f1295b1d
commit a9d4bace86
6 changed files with 832 additions and 286 deletions

3
.gitattributes vendored
View File

@ -8343,6 +8343,7 @@ src/mess/layout/fidelz80.lay svneol=native#text/xml
src/mess/layout/gl3000s.lay svneol=native#text/xml
src/mess/layout/glasgow.lay svneol=native#text/xml
src/mess/layout/h8.lay svneol=native#text/xml
src/mess/layout/ie15.lay svneol=native#text/xml
src/mess/layout/instruct.lay svneol=native#text/xml
src/mess/layout/junior.lay svneol=native#text/xml
src/mess/layout/k1003.lay svneol=native#text/xml
@ -8509,6 +8510,8 @@ src/mess/machine/genpc.c svneol=native#text/plain
src/mess/machine/hec2hrp.c svneol=native#text/plain
src/mess/machine/hecdisk2.c svneol=native#text/plain
src/mess/machine/hp48.c svneol=native#text/plain
src/mess/machine/ie15_kbd.c svneol=native#text/plain
src/mess/machine/ie15_kbd.h svneol=native#text/plain
src/mess/machine/intv.c svneol=native#text/plain
src/mess/machine/isbc_215g.c svneol=native#text/plain
src/mess/machine/isbc_215g.h svneol=native#text/plain

View File

@ -1,36 +1,38 @@
/***************************************************************************
15IE-00-013 Terminal
15IE-00-013 Terminal
board images : http://asvcorp.ru/darch/hardware/pdp/fryazin-display/index.html
A serial (RS232 or current loop) green-screen terminal, mostly VT52
compatible (no Hold Screen mode and no graphics character set).
29/06/2012 Skeleton driver.
A serial (RS232 or current loop) green-screen terminal, mostly VT52 compatible
(no Hold Screen mode and no graphics character set, but has Cyrillic characters).
The top line is a status line.
Alternate character set (selected by SO/SI chars) is Cyrillic.
****************************************************************************/
#include "emu.h"
#include "bus/rs232/rs232.h"
#include "cpu/ie15/ie15.h"
#include "imagedev/bitbngr.h"
#include "machine/keyboard.h"
#include "machine/ie15_kbd.h"
#include "sound/beep.h"
#include "ie15.lh"
#define SCREEN_PAGE (80*48)
#define IE_1 0x80
#define IE_KB_ACK 1
#define IE_TRUE 0x80
#define IE_FALSE 0
#define IE15_TOTAL_HORZ 1000
#define IE15_TOTAL_VERT 28*11
#define IE15_DISP_HORZ 800
#define IE15_DISP_VERT 25*11
#define IE15_HORZ_START 200
#define IE15_HORZ_START 100
#define IE15_TOTAL_VERT 28*11
#define IE15_DISP_VERT 25*11
#define IE15_VERT_START 2*11
#define IE15_STATUSLINE 11
#define VERBOSE_DBG 1 /* general debug messages */
@ -44,36 +46,32 @@
} \
} while (0)
#if VERBOSE_DBG > 0
#define LOOPBACK (m_io_keyboard->read() & 0x20)
#else
#define LOOPBACK (0)
#endif
#define BITBANGER_TAG "bitbanger"
#define KEYBOARD_TAG "keyboard"
class ie15_state : public driver_device
class ie15_state : public driver_device,
public device_serial_interface
{
public:
ie15_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
ie15_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
device_serial_interface(mconfig, *this),
m_maincpu(*this, "maincpu"),
m_beeper(*this, "beeper"),
m_bitbanger(*this, BITBANGER_TAG),
m_io_keyboard(*this, KEYBOARD_TAG)
m_rs232(*this, "rs232"),
m_io_keyboard(*this, "keyboard")
{ }
virtual void machine_reset();
virtual void video_start();
DECLARE_PALETTE_INIT(ie15);
UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
UINT32 screen_update_hle(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
TIMER_DEVICE_CALLBACK_MEMBER(scanline_callback);
DECLARE_WRITE8_MEMBER(kbd_put);
static const bitbanger_config ie15_bitbanger_config;
TIMER_CALLBACK_MEMBER(serial_tx_callback);
emu_timer *m_serial_tx_timer;
TIMER_DEVICE_CALLBACK_MEMBER( scanline_callback );
DECLARE_WRITE16_MEMBER( kbd_put );
DECLARE_WRITE_LINE_MEMBER( serial_rx_callback );
virtual void rcv_complete();
virtual void tra_callback();
virtual void tra_complete();
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
DECLARE_WRITE8_MEMBER( mem_w );
DECLARE_READ8_MEMBER( mem_r );
@ -96,117 +94,116 @@ public:
DECLARE_WRITE8_MEMBER( serial_w );
DECLARE_READ8_MEMBER( serial_rx_ready_r );
DECLARE_READ8_MEMBER( serial_r );
#if 0
DECLARE_WRITE8_MEMBER( serial_speed_w );
#endif
private:
TIMER_CALLBACK_MEMBER(ie15_beepoff);
UINT32 draw_scanline(UINT16 *p, UINT16 offset, UINT8 scanline, UINT8 y);
void update_leds();
UINT32 draw_scanline(UINT16 *p, UINT16 offset, UINT8 scanline);
rectangle m_tmpclip;
bitmap_ind16 m_tmpbmp;
bitmap_ind16 m_offbmp;
const UINT8 *m_p_chargen;
UINT8 *m_p_videoram;
UINT8 m_beep;
UINT8 m_cursor;
UINT8 m_long_beep;
UINT8 m_kb_control;
UINT8 m_kb_data;
UINT8 m_kb_flag;
UINT8 m_kb_flag0;
UINT8 m_kb_flag;
UINT8 m_kb_ruslat;
UINT8 m_latch;
UINT8 m_ruslat;
UINT8 m_serial_rx_bits;
UINT8 m_serial_rx_buffer;
UINT8 m_serial_rx_data;
UINT8 m_serial_tx_bits;
UINT8 m_serial_tx_data;
UINT8 m_statusline;
UINT8 m_video;
UINT32 m_videoptr;
UINT32 m_videoptr_2;
struct {
UINT8 cursor;
UINT8 enable;
UINT8 line25;
UINT32 ptr1;
UINT32 ptr2;
} m_video;
static void bitbanger_callback(running_machine &machine, UINT8 bit);
DECLARE_WRITE_LINE_MEMBER( serial_rx_callback );
UINT8 m_serial_rx_ready;
UINT8 m_serial_tx_ready;
protected:
required_device<cpu_device> m_maincpu;
required_device<beep_device> m_beeper;
required_device<bitbanger_device> m_bitbanger;
required_device<rs232_port_device> m_rs232;
required_ioport m_io_keyboard;
};
READ8_MEMBER( ie15_state::mem_r ) {
UINT8 ret;
ret = m_p_videoram[m_videoptr];
if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0 && m_videoptr >= SCREEN_PAGE)
ret = m_p_videoram[m_video.ptr1];
if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0 && m_video.ptr1 >= SCREEN_PAGE)
{
DBG_LOG(2,"memory",("R @ %03x == %02x\n", m_videoptr, ret));
DBG_LOG(2,"memory",("R @ %03x == %02x\n", m_video.ptr1, ret));
}
m_videoptr++;
m_videoptr &= 0xfff;
m_video.ptr1++;
m_video.ptr1 &= 0xfff;
m_latch = 0;
return ret;
}
WRITE8_MEMBER( ie15_state::mem_w ) {
if ((m_latch ^= 1) == 0) {
if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0 && m_videoptr >= SCREEN_PAGE)
if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0 && m_video.ptr1 >= SCREEN_PAGE)
{
DBG_LOG(2,"memory",("W @ %03x <- %02x\n", m_videoptr, data));
DBG_LOG(2,"memory",("W @ %03x <- %02x\n", m_video.ptr1, data));
}
m_p_videoram[m_videoptr++] = data;
m_videoptr &= 0xfff;
m_p_videoram[m_video.ptr1++] = data;
m_video.ptr1 &= 0xfff;
}
}
WRITE8_MEMBER( ie15_state::mem_addr_inc_w ) {
if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
{
DBG_LOG(2,"memory",("++ %03x\n", m_videoptr));
DBG_LOG(2,"memory",("++ %03x\n", m_video.ptr1));
}
m_videoptr++;
m_videoptr &= 0xfff;
if (m_video)
m_videoptr_2 = m_videoptr;
m_video.ptr1++;
m_video.ptr1 &= 0xfff;
if (m_video.enable)
m_video.ptr2 = m_video.ptr1;
}
WRITE8_MEMBER( ie15_state::mem_addr_dec_w ) {
if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
{
DBG_LOG(2,"memory",("-- %03x\n", m_videoptr));
DBG_LOG(2,"memory",("-- %03x\n", m_video.ptr1));
}
m_videoptr--;
m_videoptr &= 0xfff;
if (m_video)
m_videoptr_2 = m_videoptr;
m_video.ptr1--;
m_video.ptr1 &= 0xfff;
if (m_video.enable)
m_video.ptr2 = m_video.ptr1;
}
WRITE8_MEMBER( ie15_state::mem_addr_lo_w ) {
UINT16 tmp = m_videoptr;
UINT16 tmp = m_video.ptr1;
tmp &= 0xff0;
tmp |= ((data >> 4) & 0xf);
if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
{
DBG_LOG(2,"memory",("lo %03x <- %02x = %03x\n", m_videoptr, data, tmp));
DBG_LOG(2,"memory",("lo %03x <- %02x = %03x\n", m_video.ptr1, data, tmp));
}
m_videoptr = tmp;
if (m_video)
m_videoptr_2 = tmp;
m_video.ptr1 = tmp;
if (m_video.enable)
m_video.ptr2 = tmp;
}
WRITE8_MEMBER( ie15_state::mem_addr_hi_w ) {
UINT16 tmp = m_videoptr;
UINT16 tmp = m_video.ptr1;
tmp &= 0xf;
tmp |= (data << 4);
if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
{
DBG_LOG(2,"memory",("hi %03x <- %02x = %03x\n", m_videoptr, data, tmp));
DBG_LOG(2,"memory",("hi %03x <- %02x = %03x\n", m_video.ptr1, data, tmp));
}
m_videoptr = tmp;
if (m_video)
m_videoptr_2 = tmp;
m_video.ptr1 = tmp;
if (m_video.enable)
m_video.ptr2 = tmp;
}
TIMER_CALLBACK_MEMBER(ie15_state::ie15_beepoff)
@ -215,27 +212,29 @@ TIMER_CALLBACK_MEMBER(ie15_state::ie15_beepoff)
}
WRITE8_MEMBER( ie15_state::beep_w ) {
UINT16 length = (m_beep&128)?150:400;
UINT16 length = (m_long_beep & IE_TRUE) ? 150 : 400;
if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
{
DBG_LOG(1,"beep",("(%s)\n", m_beep?"short":"long"));
DBG_LOG(1,"beep",("(%s)\n", m_long_beep ? "short" : "long"));
}
machine().scheduler().timer_set(attotime::from_msec(length), timer_expired_delegate(FUNC(ie15_state::ie15_beepoff),this));
machine().device<beep_device>("beeper")->set_state(1);
}
/* keyboard */
// active high
READ8_MEMBER( ie15_state::kb_r ) {
DBG_LOG(2,"keyboard",("R %02X '%c'\n", m_kb_data, m_kb_data < 0x20?' ':m_kb_data));
DBG_LOG(2,"keyboard",("R %02X '%c'\n", m_kb_data, m_kb_data < 0x20 ? ' ' : m_kb_data));
return m_kb_data;
}
// active low
READ8_MEMBER( ie15_state::kb_ready_r ) {
m_kb_flag &= IE_1;
m_kb_flag &= IE_TRUE;
if (m_kb_flag != m_kb_flag0) {
DBG_LOG(2,"keyboard",("? %c\n", m_kb_flag?'n':'y'));
DBG_LOG(2,"keyboard",("? %c\n", m_kb_flag ? 'n' : 'y'));
m_kb_flag0 = m_kb_flag;
}
return m_kb_flag;
@ -244,136 +243,93 @@ READ8_MEMBER( ie15_state::kb_ready_r ) {
// active low
WRITE8_MEMBER( ie15_state::kb_ready_w ) {
DBG_LOG(2,"keyboard",("clear ready\n"));
m_kb_flag = IE_1 | IE_KB_ACK;
m_kb_flag = IE_TRUE | IE_KB_ACK;
}
// active high; active = interpret controls, inactive = display controls
READ8_MEMBER( ie15_state::kb_s_red_r ) {
return m_io_keyboard->read() & 0x01 ? IE_1 : 0;
return m_io_keyboard->read() & IE_KB_RED ? IE_TRUE : 0;
}
// active high; active = setup mode
READ8_MEMBER( ie15_state::kb_s_sdv_r ) {
return m_io_keyboard->read() & 0x02 ? IE_1 : 0;
return m_kb_control & IE_KB_SDV ? IE_TRUE : 0;
}
// active high, XXX stub
// active high; active = keypress detected on aux keypad
READ8_MEMBER( ie15_state::kb_s_dk_r ) {
return 0;
return m_kb_control & IE_KB_DK ? IE_TRUE : 0;
}
// active low; active = full duplex, inactive = half duplex
READ8_MEMBER( ie15_state::kb_s_dupl_r ) {
return m_io_keyboard->read() & 0x08 ? IE_1 : 0;
return m_io_keyboard->read() & IE_KB_DUP ? IE_TRUE : 0;
}
// active high; active = on-line, inactive = local editing
READ8_MEMBER( ie15_state::kb_s_lin_r ) {
return m_io_keyboard->read() & 0x10 ? IE_1 : 0;
return m_io_keyboard->read() & IE_KB_LIN ? IE_TRUE : 0;
}
/* serial port */
void ie15_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
device_serial_interface::device_timer(timer, id, param, ptr);
}
WRITE_LINE_MEMBER( ie15_state::serial_rx_callback )
{
device_serial_interface::rx_w(state);
}
void ie15_state::rcv_complete()
{
receive_register_extract();
m_serial_rx_ready = IE_FALSE;
}
void ie15_state::tra_callback()
{
UINT8 bit = transmit_register_get_data_bit();
m_rs232->write_txd(bit);
}
void ie15_state::tra_complete()
{
m_serial_tx_ready = IE_TRUE;
}
// active low
READ8_MEMBER( ie15_state::serial_rx_ready_r ) {
if (LOOPBACK)
return m_serial_tx_data ? 0 : IE_1;
else
return m_serial_rx_data ? 0 : IE_1;
return m_serial_rx_ready;
}
// not called unless data is ready
READ8_MEMBER( ie15_state::serial_r ) {
UINT8 tmp;
if (LOOPBACK) {
tmp = m_serial_tx_data;
m_serial_tx_data = 0;
} else {
tmp = m_serial_rx_data;
m_serial_rx_data = 0;
}
DBG_LOG(2,"serial",("R %02X '%c'\n", tmp, tmp < 0x20?' ':tmp));
return tmp;
}
/*
m_serial_rx_buffer incoming bits.
m_serial_rx_bits number of bits in _buffer.
m_serial_rx_data complete byte, ready to be read by host, or 0 if no data.
*/
WRITE_LINE_MEMBER( ie15_state::serial_rx_callback )
{
UINT8 tmp = m_serial_rx_bits;
switch (m_serial_rx_bits) {
// wait for start bit (0)
case 10:
m_serial_rx_bits = 0;
case 0:
if (!state) {
m_serial_rx_bits++;
m_serial_rx_buffer = 0;
}
break;
// stuff incoming bits into byte buffer
case 1: case 2: case 3: case 4:
case 5: case 6: case 7: case 8:
m_serial_rx_buffer |= state << (m_serial_rx_bits-1);
m_serial_rx_bits++;
break;
// expecting stop bit (1)
case 9:
if (state && !m_serial_rx_data) {
m_serial_rx_data = m_serial_rx_buffer;
m_serial_rx_bits++;
} else
m_serial_rx_bits = 0;
break;
default:
// overflow
break;
}
DBG_LOG(2,"serial",("r %d bits %02d->%02d buffer %02X data %02X\n",
state, tmp, m_serial_rx_bits, m_serial_rx_buffer, m_serial_rx_data));
}
const bitbanger_config ie15_state::ie15_bitbanger_config =
{
DEVCB_DRIVER_LINE_MEMBER(ie15_state, serial_rx_callback), /* callback */
BITBANGER_PRINTER, /* default mode */
BITBANGER_9600, /* default output baud */
BITBANGER_0PERCENT /* default fine tune adjustment */
};
// active high
READ8_MEMBER( ie15_state::serial_tx_ready_r ) {
return m_serial_tx_data ? 0 : IE_1;
return m_serial_tx_ready;
}
// not called unless data are ready
READ8_MEMBER( ie15_state::serial_r ) {
UINT8 data;
data = get_received_char();
m_serial_rx_ready = IE_TRUE;
DBG_LOG(1,"serial",("R %02X '%c'\n", data, data < 0x20?' ':data));
return data;
}
WRITE8_MEMBER( ie15_state::serial_w ) {
DBG_LOG(2,"serial",("W %02X '%c'\n", data, data < 0x20?' ':data));
if (LOOPBACK) {
if (!m_serial_tx_data)
m_serial_tx_data = data;
} else {
/* 1 start bit */
m_bitbanger->output(0);
/* 8 data bits, 1 stop bit, no parity */
m_serial_tx_bits = 8;
m_serial_tx_data = data;
m_serial_tx_timer->adjust(attotime::from_hz(9600));
}
DBG_LOG(1,"serial",("W %02X '%c'\n", data, data < 0x20?' ':data));
m_serial_tx_ready = IE_FALSE;
transmit_register_setup(data);
}
TIMER_CALLBACK_MEMBER(ie15_state::serial_tx_callback) {
if (!m_serial_tx_bits) {
m_bitbanger->output(1);
m_serial_tx_data = 0;
} else {
m_bitbanger->output(BIT(m_serial_tx_data, 8-(m_serial_tx_bits--)));
m_serial_tx_timer->adjust(attotime::from_hz(9600));
}
WRITE8_MEMBER( ie15_state::serial_speed_w ) {
return;
}
READ8_MEMBER( ie15_state::flag_r ) {
@ -391,7 +347,7 @@ READ8_MEMBER( ie15_state::flag_r ) {
ret = !machine().first_screen()->vblank();
break;
case 4:
ret = m_ruslat;
ret = m_kb_ruslat;
break;
default:
break;
@ -407,24 +363,24 @@ WRITE8_MEMBER( ie15_state::flag_w ) {
switch (offset)
{
case 0:
m_video = data;
m_video.enable = data;
break;
case 1:
m_cursor = data;
m_video.cursor = data;
break;
case 2:
m_beep = data;
m_long_beep = data;
break;
case 3:
m_statusline = data;
m_video.line25 = data;
break;
case 4:
m_ruslat = data;
m_kb_ruslat = data;
break;
default:
break;
}
if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0 && !offset)
{
DBG_LOG(2,"flag",("%sset %d\n", data?"":"re", offset));
}
@ -449,7 +405,7 @@ static ADDRESS_MAP_START(ie15_io, AS_IO, 8, ie15_state)
AM_RANGE(011, 011) AM_READ(kb_r) // 09h R: keyboard data [6.1.5.2]
AM_RANGE(012, 012) AM_READ(kb_s_red_r) // 0Ah I: keyboard mode "RED" [6.1.5.2]
AM_RANGE(013, 013) AM_READ(kb_ready_r) // 0Bh R: keyboard data ready [6.1.5.2]
AM_RANGE(014, 014) AM_READ(kb_s_sdv_r) AM_WRITENOP // 0Ch W: serial port speed [6.1.3.1], R: keyboard mode "SDV" [6.1.5.2]
AM_RANGE(014, 014) AM_READ(kb_s_sdv_r) AM_WRITE(serial_speed_w) // 0Ch W: serial port speed [6.1.3.1], R: keyboard mode "SDV" [6.1.5.2]
AM_RANGE(015, 015) AM_READ(kb_s_dk_r) AM_WRITE(kb_ready_w) // 0Dh I: keyboard mode "DK" [6.1.5.2]
AM_RANGE(016, 016) AM_READ(kb_s_dupl_r) // 0Eh I: keyboard mode "DUPL" [6.1.5.2]
AM_RANGE(017, 017) AM_READ(kb_s_lin_r) // 0Fh I: keyboard mode "LIN" [6.1.5.2]
@ -460,131 +416,172 @@ ADDRESS_MAP_END
/* Input ports */
static INPUT_PORTS_START( ie15 )
PORT_START("keyboard")
PORT_DIPNAME(0x01, 0x00, "RED mode")
PORT_DIPSETTING(0x00, "Off" )
PORT_DIPSETTING(0x01, "On" )
PORT_DIPNAME(0x02, 0x00, "SDV mode (Setup)")
PORT_DIPSETTING(0x00, "Off" )
PORT_DIPSETTING(0x02, "On" )
PORT_DIPNAME(0x08, 0x00, "DUPL mode")
PORT_DIPSETTING(0x00, "Off" )
PORT_DIPSETTING(0x08, "On" )
PORT_DIPNAME(0x10, 0x00, "LIN mode")
PORT_DIPSETTING(0x00, "Off" )
PORT_DIPSETTING(0x10, "On" )
PORT_DIPNAME(0x20, 0x00, "digital loopback")
PORT_DIPSETTING(0x00, "Off" )
PORT_DIPSETTING(0x20, "On" )
PORT_DIPNAME(IE_KB_RED, IE_KB_RED, "RED (Interpret controls)")
PORT_DIPSETTING(0x00, "Off")
PORT_DIPSETTING(IE_KB_RED, "On")
PORT_DIPNAME(IE_KB_DUP, IE_KB_DUP, "DUP (Full duplex)")
PORT_DIPSETTING(0x00, "Off")
PORT_DIPSETTING(IE_KB_DUP, "On")
PORT_DIPNAME(IE_KB_LIN, IE_KB_LIN, "LIN (Online)")
PORT_DIPSETTING(0x00, "Off")
PORT_DIPSETTING(IE_KB_LIN, "On")
INPUT_PORTS_END
WRITE8_MEMBER( ie15_state::kbd_put )
WRITE16_MEMBER( ie15_state::kbd_put )
{
DBG_LOG(2,"keyboard",("W %02X<-%02X '%c' %c\n", m_kb_data, data, data < 0x20?' ':data, m_kb_flag?'n':'y'));
if (m_kb_flag == IE_1) {
m_kb_data = data;
DBG_LOG(2,"keyboard",("W %02X<-%02X '%c' %02X (%c)\n", m_kb_data, data, 'x' /* data < 0x20 ? ' ' : (data & 255) */,
m_kb_flag, m_kb_flag ? 'n' : 'y'));
m_kb_control = (data >> 8) & 255;
// send new key only when firmware has processed previous one
if (m_kb_flag == IE_TRUE) {
m_kb_data = data & 255;
m_kb_flag = 0;
}
}
static IE15_KEYBOARD_INTERFACE( keyboard_intf )
{
DEVCB_DRIVER_MEMBER16(ie15_state, kbd_put)
};
void ie15_state::machine_reset()
{
m_ruslat = m_beep = m_statusline = m_cursor = m_video = m_kb_data = m_kb_flag0 = 0;
m_serial_tx_data = m_serial_tx_bits = m_serial_rx_buffer = m_serial_rx_data = m_serial_rx_bits = 0;
m_kb_flag = IE_1;
memset(&m_video, 0, sizeof(m_video));
m_kb_ruslat = m_long_beep = m_kb_control = m_kb_data = m_kb_flag0 = 0;
m_kb_flag = IE_TRUE;
machine().device<beep_device>("beeper")->set_frequency(2400);
machine().device<beep_device>("beeper")->set_state(0);
m_serial_tx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ie15_state::serial_tx_callback),this));
m_serial_tx_ready = m_serial_rx_ready = IE_TRUE;
set_data_frame(1 /* start bits */, 8 /* data bits */, PARITY_NONE, STOP_BITS_1);
// device supports rates from 150 to 9600 baud but null_modem has hardcoded 9600
set_tra_rate(9600);
set_rcv_rate(9600);
}
void ie15_state::video_start()
{
m_p_chargen = machine().root_device().memregion("chargen")->base();
m_p_chargen = memregion("chargen")->base();
m_p_videoram = memregion("video")->base();
m_videoptr = m_videoptr_2 = m_latch = 0;
m_video.ptr1 = m_video.ptr2 = m_latch = 0;
m_tmpclip = rectangle(0, IE15_DISP_HORZ-1, 0, IE15_DISP_VERT-1);
m_tmpbmp.allocate(IE15_DISP_HORZ, IE15_DISP_VERT);
m_offbmp.allocate(IE15_DISP_HORZ, 1);
if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0) {
m_offbmp.fill(0);
}
}
UINT32 ie15_state::draw_scanline(UINT16 *p, UINT16 offset, UINT8 scanline, UINT8 y)
/*
Usable raster is 800 x 275 pixels (80 x 25 characters). 24 lines are
available to the user and 25th (topmost) line is the status line.
Status line, if enabled, displays current serial port speed, 16 setup
bits, and clock. There is no NVRAM, so setup bits are always 0 after
reset and clock starts counting at 0 XXX.
No character attributes are available, but in 'display controls' mode
control characters stored in memory are shown as blinking chars.
Character cell is 10 x 11; character generator provides 7 x 8 of that.
3 extra horizontal pixels are always blank. Blinking cursor may be
displayed on 3 extra scan lines.
On each scan line, video board draws 80 characters from any location
in video memory; this is used by firmware to provide instant scroll
and cursor, which is a character with code 0x7F stored in XXX.
Video board output is controlled by
- control flag 0 "disable video": 0 == disable
- control flag 1 "cursor": 0 == if this scan line is one of extra 3,
enable video every 5 frames.
- control flag 3 "status line": 0 == current scan line is part of status line
- keyboard mode 'RED' ('display controls'): if character code is
less than 0x20 and RED is set, enable video every 5 frames; if RED is
unset, disable video.
XXX 'dotted look' is caused by strobe at 2x pixel clock -- use HLSL for this.
*/
UINT32 ie15_state::draw_scanline(UINT16 *p, UINT16 offset, UINT8 scanline)
{
UINT8 gfx,fg,bg,ra,blink,red;
UINT16 x,chr;
UINT8 gfx, fg, bg, ra, blink, red;
UINT16 x, chr;
bg = 0; fg = 1; ra = scanline % 8;
blink = (machine().first_screen()->frame_number() % 10) >= 5;
red = m_io_keyboard->read() & 0x01;
DBG_LOG(2,"draw_scanline",
("addr %03x row %d-%d video %d\n", offset, y, scanline, m_video));
blink = (machine().first_screen()->frame_number() % 10) > 4;
red = m_io_keyboard->read() & IE_KB_RED;
for (x = offset; x < offset + 80; x++)
{
if (m_video) {
chr = m_p_videoram[x] << 3;
gfx = m_p_chargen[chr | ra];
chr = m_p_videoram[x] << 3;
gfx = m_p_chargen[chr | ra];
/*
Cursor is a character with only 3 scan lines, and is
not shown if flag 1 is not active on this scan line.
It always blinks if shown.
Control characters blink if RED mode is on and they
are not on status line; else they are blanked out.
*/
if (scanline > 7 && (!m_cursor || blink))
if (scanline > 7 && (!m_video.cursor || blink))
gfx = 0;
else if (chr < (0x20<<3)) {
if (red && blink && m_video.line25)
gfx = m_p_chargen[chr | 0x200 | ra];
else
gfx = 0;
if (chr < (0x20<<3)) {
if (!y || !red || blink)
gfx = 0;
else
gfx = m_p_chargen[chr | 0x200 | ra];
}
/* Display a scanline of a character */
*p++ = BIT(gfx, 7) ? fg : bg;
*p++ = BIT(gfx, 6) ? fg : bg;
*p++ = BIT(gfx, 5) ? fg : bg;
*p++ = BIT(gfx, 4) ? fg : bg;
*p++ = BIT(gfx, 3) ? fg : bg;
*p++ = BIT(gfx, 2) ? fg : bg;
*p++ = BIT(gfx, 1) ? fg : bg;
*p++ = bg;
*p++ = bg;
*p++ = bg;
} else {
*p++ = bg;
*p++ = bg;
*p++ = bg;
*p++ = bg;
*p++ = bg;
*p++ = bg;
*p++ = bg;
*p++ = bg;
*p++ = bg;
*p++ = bg;
}
*p++ = BIT(gfx, 7) ? fg : bg;
*p++ = BIT(gfx, 6) ? fg : bg;
*p++ = BIT(gfx, 5) ? fg : bg;
*p++ = BIT(gfx, 4) ? fg : bg;
*p++ = BIT(gfx, 3) ? fg : bg;
*p++ = BIT(gfx, 2) ? fg : bg;
*p++ = BIT(gfx, 1) ? fg : bg;
*p++ = bg;
*p++ = bg;
*p++ = bg;
}
return 0;
}
void ie15_state::update_leds()
{
UINT8 data = m_io_keyboard->read();
output_set_value("lat_led", m_kb_ruslat ^ 1);
output_set_value("nr_led", BIT(m_kb_control, IE_KB_NR_BIT) ^ 1);
output_set_value("pch_led", BIT(data, IE_KB_PCH_BIT) ^ 1);
output_set_value("dup_led", BIT(data, IE_KB_DUP_BIT) ^ 1);
output_set_value("lin_led", BIT(data, IE_KB_LIN_BIT) ^ 1);
output_set_value("red_led", BIT(data, IE_KB_RED_BIT) ^ 1);
output_set_value("sdv_led", BIT(m_kb_control, IE_KB_SDV_BIT) ^ 1);
output_set_value("prd_led", 1); // XXX
}
/*
VBlank is active for 3 topmost on-screen rows and 1 at the bottom; however, control flag 3 overrides VBlank,
allowing status line to be switched on and off.
*/
TIMER_DEVICE_CALLBACK_MEMBER(ie15_state::scanline_callback)
{
UINT16 y = machine().first_screen()->vpos();
// DBG_LOG(2,"scanline",
// ("addr %03x frame %lld x %04d y %03d\n", m_videoptr_2, machine().first_screen()->frame_number(), machine().first_screen()->hpos(), y));
if (y>=IE15_VERT_START) {
y -= IE15_VERT_START;
if (y < IE15_DISP_VERT) {
draw_scanline(&m_tmpbmp.pix16(y), m_videoptr_2, y%11, y/11);
}
DBG_LOG(3,"scanline_cb",
("addr %03x frame %" I64FMT "d x %.4d y %.3d row %.2d e:c:s %d:%d:%d\n",
m_video.ptr2, machine().first_screen()->frame_number(), machine().first_screen()->hpos(), y,
y%11, m_video.enable, m_video.cursor, m_video.line25));
if (y < IE15_VERT_START) return;
y -= IE15_VERT_START;
if (y >= IE15_DISP_VERT) return;
if (!m_video.enable || (y < IE15_STATUSLINE && m_video.line25)) {
copybitmap( m_tmpbmp, m_offbmp, 0, 0, 0, y, m_tmpclip );
} else {
draw_scanline( &m_tmpbmp.pix16(y), m_video.ptr2, y%11 );
}
}
UINT32 ie15_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
copybitmap( bitmap, m_tmpbmp, 0, 0, IE15_HORZ_START, IE15_VERT_START, cliprect );
update_leds();
copybitmap(bitmap, m_tmpbmp, 0, 0, IE15_HORZ_START, IE15_VERT_START, cliprect);
return 0;
}
@ -604,15 +601,9 @@ static const gfx_layout ie15_charlayout =
};
static GFXDECODE_START( ie15 )
GFXDECODE_ENTRY( "chargen", 0x0000, ie15_charlayout, 0, 1 )
GFXDECODE_ENTRY("chargen", 0x0000, ie15_charlayout, 0, 1)
GFXDECODE_END
PALETTE_INIT_MEMBER(ie15_state, ie15)
{
palette.set_pen_color(0, rgb_t::black); // black
palette.set_pen_color(1, 0x00, 0xc0, 0x00); // green
}
static MACHINE_CONFIG_START( ie15, ie15_state )
/* Basic machine hardware */
MCFG_CPU_ADD("maincpu", IE15, XTAL_30_8MHz / 10)
@ -630,13 +621,17 @@ static MACHINE_CONFIG_START( ie15, ie15_state )
MCFG_SCREEN_PALETTE("palette")
MCFG_GFXDECODE_ADD("gfxdecode", "palette", ie15)
MCFG_PALETTE_ADD("palette", 2)
MCFG_PALETTE_INIT_OWNER(ie15_state, ie15)
MCFG_PALETTE_ADD_MONOCHROME_GREEN("palette")
MCFG_DEFAULT_LAYOUT( layout_ie15 )
/* Devices */
MCFG_DEVICE_ADD(KEYBOARD_TAG, GENERIC_KEYBOARD, 0)
MCFG_GENERIC_KEYBOARD_CB(WRITE8(ie15_state, kbd_put))
MCFG_BITBANGER_ADD(BITBANGER_TAG, ie15_state::ie15_bitbanger_config)
MCFG_IE15_KEYBOARD_ADD("keyboard", keyboard_intf)
MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, NULL)
MCFG_RS232_RXD_HANDLER(WRITELINE(ie15_state, serial_rx_callback))
MCFG_DEVICE_MODIFY("rs232")
MCFG_SLOT_DEFAULT_OPTION("null_modem")
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_SOUND_ADD("beeper", BEEP, 0)

124
src/mess/layout/ie15.lay Normal file
View File

@ -0,0 +1,124 @@
<mamelayout version="2">
<element name="e_led">
<disk>
<color red="1.0" green="0.0" blue="0.0" />
</disk>
</element>
<element name="e_LAT">
<text string="LAT">
<color red="1.0" green="1.0" blue="1.0" />
</text>
</element>
<element name="e_NR">
<text string="NR">
<color red="1.0" green="1.0" blue="1.0" />
</text>
</element>
<element name="e_PCH">
<text string="PCH">
<color red="1.0" green="1.0" blue="1.0" />
</text>
</element>
<element name="e_DUP">
<text string="DUP">
<color red="1.0" green="1.0" blue="1.0" />
</text>
</element>
<element name="e_LIN">
<text string="LIN">
<color red="1.0" green="1.0" blue="1.0" />
</text>
</element>
<element name="e_RED">
<text string="RED">
<color red="1.0" green="1.0" blue="1.0" />
</text>
</element>
<element name="e_SDV">
<text string="SDV">
<color red="1.0" green="1.0" blue="1.0" />
</text>
</element>
<element name="e_PRD">
<text string="PRD">
<color red="1.0" green="1.0" blue="1.0" />
</text>
</element>
<element name="e_background">
<rect>
<bounds left="0" top="0" right="1" bottom="1" />
<color red="0.0" green="0.0" blue="0.5" />
</rect>
</element>
<view name="Keyboard LEDs">
<bezel name="lat_txt" element="e_LAT">
<bounds left="0" right="100" top="550" bottom="570" />
</bezel>
<bezel name="lat_led" element="e_led">
<bounds left="40" right="60" top="580" bottom="600" />
</bezel>
<bezel name="nr_txt" element="e_NR">
<bounds left="100" right="200" top="550" bottom="570" />
</bezel>
<bezel name="nr_led" element="e_led">
<bounds left="140" right="160" top="580" bottom="600" />
</bezel>
<bezel name="pch_txt" element="e_PCH">
<bounds left="200" right="300" top="550" bottom="570" />
</bezel>
<bezel name="pch_led" element="e_led">
<bounds left="240" right="260" top="580" bottom="600" />
</bezel>
<bezel name="dup_txt" element="e_DUP">
<bounds left="300" right="400" top="550" bottom="570" />
</bezel>
<bezel name="dup_led" element="e_led">
<bounds left="340" right="360" top="580" bottom="600" />
</bezel>
<bezel name="lin_txt" element="e_LIN">
<bounds left="400" right="500" top="550" bottom="570" />
</bezel>
<bezel name="lin_led" element="e_led">
<bounds left="440" right="460" top="580" bottom="600" />
</bezel>
<bezel name="red_txt" element="e_RED">
<bounds left="500" right="600" top="550" bottom="570" />
</bezel>
<bezel name="red_led" element="e_led">
<bounds left="540" right="560" top="580" bottom="600" />
</bezel>
<bezel name="sdv_txt" element="e_SDV">
<bounds left="600" right="700" top="550" bottom="570" />
</bezel>
<bezel name="sdv_led" element="e_led">
<bounds left="640" right="660" top="580" bottom="600" />
</bezel>
<bezel name="prd_txt" element="e_PRD">
<bounds left="700" right="800" top="550" bottom="570" />
</bezel>
<bezel name="prd_led" element="e_led">
<bounds left="740" right="760" top="580" bottom="600" />
</bezel>
<!--
<bezel element="e_background">
<bounds left="0" right="800" top="550" bottom="600" />
</bezel>
-->
<screen index="0">
<bounds x="0" y="0" width="800" height="550" />
</screen>
</view>
</mamelayout>

334
src/mess/machine/ie15_kbd.c Normal file
View File

@ -0,0 +1,334 @@
/***************************************************************************
15WWW-97-006 keyboard, normally used with 15IE-00-013.
Irisha can use it too.
***************************************************************************/
#include "machine/ie15_kbd.h"
/***************************************************************************
IMPLEMENTATION
***************************************************************************/
ie15_keyboard_device::ie15_keyboard_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
: device_t(mconfig, type, name, tag, owner, clock, shortname, source)
, m_io_kbd0(*this, "TERM_LINE0")
, m_io_kbd1(*this, "TERM_LINE1")
, m_io_kbd2(*this, "TERM_LINE2")
, m_io_kbd3(*this, "TERM_LINE3")
, m_io_kbdc(*this, "TERM_LINEC")
{
}
ie15_keyboard_device::ie15_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, IE15_KEYBOARD, "15WWW-97-006 Keyboard", tag, owner, clock, "ie15_keyboard", __FILE__)
, m_io_kbd0(*this, "TERM_LINE0")
, m_io_kbd1(*this, "TERM_LINE1")
, m_io_kbd2(*this, "TERM_LINE2")
, m_io_kbd3(*this, "TERM_LINE3")
, m_io_kbdc(*this, "TERM_LINEC")
{
}
UINT8 ie15_keyboard_device::row_number(UINT32 code)
{
if BIT(code,0) return 0;
if BIT(code,1) return 1;
if BIT(code,2) return 2;
if BIT(code,3) return 3;
if BIT(code,4) return 4;
if BIT(code,5) return 5;
if BIT(code,6) return 6;
if BIT(code,7) return 7;
if BIT(code,8) return 8;
if BIT(code,9) return 9;
if BIT(code,10) return 10;
if BIT(code,11) return 11;
if BIT(code,12) return 12;
if BIT(code,13) return 13;
if BIT(code,14) return 14;
if BIT(code,15) return 15;
return 0;
}
UINT16 ie15_keyboard_device::keyboard_handler(UINT16 last_code, UINT8 *scan_line)
{
int i;
UINT32 code = 0;
UINT16 key_code = 0;
UINT16 retVal = 0;
UINT8 ctrl = BIT(m_io_kbdc->read(), 0);
UINT8 shift = BIT(m_io_kbdc->read(), 1);
i = *scan_line;
{
if (i == 0) code = m_io_kbd0->read();
else
if (i == 1) code = m_io_kbd1->read();
else
if (i == 2) code = m_io_kbd2->read();
else
if (i == 3) code = m_io_kbd3->read();
if (code != 0)
{
if (!m_ruslat)
i += 4;
if (shift)
i += 8;
i <<= 4;
if (code < 0x10000) {
key_code = m_rom [i + row_number(code)];
} else {
key_code = m_rom [i + row_number(code >> 16)*2 + 256];
}
if (ctrl) {
key_code &= 0x1f;
}
retVal = key_code;
} else {
*scan_line += 1;
if (*scan_line==4) {
*scan_line = 0;
}
}
}
// setup mode toggle
if (BIT(m_io_kbdc->read(), 2)) {
retVal |= (IE_KB_SDV << 8);
}
// aux keyboard flag
if (code & 0xe0e000) {
retVal |= (IE_KB_DK << 8);
}
// shift
if (shift) {
retVal |= (IE_KB_NR << 8);
}
// SI/SO handling
if ((key_code & 127) == IE_KB_SI) {
m_ruslat = 0;
}
if ((key_code & 127) == IE_KB_SO) {
m_ruslat = 1;
}
return retVal;
}
void ie15_keyboard_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
UINT16 new_code;
new_code = keyboard_handler(m_last_code, &m_scan_line);
if ((m_last_code != new_code) /* && (new_code) */)
send_key(new_code);
m_last_code = new_code;
}
/***************************************************************************
VIDEO HARDWARE
***************************************************************************/
ROM_START( ie15_keyboard )
ROM_REGION( 0x200, "ie15kbd", 0 )
ROM_LOAD( "15bbb.rt5", 0x000, 0x200, CRC(e6a4226e) SHA1(0ee46f5be1b01fa917a6d483bb51463106ae441f) )
ROM_END
const rom_entry *ie15_keyboard_device::device_rom_region() const
{
return ROM_NAME( ie15_keyboard );
}
static MACHINE_CONFIG_FRAGMENT( ie15_keyboard )
MACHINE_CONFIG_END
machine_config_constructor ie15_keyboard_device::device_mconfig_additions() const
{
return MACHINE_CONFIG_NAME(ie15_keyboard);
}
void ie15_keyboard_device::device_start()
{
m_keyboard_func.resolve(m_keyboard_cb, *this);
m_timer = timer_alloc();
m_rom = (UINT8*)memregion("ie15kbd")->base();
}
void ie15_keyboard_device::device_config_complete()
{
const ie15_keyboard_interface *intf = reinterpret_cast<const ie15_keyboard_interface *>(static_config());
if(intf != NULL)
{
*static_cast<ie15_keyboard_interface *>(this) = *intf;
}
else
{
memset(&m_keyboard_cb, 0, sizeof(m_keyboard_cb));
}
}
void ie15_keyboard_device::device_reset()
{
m_last_code = 0;
m_scan_line = 0;
m_ruslat = 0;
m_timer->adjust(attotime::from_hz(10000), 0, attotime::from_hz(10000));
}
/*
Y1 Y2 Y3 Y4 Y5 Y6 Y7 Y8 Y9 Y10 Y11 Y12 Y13 Y14 Y15 Y16 Y17 Y18 Y19 Y20 Y21 Y22 Y23 Y24
--
;+ 1! 2" 3# 4$ 5% 6& 7' 8( 9) 0 -= 7 8 9 ??? ?? ??? ??? ??? f1 f2 f3
?J ?C ?U ?K ?E ?N ?G ?[ ?] ?Z ?H :* 4 5 6 ?? ?? ??1 ?1 ??2 f4 f5 f6
?F ?Y ?W ?A ?P ?R ?O ?L ?D ?V ?\ .> ?? 1 2 3 ??? ??? ??? f7 f8 f9
?Q ?^ ?S ?M ?I ?T ?X ?B ?@ ,< /? _ SPC 0 , fA fB fC
rom:
00000000 3b 31 32 33 34 35 36 37 38 39 30 2d 00 37 38 39 |;1234567890-.789| rus + upper
00000010 6a 63 75 6b 65 6e 67 7b 7d 7a 68 3a 00 34 35 36 |jcukeng{}zh:.456|
00000020 66 79 77 61 70 72 6f 6c 64 76 7c 2e 7f 31 32 33 |fywaproldv|..123|
00000030 71 7e 73 6d 69 74 78 62 60 2c 2f 7f 20 30 30 2c |q~smitxb`,/. 00,|
00000040 3b 31 32 33 34 35 36 37 38 39 30 2d 00 37 38 39 |;1234567890-.789| lat + upper
00000050 4a 43 55 4b 45 4e 47 5b 5d 5a 48 3a 00 34 35 36 |JCUKENG[]ZH:.456|
00000060 46 59 57 41 50 52 4f 4c 44 56 5c 2e 7f 31 32 33 |FYWAPROLDV\..123|
00000070 51 5e 53 4d 49 54 58 42 40 2c 2f 5f 20 30 30 2c |Q^SMITXB@,/_ 00,|
00000080 2b 21 22 23 24 25 26 27 28 29 30 3d 00 37 38 39 |+!"#$%&'()0=.789| rus + lower
00000090 4a 43 55 4b 45 4e 47 5b 5d 5a 48 2a 00 34 35 36 |JCUKENG[]ZH*.456|
000000a0 46 59 57 41 50 52 4f 4c 44 56 5c 3e 7f 31 32 33 |FYWAPROLDV\>.123|
000000b0 51 5e 53 4d 49 54 58 42 40 3c 3f 5f 20 30 30 2c |Q^SMITXB@<?_ 00,|
000000c0 2b 21 22 23 24 25 26 27 28 29 30 3d 00 37 38 39 |+!"#$%&'()0=.789| lat + lower
000000d0 6a 63 75 6b 65 6e 67 7b 7d 7a 68 2a 00 34 35 36 |jcukeng{}zh*.456|
000000e0 66 79 77 61 70 72 6f 6c 64 76 7c 3e 7f 31 32 33 |fywaproldv|>.123|
000000f0 71 7e 73 6d 69 74 78 62 60 3c 3f 7f 20 30 30 2c |q~smitxb`<?. 00,|
00000100 18 18 09 09 0c 0c 1f 1f 0b 0b 15 15 1c 1c 0d 0d |................|
00000110 0a 0a 0d 0d 10 10 01 01 1b 1b 1a 1a 08 08 19 19 |................|
00000120 7f 7f 7f 7f 1e 1e 11 11 06 06 14 14 1d 1d 13 13 |................|
00000130 0e 0e 0f 0f 7f 7f 7f 7f 7f 7f 16 16 02 02 12 12 |................|
*/
static INPUT_PORTS_START( ie15_keyboard )
PORT_START("TERM_LINE0")
PORT_BIT(0x000001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('+')
PORT_BIT(0x000002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
PORT_BIT(0x000004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"')
PORT_BIT(0x000008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#')
PORT_BIT(0x000010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')
PORT_BIT(0x000020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%')
PORT_BIT(0x000040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&')
PORT_BIT(0x000080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'')
PORT_BIT(0x000100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(')
PORT_BIT(0x000200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')')
PORT_BIT(0x000400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0')
PORT_BIT(0x000800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') // PORT_CHAR('=')
PORT_BIT(0x001000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x002000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Keypad 7") PORT_CODE(KEYCODE_7_PAD)
PORT_BIT(0x004000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Keypad 8") PORT_CODE(KEYCODE_8_PAD)
PORT_BIT(0x008000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Keypad 9") PORT_CODE(KEYCODE_9_PAD)
PORT_BIT(0x010000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("TAB (VT)") PORT_CODE(KEYCODE_F11) PORT_CHAR(UCHAR_MAMEKEY(F11)) // Vertical Tab
PORT_BIT(0x020000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TAB) PORT_CHAR(9)
PORT_BIT(0x040000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("SBR") PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1))
PORT_BIT(0x080000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("STR") PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2))
PORT_BIT(0x100000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("STS") PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3))
PORT_BIT(0x200000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) // 'f1'
PORT_BIT(0x400000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Up") PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) // 'f2'
PORT_BIT(0x800000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Home") PORT_CODE(KEYCODE_HOME) PORT_CHAR(UCHAR_MAMEKEY(HOME)) // 'f3'
PORT_START("TERM_LINE1")
PORT_BIT(0x000001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J')
PORT_BIT(0x000002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C')
PORT_BIT(0x000004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U')
PORT_BIT(0x000008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K')
PORT_BIT(0x000010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E')
PORT_BIT(0x000020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N')
PORT_BIT(0x000040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G')
PORT_BIT(0x000080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{')
PORT_BIT(0x000100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}')
PORT_BIT(0x000200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z')
PORT_BIT(0x000400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H')
PORT_BIT(0x000800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(':') PORT_CHAR('*')
PORT_BIT(0x001000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x002000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Keypad 4") PORT_CODE(KEYCODE_4_PAD)
PORT_BIT(0x004000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Keypad 5") PORT_CODE(KEYCODE_5_PAD)
PORT_BIT(0x008000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Keypad 6") PORT_CODE(KEYCODE_6_PAD)
PORT_BIT(0x010000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("PS (LF)") PORT_CODE(KEYCODE_F12) PORT_CHAR(UCHAR_MAMEKEY(F12)) // Line Feed
PORT_BIT(0x020000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)
PORT_BIT(0x040000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("AR1") PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4))
PORT_BIT(0x080000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("S1") PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5))
PORT_BIT(0x100000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("AR2 (Escape)") PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC))
PORT_BIT(0x200000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Left") PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT))
PORT_BIT(0x400000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Begin") PORT_CODE(KEYCODE_END) PORT_CHAR(UCHAR_MAMEKEY(END))
PORT_BIT(0x800000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Right") PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT))
PORT_START("TERM_LINE2")
PORT_BIT(0x000001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F')
PORT_BIT(0x000002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y')
PORT_BIT(0x000004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W')
PORT_BIT(0x000008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A')
PORT_BIT(0x000010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P')
PORT_BIT(0x000020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R')
PORT_BIT(0x000040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O')
PORT_BIT(0x000080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L')
PORT_BIT(0x000100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D')
PORT_BIT(0x000200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V')
PORT_BIT(0x000400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|')
PORT_BIT(0x000800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>')
PORT_BIT(0x001000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Backspace") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8)
PORT_BIT(0x002000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Keypad 1") PORT_CODE(KEYCODE_1_PAD)
PORT_BIT(0x004000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Keypad 2") PORT_CODE(KEYCODE_2_PAD)
PORT_BIT(0x008000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Keypad 3") PORT_CODE(KEYCODE_3_PAD)
PORT_BIT(0x010000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x020000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x040000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("PRD") PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6))
PORT_BIT(0x080000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("PRM") PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7))
PORT_BIT(0x100000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("PRS") PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8))
PORT_BIT(0x200000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Del") PORT_CODE(KEYCODE_DEL) PORT_CHAR(UCHAR_MAMEKEY(DEL))
PORT_BIT(0x400000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Down") PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN))
PORT_BIT(0x800000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Ins") PORT_CODE(KEYCODE_INSERT) PORT_CHAR(UCHAR_MAMEKEY(INSERT))
PORT_START("TERM_LINE3")
PORT_BIT(0x000001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q')
PORT_BIT(0x000002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('^') PORT_CHAR('~')
PORT_BIT(0x000004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S')
PORT_BIT(0x000008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M')
PORT_BIT(0x000010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I')
PORT_BIT(0x000020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T')
PORT_BIT(0x000040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X')
PORT_BIT(0x000080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B')
PORT_BIT(0x000100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH_PAD) PORT_CHAR(UCHAR_MAMEKEY(SLASH_PAD)) // PORT_CHAR('`') PORT_CHAR('@') // XXX
PORT_BIT(0x000200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<')
PORT_BIT(0x000400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?')
PORT_BIT(0x000800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('_') // XXX
PORT_BIT(0x001000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')
PORT_BIT(0x002000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Keypad 0") PORT_CODE(KEYCODE_0_PAD)
PORT_BIT(0x004000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x008000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Keypad ,") PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD))
PORT_BIT(0x010000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Lat (SO)") PORT_CODE(KEYCODE_LALT)
PORT_BIT(0x020000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Rus (SI)") PORT_CODE(KEYCODE_RALT)
PORT_BIT(0x040000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x080000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x100000, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_BIT(0x200000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("PgDn") PORT_CODE(KEYCODE_PGDN) PORT_CHAR(UCHAR_MAMEKEY(PGDN))
PORT_BIT(0x400000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Next SetUp") PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR(UCHAR_MAMEKEY(ASTERISK))
PORT_BIT(0x800000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("PgUp") PORT_CODE(KEYCODE_PGUP) PORT_CHAR(UCHAR_MAMEKEY(PGUP))
PORT_START("TERM_LINEC")
PORT_BIT(0x000001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Ctrl") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL)
// PORT_BIT(0x000002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
PORT_BIT(0x000002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("SetUp") PORT_CODE(KEYCODE_RSHIFT) PORT_TOGGLE PORT_CHAR(UCHAR_MAMEKEY(RSHIFT))
PORT_BIT(0x000004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("SetUp") PORT_CODE(KEYCODE_PRTSCR) PORT_TOGGLE PORT_CHAR(UCHAR_MAMEKEY(PRTSCR))
INPUT_PORTS_END
ioport_constructor ie15_keyboard_device::device_input_ports() const
{
return INPUT_PORTS_NAME(ie15_keyboard);
}
const device_type IE15_KEYBOARD = &device_creator<ie15_keyboard_device>;

View File

@ -0,0 +1,89 @@
#ifndef __IE15_KEYBOARD_H__
#define __IE15_KEYBOARD_H__
#include "emu.h"
#define IE_KB_ACK 1
#define IE_KB_RED 0x01
#define IE_KB_SDV 0x02
#define IE_KB_DUP 0x08
#define IE_KB_LIN 0x10
#define IE_KB_DK 0x20
#define IE_KB_PCH 0x40
#define IE_KB_NR 0x80
#define IE_KB_RED_BIT 0
#define IE_KB_SDV_BIT 1
#define IE_KB_DUP_BIT 3
#define IE_KB_LIN_BIT 4
#define IE_KB_DK_BIT 5
#define IE_KB_PCH_BIT 6
#define IE_KB_NR_BIT 7
#define IE_KB_SI 0x0f
#define IE_KB_SO 0x0e
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
struct ie15_keyboard_interface
{
devcb_write16 m_keyboard_cb;
};
#define IE15_KEYBOARD_INTERFACE(name) const ie15_keyboard_interface (name) =
/***************************************************************************
DEVICE CONFIGURATION MACROS
***************************************************************************/
#define MCFG_IE15_KEYBOARD_ADD(_tag, _intrf) \
MCFG_DEVICE_ADD(_tag, IE15_KEYBOARD, 0) \
MCFG_DEVICE_CONFIG(_intrf)
/***************************************************************************
FUNCTION PROTOTYPES
***************************************************************************/
class ie15_keyboard_device :
public device_t,
public ie15_keyboard_interface
{
public:
ie15_keyboard_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
ie15_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
virtual ioport_constructor device_input_ports() const;
virtual machine_config_constructor device_mconfig_additions() const;
virtual const rom_entry *device_rom_region() const;
protected:
required_ioport m_io_kbd0;
required_ioport m_io_kbd1;
required_ioport m_io_kbd2;
required_ioport m_io_kbd3;
required_ioport m_io_kbdc;
virtual void device_start();
virtual void device_reset();
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
virtual void device_config_complete();
virtual void send_key(UINT16 code) { m_keyboard_func(0, code); }
emu_timer *m_timer;
private:
virtual UINT16 keyboard_handler(UINT16 last_code, UINT8 *scan_line);
UINT8 row_number(UINT32 code);
UINT16 m_last_code;
UINT8 m_scan_line;
UINT8 m_ruslat;
UINT8 *m_rom;
devcb_resolved_write16 m_keyboard_func;
};
extern const device_type IE15_KEYBOARD;
#endif /* __IE15_KEYBOARD_H__ */

View File

@ -2063,7 +2063,7 @@ $(MESSOBJ)/skeleton.a: \
$(MESS_DRIVERS)/hunter2.o \
$(EMU_MACHINE)/nsc810.o \
$(MESS_DRIVERS)/ibm6580.o \
$(MESS_DRIVERS)/ie15.o \
$(MESS_DRIVERS)/ie15.o $(MESS_MACHINE)/ie15_kbd.o \
$(MESS_DRIVERS)/if800.o \
$(MESS_DRIVERS)/imsai.o \
$(MESS_DRIVERS)/indiana.o \
@ -2232,6 +2232,7 @@ $(MESS_DRIVERS)/fidelz80.o: $(MESS_LAYOUT)/fidelz80.lh \
$(MESS_LAYOUT)/vsc.lh
$(MESS_DRIVERS)/glasgow.o: $(MESS_LAYOUT)/glasgow.lh
$(MESS_DRIVERS)/h8.o: $(MESS_LAYOUT)/h8.lh
$(MESS_DRIVERS)/ie15.o: $(MESS_LAYOUT)/ie15.lh
$(MESS_DRIVERS)/instruct.o: $(MESS_LAYOUT)/instruct.lh
$(MESS_DRIVERS)/k1003.o: $(MESS_LAYOUT)/k1003.lh
$(MESS_DRIVERS)/kim1.o: $(MESS_LAYOUT)/kim1.lh