From 04cca4aa9139cebc98b2f09fe28c95a81125ec7a Mon Sep 17 00:00:00 2001 From: "R. Belmont" Date: Mon, 24 Feb 2014 02:43:26 +0000 Subject: [PATCH] (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. --- src/mess/drivers/apollo.c | 134 ++++++------ src/mess/includes/apollo.h | 20 +- src/mess/machine/apollo.c | 347 +++++-------------------------- src/mess/machine/apollo_kbd.c | 381 ++++++++-------------------------- src/mess/machine/apollo_kbd.h | 86 +++----- 5 files changed, 250 insertions(+), 718 deletions(-) diff --git a/src/mess/drivers/apollo.c b/src/mess/drivers/apollo.c index b94bc8a9c9e..2c87b9eb661 100644 --- a/src/mess/drivers/apollo.c +++ b/src/mess/drivers/apollo.c @@ -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(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 /*************************************************************************** diff --git a/src/mess/includes/apollo.h b/src/mess/includes/apollo.h index bdbdef15ab1..9b4aa126ff5 100644 --- a/src/mess/includes/apollo.h +++ b/src/mess/includes/apollo.h @@ -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 m_maincpu; @@ -142,7 +144,9 @@ public: required_device m_pic8259_master; required_device m_pic8259_slave; required_device m_ptm; + required_device m_sio; optional_device m_sio2; + required_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 -----------*/ diff --git a/src/mess/machine/apollo.c b/src/mess/machine/apollo.c index f477b7493a0..fd8c0b41ce0 100644 --- a/src/mess/machine/apollo.c +++ b/src/mess/machine/apollo.c @@ -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(); 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 (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 (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; } diff --git a/src/mess/machine/apollo_kbd.c b/src/mess/machine/apollo_kbd.c index 4afa7d7f4fc..dad93af90b6 100644 --- a/src/mess/machine/apollo_kbd.c +++ b/src/mess/machine/apollo_kbd.c @@ -16,16 +16,6 @@ #include "machine/apollo_kbd.h" #include "sound/beep.h" -#if defined(APOLLO_FOR_LINUX) -#include -#include -#include -// on linux we may attach a real Apollo keyboard at /dev/ttyS0 -#include -#include -#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(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(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 (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 (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 (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*/ diff --git a/src/mess/machine/apollo_kbd.h b/src/mess/machine/apollo_kbd.h index de9105fd84e..142fadbd83e 100644 --- a/src/mess/machine/apollo_kbd.h +++ b/src/mess/machine/apollo_kbd.h @@ -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 static devcb2_base &set_tx_cb(device_t &device, _Object object) { return downcast(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)