From ee277264e2ea7e2b585506aca75103f8fb0ea5cb Mon Sep 17 00:00:00 2001 From: Curt Coder Date: Sat, 11 Nov 2017 14:04:25 +0200 Subject: [PATCH] tmc600: Fixed printer handshake, RAM/ROM region sizes, and implemented video according to actual hardware. [Curt Coder] --- src/mame/drivers/tmc600.cpp | 137 ++++++++++++++++++------------------ src/mame/includes/tmc600.h | 29 ++++---- src/mame/video/tmc600.cpp | 63 +++++++---------- 3 files changed, 111 insertions(+), 118 deletions(-) diff --git a/src/mame/drivers/tmc600.cpp b/src/mame/drivers/tmc600.cpp index 5ab8ae1df32..82ed32a6064 100644 --- a/src/mame/drivers/tmc600.cpp +++ b/src/mame/drivers/tmc600.cpp @@ -50,30 +50,30 @@ Notes: CN2 - 10x2 pin printer connector [TMC-700] CN3 - 32x3 pin EURO connector CN4 - DIN5D tape connector - 1 input (500 mV / 47 kohm) + 1 input (500 mV / 47 Kohm) 2 GND - 3 output (580 mV / 47 kohm) - 4 input (500 mV / 47 kohm) - 5 output (580 mV / 47 kohm) + 3 output (580 mV / 47 Kohm) + 4 input (500 mV / 47 Kohm) + 5 output (580 mV / 47 Kohm) CN5 - DIN5X video connector 1 GND 2 GND - 3 ? + 3 composite video output (75 ohm) 4 GND - 5 ? + 5 composite video output (75 ohm) CN6 - DIN2 power connector - 1 8..12V DC..400Hz 300mA + 1 input 8..12V DC..400Hz 300mA 2 GND CN7 - DIN5D audio connector [TMCP-300] - 1 NC + 1 N/C 2 GND - 3 AUDIO - 4 NC - 5 AUDIO + 3 mono audio output + 4 N/C + 5 mono audio output CN8 - 10x2 pin keyboard connector - SW1 - RUN/STOP switch + SW1 - RUN/STOP switch (left=run, right=stop) SW2 - internal speaker/external audio switch [TMCP-300] - P1 - color phase lock adjustment + P1 - color phase lock adjustment potentiometer C1 - dot oscillator adjustment variable capacitor C2 - chroma oscillator adjustment variable capacitor T1 - RF signal strength adjustment potentiometer [TMC-700] @@ -88,37 +88,43 @@ Notes: /* - TODO: + TODO - - proper emulation of the VISMAC interface (cursor blinking, color RAM), schematics are needed - - disk interface - - serial interface expansion card - - centronics printer handshaking + - real time clock + - connect expansion bus */ #include "emu.h" #include "includes/tmc600.h" -/* Read/Write Handlers */ - -WRITE8_MEMBER( tmc600_state::keyboard_latch_w ) +WRITE8_MEMBER( tmc600_state::printer_w ) { - m_keylatch = data; + m_centronics->write_data0(BIT(data, 0)); + m_centronics->write_data1(BIT(data, 1)); + m_centronics->write_data2(BIT(data, 2)); + m_centronics->write_data3(BIT(data, 3)); + m_centronics->write_data4(BIT(data, 4)); + m_centronics->write_data5(BIT(data, 5)); + m_centronics->write_data6(BIT(data, 6)); + m_centronics->write_data7(BIT(data, 7)); + + m_centronics->write_strobe(0); + m_centronics->write_strobe(1); } /* Memory Maps */ static ADDRESS_MAP_START( tmc600_map, AS_PROGRAM, 8, tmc600_state ) - AM_RANGE(0x0000, 0x4fff) AM_ROM - AM_RANGE(0x6000, 0xbfff) AM_RAM + AM_RANGE(0x0000, 0x5fff) AM_ROM + AM_RANGE(0x6000, 0x7fff) AM_RAM AM_RANGE(0xf400, 0xf7ff) AM_DEVICE(CDP1869_TAG, cdp1869_device, char_map) AM_RANGE(0xf800, 0xffff) AM_DEVICE(CDP1869_TAG, cdp1869_device, page_map) ADDRESS_MAP_END static ADDRESS_MAP_START( tmc600_io_map, AS_IO, 8, tmc600_state ) - AM_RANGE(0x03, 0x03) AM_WRITE(keyboard_latch_w) - AM_RANGE(0x04, 0x04) AM_DEVWRITE("cent_data_out", output_latch_device, write) + AM_RANGE(0x03, 0x03) AM_DEVWRITE(CDP1852_KB_TAG, cdp1852_device, write) + AM_RANGE(0x04, 0x04) AM_DEVWRITE(CDP1852_TMC700_TAG, cdp1852_device, write) AM_RANGE(0x05, 0x05) AM_WRITE(vismac_data_w) // AM_RANGE(0x06, 0x06) AM_WRITE(floppy_w) AM_RANGE(0x07, 0x07) AM_WRITE(vismac_register_w) @@ -208,16 +214,11 @@ static INPUT_PORTS_START( tmc600 ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(UTF8_LEFT) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_START("RUN") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Run/Stop") PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_TOGGLE + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Run/Stop") PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_TOGGLE PORT_WRITE_LINE_DEVICE_MEMBER(CDP1802_TAG, cosmac_device, clear_w) INPUT_PORTS_END /* CDP1802 Interface */ -READ_LINE_MEMBER( tmc600_state::clear_r ) -{ - return BIT(m_run->read(), 0); -} - READ_LINE_MEMBER( tmc600_state::ef2_r ) { return m_cassette->input() < 0; @@ -225,9 +226,9 @@ READ_LINE_MEMBER( tmc600_state::ef2_r ) READ_LINE_MEMBER( tmc600_state::ef3_r ) { - uint8_t data = ~m_key_row[m_keylatch / 8]->read(); + uint8_t keylatch = m_bwio->do_r(); - return BIT(data, m_keylatch % 8); + return !BIT(m_key_row[(keylatch >> 3) & 0x07]->read(), keylatch & 0x07); } WRITE_LINE_MEMBER( tmc600_state::q_w ) @@ -235,37 +236,14 @@ WRITE_LINE_MEMBER( tmc600_state::q_w ) m_cassette->output(state ? +1.0 : -1.0); } -/* Machine Initialization */ - -void tmc600_state::machine_start() -{ - address_space &program = m_maincpu->space(AS_PROGRAM); - - /* configure RAM */ - switch (m_ram->size()) - { - case 8*1024: - program.unmap_readwrite(0x8000, 0xbfff); - break; - - case 16*1024: - program.unmap_readwrite(0xa000, 0xbfff); - break; - } - - /* register for state saving */ - save_item(NAME(m_keylatch)); -} - /* Machine Drivers */ static MACHINE_CONFIG_START( tmc600 ) - // basic system hardware + // CPU MCFG_CPU_ADD(CDP1802_TAG, CDP1802, XTAL_3_57MHz) MCFG_CPU_PROGRAM_MAP(tmc600_map) MCFG_CPU_IO_MAP(tmc600_io_map) MCFG_COSMAC_WAIT_CALLBACK(VCC) - MCFG_COSMAC_CLEAR_CALLBACK(READLINE(tmc600_state, clear_r)) MCFG_COSMAC_EF2_CALLBACK(READLINE(tmc600_state, ef2_r)) MCFG_COSMAC_EF3_CALLBACK(READLINE(tmc600_state, ef3_r)) MCFG_COSMAC_Q_CALLBACK(WRITELINE(tmc600_state, q_w)) @@ -273,43 +251,66 @@ static MACHINE_CONFIG_START( tmc600 ) // sound and video hardware MCFG_FRAGMENT_ADD(tmc600_video) - /* devices */ - MCFG_CENTRONICS_ADD(CENTRONICS_TAG, centronics_devices, "printer") + // keyboard output latch + MCFG_DEVICE_ADD(CDP1852_KB_TAG, CDP1852, XTAL_3_57MHz/8) // clock is CDP1802 TPB + MCFG_CDP1852_MODE_CALLBACK(VCC) - MCFG_CENTRONICS_OUTPUT_LATCH_ADD("cent_data_out", CENTRONICS_TAG) + // address bus demux for expansion bus + MCFG_DEVICE_ADD(CDP1852_BUS_TAG, CDP1852, 0) // clock is expansion bus TPA + MCFG_CDP1852_MODE_CALLBACK(GND) + // printer output latch + MCFG_DEVICE_ADD(CDP1852_TMC700_TAG, CDP1852, XTAL_3_57MHz/8) // clock is CDP1802 TPB + MCFG_CDP1852_MODE_CALLBACK(VCC) + MCFG_CDP1852_DO_CALLBACK(WRITE8(tmc600_state, printer_w)) + + // printer connector + MCFG_CENTRONICS_ADD(CENTRONICS_TAG, centronics_devices, nullptr) + MCFG_CENTRONICS_BUSY_HANDLER(DEVWRITELINE(CDP1802_TAG, cosmac_device, ef4_w)) MCFG_DEVCB_XOR(1) + + // cassette MCFG_CASSETTE_ADD("cassette") MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_MUTED) - /* internal ram */ + // expansion bus connector + MCFG_TMC600_EURO_BUS_SLOT_ADD(TMC600_EURO_BUS_TAG, tmc600_euro_bus_cards, nullptr) + + // internal RAM MCFG_RAM_ADD(RAM_TAG) MCFG_RAM_DEFAULT_SIZE("8K") - MCFG_RAM_EXTRA_OPTIONS("16K,24K") MACHINE_CONFIG_END /* ROMs */ #if 0 ROM_START( tmc600s1 ) - ROM_REGION( 0x5000, CDP1802_TAG, 0 ) + ROM_REGION( 0x6000, CDP1802_TAG, 0 ) ROM_LOAD( "sb20", 0x0000, 0x1000, NO_DUMP ) ROM_LOAD( "sb21", 0x1000, 0x1000, NO_DUMP ) ROM_LOAD( "sb22", 0x2000, 0x1000, NO_DUMP ) ROM_LOAD( "sb23", 0x3000, 0x1000, NO_DUMP ) - ROM_LOAD( "190482_2", 0x4000, 0x1000, NO_DUMP ) + ROM_SYSTEM_BIOS( 0, "sb040282", "SB040282" ) + ROMX_LOAD( "190482", 0x4000, 0x1000, NO_DUMP, ROM_BIOS(1) ) + ROM_SYSTEM_BIOS( 1, "sbdos", "SBDOS" ) + ROMX_LOAD( "190482_", 0x4000, 0x1000, NO_DUMP, ROM_BIOS(2) ) + ROMX_LOAD( "190482_v", 0x5000, 0x1000, NO_DUMP, ROM_BIOS(2) ) ROM_REGION( 0x1000, "chargen", 0 ) - ROM_LOAD( "chargen", 0x0000, 0x1000, NO_DUMP ) + ROM_LOAD( "chargen", 0x0000, 0x1000, CRC(93f92cbf) SHA1(371156fb38fa5319c6fde537ccf14eed94e7adfb) ) ROM_END #endif ROM_START( tmc600s2 ) - ROM_REGION( 0x5000, CDP1802_TAG, 0 ) + ROM_REGION( 0x6000, CDP1802_TAG, 0 ) ROM_LOAD( "sb30", 0x0000, 0x1000, CRC(95d1292a) SHA1(1fa52d59d3005f8ac74a32c2164fdb22947c2748) ) ROM_LOAD( "sb31", 0x1000, 0x1000, CRC(2c8f3d17) SHA1(f14e8adbcddeaeaa29b1e7f3dfa741f4e230f599) ) ROM_LOAD( "sb32", 0x2000, 0x1000, CRC(dd58a128) SHA1(be9bdb0fc5e0cc3dcc7f2fb7ccab69bf5b043803) ) ROM_LOAD( "sb33", 0x3000, 0x1000, CRC(b7d241fa) SHA1(6f3eadf86c4e3aaf93d123e302a18dc4d9db964b) ) - ROM_LOAD( "151182", 0x4000, 0x1000, CRC(c1a8d9d8) SHA1(4552e1f06d0e338ba7b0f1c3a20b8a51c27dafde) ) + ROM_SYSTEM_BIOS( 0, "sb040282", "SB040282" ) + ROMX_LOAD( "151182", 0x4000, 0x1000, CRC(c1a8d9d8) SHA1(4552e1f06d0e338ba7b0f1c3a20b8a51c27dafde), ROM_BIOS(1) ) + ROM_SYSTEM_BIOS( 1, "sbdos", "SBDOS" ) + ROMX_LOAD( "151182_", 0x4000, 0x1000, NO_DUMP, ROM_BIOS(2) ) + ROMX_LOAD( "151182_v", 0x5000, 0x1000, NO_DUMP, ROM_BIOS(2) ) ROM_REGION( 0x1000, "chargen", 0 ) ROM_LOAD( "chargen", 0x0000, 0x1000, CRC(93f92cbf) SHA1(371156fb38fa5319c6fde537ccf14eed94e7adfb) ) diff --git a/src/mame/includes/tmc600.h b/src/mame/includes/tmc600.h index 4c447910ed4..1b212e9624d 100644 --- a/src/mame/includes/tmc600.h +++ b/src/mame/includes/tmc600.h @@ -9,15 +9,20 @@ #include "imagedev/cassette.h" #include "imagedev/snapquik.h" #include "bus/centronics/ctronics.h" +#include "bus/tmc600/euro.h" +#include "machine/cdp1852.h" #include "machine/ram.h" #include "machine/timer.h" #include "sound/cdp1869.h" #include "speaker.h" -#define SCREEN_TAG "screen" -#define CDP1802_TAG "cdp1802" -#define CDP1869_TAG "cdp1869" -#define CENTRONICS_TAG "centronics" +#define SCREEN_TAG "screen" +#define CDP1802_TAG "cdp1802" +#define CDP1869_TAG "cdp1869" +#define CDP1852_KB_TAG "cdp1852_kb" +#define CDP1852_BUS_TAG "cdp1852_bus" +#define CDP1852_TMC700_TAG "cdp1852_printer" +#define CENTRONICS_TAG "centronics" #define TMC600_PAGE_RAM_SIZE 0x400 #define TMC600_PAGE_RAM_MASK 0x3ff @@ -29,8 +34,10 @@ public: driver_device(mconfig, type, tag), m_maincpu(*this, CDP1802_TAG), m_vis(*this, CDP1869_TAG), + m_bwio(*this, CDP1852_KB_TAG), m_cassette(*this, "cassette"), m_centronics(*this, "centronics"), + m_bus(*this, TMC600_EURO_BUS_TAG), m_ram(*this, RAM_TAG), m_char_rom(*this, "chargen"), m_page_ram(*this, "page_ram"), @@ -41,8 +48,10 @@ public: required_device m_maincpu; required_device m_vis; + required_device m_bwio; required_device m_cassette; required_device m_centronics; + required_device m_bus; required_device m_ram; required_region_ptr m_char_rom; required_shared_ptr m_page_ram; @@ -50,11 +59,9 @@ public: required_ioport m_run; required_ioport_array<8> m_key_row; - virtual void machine_start() override; - virtual void video_start() override; - DECLARE_WRITE8_MEMBER( keyboard_latch_w ); + DECLARE_WRITE8_MEMBER( printer_w ); DECLARE_WRITE8_MEMBER( vismac_register_w ); DECLARE_WRITE8_MEMBER( vismac_data_w ); DECLARE_WRITE8_MEMBER( page_ram_w ); @@ -62,17 +69,15 @@ public: DECLARE_READ_LINE_MEMBER( ef2_r ); DECLARE_READ_LINE_MEMBER( ef3_r ); DECLARE_WRITE_LINE_MEMBER( q_w ); + DECLARE_WRITE_LINE_MEMBER( prd_w ); uint8_t get_color(uint16_t pma); // video state int m_vismac_reg_latch; // video register latch int m_vismac_color_latch; // color latch - int m_vismac_bkg_latch; // background color latch - int m_blink; // cursor blink - - // keyboard state - int m_keylatch; // key latch + bool m_blink; // cursor blink + int m_frame; TIMER_DEVICE_CALLBACK_MEMBER(blink_tick); CDP1869_CHAR_RAM_READ_MEMBER(tmc600_char_ram_r); diff --git a/src/mame/video/tmc600.cpp b/src/mame/video/tmc600.cpp index ac1e739476e..93c86807181 100644 --- a/src/mame/video/tmc600.cpp +++ b/src/mame/video/tmc600.cpp @@ -5,50 +5,24 @@ WRITE8_MEMBER( tmc600_state::vismac_register_w ) { - m_vismac_reg_latch = data; + m_vismac_reg_latch = data >> 4; } WRITE8_MEMBER( tmc600_state::vismac_data_w ) { uint16_t ma = m_maincpu->get_memory_address(); - switch (m_vismac_reg_latch) + switch (m_vismac_reg_latch & 0x07) { - case 0x20: - // character color latch - m_vismac_color_latch = data; - break; - - case 0x30: - // background color latch - m_vismac_bkg_latch = data & 0x07; - - m_vis->out3_w(space, ma, data); - break; - - case 0x40: - m_vis->out4_w(space, ma, data); - break; - - case 0x50: - m_vis->out5_w(space, ma, data); - break; - - case 0x60: - m_vis->out6_w(space, ma, data); - break; - - case 0x70: - m_vis->out7_w(space, ma, data); - break; + case 2: m_vismac_color_latch = data & 0x0f; break; + case 3: m_vis->out3_w(space, ma, data); break; + case 4: m_vis->out4_w(space, ma, data); break; + case 5: m_vis->out5_w(space, ma, data); break; + case 6: m_vis->out6_w(space, ma, data); break; + case 7: m_vis->out7_w(space, ma, data); break; } } -TIMER_DEVICE_CALLBACK_MEMBER(tmc600_state::blink_tick) -{ - m_blink = !m_blink; -} - uint8_t tmc600_state::get_color(uint16_t pma) { uint16_t pageaddr = pma & TMC600_PAGE_RAM_MASK; @@ -56,7 +30,7 @@ uint8_t tmc600_state::get_color(uint16_t pma) if (BIT(color, 3) && m_blink) { - color = m_vismac_bkg_latch; + color ^= 0x07; } return color; @@ -93,15 +67,28 @@ CDP1869_PCB_READ_MEMBER( tmc600_state::tmc600_pcb_r ) return BIT(color, 0); } +WRITE_LINE_MEMBER( tmc600_state::prd_w ) +{ + if (state) { + m_frame++; + + if (m_frame == 32) { + m_frame = 0; + + m_blink = !m_blink; + } + } +} + void tmc600_state::video_start() { // allocate memory m_color_ram.allocate(TMC600_PAGE_RAM_SIZE); - // register for state saving + // state saving save_item(NAME(m_vismac_reg_latch)); save_item(NAME(m_vismac_color_latch)); - save_item(NAME(m_vismac_bkg_latch)); + save_item(NAME(m_frame)); save_item(NAME(m_blink)); } @@ -125,7 +112,6 @@ GFXDECODE_END MACHINE_CONFIG_START( tmc600_video ) // video hardware MCFG_CDP1869_SCREEN_PAL_ADD(CDP1869_TAG, SCREEN_TAG, cdp1869_device::DOT_CLK_PAL) - MCFG_TIMER_DRIVER_ADD_PERIODIC("blink", tmc600_state, blink_tick, attotime::from_hz(2)) MCFG_GFXDECODE_ADD("gfxdecode", CDP1869_TAG":palette", tmc600) @@ -136,6 +122,7 @@ MACHINE_CONFIG_START( tmc600_video ) MCFG_CDP1869_CHAR_PCB_READ_OWNER(tmc600_state, tmc600_pcb_r) MCFG_CDP1869_CHAR_RAM_READ_OWNER(tmc600_state, tmc600_char_ram_r) MCFG_CDP1869_PAL_NTSC_CALLBACK(VCC) + MCFG_CDP1869_PRD_CALLBACK(WRITELINE(tmc600_state, prd_w)) MCFG_VIDEO_SET_SCREEN(SCREEN_TAG) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) MACHINE_CONFIG_END