diff --git a/src/mame/drivers/pmd85.cpp b/src/mame/drivers/pmd85.cpp index 6a7dec2dc20..e5a3a2e8748 100644 --- a/src/mame/drivers/pmd85.cpp +++ b/src/mame/drivers/pmd85.cpp @@ -177,10 +177,38 @@ JUMP aaaa - start program at aaaa MEM aaaa - show 16 bytes from aaaa-up MGLD xx - load file number xx from cassette MGSV xx aaaa bbbb yyyyyyyy - save memory range aaaa to bbbb to cassette with file number xx and filename yyyyyyyy +MGEND - ? SUB aaaa bb cc dd... - write bytes to memory starting at aaaa with bb,cc,dd... -*******************************************************************************/ +Cassette +-------- +The systems belong to 3 groups which are not compatible with each other. +- pmd851, alfa +- mato +- pmd852, pmd852a, pmd852b, pmd853, c2717, c2717pmd + +Cassettes tested with Basic +- pmd852,pmd852a,pmd852b,pmd853,c2717,c2717pmd - these can save and load back their own files +- pmd851 - won't go into basic +- mato,alfa - don't come with basic? + +Software list items +- mato - not compatible +- all others - recognise headers of sw-item-tapes, but won't load? Maybe the usage is not understood properly. + +- Some software items will crash the emulator, for example >mame pmd851 bdash + +Header information from what I can understand +xx/z yyyyyyyy +xx = file number +z = status code (guesses below) + > - only loadable by Basic + ? - only loadable by the monitor - it gives no clue as to the exec address + P - protected? I've had no luck getting one to load +yyyyyyyy = filename + +*******************************************************************************************************************/ #include "emu.h" #include "includes/pmd85.h" @@ -474,7 +502,7 @@ static INPUT_PORTS_START( pmd85 ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_START("RESET") /* port 0x10 */ - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("RST") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(UCHAR_MAMEKEY(BACKSPACE)) PORT_CHANGED_MEMBER(DEVICE_SELF, pmd85_state, pmd85_reset, 0) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("RST") PORT_CODE(KEYCODE_1_PAD) PORT_CHANGED_MEMBER(DEVICE_SELF, pmd85_state, pmd85_reset, 0) PORT_START("DSW0") /* port 0x11 */ PORT_CONFNAME( 0x01, 0x00, "Basic ROM Module" ) @@ -577,23 +605,23 @@ static INPUT_PORTS_START (mato) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Continue") PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_MAMEKEY(RCONTROL)) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_START("RESET") /* port 0x09 */ - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("RST") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(UCHAR_MAMEKEY(BACKSPACE)) PORT_CHANGED_MEMBER(DEVICE_SELF, pmd85_state, pmd85_reset, 0) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("RST") PORT_CODE(KEYCODE_1_PAD) PORT_CHANGED_MEMBER(DEVICE_SELF, pmd85_state, pmd85_reset, 0) INPUT_PORTS_END -static const struct CassetteOptions pmd85_cassette_options = -{ - 1, /* channels */ - 16, /* bits per sample */ - 7200 /* sample frequency */ -}; +//static const struct CassetteOptions pmd85_cassette_options = +//{ +// 1, /* channels */ +// 16, /* bits per sample */ +// 7200 /* sample frequency */ +//}; /* machine definition */ void pmd85_state::pmd85(machine_config &config, bool with_uart) { /* basic machine hardware */ - I8080(config, m_maincpu, 2000000); /* 2.048MHz ??? */ + I8080(config, m_maincpu, XTAL(18'432'000)/9); m_maincpu->set_addrmap(AS_PROGRAM, &pmd85_state::pmd85_mem); m_maincpu->set_addrmap(AS_IO, &pmd85_state::pmd85_io_map); config.m_minimum_quantum = attotime::from_hz(60); @@ -621,7 +649,7 @@ void pmd85_state::pmd85(machine_config &config, bool with_uart) PIT8253(config, m_pit8253, 0); m_pit8253->set_clk<0>(0); - m_pit8253->set_clk<1>(2000000); + m_pit8253->set_clk<1>(XTAL(18'432'000)/9); m_pit8253->set_clk<2>(1); /* video hardware */ @@ -642,7 +670,7 @@ void pmd85_state::pmd85(machine_config &config, bool with_uart) /* cassette */ CASSETTE(config, m_cassette); m_cassette->set_formats(pmd85_cassette_formats); - m_cassette->set_create_opts(&pmd85_cassette_options); +// m_cassette->set_create_opts(&pmd85_cassette_options); m_cassette->set_default_state(CASSETTE_STOPPED | CASSETTE_SPEAKER_ENABLED); m_cassette->add_route(ALL_OUTPUTS, "mono", 0.05); m_cassette->set_interface("pmd85_cass"); @@ -654,7 +682,8 @@ void pmd85_state::pmd85(machine_config &config, bool with_uart) if (with_uart) { I8251(config, m_uart, 0); - m_uart->txd_handler().set(FUNC(pmd85_state::write_cas_tx)); + m_uart->txd_handler().set([this] (bool state) { m_txd = state; }); + m_uart->rts_handler().set([this] (bool state) { m_uart->write_cts(state); }); } /* internal ram */ @@ -834,7 +863,7 @@ ROM_END // YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS COMP( 1985, pmd851, 0, 0, pmd851, pmd85, pmd85_state, init_pmd851, "Tesla", "PMD-85.1", 0 ) -COMP( 1985, pmd852, pmd851, 0, pmd851, pmd85, pmd85_state, init_pmd851, "Tesla", "PMD-85.2", 0 ) +COMP( 1985, pmd852, pmd851, 0, pmd851, pmd85, pmd85_state, init_pmd852, "Tesla", "PMD-85.2", 0 ) COMP( 1985, pmd852a, pmd851, 0, pmd852a, pmd85, pmd85_state, init_pmd852a, "Tesla", "PMD-85.2A", 0 ) COMP( 1985, pmd852b, pmd851, 0, pmd852a, pmd85, pmd85_state, init_pmd852a, "Tesla", "PMD-85.2B", 0 ) COMP( 1988, pmd853, pmd851, 0, pmd853, pmd85, pmd85_state, init_pmd853, "Tesla", "PMD-85.3", 0 ) diff --git a/src/mame/includes/pmd85.h b/src/mame/includes/pmd85.h index 9be9bf5711f..14bd7c4d446 100644 --- a/src/mame/includes/pmd85.h +++ b/src/mame/includes/pmd85.h @@ -65,6 +65,7 @@ public: void init_mato(); void init_pmd852a(); void init_pmd851(); + void init_pmd852(); void init_pmd853(); void init_alfa(); void init_c2717(); @@ -81,9 +82,9 @@ private: uint8_t m_ppi_port_outputs[4][3]; uint8_t m_startup_mem_map; uint8_t m_pmd853_memory_mapping; - int m_previous_level; - int m_clk_level; - int m_clk_level_tape; + bool m_previous_level; + bool m_clk_level; + bool m_clk_level_tape; uint8_t m_model; emu_timer * m_cassette_timer; void (pmd85_state::*update_memory)(); @@ -95,7 +96,6 @@ private: virtual void machine_reset() override; uint32_t screen_update_pmd85(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); TIMER_CALLBACK_MEMBER(pmd85_cassette_timer_callback); - DECLARE_WRITE_LINE_MEMBER(write_cas_tx); DECLARE_READ8_MEMBER(pmd85_ppi_0_porta_r); DECLARE_READ8_MEMBER(pmd85_ppi_0_portb_r); DECLARE_READ8_MEMBER(pmd85_ppi_0_portc_r); @@ -175,7 +175,7 @@ private: void pmd85_common_driver_init(); virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; - int m_cas_tx; + bool m_txd, m_rts; }; diff --git a/src/mame/machine/pmd85.cpp b/src/mame/machine/pmd85.cpp index faa9fcf8d73..37cad7aef89 100644 --- a/src/mame/machine/pmd85.cpp +++ b/src/mame/machine/pmd85.cpp @@ -284,7 +284,9 @@ READ8_MEMBER(pmd85_state::mato_ppi_0_portb_r) READ8_MEMBER(pmd85_state::mato_ppi_0_portc_r) { - return m_io_port[8]->read() | 0x8f; + u8 data = m_io_port[8]->read() & 0x7f; + data |= (m_cassette->input() > 0.038) ? 0x80 : 0; + return data; } WRITE8_MEMBER(pmd85_state::mato_ppi_0_portc_w) @@ -292,6 +294,7 @@ WRITE8_MEMBER(pmd85_state::mato_ppi_0_portc_w) m_ppi_port_outputs[0][2] = data; m_leds[PMD85_LED_2] = BIT(data, 3); m_leds[PMD85_LED_3] = BIT(data, 2); + m_cassette->output(BIT(data, 0) ? 1 : -1); } /******************************************************************************* @@ -473,22 +476,13 @@ READ8_MEMBER(pmd85_state::pmd85_io_r) } break; case 0x08: /* ROM module connector */ - switch (m_model) + if (m_rom_module_present) { - case PMD85_1: - case PMD85_2: - case PMD85_2A: - case C2717: - case PMD85_3: - if (m_rom_module_present) - { - switch (offset & 0x80) - { - case 0x80: /* ROM module 8255 */ - return m_ppi8255_3->read(offset & 0x03); - } - } - break; + switch (offset & 0x80) + { + case 0x80: /* ROM module 8255 */ + return m_ppi8255_3->read(offset & 0x03); + } } break; case 0x0c: /* I/O board */ @@ -497,9 +491,9 @@ READ8_MEMBER(pmd85_state::pmd85_io_r) case 0x00: /* I/O board interfaces */ switch (offset & 0x70) { - case 0x10: /* 8251 (casette recorder, V24) */ + case 0x10: /* 8251 (cassette recorder, V24) */ return m_uart->read(offset & 0x01); - case 0x40: /* 8255 (GPIO/0, GPIO/1) */ + case 0x40: /* 8255 (GPIO/0, GPIO/1) */ return m_ppi8255_1->read(offset & 0x03); case 0x50: /* 8253 */ return m_pit8253->read(offset & 0x03); @@ -512,6 +506,8 @@ READ8_MEMBER(pmd85_state::pmd85_io_r) } break; } + if ((m_model == ALFA) && ((offset & 0xfe) == 0xf0)) + return m_uart->read(offset & 0x01); logerror ("Reading from unmapped port: %02x\n", offset); return 0xff; @@ -542,23 +538,14 @@ WRITE8_MEMBER(pmd85_state::pmd85_io_w) } break; case 0x08: /* ROM module connector */ - switch (m_model) + if (m_rom_module_present) { - case PMD85_1: - case PMD85_2: - case PMD85_2A: - case C2717: - case PMD85_3: - if (m_rom_module_present) - { - switch (offset & 0x80) - { - case 0x80: /* ROM module 8255 */ - m_ppi8255_3->write(offset & 0x03, data); - break; - } - } - break; + switch (offset & 0x80) + { + case 0x80: /* ROM module 8255 */ + m_ppi8255_3->write(offset & 0x03, data); + break; + } } break; case 0x0c: /* I/O board */ @@ -567,10 +554,10 @@ WRITE8_MEMBER(pmd85_state::pmd85_io_w) case 0x00: /* I/O board interfaces */ switch (offset & 0x70) { - case 0x10: /* 8251 (casette recorder, V24) */ + case 0x10: /* 8251 (cassette recorder, V24) */ m_uart->write(offset & 0x01, data); break; - case 0x40: /* 8255 (GPIO/0, GPIO/0) */ + case 0x40: /* 8255 (GPIO/0, GPIO/0) */ m_ppi8255_1->write(offset & 0x03, data); break; case 0x50: /* 8253 */ @@ -587,6 +574,9 @@ WRITE8_MEMBER(pmd85_state::pmd85_io_w) } break; } + if ((m_model == ALFA) && ((offset & 0xfe) == 0xf0)) + m_uart->write(offset & 0x01, data); + //logerror ("Writing to unmapped port: %02x:%02X\n", offset,data); } /******************************************************************************* @@ -653,15 +643,10 @@ void pmd85_state::device_timer(emu_timer &timer, device_timer_id id, int param, } } -WRITE_LINE_MEMBER(pmd85_state::write_cas_tx) -{ - m_cas_tx = state; -} - TIMER_CALLBACK_MEMBER(pmd85_state::pmd85_cassette_timer_callback) { - int data; - int current_level; + bool data; + bool current_level; if (!(m_io_dsw0->read() & 0x02)) /* V.24 / Tape Switch */ { @@ -671,6 +656,7 @@ TIMER_CALLBACK_MEMBER(pmd85_state::pmd85_cassette_timer_callback) switch (m_model) { case PMD85_1: + case ALFA: if (m_clk_level_tape) { m_previous_level = (m_cassette->input() > 0.038) ? 1 : 0; @@ -696,8 +682,8 @@ TIMER_CALLBACK_MEMBER(pmd85_state::pmd85_cassette_timer_callback) case PMD85_2A: case C2717: case PMD85_3: - case ALFA: - /* not hardware data decoding */ + // works for pmd852, pmd852a, pmd852b, pmd853, c2717, c2717pmd + m_uart->write_dsr( (m_cassette->input() > 0.038) ? 0 : 1); return; } } @@ -705,9 +691,7 @@ TIMER_CALLBACK_MEMBER(pmd85_state::pmd85_cassette_timer_callback) /* tape writing */ if (m_cassette->get_state()&CASSETTE_RECORD) { - data = m_cas_tx; - data ^= m_clk_level_tape; - m_cassette->output(data&0x01 ? 1 : -1); + m_cassette->output((m_txd ^ m_clk_level_tape) ? 1 : -1); m_clk_level_tape = m_clk_level_tape ? 0 : 1; m_uart->write_txc(m_clk_level_tape); @@ -752,6 +736,13 @@ void pmd85_state::init_pmd851() pmd85_common_driver_init(); } +void pmd85_state::init_pmd852() +{ + m_model = PMD85_2; + update_memory = &pmd85_state::pmd851_update_memory; + pmd85_common_driver_init(); +} + void pmd85_state::init_pmd852a() { m_model = PMD85_2A; @@ -804,13 +795,15 @@ void pmd85_state::machine_reset() int i, j; /* checking for Rom Module */ + m_rom_module_present = 0; switch (m_model) { case PMD85_1: + case PMD85_2: case PMD85_2A: case PMD85_3: case C2717: - m_rom_module_present = (m_io_dsw0->read() & 0x01) ? 1 : 0; + m_rom_module_present = BIT(m_io_dsw0->read(), 0); break; case ALFA: case MATO: @@ -826,7 +819,4 @@ void pmd85_state::machine_reset() m_pmd853_memory_mapping = 1; m_startup_mem_map = 1; (this->*update_memory)(); - - if (m_uart) - m_uart->write_cts(0); }