(MESS) ngen: started keyboard support, plus a few minor updates.
This commit is contained in:
parent
34ce110109
commit
2e290e4fae
@ -4,6 +4,11 @@
|
|||||||
|
|
||||||
10-11-14 - Skeleton driver
|
10-11-14 - Skeleton driver
|
||||||
|
|
||||||
|
Interrupts based on patents:
|
||||||
|
level 1 - SIO
|
||||||
|
level 3 - timer (from PIT, presumably channel 0? Patent says "channel 3")
|
||||||
|
level 4 - "interrupt detector" - keyboard, printer, RTC
|
||||||
|
level 7 - floppy/hard disk
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
@ -16,6 +21,8 @@
|
|||||||
#include "machine/pit8253.h"
|
#include "machine/pit8253.h"
|
||||||
#include "machine/z80dart.h"
|
#include "machine/z80dart.h"
|
||||||
#include "bus/rs232/rs232.h"
|
#include "bus/rs232/rs232.h"
|
||||||
|
#include "machine/ngen_kb.h"
|
||||||
|
#include "machine/clock.h"
|
||||||
|
|
||||||
class ngen_state : public driver_device
|
class ngen_state : public driver_device
|
||||||
{
|
{
|
||||||
@ -36,21 +43,35 @@ public:
|
|||||||
DECLARE_WRITE_LINE_MEMBER(pit_out0_w);
|
DECLARE_WRITE_LINE_MEMBER(pit_out0_w);
|
||||||
DECLARE_WRITE_LINE_MEMBER(pit_out1_w);
|
DECLARE_WRITE_LINE_MEMBER(pit_out1_w);
|
||||||
DECLARE_WRITE_LINE_MEMBER(pit_out2_w);
|
DECLARE_WRITE_LINE_MEMBER(pit_out2_w);
|
||||||
|
DECLARE_WRITE_LINE_MEMBER(cpu_timer_w);
|
||||||
|
DECLARE_WRITE_LINE_MEMBER(timer_clk_out);
|
||||||
DECLARE_WRITE16_MEMBER(cpu_peripheral_cb);
|
DECLARE_WRITE16_MEMBER(cpu_peripheral_cb);
|
||||||
DECLARE_WRITE16_MEMBER(peripheral_w);
|
DECLARE_WRITE16_MEMBER(peripheral_w);
|
||||||
DECLARE_READ16_MEMBER(peripheral_r);
|
DECLARE_READ16_MEMBER(peripheral_r);
|
||||||
DECLARE_WRITE16_MEMBER(port00_w);
|
DECLARE_WRITE16_MEMBER(port00_w);
|
||||||
DECLARE_READ16_MEMBER(port00_r);
|
DECLARE_READ16_MEMBER(port00_r);
|
||||||
DECLARE_WRITE_LINE_MEMBER(dma_hrq_changed);
|
DECLARE_WRITE_LINE_MEMBER(dma_hrq_changed);
|
||||||
|
DECLARE_WRITE_LINE_MEMBER(dma_eop_changed);
|
||||||
DECLARE_WRITE_LINE_MEMBER(dack0_w);
|
DECLARE_WRITE_LINE_MEMBER(dack0_w);
|
||||||
DECLARE_WRITE_LINE_MEMBER(dack1_w);
|
DECLARE_WRITE_LINE_MEMBER(dack1_w);
|
||||||
DECLARE_WRITE_LINE_MEMBER(dack2_w);
|
DECLARE_WRITE_LINE_MEMBER(dack2_w);
|
||||||
DECLARE_WRITE_LINE_MEMBER(dack3_w);
|
DECLARE_WRITE_LINE_MEMBER(dack3_w);
|
||||||
DECLARE_READ8_MEMBER(dma_read_byte);
|
DECLARE_READ8_MEMBER(dma_read_word);
|
||||||
DECLARE_WRITE8_MEMBER(dma_write_byte);
|
DECLARE_WRITE8_MEMBER(dma_write_word);
|
||||||
MC6845_UPDATE_ROW(crtc_update_row);
|
MC6845_UPDATE_ROW(crtc_update_row);
|
||||||
|
// TODO: sort out what devices use which channels
|
||||||
|
DECLARE_READ8_MEMBER( dma_0_dack_r ) { UINT16 ret = 0xffff; m_dma_high_byte = ret & 0xff00; return ret; }
|
||||||
|
DECLARE_READ8_MEMBER( dma_1_dack_r ) { UINT16 ret = 0xffff; m_dma_high_byte = ret & 0xff00; return ret; }
|
||||||
|
DECLARE_READ8_MEMBER( dma_2_dack_r ) { UINT16 ret = 0xffff; m_dma_high_byte = ret & 0xff00; return ret; }
|
||||||
|
DECLARE_READ8_MEMBER( dma_3_dack_r ) { UINT16 ret = 0xffff; m_dma_high_byte = ret & 0xff00; return ret; }
|
||||||
|
DECLARE_WRITE8_MEMBER( dma_0_dack_w ){ popmessage("IOW: data %02x",data); }
|
||||||
|
DECLARE_WRITE8_MEMBER( dma_1_dack_w ){ }
|
||||||
|
DECLARE_WRITE8_MEMBER( dma_2_dack_w ){ }
|
||||||
|
DECLARE_WRITE8_MEMBER( dma_3_dack_w ){ }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual void machine_reset();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
required_device<cpu_device> m_maincpu;
|
required_device<cpu_device> m_maincpu;
|
||||||
required_device<mc6845_device> m_crtc;
|
required_device<mc6845_device> m_crtc;
|
||||||
@ -71,25 +92,39 @@ private:
|
|||||||
UINT16 m_periph141;
|
UINT16 m_periph141;
|
||||||
UINT8 m_dma_offset[4];
|
UINT8 m_dma_offset[4];
|
||||||
INT8 m_dma_channel;
|
INT8 m_dma_channel;
|
||||||
|
UINT16 m_dma_high_byte;
|
||||||
|
UINT16 m_control;
|
||||||
};
|
};
|
||||||
|
|
||||||
WRITE_LINE_MEMBER(ngen_state::pit_out0_w)
|
WRITE_LINE_MEMBER(ngen_state::pit_out0_w)
|
||||||
{
|
{
|
||||||
//m_pic->ir0_w(state);
|
m_pic->ir3_w(state); // Timer interrupt
|
||||||
logerror("80186 Timer 1 state %i\n",state);
|
popmessage("PIT Timer 0 state %i\n",state);
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE_LINE_MEMBER(ngen_state::pit_out1_w)
|
WRITE_LINE_MEMBER(ngen_state::pit_out1_w)
|
||||||
{
|
{
|
||||||
logerror("PIT Timer 1 state %i\n",state);
|
popmessage("PIT Timer 1 state %i\n",state);
|
||||||
|
m_iouart->rxcb_w(state);
|
||||||
|
m_iouart->txcb_w(state); // channels in the correct order?
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE_LINE_MEMBER(ngen_state::pit_out2_w)
|
WRITE_LINE_MEMBER(ngen_state::pit_out2_w)
|
||||||
{
|
{
|
||||||
m_iouart->rxca_w(state);
|
m_iouart->rxca_w(state);
|
||||||
m_iouart->rxcb_w(state);
|
|
||||||
m_iouart->txca_w(state);
|
m_iouart->txca_w(state);
|
||||||
m_iouart->txcb_w(state);
|
//logerror("PIT Timer 2 state %i\n",state);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE_LINE_MEMBER(ngen_state::cpu_timer_w)
|
||||||
|
{
|
||||||
|
logerror("80186 Timer 1 state %i\n",state);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE_LINE_MEMBER(ngen_state::timer_clk_out)
|
||||||
|
{
|
||||||
|
m_viduart->write_rxc(state); // Keyboard UART Rx/Tx clocks
|
||||||
|
m_viduart->write_txc(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE16_MEMBER(ngen_state::cpu_peripheral_cb)
|
WRITE16_MEMBER(ngen_state::cpu_peripheral_cb)
|
||||||
@ -184,10 +219,12 @@ WRITE16_MEMBER(ngen_state::peripheral_w)
|
|||||||
m_crtc->register_w(space,0,data & 0xff);
|
m_crtc->register_w(space,0,data & 0xff);
|
||||||
break;
|
break;
|
||||||
case 0x146:
|
case 0x146:
|
||||||
logerror("Video write offset 0x146 data %04x mask %04x\n",data,mem_mask);
|
if(mem_mask & 0x00ff)
|
||||||
|
m_viduart->data_w(space,0,data & 0xff);
|
||||||
break;
|
break;
|
||||||
case 0x147:
|
case 0x147:
|
||||||
//logerror("Video write offset 0x147 data %04x mask %04x\n",data,mem_mask);
|
if(mem_mask & 0x00ff)
|
||||||
|
m_viduart->control_w(space,0,data & 0xff);
|
||||||
break;
|
break;
|
||||||
case 0x1a0: // serial?
|
case 0x1a0: // serial?
|
||||||
logerror("(PC=%06x) Serial(?) 0x1a0 write offset %04x data %04x mask %04x\n",m_maincpu->device_t::safe_pc(),offset,data,mem_mask);
|
logerror("(PC=%06x) Serial(?) 0x1a0 write offset %04x data %04x mask %04x\n",m_maincpu->device_t::safe_pc(),offset,data,mem_mask);
|
||||||
@ -257,15 +294,16 @@ READ16_MEMBER(ngen_state::peripheral_r)
|
|||||||
ret = m_crtc->register_r(space,0);
|
ret = m_crtc->register_r(space,0);
|
||||||
break;
|
break;
|
||||||
case 0x146:
|
case 0x146:
|
||||||
|
if(mem_mask & 0x00ff)
|
||||||
|
ret = m_viduart->data_r(space,0);
|
||||||
break;
|
break;
|
||||||
case 0x147: // definitely video related, maybe UART sending data to the monitor?
|
case 0x147: // keyboard UART
|
||||||
// expects bit 0 to be set (Video ready signal?)
|
// expects bit 0 to be set (UART transmit ready)
|
||||||
ret = 0;
|
if(mem_mask & 0x00ff)
|
||||||
ret |= 1;
|
ret = m_viduart->status_r(space,0);
|
||||||
break;
|
break;
|
||||||
case 0x1a0: // status?
|
case 0x1a0: // I/O control register?
|
||||||
ret = 0;
|
ret = m_control; // end of DMA transfer? (maybe a per-channel EOP?) Add a '| 0x40' to force a serial I/O failure, so that the keyboard can be tested
|
||||||
ret |= 0x02; // end of DMA transfer?
|
|
||||||
break;
|
break;
|
||||||
case 0x1b1:
|
case 0x1b1:
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@ -299,6 +337,17 @@ WRITE_LINE_MEMBER( ngen_state::dma_hrq_changed )
|
|||||||
m_maincpu->set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE);
|
m_maincpu->set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WRITE_LINE_MEMBER( ngen_state::dma_eop_changed )
|
||||||
|
{
|
||||||
|
if(m_dma_channel == 0)
|
||||||
|
{
|
||||||
|
if(state)
|
||||||
|
m_control |= 0x02;
|
||||||
|
else
|
||||||
|
m_control &= ~0x02;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ngen_state::set_dma_channel(int channel, int state)
|
void ngen_state::set_dma_channel(int channel, int state)
|
||||||
{
|
{
|
||||||
if(!state)
|
if(!state)
|
||||||
@ -312,29 +361,30 @@ WRITE_LINE_MEMBER( ngen_state::dack1_w ) { set_dma_channel(1, state); }
|
|||||||
WRITE_LINE_MEMBER( ngen_state::dack2_w ) { set_dma_channel(2, state); }
|
WRITE_LINE_MEMBER( ngen_state::dack2_w ) { set_dma_channel(2, state); }
|
||||||
WRITE_LINE_MEMBER( ngen_state::dack3_w ) { set_dma_channel(3, state); }
|
WRITE_LINE_MEMBER( ngen_state::dack3_w ) { set_dma_channel(3, state); }
|
||||||
|
|
||||||
READ8_MEMBER(ngen_state::dma_read_byte)
|
READ8_MEMBER(ngen_state::dma_read_word)
|
||||||
{
|
{
|
||||||
address_space& prog_space = m_maincpu->space(AS_PROGRAM); // get the right address space
|
address_space& prog_space = m_maincpu->space(AS_PROGRAM); // get the right address space
|
||||||
UINT8 result;
|
UINT16 result;
|
||||||
if(m_dma_channel == -1)
|
if(m_dma_channel == -1)
|
||||||
return 0xff;
|
return 0xff;
|
||||||
offs_t page_offset = (((offs_t) m_dma_offset[m_dma_channel]) << 16) & 0xFF0000;
|
offs_t page_offset = (((offs_t) m_dma_offset[m_dma_channel]) << 16) & 0xFE0000;
|
||||||
|
|
||||||
result = prog_space.read_byte(page_offset + offset);
|
result = prog_space.read_word(page_offset + (offset << 1));
|
||||||
popmessage("DMA byte address %06x read %02x\n",page_offset+offset,result);
|
m_dma_high_byte = result & 0xFF00;
|
||||||
return result;
|
popmessage("DMA byte address %06x read %04x\n",page_offset+(offset<<1),result);
|
||||||
|
return result & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WRITE8_MEMBER(ngen_state::dma_write_byte)
|
WRITE8_MEMBER(ngen_state::dma_write_word)
|
||||||
{
|
{
|
||||||
address_space& prog_space = m_maincpu->space(AS_PROGRAM); // get the right address space
|
address_space& prog_space = m_maincpu->space(AS_PROGRAM); // get the right address space
|
||||||
if(m_dma_channel == -1)
|
if(m_dma_channel == -1)
|
||||||
return;
|
return;
|
||||||
offs_t page_offset = (((offs_t) m_dma_offset[m_dma_channel]) << 16) & 0xFF0000;
|
offs_t page_offset = (((offs_t) m_dma_offset[m_dma_channel]) << 16) & 0xFE0000;
|
||||||
|
|
||||||
prog_space.write_byte(page_offset + offset, data);
|
prog_space.write_word(page_offset + (offset << 1), data);
|
||||||
popmessage("DMA byte address %06x write %02x\n",page_offset+offset,data);
|
popmessage("DMA byte address %06x write %04x\n",page_offset+(offset<<1), m_dma_high_byte | data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -355,6 +405,13 @@ MC6845_UPDATE_ROW( ngen_state::crtc_update_row )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ngen_state::machine_reset()
|
||||||
|
{
|
||||||
|
m_control = 0;
|
||||||
|
m_viduart->write_dsr(0);
|
||||||
|
m_viduart->write_cts(0);
|
||||||
|
}
|
||||||
|
|
||||||
static ADDRESS_MAP_START( ngen_mem, AS_PROGRAM, 16, ngen_state )
|
static ADDRESS_MAP_START( ngen_mem, AS_PROGRAM, 16, ngen_state )
|
||||||
AM_RANGE(0x00000, 0xf7fff) AM_RAM
|
AM_RANGE(0x00000, 0xf7fff) AM_RAM
|
||||||
AM_RANGE(0xf8000, 0xf9fff) AM_RAM AM_SHARE("vram")
|
AM_RANGE(0xf8000, 0xf9fff) AM_RAM AM_SHARE("vram")
|
||||||
@ -385,32 +442,45 @@ ADDRESS_MAP_END
|
|||||||
static INPUT_PORTS_START( ngen )
|
static INPUT_PORTS_START( ngen )
|
||||||
INPUT_PORTS_END
|
INPUT_PORTS_END
|
||||||
|
|
||||||
|
static SLOT_INTERFACE_START(keyboard)
|
||||||
|
SLOT_INTERFACE("ngen", NGEN_KEYBOARD)
|
||||||
|
SLOT_INTERFACE_END
|
||||||
|
|
||||||
static MACHINE_CONFIG_START( ngen, ngen_state )
|
static MACHINE_CONFIG_START( ngen, ngen_state )
|
||||||
// basic machine hardware
|
// basic machine hardware
|
||||||
MCFG_CPU_ADD("maincpu", I80186, XTAL_16MHz / 2)
|
MCFG_CPU_ADD("maincpu", I80186, XTAL_16MHz / 2)
|
||||||
MCFG_CPU_PROGRAM_MAP(ngen_mem)
|
MCFG_CPU_PROGRAM_MAP(ngen_mem)
|
||||||
MCFG_CPU_IO_MAP(ngen_io)
|
MCFG_CPU_IO_MAP(ngen_io)
|
||||||
MCFG_80186_CHIP_SELECT_CB(WRITE16(ngen_state, cpu_peripheral_cb))
|
MCFG_80186_CHIP_SELECT_CB(WRITE16(ngen_state, cpu_peripheral_cb))
|
||||||
MCFG_80186_TMROUT1_HANDLER(WRITELINE(ngen_state, pit_out0_w))
|
MCFG_80186_TMROUT1_HANDLER(WRITELINE(ngen_state, cpu_timer_w))
|
||||||
|
|
||||||
MCFG_PIC8259_ADD( "pic", INPUTLINE("maincpu", 0), VCC, NULL )
|
MCFG_PIC8259_ADD( "pic", INPUTLINE("maincpu", 0), VCC, NULL )
|
||||||
|
|
||||||
MCFG_DEVICE_ADD("pit", PIT8254, 0)
|
MCFG_DEVICE_ADD("pit", PIT8254, 0)
|
||||||
MCFG_PIT8253_CLK0(XTAL_14_7456MHz/8) // correct?
|
MCFG_PIT8253_CLK0(78120/4) // 19.53kHz, /4 of the CPU timer output?
|
||||||
MCFG_PIT8253_OUT0_HANDLER(WRITELINE(ngen_state, pit_out0_w))
|
MCFG_PIT8253_OUT0_HANDLER(WRITELINE(ngen_state, pit_out0_w)) // RS232 channel B baud rate
|
||||||
MCFG_PIT8253_CLK1(XTAL_14_7456MHz/8)
|
MCFG_PIT8253_CLK1(XTAL_14_7456MHz/12) // correct? - based on patent
|
||||||
MCFG_PIT8253_OUT1_HANDLER(WRITELINE(ngen_state, pit_out1_w))
|
MCFG_PIT8253_OUT1_HANDLER(WRITELINE(ngen_state, pit_out1_w)) // RS232 channel A baud rate
|
||||||
MCFG_PIT8253_CLK2(XTAL_14_7456MHz/8)
|
MCFG_PIT8253_CLK2(XTAL_14_7456MHz/12)
|
||||||
MCFG_PIT8253_OUT2_HANDLER(WRITELINE(ngen_state, pit_out2_w))
|
MCFG_PIT8253_OUT2_HANDLER(WRITELINE(ngen_state, pit_out2_w))
|
||||||
|
|
||||||
MCFG_DEVICE_ADD("dmac", AM9517A, XTAL_14_7456MHz / 3) // NEC D8237A, divisor unknown
|
MCFG_DEVICE_ADD("dmac", AM9517A, XTAL_14_7456MHz / 3) // NEC D8237A, divisor unknown
|
||||||
MCFG_I8237_OUT_HREQ_CB(WRITELINE(ngen_state, dma_hrq_changed))
|
MCFG_I8237_OUT_HREQ_CB(WRITELINE(ngen_state, dma_hrq_changed))
|
||||||
MCFG_I8237_IN_MEMR_CB(READ8(ngen_state, dma_read_byte))
|
MCFG_I8237_OUT_EOP_CB(WRITELINE(ngen_state, dma_eop_changed))
|
||||||
MCFG_I8237_OUT_MEMW_CB(WRITE8(ngen_state, dma_write_byte))
|
MCFG_I8237_IN_MEMR_CB(READ8(ngen_state, dma_read_word)) // DMA is always 16-bit
|
||||||
|
MCFG_I8237_OUT_MEMW_CB(WRITE8(ngen_state, dma_write_word))
|
||||||
MCFG_I8237_OUT_DACK_0_CB(WRITELINE(ngen_state, dack0_w))
|
MCFG_I8237_OUT_DACK_0_CB(WRITELINE(ngen_state, dack0_w))
|
||||||
MCFG_I8237_OUT_DACK_1_CB(WRITELINE(ngen_state, dack1_w))
|
MCFG_I8237_OUT_DACK_1_CB(WRITELINE(ngen_state, dack1_w))
|
||||||
MCFG_I8237_OUT_DACK_2_CB(WRITELINE(ngen_state, dack2_w))
|
MCFG_I8237_OUT_DACK_2_CB(WRITELINE(ngen_state, dack2_w))
|
||||||
MCFG_I8237_OUT_DACK_3_CB(WRITELINE(ngen_state, dack3_w))
|
MCFG_I8237_OUT_DACK_3_CB(WRITELINE(ngen_state, dack3_w))
|
||||||
|
MCFG_I8237_IN_IOR_0_CB(READ8(ngen_state, dma_0_dack_r))
|
||||||
|
MCFG_I8237_IN_IOR_1_CB(READ8(ngen_state, dma_1_dack_r))
|
||||||
|
MCFG_I8237_IN_IOR_2_CB(READ8(ngen_state, dma_2_dack_r))
|
||||||
|
MCFG_I8237_IN_IOR_3_CB(READ8(ngen_state, dma_3_dack_r))
|
||||||
|
MCFG_I8237_OUT_IOW_0_CB(WRITE8(ngen_state, dma_0_dack_w))
|
||||||
|
MCFG_I8237_OUT_IOW_1_CB(WRITE8(ngen_state, dma_1_dack_w))
|
||||||
|
MCFG_I8237_OUT_IOW_2_CB(WRITE8(ngen_state, dma_2_dack_w))
|
||||||
|
MCFG_I8237_OUT_IOW_3_CB(WRITE8(ngen_state, dma_3_dack_w))
|
||||||
|
|
||||||
// I/O board
|
// I/O board
|
||||||
MCFG_UPD7201_ADD("iouart",0,0,0,0,0) // clocked by PIT channel 2?
|
MCFG_UPD7201_ADD("iouart",0,0,0,0,0) // clocked by PIT channel 2?
|
||||||
@ -447,7 +517,15 @@ static MACHINE_CONFIG_START( ngen, ngen_state )
|
|||||||
MCFG_MC6845_UPDATE_ROW_CB(ngen_state, crtc_update_row)
|
MCFG_MC6845_UPDATE_ROW_CB(ngen_state, crtc_update_row)
|
||||||
MCFG_VIDEO_SET_SCREEN("screen")
|
MCFG_VIDEO_SET_SCREEN("screen")
|
||||||
|
|
||||||
MCFG_DEVICE_ADD("videouart", I8251, 19980000 / 9) // divisor unknown
|
// keyboard UART (patent says i8251 is used for keyboard communications, it is located on the video board)
|
||||||
|
MCFG_DEVICE_ADD("videouart", I8251, 0) // main clock unknown, Rx/Tx clocks are 19.53kHz
|
||||||
|
MCFG_I8251_TXEMPTY_HANDLER(DEVWRITELINE("pic",pic8259_device,ir4_w))
|
||||||
|
MCFG_I8251_TXD_HANDLER(DEVWRITELINE("keyboard", rs232_port_device, write_txd))
|
||||||
|
MCFG_RS232_PORT_ADD("keyboard", keyboard, "ngen")
|
||||||
|
MCFG_RS232_RXD_HANDLER(DEVWRITELINE("videouart", i8251_device, write_rxd))
|
||||||
|
|
||||||
|
MCFG_DEVICE_ADD("refresh_clock", CLOCK, 19200*16) // should be 19530Hz
|
||||||
|
MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(ngen_state,timer_clk_out))
|
||||||
|
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
|
219
src/mess/machine/ngen_kb.c
Normal file
219
src/mess/machine/ngen_kb.c
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
// Convergent NGEN keyboard device
|
||||||
|
|
||||||
|
#include "ngen_kb.h"
|
||||||
|
|
||||||
|
ngen_keyboard_device::ngen_keyboard_device(const machine_config& mconfig, const char* tag, device_t* owner, UINT32 clock) :
|
||||||
|
serial_keyboard_device(mconfig, NGEN_KEYBOARD, "NGEN Keyboard", tag, owner, 0, "ngen_keyboard", __FILE__),
|
||||||
|
m_keys_down(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ngen_keyboard_device::write(UINT8 data)
|
||||||
|
{
|
||||||
|
// To be figured out
|
||||||
|
logerror("KB: received character %02x\n",data);
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT8 ngen_keyboard_device::row_number(UINT8 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;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT8 ngen_keyboard_device::keyboard_handler(UINT8 last_code, UINT8 *scan_line)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
UINT8 code = 0;
|
||||||
|
UINT8 key_code = 0;
|
||||||
|
UINT8 retVal = 0;
|
||||||
|
UINT8 shift = BIT(m_io_kbdc->read(), 1);
|
||||||
|
UINT8 caps = BIT(m_io_kbdc->read(), 2);
|
||||||
|
UINT8 ctrl = BIT(m_io_kbdc->read(), 0);
|
||||||
|
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();
|
||||||
|
else
|
||||||
|
if (i == 4) code = m_io_kbd4->read();
|
||||||
|
else
|
||||||
|
if (i == 5) code = m_io_kbd5->read();
|
||||||
|
else
|
||||||
|
if (i == 6) code = m_io_kbd6->read();
|
||||||
|
else
|
||||||
|
if (i == 7) code = m_io_kbd7->read();
|
||||||
|
else
|
||||||
|
if (i == 8) code = m_io_kbd8->read();
|
||||||
|
else
|
||||||
|
if (i == 9) code = m_io_kbd9->read();
|
||||||
|
|
||||||
|
if (code != 0)
|
||||||
|
{
|
||||||
|
if (i==0 && shift==0) {
|
||||||
|
key_code = 0x30 + row_number(code) + 8*i; // for numbers and some signs
|
||||||
|
}
|
||||||
|
if (i==0 && shift==1) {
|
||||||
|
key_code = 0x20 + row_number(code) + 8*i; // for shifted numbers
|
||||||
|
}
|
||||||
|
if (i==1 && shift==0) {
|
||||||
|
if (row_number(code) < 4) {
|
||||||
|
key_code = 0x30 + row_number(code) + 8*i; // for numbers and some signs
|
||||||
|
} else {
|
||||||
|
key_code = 0x20 + row_number(code) + 8*i; // for numbers and some signs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i==1 && shift==1) {
|
||||||
|
if (row_number(code) < 4) {
|
||||||
|
key_code = 0x20 + row_number(code) + 8*i; // for numbers and some signs
|
||||||
|
} else {
|
||||||
|
key_code = 0x30 + row_number(code) + 8*i; // for numbers and some signs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i>=2 && i<=4 && (shift ^ caps)==0 && ctrl==0) {
|
||||||
|
key_code = 0x60 + row_number(code) + (i-2)*8; // for small letters
|
||||||
|
}
|
||||||
|
if (i>=2 && i<=4 && (shift ^ caps)==1 && ctrl==0) {
|
||||||
|
key_code = 0x40 + row_number(code) + (i-2)*8; // for big letters
|
||||||
|
}
|
||||||
|
if (i>=2 && i<=5 && ctrl==1) {
|
||||||
|
key_code = 0x00 + row_number(code) + (i-2)*8; // for CTRL + letters
|
||||||
|
}
|
||||||
|
if (i==5 && shift==1 && ctrl==0) {
|
||||||
|
if (row_number(code)<7) {
|
||||||
|
if (row_number(code)<3) {
|
||||||
|
key_code = (caps ? 0x60 : 0x40) + row_number(code) + (i-2)*8; // for big letters
|
||||||
|
} else {
|
||||||
|
key_code = 0x60 + row_number(code) + (i-2)*8; // for upper symbols letters
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
key_code = 0x40 + row_number(code) + (i-2)*8; // for DEL it is switched
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i==5 && shift==0 && ctrl==0) {
|
||||||
|
if (row_number(code)<7) {
|
||||||
|
if (row_number(code)<3) {
|
||||||
|
key_code = (caps ? 0x40 : 0x60) + row_number(code) + (i-2)*8; // for small letters
|
||||||
|
} else {
|
||||||
|
key_code = 0x40 + row_number(code) + (i-2)*8; // for lower symbols letters
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
key_code = 0x60 + row_number(code) + (i-2)*8; // for DEL it is switched
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i==6) {
|
||||||
|
switch(row_number(code))
|
||||||
|
{
|
||||||
|
/* case 0: key_code = 0x11; break;
|
||||||
|
case 1: key_code = 0x12; break;
|
||||||
|
case 2: key_code = 0x13; break;
|
||||||
|
case 3: key_code = 0x14; break;*/
|
||||||
|
case 4: key_code = 0x20; break; // Space
|
||||||
|
case 5: key_code = 0x0A; break; // LineFeed
|
||||||
|
case 6: key_code = 0x09; break; // TAB
|
||||||
|
case 7: key_code = 0x0D; break; // Enter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i==7)
|
||||||
|
{
|
||||||
|
switch(row_number(code))
|
||||||
|
{
|
||||||
|
case 0: key_code = 0x1B; break; // Escape
|
||||||
|
case 1: key_code = 0x08; break; // Backspace
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (i==8)
|
||||||
|
{
|
||||||
|
key_code = row_number(code)+0x81;
|
||||||
|
if (ctrl) key_code+=0x10;
|
||||||
|
if (shift) key_code+=0x20;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (i==9)
|
||||||
|
{
|
||||||
|
key_code = row_number(code)+0x89;
|
||||||
|
if (ctrl) key_code+=0x10;
|
||||||
|
if (shift) key_code+=0x20;
|
||||||
|
}
|
||||||
|
m_keys_down = true;
|
||||||
|
retVal = key_code;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*scan_line += 1;
|
||||||
|
if (*scan_line==10)
|
||||||
|
*scan_line = 0;
|
||||||
|
if(m_keys_down)
|
||||||
|
{
|
||||||
|
retVal = 0xc0;
|
||||||
|
m_keys_down = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO: add scan code 0xc0 (all keys up)
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
static INPUT_PORTS_START( ngen_keyboard )
|
||||||
|
PORT_INCLUDE(generic_keyboard)
|
||||||
|
|
||||||
|
PORT_START("RS232_TXBAUD")
|
||||||
|
PORT_CONFNAME(0xff, RS232_BAUD_19200, "TX Baud") PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, serial_keyboard_device, update_serial)
|
||||||
|
PORT_CONFSETTING( RS232_BAUD_19200, "19200") // TODO: Based on the RAM refresh timer (~78kHz) to be 19530Hz
|
||||||
|
|
||||||
|
PORT_START("RS232_STARTBITS")
|
||||||
|
PORT_CONFNAME(0xff, RS232_STARTBITS_1, "Start Bits") PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, serial_keyboard_device, update_serial)
|
||||||
|
PORT_CONFSETTING( RS232_STARTBITS_1, "1")
|
||||||
|
|
||||||
|
PORT_START("RS232_DATABITS")
|
||||||
|
PORT_CONFNAME(0xff, RS232_DATABITS_8, "Data Bits") PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, serial_keyboard_device, update_serial)
|
||||||
|
PORT_CONFSETTING( RS232_DATABITS_8, "8")
|
||||||
|
|
||||||
|
PORT_START("RS232_PARITY")
|
||||||
|
PORT_CONFNAME(0xff, RS232_PARITY_NONE, "Parity") PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, serial_keyboard_device, update_serial)
|
||||||
|
PORT_CONFSETTING( RS232_PARITY_NONE, "None")
|
||||||
|
|
||||||
|
PORT_START("RS232_STOPBITS")
|
||||||
|
PORT_CONFNAME(0xff, RS232_STOPBITS_2, "Stop Bits") PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, serial_keyboard_device, update_serial)
|
||||||
|
PORT_CONFSETTING( RS232_STOPBITS_2, "2")
|
||||||
|
INPUT_PORTS_END
|
||||||
|
|
||||||
|
|
||||||
|
ioport_constructor ngen_keyboard_device::device_input_ports() const
|
||||||
|
{
|
||||||
|
return INPUT_PORTS_NAME(ngen_keyboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ngen_keyboard_device::device_start()
|
||||||
|
{
|
||||||
|
serial_keyboard_device::device_start();
|
||||||
|
set_rcv_rate(19200);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ngen_keyboard_device::device_reset()
|
||||||
|
{
|
||||||
|
serial_keyboard_device::device_reset();
|
||||||
|
m_keys_down = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ngen_keyboard_device::rcv_complete()
|
||||||
|
{
|
||||||
|
receive_register_extract();
|
||||||
|
write(get_received_char());
|
||||||
|
}
|
||||||
|
|
||||||
|
const device_type NGEN_KEYBOARD = &device_creator<ngen_keyboard_device>;
|
||||||
|
|
30
src/mess/machine/ngen_kb.h
Normal file
30
src/mess/machine/ngen_kb.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Convergent NGEN keyboard
|
||||||
|
|
||||||
|
#ifndef NGEN_KB_H_
|
||||||
|
#define NGEN_KB_H_
|
||||||
|
|
||||||
|
#include "bus/rs232/keyboard.h"
|
||||||
|
|
||||||
|
class ngen_keyboard_device : public serial_keyboard_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ngen_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
virtual ioport_constructor device_input_ports() const;
|
||||||
|
virtual DECLARE_WRITE_LINE_MEMBER( input_txd ) {/* printf("TX: %i\n",state);*/ device_serial_interface::rx_w(state); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void device_start();
|
||||||
|
virtual void device_reset();
|
||||||
|
virtual void rcv_complete();
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual UINT8 keyboard_handler(UINT8 last_code, UINT8 *scan_line);
|
||||||
|
UINT8 row_number(UINT8 code);
|
||||||
|
void write(UINT8 data);
|
||||||
|
|
||||||
|
bool m_keys_down;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const device_type NGEN_KEYBOARD;
|
||||||
|
|
||||||
|
#endif /* NGENKB_H_ */
|
@ -1952,7 +1952,7 @@ $(MESSOBJ)/skeleton.a: \
|
|||||||
$(MESS_DRIVERS)/mx2178.o \
|
$(MESS_DRIVERS)/mx2178.o \
|
||||||
$(MESS_DRIVERS)/mycom.o \
|
$(MESS_DRIVERS)/mycom.o \
|
||||||
$(MESS_DRIVERS)/myvision.o \
|
$(MESS_DRIVERS)/myvision.o \
|
||||||
$(MESS_DRIVERS)/ngen.o \
|
$(MESS_DRIVERS)/ngen.o $(MESS_MACHINE)/ngen_kb.o \
|
||||||
$(MESS_DRIVERS)/octopus.o \
|
$(MESS_DRIVERS)/octopus.o \
|
||||||
$(MESS_DRIVERS)/onyx.o \
|
$(MESS_DRIVERS)/onyx.o \
|
||||||
$(MESS_DRIVERS)/okean240.o \
|
$(MESS_DRIVERS)/okean240.o \
|
||||||
|
Loading…
Reference in New Issue
Block a user