(MESS) More apollo updates [R. Belmont]

- Old 68681 is gone
- Apollo keyboard now speaks diserial
- Headless configs use the serial terminal device

nw: And Domain/OS still boots and X11 comes up and works.
This commit is contained in:
R. Belmont 2014-02-24 02:43:26 +00:00
parent 020c376df5
commit 04cca4aa91
5 changed files with 250 additions and 718 deletions

View File

@ -115,8 +115,6 @@ static int node_type;
// FIXME: value of ram_config_byte must match with default/selected RAM size
static UINT8 ram_config_byte;
static device_t *dsp_terminal = NULL;
static UINT32 log_line_counter = 0;
/***************************************************************************
@ -735,9 +733,9 @@ static ADDRESS_MAP_START(dn3500_map, AS_PROGRAM, 32, apollo_state )
AM_RANGE(0x010100, 0x0101ff) AM_READWRITE16(apollo_csr_control_register_r, apollo_csr_control_register_w, 0xffffffff)
AM_RANGE(0x010200, 0x0102ff) AM_READWRITE8(cache_status_register_r, cache_control_register_w, 0xffffffff )
AM_RANGE(0x010300, 0x0103ff) AM_READWRITE8(task_alias_register_r , task_alias_register_w , 0xffffffff )
AM_RANGE(0x010400, 0x0104ff) AM_DEVREADWRITE8_LEGACY(APOLLO_SIO_TAG, apollo_sio_r, apollo_sio_w, 0xffffffff )
AM_RANGE(0x010500, 0x0105ff) AM_DEVREADWRITE8(APOLLO_SIO2_TAG, duartn68681_device, read, write, 0xffffffff )
AM_RANGE(0x010800, 0x0108ff) AM_DEVREADWRITE8(APOLLO_PTM_TAG, ptm6840_device, read, write, 0xffffffff )
AM_RANGE(0x010400, 0x0104ff) AM_DEVREADWRITE8(APOLLO_SIO_TAG, duartn68681_device, read, write, 0x00ff00ff )
AM_RANGE(0x010500, 0x0105ff) AM_DEVREADWRITE8(APOLLO_SIO2_TAG, duartn68681_device, read, write, 0x00ff00ff )
AM_RANGE(0x010800, 0x0108ff) AM_DEVREADWRITE8(APOLLO_PTM_TAG, ptm6840_device, read, write, 0x00ff00ff )
AM_RANGE(0x010900, 0x0109ff) AM_READWRITE8(apollo_rtc_r, apollo_rtc_w, 0xffffffff )
AM_RANGE(0x010c00, 0x010cff) AM_READWRITE8(/*"dma1",*/apollo_dma_1_r, apollo_dma_1_w, 0xffffffff )
AM_RANGE(0x010d00, 0x010dff) AM_READWRITE8(/*"dma2",*/apollo_dma_2_r, apollo_dma_2_w, 0xffffffff )
@ -786,9 +784,9 @@ static ADDRESS_MAP_START(dsp3500_map, AS_PROGRAM, 32, apollo_state )
AM_RANGE(0x010100, 0x0101ff) AM_READWRITE16(apollo_csr_control_register_r, apollo_csr_control_register_w, 0xffffffff)
AM_RANGE(0x010200, 0x0102ff) AM_READWRITE8(cache_status_register_r, cache_control_register_w, 0xffffffff )
AM_RANGE(0x010300, 0x0103ff) AM_READWRITE8(task_alias_register_r , task_alias_register_w , 0xffffffff )
AM_RANGE(0x010400, 0x0104ff) AM_DEVREADWRITE8_LEGACY(APOLLO_SIO_TAG, apollo_sio_r, apollo_sio_w, 0xffffffff )
AM_RANGE(0x010500, 0x0105ff) AM_DEVREADWRITE8(APOLLO_SIO2_TAG, duartn68681_device, read, write, 0xffffffff )
AM_RANGE(0x010800, 0x0108ff) AM_DEVREADWRITE8(APOLLO_PTM_TAG, ptm6840_device, read, write, 0xffffffff )
AM_RANGE(0x010400, 0x0104ff) AM_DEVREADWRITE8(APOLLO_SIO_TAG, duartn68681_device, read, write, 0x00ff00ff )
AM_RANGE(0x010500, 0x0105ff) AM_DEVREADWRITE8(APOLLO_SIO2_TAG, duartn68681_device, read, write, 0x00ff00ff )
AM_RANGE(0x010800, 0x0108ff) AM_DEVREADWRITE8(APOLLO_PTM_TAG, ptm6840_device, read, write, 0x00ff00ff )
AM_RANGE(0x010900, 0x0109ff) AM_READWRITE8(apollo_rtc_r, apollo_rtc_w, 0xffffffff )
AM_RANGE(0x010c00, 0x010cff) AM_READWRITE8(/*"dma1",*/apollo_dma_1_r, apollo_dma_1_w, 0xffffffff )
AM_RANGE(0x010d00, 0x010dff) AM_READWRITE8(/*"dma2",*/apollo_dma_2_r, apollo_dma_2_w, 0xffffffff )
@ -831,8 +829,8 @@ static ADDRESS_MAP_START(dn3000_map, AS_PROGRAM, 32, apollo_state )
AM_RANGE(0x000000, 0x007fff) AM_WRITE(apollo_rom_w)
AM_RANGE(0x008000, 0x0080ff) AM_READWRITE16(apollo_csr_status_register_r, apollo_csr_status_register_w, 0xffffffff)
AM_RANGE(0x008100, 0x0081ff) AM_READWRITE16(apollo_csr_control_register_r, apollo_csr_control_register_w, 0xffffffff)
AM_RANGE(0x008400, 0x0087ff) AM_DEVREADWRITE8_LEGACY(APOLLO_SIO_TAG, apollo_sio_r, apollo_sio_w, 0xffffffff )
AM_RANGE(0x008800, 0x0088ff) AM_DEVREADWRITE8(APOLLO_PTM_TAG, ptm6840_device, read, write, 0xffffffff )
AM_RANGE(0x008400, 0x0087ff) AM_DEVREADWRITE8(APOLLO_SIO_TAG, duartn68681_device, read, write, 0x00ff00ff )
AM_RANGE(0x008800, 0x0088ff) AM_DEVREADWRITE8(APOLLO_PTM_TAG, ptm6840_device, read, write, 0x00ff00ff )
AM_RANGE(0x008900, 0x0089ff) AM_READWRITE8(apollo_rtc_r, apollo_rtc_w, 0xffffffff )
AM_RANGE(0x009000, 0x0090ff) AM_READWRITE8(/*"dma1",*/apollo_dma_1_r, apollo_dma_1_w, 0xffffffff )
@ -872,8 +870,8 @@ static ADDRESS_MAP_START(dsp3000_map, AS_PROGRAM, 32, apollo_state )
AM_RANGE(0x000000, 0x007fff) AM_WRITE(apollo_rom_w)
AM_RANGE(0x008000, 0x0080ff) AM_READWRITE16(apollo_csr_status_register_r, apollo_csr_status_register_w, 0xffffffff)
AM_RANGE(0x008100, 0x0081ff) AM_READWRITE16(apollo_csr_control_register_r, apollo_csr_control_register_w, 0xffffffff)
AM_RANGE(0x008400, 0x0087ff) AM_DEVREADWRITE8_LEGACY(APOLLO_SIO_TAG, apollo_sio_r, apollo_sio_w, 0xffffffff )
AM_RANGE(0x008800, 0x0088ff) AM_DEVREADWRITE8(APOLLO_PTM_TAG, ptm6840_device, read, write, 0xffffffff )
AM_RANGE(0x008400, 0x0087ff) AM_DEVREADWRITE8(APOLLO_SIO_TAG, duartn68681_device, read, write, 0x00ff00ff )
AM_RANGE(0x008800, 0x0088ff) AM_DEVREADWRITE8(APOLLO_PTM_TAG, ptm6840_device, read, write, 0x00ff00ff )
AM_RANGE(0x008900, 0x0089ff) AM_READWRITE8(apollo_rtc_r, apollo_rtc_w, 0xffffffff )
AM_RANGE(0x009000, 0x0090ff) AM_READWRITE8(/*"dma1",*/apollo_dma_1_r, apollo_dma_1_w, 0xffffffff )
@ -916,9 +914,9 @@ static ADDRESS_MAP_START(dn5500_map, AS_PROGRAM, 32, apollo_state )
AM_RANGE(0x010100, 0x0101ff) AM_READWRITE16(apollo_csr_control_register_r, apollo_csr_control_register_w, 0xffffffff)
AM_RANGE(0x010200, 0x0102ff) AM_READWRITE8(cache_status_register_r, cache_control_register_w, 0xffffffff )
AM_RANGE(0x010300, 0x0103ff) AM_READWRITE8(task_alias_register_r , task_alias_register_w , 0xffffffff )
AM_RANGE(0x010400, 0x0104ff) AM_DEVREADWRITE8_LEGACY(APOLLO_SIO_TAG, apollo_sio_r, apollo_sio_w, 0xffffffff )
AM_RANGE(0x010500, 0x0105ff) AM_DEVREADWRITE8(APOLLO_SIO2_TAG, duartn68681_device, read, write, 0xffffffff )
AM_RANGE(0x010800, 0x0108ff) AM_DEVREADWRITE8(APOLLO_PTM_TAG, ptm6840_device, read, write, 0xffffffff )
AM_RANGE(0x010400, 0x0104ff) AM_DEVREADWRITE8(APOLLO_SIO_TAG, duartn68681_device, read, write, 0x00ff00ff )
AM_RANGE(0x010500, 0x0105ff) AM_DEVREADWRITE8(APOLLO_SIO2_TAG, duartn68681_device, read, write, 0x00ff00ff )
AM_RANGE(0x010800, 0x0108ff) AM_DEVREADWRITE8(APOLLO_PTM_TAG, ptm6840_device, read, write, 0x00ff00ff )
AM_RANGE(0x010900, 0x0109ff) AM_READWRITE8(apollo_rtc_r, apollo_rtc_w, 0xffffffff )
AM_RANGE(0x010c00, 0x010cff) AM_READWRITE8(/*"dma1",*/apollo_dma_1_r, apollo_dma_1_w, 0xffffffff )
AM_RANGE(0x010d00, 0x010dff) AM_READWRITE8(/*"dma2",*/apollo_dma_2_r, apollo_dma_2_w, 0xffffffff )
@ -970,9 +968,9 @@ static ADDRESS_MAP_START(dsp5500_map, AS_PROGRAM, 32, apollo_state )
AM_RANGE(0x010100, 0x0101ff) AM_READWRITE16(apollo_csr_control_register_r, apollo_csr_control_register_w, 0xffffffff)
AM_RANGE(0x010200, 0x0102ff) AM_READWRITE8(cache_status_register_r, cache_control_register_w, 0xffffffff )
AM_RANGE(0x010300, 0x0103ff) AM_READWRITE8(task_alias_register_r , task_alias_register_w , 0xffffffff )
AM_RANGE(0x010400, 0x0104ff) AM_DEVREADWRITE8_LEGACY(APOLLO_SIO_TAG, apollo_sio_r, apollo_sio_w, 0xffffffff )
AM_RANGE(0x010500, 0x0105ff) AM_DEVREADWRITE8(APOLLO_SIO2_TAG, duartn68681_device, read, write, 0xffffffff )
AM_RANGE(0x010800, 0x0108ff) AM_DEVREADWRITE8(APOLLO_PTM_TAG, ptm6840_device, read, write, 0xffffffff )
AM_RANGE(0x010400, 0x0104ff) AM_DEVREADWRITE8(APOLLO_SIO_TAG, duartn68681_device, read, write, 0x00ff00ff )
AM_RANGE(0x010500, 0x0105ff) AM_DEVREADWRITE8(APOLLO_SIO2_TAG, duartn68681_device, read, write, 0x00ff00ff )
AM_RANGE(0x010800, 0x0108ff) AM_DEVREADWRITE8(APOLLO_PTM_TAG, ptm6840_device, read, write, 0x00ff00ff )
AM_RANGE(0x010900, 0x0109ff) AM_READWRITE8(apollo_rtc_r, apollo_rtc_w, 0xffffffff )
AM_RANGE(0x010c00, 0x010cff) AM_READWRITE8(/*"dma1",*/apollo_dma_1_r, apollo_dma_1_w, 0xffffffff )
AM_RANGE(0x010d00, 0x010dff) AM_READWRITE8(/*"dma2",*/apollo_dma_2_r, apollo_dma_2_w, 0xffffffff )
@ -1112,7 +1110,6 @@ DRIVER_INIT_MEMBER(apollo_state,dsp3500)
DRIVER_INIT_CALL( dn3500 );
// MLOG1(("driver_init_dsp3500"));
node_type = NODE_TYPE_DSP3500;
dsp_terminal = machine().device(TERMINAL_TAG);
}
DRIVER_INIT_MEMBER(apollo_state,dn3000)
@ -1132,7 +1129,6 @@ DRIVER_INIT_MEMBER(apollo_state,dsp3000)
DRIVER_INIT_CALL( dn3000 );
// MLOG1(("driver_init_dsp3000"));
node_type = NODE_TYPE_DSP3000;
dsp_terminal = machine().device(TERMINAL_TAG);
}
DRIVER_INIT_MEMBER(apollo_state,dn5500)
@ -1152,7 +1148,6 @@ DRIVER_INIT_MEMBER(apollo_state,dsp5500)
DRIVER_INIT_CALL( dn5500 );
// MLOG1(("driver_init_dsp5500"));
node_type = NODE_TYPE_DSP5500;
dsp_terminal = machine().device(TERMINAL_TAG);
}
/***************************************************************************
@ -1168,12 +1163,6 @@ static INPUT_PORTS_START( dsp3500 )
PORT_INCLUDE(apollo_config)
INPUT_PORTS_END
WRITE8_MEMBER( apollo_state::apollo_kbd_putchar ) {
// put keyboard character to the keyboard sio
// DLOG1(("apollo_kbd_putchar: 0x%02x", data));
apollo_sio_rx_data(machine().device(APOLLO_SIO_TAG), 0, data);
}
READ8_MEMBER( apollo_state::apollo_kbd_has_beeper ) {
return 1; // apollo_config(APOLLO_CONF_KBD_BEEPER);
}
@ -1183,32 +1172,10 @@ READ8_MEMBER( apollo_state::apollo_kbd_is_german ) {
}
static APOLLO_KBD_INTERFACE( apollo_kbd_config ) = {
DEVCB_DRIVER_MEMBER(apollo_state, apollo_kbd_putchar),
DEVCB_DRIVER_MEMBER(apollo_state, apollo_kbd_has_beeper),
DEVCB_DRIVER_MEMBER(apollo_state, apollo_kbd_is_german)
};
WRITE8_MEMBER( apollo_state::terminal_kbd_putchar ) {
// put input character from terminal to the RS232 sio (i.e. sio1)
//DLOG1(("terminal_kbd_putchar: 0x%02x", data));
// FIXME: as of mess0145u1, terminal.c will append a null character after each input character
if (data != 0)
{
apollo_sio_rx_data(machine().device(APOLLO_SIO_TAG), 1, data);
}
}
static GENERIC_TERMINAL_INTERFACE( apollo_terminal_config ) {
DEVCB_DRIVER_MEMBER(apollo_state, terminal_kbd_putchar)
};
void apollo_terminal_write(UINT8 data) {
if (dsp_terminal != NULL) {
// output data to the terminal emulator
dynamic_cast<generic_terminal_device *>(dsp_terminal)->write(dsp_terminal->machine().driver_data()->generic_space(), 0, data);
}
}
/***************************************************************************
MACHINE DRIVERS
***************************************************************************/
@ -1219,7 +1186,6 @@ static MACHINE_CONFIG_START( dn3500, apollo_state )
MCFG_CPU_PROGRAM_MAP(dn3500_map)
MCFG_QUANTUM_TIME(attotime::from_hz(60))
MCFG_FRAGMENT_ADD( apollo )
/* keyboard beeper */
@ -1233,26 +1199,39 @@ static MACHINE_CONFIG_START( dn3500, apollo_state )
MCFG_RAM_EXTRA_OPTIONS("4M,8M,16M,32M")
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( dsp3500, dn3500 )
// strange: MCFG_CPU_PROGRAM_MAP will fail w/o MCFG_CPU_REPLACE
MCFG_CPU_REPLACE(MAINCPU, M68030, 25000000) /* 25 MHz 68030 */
static MACHINE_CONFIG_START( dsp3500, apollo_state )
MCFG_CPU_ADD(MAINCPU, M68030, 25000000) /* 25 MHz 68030 */
MCFG_CPU_PROGRAM_MAP(dsp3500_map)
MCFG_QUANTUM_TIME(attotime::from_hz(60))
MCFG_FRAGMENT_ADD( apollo_terminal )
/* keyboard beeper */
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_SOUND_ADD("beep", BEEP, 0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
/* internal ram */
MCFG_RAM_ADD("messram")
MCFG_RAM_DEFAULT_SIZE("8M")
MCFG_RAM_EXTRA_OPTIONS("4M,8M,16M,32M")
/* terminal hardware */
MCFG_DEFAULT_LAYOUT( layout_apollo_dsp )
// MCFG_FRAGMENT_ADD( generic_terminal )
MCFG_GENERIC_TERMINAL_ADD(TERMINAL_TAG, apollo_terminal_config)
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( dn3500_19i, dn3500 )
/* video hardware 19" monochrome */
MCFG_APOLLO_MONO19I_ADD(APOLLO_SCREEN_TAG)
MCFG_APOLLO_KBD_ADD( APOLLO_KBD_TAG, apollo_kbd_config )
MCFG_APOLLO_KBD_TX_CALLBACK(DEVWRITELINE(APOLLO_SIO_TAG, duartn68681_device, rx_a_w))
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( dn3500_15i, dn3500 )
/* video hardware is 15" monochrome or color */
MCFG_APOLLO_GRAPHICS_ADD(APOLLO_SCREEN_TAG)
MCFG_APOLLO_KBD_ADD( APOLLO_KBD_TAG, apollo_kbd_config )
MCFG_APOLLO_KBD_TX_CALLBACK(DEVWRITELINE(APOLLO_SIO_TAG, duartn68681_device, rx_a_w))
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( dn3000, dn3500 )
@ -1264,54 +1243,77 @@ static MACHINE_CONFIG_DERIVED( dn3000, dn3500 )
MCFG_RAM_EXTRA_OPTIONS("4M")
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( dsp3000, dn3000 )
// strange: MCFG_CPU_PROGRAM_MAP will fail w/o MCFG_CPU_REPLACE
MCFG_CPU_REPLACE(MAINCPU, M68020PMMU, 12000000) /* 12 MHz */
static MACHINE_CONFIG_START( dsp3000, apollo_state )
MCFG_CPU_ADD(MAINCPU, M68020PMMU, 12000000) /* 12 MHz */
MCFG_CPU_PROGRAM_MAP(dsp3000_map)
MCFG_QUANTUM_TIME(attotime::from_hz(60))
MCFG_FRAGMENT_ADD( apollo_terminal )
/* keyboard beeper */
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_SOUND_ADD("beep", BEEP, 0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
/* internal ram */
MCFG_RAM_ADD("messram")
MCFG_RAM_DEFAULT_SIZE("8M")
MCFG_RAM_EXTRA_OPTIONS("4M")
MCFG_DEVICE_REMOVE( APOLLO_SIO2_TAG )
MCFG_RAM_MODIFY("messram")
/* terminal hardware */
MCFG_DEFAULT_LAYOUT( layout_apollo_dsp )
// MCFG_FRAGMENT_ADD( generic_terminal )
MCFG_GENERIC_TERMINAL_ADD(TERMINAL_TAG, apollo_terminal_config)
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( dn3000_19i, dn3000 )
/* video hardware 19" monochrome */
MCFG_APOLLO_MONO19I_ADD(APOLLO_SCREEN_TAG)
MCFG_APOLLO_KBD_ADD( APOLLO_KBD_TAG, apollo_kbd_config )
MCFG_APOLLO_KBD_TX_CALLBACK(DEVWRITELINE(APOLLO_SIO_TAG, duartn68681_device, rx_a_w))
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( dn3000_15i, dn3000 )
/* video hardware 15" monochrome */
MCFG_APOLLO_GRAPHICS_ADD(APOLLO_SCREEN_TAG)
MCFG_APOLLO_KBD_ADD( APOLLO_KBD_TAG, apollo_kbd_config )
MCFG_APOLLO_KBD_TX_CALLBACK(DEVWRITELINE(APOLLO_SIO_TAG, duartn68681_device, rx_a_w))
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( dn5500, dn3500 )
MCFG_CPU_REPLACE(MAINCPU, M68040, 25000000) /* 25 MHz */
MCFG_CPU_PROGRAM_MAP(dn5500_map)
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( dsp5500, dn5500 )
// strange: MCFG_CPU_PROGRAM_MAP will fail w/o MCFG_CPU_REPLACE
MCFG_CPU_REPLACE(MAINCPU, M68040, 25000000) /* 25 MHz */
static MACHINE_CONFIG_START( dsp5500, apollo_state )
MCFG_CPU_ADD(MAINCPU, M68040, 25000000) /* 25 MHz */
MCFG_CPU_PROGRAM_MAP(dsp5500_map)
MCFG_QUANTUM_TIME(attotime::from_hz(60))
MCFG_FRAGMENT_ADD(apollo_terminal)
/* keyboard beeper */
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_SOUND_ADD("beep", BEEP, 0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
/* terminal hardware */
MCFG_DEFAULT_LAYOUT( layout_apollo_dsp )
// MCFG_FRAGMENT_ADD( generic_terminal )
MCFG_GENERIC_TERMINAL_ADD(TERMINAL_TAG, apollo_terminal_config)
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( dn5500_19i, dn5500 )
/* video hardware 19" monochrome */
MCFG_APOLLO_MONO19I_ADD(APOLLO_SCREEN_TAG)
MCFG_APOLLO_KBD_ADD( APOLLO_KBD_TAG, apollo_kbd_config )
MCFG_APOLLO_KBD_TX_CALLBACK(DEVWRITELINE(APOLLO_SIO_TAG, duartn68681_device, rx_a_w))
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( dn5500_15i, dn5500 )
/* video hardware 15" monochrome */
MCFG_APOLLO_GRAPHICS_ADD(APOLLO_SCREEN_TAG)
MCFG_APOLLO_KBD_ADD( APOLLO_KBD_TAG, apollo_kbd_config )
MCFG_APOLLO_KBD_TX_CALLBACK(DEVWRITELINE(APOLLO_SIO_TAG, duartn68681_device, rx_a_w))
MACHINE_CONFIG_END
/***************************************************************************

View File

@ -17,13 +17,13 @@
#include "emu.h"
#include "cpu/m68000/m68000.h"
#include "bus/rs232/rs232.h"
#include "machine/terminal.h"
#include "machine/ram.h"
#include "machine/omti8621.h"
#include "machine/sc499.h"
#include "machine/3c505.h"
#include "machine/6840ptm.h"
#include "machine/68681.h"
#include "machine/n68681.h"
#include "machine/pc_fdc.h"
#include "machine/am9517a.h"
@ -130,7 +130,9 @@ public:
m_pic8259_master(*this, "pic8259_master"),
m_pic8259_slave(*this, "pic8259_slave"),
m_ptm(*this, APOLLO_PTM_TAG),
m_sio2(*this, APOLLO_SIO2_TAG)
m_sio(*this, APOLLO_SIO_TAG),
m_sio2(*this, APOLLO_SIO2_TAG),
m_rtc(*this, APOLLO_RTC_TAG)
{ }
required_device<m68000_base_device> m_maincpu;
@ -142,7 +144,9 @@ public:
required_device<pic8259_device> m_pic8259_master;
required_device<pic8259_device> m_pic8259_slave;
required_device<ptm6840_device> m_ptm;
required_device<duartn68681_device> m_sio;
optional_device<duartn68681_device> m_sio2;
required_device<mc146818_device> m_rtc;
DECLARE_WRITE16_MEMBER(apollo_csr_status_register_w);
DECLARE_READ16_MEMBER(apollo_csr_status_register_r);
@ -213,7 +217,6 @@ public:
DECLARE_WRITE8_MEMBER( apollo_kbd_putchar );
DECLARE_READ8_MEMBER( apollo_kbd_has_beeper );
DECLARE_READ8_MEMBER( apollo_kbd_is_german );
DECLARE_WRITE8_MEMBER( terminal_kbd_putchar );
DECLARE_READ8_MEMBER( apollo_dma8237_ctape_dack_r );
DECLARE_WRITE8_MEMBER( apollo_dma8237_ctape_dack_w );
DECLARE_READ8_MEMBER( apollo_dma8237_fdc_dack_r );
@ -225,6 +228,8 @@ public:
DECLARE_WRITE_LINE_MEMBER( apollo_dma_2_hrq_changed );
DECLARE_WRITE_LINE_MEMBER( apollo_pic8259_master_set_int_line );
DECLARE_WRITE_LINE_MEMBER( apollo_pic8259_slave_set_int_line );
DECLARE_WRITE_LINE_MEMBER( sio_irq_handler );
DECLARE_WRITE8_MEMBER( sio_output );
DECLARE_WRITE_LINE_MEMBER( sio2_irq_handler );
DECLARE_WRITE_LINE_MEMBER( apollo_ptm_irq_function );
DECLARE_WRITE_LINE_MEMBER( apollo_ptm_timer_tick );
@ -232,9 +237,11 @@ public:
private:
UINT32 ptm_counter;
UINT8 sio_output_data;
};
MACHINE_CONFIG_EXTERN( apollo );
MACHINE_CONFIG_EXTERN( apollo_terminal );
/*----------- machine/apollo_config.c -----------*/
@ -300,13 +307,6 @@ DECLARE_READ8_DEVICE_HANDLER( apollo_pic8259_slave_r );
/*----------- machine/apollo_rtc.c -----------*/
/*----------- machine/apollo_sio.c -----------*/
void apollo_sio_rx_data( device_t* device, int ch, UINT8 data );
DECLARE_READ8_DEVICE_HANDLER(apollo_sio_r);
DECLARE_WRITE8_DEVICE_HANDLER(apollo_sio_w);
/*----------- machine/apollo_fdc.c -----------*/

View File

@ -22,6 +22,10 @@
* - http://www.bitsavers.org/pdf/apollo/008778-03_DOMAIN_Series_3000_4000_Technical_Reference_Aug87.pdf
* - http://www.freescale.com/files/32bit/doc/inactive/MC68681UM.pdf
*
* SIO usage:
* SIO: ch A keyboard, ch B serial console
* SIO2: modem/printer?
*
*/
#include "includes/apollo.h"
@ -191,10 +195,10 @@ static UINT16 cpu_control_register = 0x0000;
apollo_csr_get/set_servicemode
-------------------------------------------------*/
static int apollo_csr_get_servicemode()
/*static int apollo_csr_get_servicemode()
{
return cpu_status_register & APOLLO_CSR_SR_SERVICE ? 0 : 1;
}
}*/
static void apollo_csr_set_servicemode(int mode)
{
@ -780,7 +784,8 @@ static const ptm6840_interface apollo_ptm_config = {
DN3000/DN3500 Realtime Calendar MC146818 at 0x8900/0x10900
***************************************************************************/
static DEVICE_RESET( apollo_rtc ) {
static DEVICE_RESET( apollo_rtc )
{
address_space &space = device->machine().device(MAINCPU)->memory().space(AS_PROGRAM);
apollo_state *state = device->machine().driver_data<apollo_state>();
UINT8 year = state->apollo_rtc_r(space, 9);
@ -802,9 +807,8 @@ static DEVICE_RESET( apollo_rtc ) {
WRITE8_MEMBER(apollo_state::apollo_rtc_w)
{
mc146818_device *rtc = machine().device<mc146818_device> (APOLLO_RTC_TAG);
rtc->write(space, 0, offset);
rtc->write(space, 1, data);
m_rtc->write(space, 0, offset);
m_rtc->write(space, 1, data);
if (offset >= 0x0b && offset <= 0x0c)
{
SLOG2(("writing MC146818 at offset %02x = %02x", offset, data));
@ -814,9 +818,8 @@ WRITE8_MEMBER(apollo_state::apollo_rtc_w)
READ8_MEMBER(apollo_state::apollo_rtc_r)
{
UINT8 data;
mc146818_device *rtc = machine().device<mc146818_device> (APOLLO_RTC_TAG);
rtc->write(space, 0, offset);
data = rtc->read(space, 1);
m_rtc->write(space, 0, offset);
data = m_rtc->read(space, 1);
if (offset >= 0x0b && offset <= 0x0c)
{
SLOG2(("reading MC146818 at offset %02x = %02x", offset, data));
@ -841,298 +844,30 @@ static TIMER_CALLBACK( apollo_rtc_timer )
// machine/apollo_sio.c - APOLLO DS3500 SIO
//##########################################################################
#undef VERBOSE
#define VERBOSE 0
#define SIO_SLEEP_DELAY_TIME 30000 // ms
static int isInitialized = 0;
static int input_from_stdin = 0;
static UINT8 sio_input_data = 0xff;
static UINT8 sio_output_data = 0xff;
static emu_timer *kbd_timer;
static int sleep_time = 0;
static int sio_irq_line = 0;
static UINT8 sio_csrb = 0;
/*-------------------------------------------------
sio_sleep - sleep to reduce the CPU usage
-------------------------------------------------*/
// we reduce the CPU usage, if SRB is being polled for input
// but only as long as the transmitter is empty and ready
// and the initial delay time has passed w/o IO
static void sio_sleep(int delay) {
if (!apollo_config(APOLLO_CONF_IDLE_SLEEP)) {
// nothing to do; sleeping is not enabled
} else if (delay <= 0) {
//reset the sleep delay time
if (sleep_time > 0) {
LOG2(("sio_sleep: sleeping stopped"))
sleep_time = 0;
}
} else if (sleep_time < delay) {
// sleep delay pending (i.e. don't sleep)
sleep_time++;
} else {
if (sleep_time == delay) {
LOG2(("sio_sleep: sleeping started after %d ms",sleep_time));
sleep_time++;
}
// Note: ticks_per_second/100 will sleep for 6 ms (= 4-10 ms)
osd_sleep(osd_ticks_per_second() / 50);
}
WRITE_LINE_MEMBER(apollo_state::sio_irq_handler)
{
apollo_pic_set_irq_line(this, APOLLO_IRQ_SIO1, state);
}
/*-------------------------------------------------
apollo_sio_rx_data - get character from keyboard/stdin
-------------------------------------------------*/
void apollo_sio_rx_data(device_t* device, int ch, UINT8 data) {
// omit logging for channel 1
if (ch == 0) {
DLOG1(("apollo_sio_rx_data ch=%d <- data=%02x", ch, data ));
}
if (ch == 1 && !isInitialized && data == '\r' && apollo_csr_get_servicemode()) {
// force baudrate recognition
data = 0xff;
isInitialized = 1;
}
duart68681_rx_data(device, ch, data);
}
/*-------------------------------------------------
apollo_sio_tx_data - put character to display/stdout
-------------------------------------------------*/
static void apollo_sio_tx_data(device_t *device, int channel, UINT8 data) {
if (channel == 0) {
DLOG1(("apollo_sio_tx_data ch=%d -> data=%02x", channel, data ));
device_t *keyboard = device->machine().device( APOLLO_KBD_TAG );
if (keyboard != NULL) {
apollo_kbd_getchar(keyboard, data);
}
} else if (channel == 1) {
DLOG2(("apollo_sio_tx_data ch=%d -> data=%02x", channel, data ));
if (data != '\r') {
// output data to stdout
putchar(data);
fflush(stdout);
if (apollo_is_dsp3x00()) {
// output data to terminal emulator
apollo_terminal_write(data);
}
}
}
}
/*-------------------------------------------------
sio configuration
-------------------------------------------------*/
static void sio_irq_handler(device_t *device, int state, UINT8 vector) {
DLOG2(("sio_irq_handler: vector=%02x", vector ));
apollo_pic_set_irq_line(device, APOLLO_IRQ_SIO1, state);
sio_irq_line = 1;
}
static UINT8 sio_input(device_t *device) {
// necessary for DN3000?
// sio_input_data = sio_input_data ? 0 : 0x0f;
DLOG2(("reading 2681 input: %02x", sio_input_data ));
return sio_input_data;
}
static void sio_output(device_t *device, UINT8 data) {
DLOG1(("writing 2681 output: %02x", data ));
if ((data & 0x80) != (sio_output_data & 0x80)) {
apollo_pic_set_irq_line(device, APOLLO_IRQ_DIAG, (data & 0x80) ? 1 : 0);
WRITE8_MEMBER(apollo_state::sio_output)
{
if ((data & 0x80) != (sio_output_data & 0x80))
{
apollo_pic_set_irq_line(this, APOLLO_IRQ_DIAG, (data & 0x80) ? 1 : 0);
sio_output_data = data;
}
}
const duart68681_config apollo_sio_config = {
sio_irq_handler,
apollo_sio_tx_data,
sio_input,
sio_output
};
/*-------------------------------------------------
DN3000/DS3500 SIO at 0x8400/0x10400
-------------------------------------------------*/
READ8_DEVICE_HANDLER(apollo_sio_r) {
static int last_read8_offset[2] = { -1, -1 };
static int last_read8_value[2] = { -1, -1 };
static const char * const duart68681_reg_read_names[0x10] = { "MRA", "SRA",
"BRG Test", "RHRA", "IPCR", "ISR", "CTU", "CTL", "MRB", "SRB",
"1X/16X Test", "RHRB", "IVR", "Input Ports", "Start Counter",
"Stop Counter" };
int data = duart68681_r(device, space, offset / 2);
if (sio_irq_line) {
apollo_pic_set_irq_line(device, APOLLO_IRQ_SIO1, 0);
sio_irq_line = 0;
}
switch (offset / 2) {
case 0x0b: /* RHRB */
if (data == 0x0d && sio_csrb == 0x77) {
// special for MD command SK (Select keyboard) with baudrate set to 2000
data = 0xff;
}
break;
}
// omit logging if sio is being polled from the boot rom
if ((offset != last_read8_offset[1] || data != last_read8_value[1])
&& (offset != last_read8_offset[0] || data != last_read8_value[0])) {
last_read8_offset[0] = last_read8_offset[1];
last_read8_value[0] = last_read8_value[1];
last_read8_offset[1] = offset;
last_read8_value[1] = data;
DLOG2(("reading 2681 reg %x (%s) returned %02x",
offset, duart68681_reg_read_names[offset/2], data ));
}
return data;
}
WRITE8_DEVICE_HANDLER(apollo_sio_w)
{
static const char * const duart68681_reg_write_names[0x10] = { "MRA",
"CSRA", "CRA", "THRA", "ACR", "IMR", "CRUR", "CTLR", "MRB", "CSRB",
"CRB", "THRB", "IVR", "OPCR", "Set OP Bits", "Reset OP Bits" };
if (sio_irq_line) {
apollo_pic_set_irq_line(device, APOLLO_IRQ_SIO1, 0);
sio_irq_line = 0;
}
// don't log THRB
if (offset != 0x17) {
DLOG2(("writing 2681 reg %x (%s) with %02x", offset, duart68681_reg_write_names[(offset/2) & 15], data ));
}
switch (offset / 2) {
case 0x09: /* CSRB */
// remember CSRB to handle MD command SK on DSP3x00
sio_csrb = data;
break;
case 0x0b: /* THRB */
// stop sleeping
sio_sleep(0);
break;
case 0x0d: /* OPCR */
if ((data & 0x0c) == 0x04) {
// Unhandled OPCR value; used for RAM refresh circuit
// ignore value; omit error message
data &= ~0x0c;
}
break;
}
duart68681_w(device, space, offset / 2, data);
}
/*-------------------------------------------------
kbd tty timer callback
-------------------------------------------------*/
static TIMER_CALLBACK(kbd_timer_callback)
{
#if defined(APOLLO_FOR_LINUX)
device_t *device = (device_t *) ptr;
address_space &space = device->machine().device(MAINCPU)->memory().space(AS_PROGRAM);
UINT8 data;
#define SRA 0x01
#define SRB 0x09
if (!(duart68681_r(device, space, SRB) & 0x02))
{
// Channel B FIFO not yet full (STATUS_FIFO_FULL)
if (read(STDIN_FILENO, &data, 1) == 1)
{
apollo_sio_rx_data(device, 1, data == '\n' ? '\r' : data);
input_from_stdin = 1;
// stop sleeping to reduce CPU usage
sio_sleep(0);
}
else if (input_from_stdin && (duart68681_r(device, space, SRB) & 0x0c) == 0x0c)
{
// we reduce the CPU usage, if SRB is being polled for input
// but only as long as the transmitter is empty and ready
// and the initial delay time has has passed
sio_sleep(SIO_SLEEP_DELAY_TIME);
}
}
#endif
// The counter/timer on the SIO chip is used for the refresh count.
// This is set up in the timer mode to produce a square wave output on output OP3.
// The period of the output is 15 microseconds.
// toggle memory refresh counter
sio_input_data ^= 0x01;
}
/*-------------------------------------------------
device start callback
-------------------------------------------------*/
static DEVICE_START(apollo_sio)
{
kbd_timer = device->machine().scheduler().timer_alloc(FUNC(kbd_timer_callback), device);
}
/*-------------------------------------------------
device reset callback
-------------------------------------------------*/
static DEVICE_RESET(apollo_sio)
{
DLOG1(("reset apollo_sio"));
isInitialized = 0;
input_from_stdin = 0;
sleep_time = 0;
sio_input_data = apollo_get_ram_config_byte();
sio_output_data = 0xff;
#if defined(APOLLO_FOR_LINUX)
// FIXME: unavailable in mingw
// set stdin to nonblocking to allow polling in sio_poll_rxb
fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL) | O_NONBLOCK);
#endif
// start the keyboard timer
kbd_timer->adjust( attotime::zero, 0, attotime::from_msec(1));
}
// sio_input_data ^= 0x01;
//##########################################################################
// machine/apollo_sio2.c - APOLLO DS3500 SIO2
//##########################################################################
#undef VERBOSE
#define VERBOSE 0
/*-------------------------------------------------
sio2 configuration (DN3500 only)
-------------------------------------------------*/
WRITE_LINE_MEMBER(apollo_state::sio2_irq_handler)
{
apollo_pic_set_irq_line(this, APOLLO_IRQ_SIO2, state);
@ -1243,7 +978,7 @@ static const sc499_interface apollo_ctape_config = {
#undef VERBOSE
#define VERBOSE 0
MACHINE_CONFIG_FRAGMENT( apollo )
MACHINE_CONFIG_FRAGMENT( common )
// configuration MUST be reset first !
MCFG_DEVICE_ADD(APOLLO_CONF_TAG, APOLLO_CONF, 0)
@ -1258,7 +993,6 @@ MACHINE_CONFIG_FRAGMENT( apollo )
MCFG_MC146818_ADD( APOLLO_RTC_TAG, XTAL_32_768kHz )
MCFG_MC146818_UTC( true )
MCFG_DUART68681_ADD( APOLLO_SIO_TAG, XTAL_3_6864MHz, apollo_sio_config )
MCFG_DUARTN68681_ADD( APOLLO_SIO2_TAG, XTAL_3_6864MHz )
MCFG_DUARTN68681_IRQ_CALLBACK(WRITELINE(apollo_state, sio2_irq_handler))
@ -1271,6 +1005,39 @@ MACHINE_CONFIG_FRAGMENT( apollo )
MCFG_THREECOM3C505_ADD(APOLLO_ETH_TAG, apollo_3c505_config)
MACHINE_CONFIG_END
// for machines with the keyboard and a graphics head
MACHINE_CONFIG_FRAGMENT( apollo )
MCFG_FRAGMENT_ADD(common)
MCFG_DUARTN68681_ADD( APOLLO_SIO_TAG, XTAL_3_6864MHz )
MCFG_DUARTN68681_IRQ_CALLBACK(WRITELINE(apollo_state, sio_irq_handler))
MCFG_DUARTN68681_OUTPORT_CALLBACK(WRITE8(apollo_state, sio_output))
MCFG_DUARTN68681_A_TX_CALLBACK(DEVWRITELINE(APOLLO_KBD_TAG, apollo_kbd_device, rx_w))
MACHINE_CONFIG_END
static DEVICE_INPUT_DEFAULTS_START( apollo_terminal )
DEVICE_INPUT_DEFAULTS( "TERM_TXBAUD", 0xff, 0x06 ) // 9600
DEVICE_INPUT_DEFAULTS( "TERM_RXBAUD", 0xff, 0x06 ) // 9600
DEVICE_INPUT_DEFAULTS( "TERM_STARTBITS", 0xff, 0x01 ) // 1
DEVICE_INPUT_DEFAULTS( "TERM_DATABITS", 0xff, 0x03 ) // 8
DEVICE_INPUT_DEFAULTS( "TERM_PARITY", 0xff, 0x00 ) // N
DEVICE_INPUT_DEFAULTS( "TERM_STOPBITS", 0xff, 0x01 ) // 1
DEVICE_INPUT_DEFAULTS_END
// for headless machines using a serial console
MACHINE_CONFIG_FRAGMENT( apollo_terminal )
MCFG_FRAGMENT_ADD(common)
MCFG_DUARTN68681_ADD( APOLLO_SIO_TAG, XTAL_3_6864MHz )
MCFG_DUARTN68681_IRQ_CALLBACK(WRITELINE(apollo_state, sio_irq_handler))
MCFG_DUARTN68681_OUTPORT_CALLBACK(WRITE8(apollo_state, sio_output))
MCFG_DUARTN68681_B_TX_CALLBACK(DEVWRITELINE("rs232", rs232_port_device, write_txd))
MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "serial_terminal")
MCFG_RS232_RXD_HANDLER(DEVWRITELINE(APOLLO_SIO_TAG, duartn68681_device, rx_b_w))
MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("serial_terminal", apollo_terminal)
MACHINE_CONFIG_END
DRIVER_INIT_MEMBER(apollo_state,apollo)
{
//MLOG1(("driver_init_apollo"));
@ -1287,8 +1054,6 @@ MACHINE_START_MEMBER(apollo_state,apollo)
// motor is on, floppy disk is ready
fdc->fdc->ready_w(1);
device_start_apollo_sio(machine().device(APOLLO_SIO_TAG));
if (apollo_is_dn3000())
{
//MLOG1(("faking mc146818 interrupts (DN3000 only)"));
@ -1305,7 +1070,7 @@ MACHINE_RESET_MEMBER(apollo_state,apollo)
apollo_csr_set_servicemode(apollo_config(APOLLO_CONF_SERVICE_MODE));
device_reset_apollo_rtc(machine().device(APOLLO_RTC_TAG));
device_reset_apollo_sio(machine().device(APOLLO_SIO_TAG));
ptm_counter = 0;
sio_output_data = 0xff;
}

View File

@ -16,16 +16,6 @@
#include "machine/apollo_kbd.h"
#include "sound/beep.h"
#if defined(APOLLO_FOR_LINUX)
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
// on linux we may attach a real Apollo keyboard at /dev/ttyS0
#include <termios.h>
#include <sys/ioctl.h>
#define KBD_TTY_NAME "/dev/ttyS0"
#endif
#define LOG(x) { logerror ("%s apollo_kbd: ", m_device->cpu_context()); logerror x; logerror ("\n"); }
#define LOG1(x) { if (VERBOSE > 0) LOG(x)}
#define LOG2(x) { if (VERBOSE > 1) LOG(x)}
@ -73,7 +63,9 @@ const device_type APOLLO_KBD = &device_creator<apollo_kbd_device>;
//-------------------------------------------------
apollo_kbd_device::apollo_kbd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, APOLLO_KBD, "Apollo Keyboard", tag, owner, clock, "apollo_kbd", __FILE__)
: device_t(mconfig, APOLLO_KBD, "Apollo Keyboard", tag, owner, clock, "apollo_kbd", __FILE__),
device_serial_interface(mconfig, *this),
m_tx_w(*this)
{
memset(static_cast<apollo_kbd_interface *>(this), 0, sizeof(apollo_kbd_interface));
}
@ -98,14 +90,13 @@ void apollo_kbd_device::device_start()
m_device = this;
LOG1(("start apollo_kbd"));
m_putchar.resolve(apollo_kbd_putchar_cb, *this);
m_tx_w.resolve_safe();
m_has_beeper.resolve(apollo_kbd_has_beeper_cb, *this);
m_is_german.resolve(apollo_kbd_is_german_cb, *this);
m_beeper.start(this);
m_mouse.start(this);
m_tx_fifo.start(this);
m_keyboard_tty.start(this);
m_io_keyboard1 = machine().root_device().ioport("keyboard1");
m_io_keyboard2 = machine().root_device().ioport("keyboard2");
@ -115,7 +106,7 @@ void apollo_kbd_device::device_start()
m_io_mouse2 = machine().root_device().ioport("mouse2");
m_io_mouse3 = machine().root_device().ioport("mouse3");
m_timer = machine().scheduler().timer_alloc(FUNC(static_poll_callback), this);
m_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(apollo_kbd_device::kbd_scan_timer), this));
}
//-------------------------------------------------
@ -128,8 +119,6 @@ void apollo_kbd_device::device_reset()
m_beeper.reset();
m_mouse.reset();
m_tx_fifo.reset();
m_keyboard_tty.reset();
// init keyboard
m_loopback_mode = 1;
@ -142,6 +131,19 @@ void apollo_kbd_device::device_reset()
// start timer
m_timer->adjust( attotime::zero, 0, attotime::from_msec(5)); // every 5ms
// keyboard comms is at 8E1, 1200 baud
set_data_frame(1, 8, PARITY_EVEN, STOP_BITS_1);
set_rcv_rate(1200);
set_tra_rate(1200);
m_tx_busy = false;
m_xmit_read = m_xmit_write = 0;
}
void apollo_kbd_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
device_serial_interface::device_timer(timer, id, param, ptr);
}
/***************************************************************************
@ -311,240 +313,20 @@ void apollo_kbd_device::mouse::read_mouse()
mouse_data_size = 3;
}
if (m_device->m_tx_fifo.putdata(mouse_data, mouse_data_size))
for (int md = 0; md < mouse_data_size; md++)
{
// mouse data submitted; update current mouse state
m_last_b = b;
m_last_x += dx;
m_last_y += dy;
m_device->xmit_char(mouse_data[md]);
}
// mouse data submitted; update current mouse state
m_last_b = b;
m_last_x += dx;
m_last_y += dy;
m_tx_pending = 100; // mouse data packet will take 40 ms
}
}
}
//**************************************************************************
// tx fifo
//**************************************************************************
apollo_kbd_device::tx_fifo::tx_fifo() :
m_device(NULL),
m_timer(NULL)
{
}
void apollo_kbd_device::tx_fifo::start(apollo_kbd_device *device)
{
m_device = device;
LOG2(("start apollo_kbd::tx_fifo"));
m_timer = m_device->machine().scheduler().timer_alloc(FUNC(static_timer_callback), this);
}
void apollo_kbd_device::tx_fifo::reset()
{
LOG2(("reset apollo_kbd::tx_fifo"));
memset(fifo, 0, sizeof(fifo));
m_read_ptr = 0;
m_write_ptr = 0;
m_char_count = 0;
m_tx_pending = 0;
m_baud_rate = 1200;
// reset timer
m_timer->adjust(attotime::never, 0);
}
UINT8 apollo_kbd_device::tx_fifo::getchar()
{
UINT8 data;
if (m_char_count == 0)
{
LOG(("apollo_kbd FIFO underflow"));
data = 0x0;
}
else
{
data = fifo[m_read_ptr++];
if (m_read_ptr == TX_FIFO_SIZE)
{
m_read_ptr = 0;
}
m_char_count--;
}
return data;
}
void apollo_kbd_device::tx_fifo::putchar(UINT8 data)
{
if (m_char_count >= TX_FIFO_SIZE)
{
LOG(("apollo_kbd FIFO overflow"));
}
else
{
fifo[m_write_ptr++] = data;
if (m_write_ptr == TX_FIFO_SIZE)
{
m_write_ptr = 0;
}
m_char_count++;
if ( m_tx_pending == 0)
{
flush();
}
}
}
int apollo_kbd_device::tx_fifo::putdata(const UINT8 *data, int data_length)
{
if (m_char_count + data_length >= TX_FIFO_SIZE-5)
{
// tx fifo is full
return 0;
}
else
{
while (data_length-- > 0) {
putchar(*data++);
}
return 1;
}
}
void apollo_kbd_device::tx_fifo::flush()
{
if (m_char_count > 0)
{
m_tx_pending = 1;
if (!m_device->m_putchar.isnull())
m_device->m_putchar(0, getchar());
// 11 = one start, 8 data, one parity (even), one stop bit
m_timer->adjust(attotime::from_hz(m_baud_rate / 11), 0);
}
else
{
m_tx_pending = 0;
// m_timer->adjust(attotime::never, 0);
}
}
void apollo_kbd_device::tx_fifo::timer_callback()
{
flush();
}
TIMER_CALLBACK( apollo_kbd_device::tx_fifo::static_timer_callback )
{
reinterpret_cast<apollo_kbd_device::tx_fifo *> (ptr)->timer_callback();
}
//**************************************************************************
// Real Apollo keyboard connected at the keyboard tty (i.e. /dev/ttyS0)
//**************************************************************************
apollo_kbd_device::keyboard_tty::keyboard_tty() :
m_device(NULL),
#if defined(KBD_TTY_NAME)
m_tty_name(NULL),
m_tty_fd(-1),
#endif
m_connected(0)
{
}
void apollo_kbd_device::keyboard_tty::start(apollo_kbd_device *device)
{
m_device = device;
LOG2(("start apollo_kbd::keyboard_tty"));
#if defined(KBD_TTY_NAME)
m_tty_name = KBD_TTY_NAME;
#endif
}
void apollo_kbd_device::keyboard_tty::reset()
{
LOG2(("reset apollo_kbd::keyboard_tty"));
m_connected = 0;
#if defined(KBD_TTY_NAME)
/* Open the tty line */
m_tty_fd = open(m_tty_name, 2);
if (m_tty_fd < 0)
{
LOG1(("failed to open %s", m_tty_name));
}
else
{
int serial;
struct termios tty_mode;
// set nonblocking mode
fcntl(m_tty_fd, F_SETFL, fcntl(m_tty_fd, F_GETFL) | O_NONBLOCK);
tcgetattr(m_tty_fd, &tty_mode);
tty_mode.c_iflag = INPCK;
tty_mode.c_oflag = 0;
tty_mode.c_cflag = B1200 | CS8 | CREAD | HUPCL | PARENB | CLOCAL;
tty_mode.c_lflag = 0;
tty_mode.c_cc[VTIME] = 0;
tty_mode.c_cc[VMIN] = 1;
tcsetattr(m_tty_fd, TCSANOW, &tty_mode);
ioctl(m_tty_fd, TIOCMGET, &serial);
if ((serial & TIOCM_RTS) && !(serial & TIOCM_CTS))
{
// Apollo keyboard not connected
close(m_tty_fd);
m_tty_fd = -1;
m_connected = 0;
}
else
{
LOG1(("opened %s with RTS=%d CTS=%d", m_tty_name,
serial & TIOCM_RTS ? 1 : 0, serial & TIOCM_CTS ? 1 : 0 ));
}
}
#endif
}
int apollo_kbd_device::keyboard_tty::isConnected()
{
return m_connected;
}
int apollo_kbd_device::keyboard_tty::getchar()
{
#if defined(KBD_TTY_NAME)
UINT8 data;
if (m_tty_fd < 0 || read(m_tty_fd, &data, 1) != 1) {
return -1;
} else {
LOG2(("keyboard_tty::getchar <---- %02x", data))
m_connected = 1;
return data;
}
#else
return -1;
#endif
}
void apollo_kbd_device::keyboard_tty::putchar(UINT8 data)
{
#if defined(KBD_TTY_NAME)
if (isConnected() && m_tty_fd >= 0 ) {
while (write(m_tty_fd, &data, 1) != 1) {
LOG(("keyboard_tty::putchar data=%02x errno=%d", data, errno ));
}
LOG2(("keyboard_tty::putchar -> %02x", data));
}
#endif
}
/*-------------------------------------------------
keyboard_is_german - check for german keyboard
-------------------------------------------------*/
@ -555,25 +337,65 @@ int apollo_kbd_device::keyboard_is_german()
m_is_german(0) : 0;
}
/*-------------------------------------------------
putchar - put keyboard char to sio
-------------------------------------------------*/
void apollo_kbd_device::set_mode(UINT16 mode)
{
putchar(0xff);
putchar(mode);
xmit_char(0xff);
xmit_char(mode);
m_mode = mode;
}
/*-------------------------------------------------
putchar - put keyboard char to sio
-------------------------------------------------*/
void apollo_kbd_device::putchar(const UINT8 data)
void apollo_kbd_device::tra_complete() // Tx completed sending byte
{
LOG1(("putchar(%d) -> %02x", m_mode, data));
m_tx_fifo.putchar(data);
// is there more waiting to send?
if (m_xmit_read != m_xmit_write)
{
transmit_register_setup(m_xmitring[m_xmit_read++]);
if (m_xmit_read >= XMIT_RING_SIZE)
{
m_xmit_read = 0;
}
}
else
{
m_tx_busy = false;
}
}
void apollo_kbd_device::rcv_complete() // Rx completed receiving byte
{
receive_register_extract();
UINT8 data = get_received_char();
kgetchar(data);
}
void apollo_kbd_device::tra_callback() // Tx send bit
{
int bit = transmit_register_get_data_bit();
m_tx_w(bit);
}
void apollo_kbd_device::input_callback(UINT8 state)
{
}
void apollo_kbd_device::xmit_char(UINT8 data)
{
// if tx is busy it'll pick this up automatically when it completes
if (!m_tx_busy)
{
m_tx_busy = true;
transmit_register_setup(data);
}
else
{
// tx is busy, it'll pick this up next time
m_xmitring[m_xmit_write++] = data;
if (m_xmit_write >= XMIT_RING_SIZE)
{
m_xmit_write = 0;
}
}
}
/*-------------------------------------------------
@ -583,13 +405,14 @@ void apollo_kbd_device::putchar(const UINT8 data)
void apollo_kbd_device::putdata(const UINT8 *data, int data_length)
{
// send data only if no real Apollo keyboard has been connected
if (!m_keyboard_tty.isConnected())
if (m_mode > KBD_MODE_1_KEYSTATE)
{
if (m_mode > KBD_MODE_1_KEYSTATE)
{
set_mode(KBD_MODE_1_KEYSTATE);
}
m_tx_fifo.putdata(data, data_length);
set_mode(KBD_MODE_1_KEYSTATE);
}
for (int i = 0; i < data_length; i++)
{
xmit_char(data[i]);
}
}
@ -602,26 +425,12 @@ void apollo_kbd_device::putstring(const char *data)
putdata((UINT8 *) data, strlen(data));
}
/*-------------------------------------------------
apollo_kbd_getchar - get char from sio line
-------------------------------------------------*/
void apollo_kbd_getchar(device_t *device, UINT8 data)
{
downcast<apollo_kbd_device *> (device)->getchar(data);
}
void apollo_kbd_device::getchar(UINT8 data)
void apollo_kbd_device::kgetchar(UINT8 data)
{
static const UINT8 ff1116_data[] = { 0x00, 0xff, 0x00 };
LOG1(("getchar <- %02x", data));
if (m_keyboard_tty.isConnected())
{
m_keyboard_tty.putchar(data);
}
if (data == 0xff)
{
m_rx_message = data;
@ -811,10 +620,10 @@ int apollo_kbd_device::push_scancode(UINT8 code, UINT8 repeat)
if (key_code & 0xff00)
{
putchar(key_code >> 8);
xmit_char(key_code >> 8);
n_chars++;
}
putchar(key_code & 0xff);
xmit_char(key_code & 0xff);
n_chars++;
}
return n_chars;
@ -867,13 +676,8 @@ void apollo_kbd_device::scan_keyboard()
}
}
void apollo_kbd_device::poll_callback()
TIMER_CALLBACK_MEMBER(apollo_kbd_device::kbd_scan_timer)
{
int data;
while ((data = m_keyboard_tty.getchar()) >= 0)
{
putchar(data);
}
scan_keyboard();
// Note: we omit extra traffic while keyboard is in Compatibility mode
@ -883,11 +687,6 @@ void apollo_kbd_device::poll_callback()
}
}
TIMER_CALLBACK( apollo_kbd_device::static_poll_callback )
{
reinterpret_cast<apollo_kbd_device *> (ptr)->poll_callback();
}
UINT16 apollo_kbd_device::m_code_table[] = {
/* Key | Keycap | Down | Up |Unshifted|Shifted|Control|Caps Lock|Up Trans|Auto */
/* Number| Legend | Code | Code|Code | Code | Code |Code | Code |Repeat*/

View File

@ -26,8 +26,6 @@
#undef putchar
#endif
#define TX_FIFO_SIZE 128
//**************************************************************************
// DEVICE CONFIGURATION MACROS
//**************************************************************************
@ -36,14 +34,11 @@
MCFG_DEVICE_ADD(_tag, APOLLO_KBD, 0) \
apollo_kbd_device::static_set_interface(*device, _interface);
#define MCFG_APOLLO_KBD_TX_CALLBACK(_cb) \
devcb = &apollo_kbd_device::set_tx_cb(*device, DEVCB2_##_cb);
INPUT_PORTS_EXTERN(apollo_kbd);
//**************************************************************************
// Keyboard READ/WRITE
//**************************************************************************
void apollo_kbd_getchar(device_t *device, UINT8 data);
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@ -52,7 +47,6 @@ void apollo_kbd_getchar(device_t *device, UINT8 data);
struct apollo_kbd_interface
{
devcb_write8 apollo_kbd_putchar_cb;
devcb_read8 apollo_kbd_has_beeper_cb;
devcb_read8 apollo_kbd_is_german_cb;
};
@ -61,7 +55,7 @@ struct apollo_kbd_interface
// ======================> apollo_kbd_device
class apollo_kbd_device : public device_t, public apollo_kbd_interface
class apollo_kbd_device : public device_t, public device_serial_interface, public apollo_kbd_interface
{
public:
// construction/destruction
@ -70,15 +64,28 @@ public:
// static configuration helpers
static void static_set_interface(device_t &device, const apollo_kbd_interface &interface);
void getchar(UINT8 data);
template<class _Object> static devcb2_base &set_tx_cb(device_t &device, _Object object) { return downcast<apollo_kbd_device &>(device).m_tx_w.set_callback(object); }
devcb2_write_line m_tx_w;
private:
// device-level overrides
virtual void device_start();
virtual void device_reset();
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
// serial overrides
virtual void rcv_complete(); // Rx completed receiving byte
virtual void tra_complete(); // Tx completed sending byte
virtual void tra_callback(); // Tx send bit
void input_callback(UINT8 state);
TIMER_CALLBACK_MEMBER( kbd_scan_timer );
const char *cpu_context() ;
void kgetchar(UINT8 data);
int keyboard_is_german();
void set_mode(UINT16 mode);
@ -127,59 +134,18 @@ private:
int m_tx_pending; // mouse data packet is pending
};
/* Transmitter fifo */
class tx_fifo
{
public:
tx_fifo();
void start(apollo_kbd_device *device);
void reset();
UINT8 getchar();
void putchar(UINT8 data);
int putdata(const UINT8 *data, int data_length);
void flush();
private:
void timer_callback();
static TIMER_CALLBACK( static_timer_callback );
apollo_kbd_device *m_device; // pointer back to our device
UINT16 m_baud_rate;
UINT16 fifo[TX_FIFO_SIZE];
UINT16 m_read_ptr;
UINT16 m_write_ptr;
UINT16 m_char_count;
UINT16 m_tx_pending;
emu_timer *m_timer;
};
// the keyboard tty
class keyboard_tty
{
public:
keyboard_tty();
void start(apollo_kbd_device *device);
void reset();
int isConnected();
int getchar();
void putchar(UINT8 data);
private:
apollo_kbd_device *m_device; // pointer back to our device
#if defined(KBD_TTY_NAME)
const char *m_tty_name;
int m_tty_fd; /* File descriptor of keyboard tty */
#endif
int m_connected;
};
// const apollo_kbd_interface &m_config;
static const int XMIT_RING_SIZE = 64;
UINT8 m_xmitring[XMIT_RING_SIZE];
int m_xmit_read, m_xmit_write;
bool m_tx_busy;
void xmit_char(UINT8 data);
beeper m_beeper;
mouse m_mouse;
tx_fifo m_tx_fifo;
keyboard_tty m_keyboard_tty;
apollo_kbd_device *m_device; // pointer to myself (nasty: used for cpu_context)