pmd85: added cassette to alfa and mato; fixed cassette on the others; added notes

This commit is contained in:
Robbbert 2019-09-08 21:40:43 +10:00
parent f0a20e02cc
commit 68d38ecac6
3 changed files with 90 additions and 71 deletions

View File

@ -177,10 +177,38 @@ JUMP aaaa - start program at aaaa
MEM aaaa - show 16 bytes from aaaa-up MEM aaaa - show 16 bytes from aaaa-up
MGLD xx - load file number xx from cassette 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 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... 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 "emu.h"
#include "includes/pmd85.h" #include "includes/pmd85.h"
@ -474,7 +502,7 @@ static INPUT_PORTS_START( pmd85 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("RESET") /* port 0x10 */ 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_START("DSW0") /* port 0x11 */
PORT_CONFNAME( 0x01, 0x00, "Basic ROM Module" ) 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( 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_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("RESET") /* port 0x09 */ 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 INPUT_PORTS_END
static const struct CassetteOptions pmd85_cassette_options = //static const struct CassetteOptions pmd85_cassette_options =
{ //{
1, /* channels */ // 1, /* channels */
16, /* bits per sample */ // 16, /* bits per sample */
7200 /* sample frequency */ // 7200 /* sample frequency */
}; //};
/* machine definition */ /* machine definition */
void pmd85_state::pmd85(machine_config &config, bool with_uart) void pmd85_state::pmd85(machine_config &config, bool with_uart)
{ {
/* basic machine hardware */ /* 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_PROGRAM, &pmd85_state::pmd85_mem);
m_maincpu->set_addrmap(AS_IO, &pmd85_state::pmd85_io_map); m_maincpu->set_addrmap(AS_IO, &pmd85_state::pmd85_io_map);
config.m_minimum_quantum = attotime::from_hz(60); 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); PIT8253(config, m_pit8253, 0);
m_pit8253->set_clk<0>(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); m_pit8253->set_clk<2>(1);
/* video hardware */ /* video hardware */
@ -642,7 +670,7 @@ void pmd85_state::pmd85(machine_config &config, bool with_uart)
/* cassette */ /* cassette */
CASSETTE(config, m_cassette); CASSETTE(config, m_cassette);
m_cassette->set_formats(pmd85_cassette_formats); 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->set_default_state(CASSETTE_STOPPED | CASSETTE_SPEAKER_ENABLED);
m_cassette->add_route(ALL_OUTPUTS, "mono", 0.05); m_cassette->add_route(ALL_OUTPUTS, "mono", 0.05);
m_cassette->set_interface("pmd85_cass"); m_cassette->set_interface("pmd85_cass");
@ -654,7 +682,8 @@ void pmd85_state::pmd85(machine_config &config, bool with_uart)
if (with_uart) if (with_uart)
{ {
I8251(config, m_uart, 0); 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 */ /* internal ram */
@ -834,7 +863,7 @@ ROM_END
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS // 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, 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, 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( 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 ) COMP( 1988, pmd853, pmd851, 0, pmd853, pmd85, pmd85_state, init_pmd853, "Tesla", "PMD-85.3", 0 )

View File

@ -65,6 +65,7 @@ public:
void init_mato(); void init_mato();
void init_pmd852a(); void init_pmd852a();
void init_pmd851(); void init_pmd851();
void init_pmd852();
void init_pmd853(); void init_pmd853();
void init_alfa(); void init_alfa();
void init_c2717(); void init_c2717();
@ -81,9 +82,9 @@ private:
uint8_t m_ppi_port_outputs[4][3]; uint8_t m_ppi_port_outputs[4][3];
uint8_t m_startup_mem_map; uint8_t m_startup_mem_map;
uint8_t m_pmd853_memory_mapping; uint8_t m_pmd853_memory_mapping;
int m_previous_level; bool m_previous_level;
int m_clk_level; bool m_clk_level;
int m_clk_level_tape; bool m_clk_level_tape;
uint8_t m_model; uint8_t m_model;
emu_timer * m_cassette_timer; emu_timer * m_cassette_timer;
void (pmd85_state::*update_memory)(); void (pmd85_state::*update_memory)();
@ -95,7 +96,6 @@ private:
virtual void machine_reset() override; virtual void machine_reset() override;
uint32_t screen_update_pmd85(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); uint32_t screen_update_pmd85(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
TIMER_CALLBACK_MEMBER(pmd85_cassette_timer_callback); 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_porta_r);
DECLARE_READ8_MEMBER(pmd85_ppi_0_portb_r); DECLARE_READ8_MEMBER(pmd85_ppi_0_portb_r);
DECLARE_READ8_MEMBER(pmd85_ppi_0_portc_r); DECLARE_READ8_MEMBER(pmd85_ppi_0_portc_r);
@ -175,7 +175,7 @@ private:
void pmd85_common_driver_init(); void pmd85_common_driver_init();
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; 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;
}; };

View File

@ -284,7 +284,9 @@ READ8_MEMBER(pmd85_state::mato_ppi_0_portb_r)
READ8_MEMBER(pmd85_state::mato_ppi_0_portc_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) 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_ppi_port_outputs[0][2] = data;
m_leds[PMD85_LED_2] = BIT(data, 3); m_leds[PMD85_LED_2] = BIT(data, 3);
m_leds[PMD85_LED_3] = BIT(data, 2); 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; break;
case 0x08: /* ROM module connector */ case 0x08: /* ROM module connector */
switch (m_model) if (m_rom_module_present)
{ {
case PMD85_1: switch (offset & 0x80)
case PMD85_2: {
case PMD85_2A: case 0x80: /* ROM module 8255 */
case C2717: return m_ppi8255_3->read(offset & 0x03);
case PMD85_3: }
if (m_rom_module_present)
{
switch (offset & 0x80)
{
case 0x80: /* ROM module 8255 */
return m_ppi8255_3->read(offset & 0x03);
}
}
break;
} }
break; break;
case 0x0c: /* I/O board */ case 0x0c: /* I/O board */
@ -497,9 +491,9 @@ READ8_MEMBER(pmd85_state::pmd85_io_r)
case 0x00: /* I/O board interfaces */ case 0x00: /* I/O board interfaces */
switch (offset & 0x70) switch (offset & 0x70)
{ {
case 0x10: /* 8251 (casette recorder, V24) */ case 0x10: /* 8251 (cassette recorder, V24) */
return m_uart->read(offset & 0x01); 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); return m_ppi8255_1->read(offset & 0x03);
case 0x50: /* 8253 */ case 0x50: /* 8253 */
return m_pit8253->read(offset & 0x03); return m_pit8253->read(offset & 0x03);
@ -512,6 +506,8 @@ READ8_MEMBER(pmd85_state::pmd85_io_r)
} }
break; break;
} }
if ((m_model == ALFA) && ((offset & 0xfe) == 0xf0))
return m_uart->read(offset & 0x01);
logerror ("Reading from unmapped port: %02x\n", offset); logerror ("Reading from unmapped port: %02x\n", offset);
return 0xff; return 0xff;
@ -542,23 +538,14 @@ WRITE8_MEMBER(pmd85_state::pmd85_io_w)
} }
break; break;
case 0x08: /* ROM module connector */ case 0x08: /* ROM module connector */
switch (m_model) if (m_rom_module_present)
{ {
case PMD85_1: switch (offset & 0x80)
case PMD85_2: {
case PMD85_2A: case 0x80: /* ROM module 8255 */
case C2717: m_ppi8255_3->write(offset & 0x03, data);
case PMD85_3: break;
if (m_rom_module_present) }
{
switch (offset & 0x80)
{
case 0x80: /* ROM module 8255 */
m_ppi8255_3->write(offset & 0x03, data);
break;
}
}
break;
} }
break; break;
case 0x0c: /* I/O board */ case 0x0c: /* I/O board */
@ -567,10 +554,10 @@ WRITE8_MEMBER(pmd85_state::pmd85_io_w)
case 0x00: /* I/O board interfaces */ case 0x00: /* I/O board interfaces */
switch (offset & 0x70) switch (offset & 0x70)
{ {
case 0x10: /* 8251 (casette recorder, V24) */ case 0x10: /* 8251 (cassette recorder, V24) */
m_uart->write(offset & 0x01, data); m_uart->write(offset & 0x01, data);
break; break;
case 0x40: /* 8255 (GPIO/0, GPIO/0) */ case 0x40: /* 8255 (GPIO/0, GPIO/0) */
m_ppi8255_1->write(offset & 0x03, data); m_ppi8255_1->write(offset & 0x03, data);
break; break;
case 0x50: /* 8253 */ case 0x50: /* 8253 */
@ -587,6 +574,9 @@ WRITE8_MEMBER(pmd85_state::pmd85_io_w)
} }
break; 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) TIMER_CALLBACK_MEMBER(pmd85_state::pmd85_cassette_timer_callback)
{ {
int data; bool data;
int current_level; bool current_level;
if (!(m_io_dsw0->read() & 0x02)) /* V.24 / Tape Switch */ 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) switch (m_model)
{ {
case PMD85_1: case PMD85_1:
case ALFA:
if (m_clk_level_tape) if (m_clk_level_tape)
{ {
m_previous_level = (m_cassette->input() > 0.038) ? 1 : 0; 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 PMD85_2A:
case C2717: case C2717:
case PMD85_3: case PMD85_3:
case ALFA: // works for pmd852, pmd852a, pmd852b, pmd853, c2717, c2717pmd
/* not hardware data decoding */ m_uart->write_dsr( (m_cassette->input() > 0.038) ? 0 : 1);
return; return;
} }
} }
@ -705,9 +691,7 @@ TIMER_CALLBACK_MEMBER(pmd85_state::pmd85_cassette_timer_callback)
/* tape writing */ /* tape writing */
if (m_cassette->get_state()&CASSETTE_RECORD) if (m_cassette->get_state()&CASSETTE_RECORD)
{ {
data = m_cas_tx; m_cassette->output((m_txd ^ m_clk_level_tape) ? 1 : -1);
data ^= m_clk_level_tape;
m_cassette->output(data&0x01 ? 1 : -1);
m_clk_level_tape = m_clk_level_tape ? 0 : 1; m_clk_level_tape = m_clk_level_tape ? 0 : 1;
m_uart->write_txc(m_clk_level_tape); m_uart->write_txc(m_clk_level_tape);
@ -752,6 +736,13 @@ void pmd85_state::init_pmd851()
pmd85_common_driver_init(); 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() void pmd85_state::init_pmd852a()
{ {
m_model = PMD85_2A; m_model = PMD85_2A;
@ -804,13 +795,15 @@ void pmd85_state::machine_reset()
int i, j; int i, j;
/* checking for Rom Module */ /* checking for Rom Module */
m_rom_module_present = 0;
switch (m_model) switch (m_model)
{ {
case PMD85_1: case PMD85_1:
case PMD85_2:
case PMD85_2A: case PMD85_2A:
case PMD85_3: case PMD85_3:
case C2717: case C2717:
m_rom_module_present = (m_io_dsw0->read() & 0x01) ? 1 : 0; m_rom_module_present = BIT(m_io_dsw0->read(), 0);
break; break;
case ALFA: case ALFA:
case MATO: case MATO:
@ -826,7 +819,4 @@ void pmd85_state::machine_reset()
m_pmd853_memory_mapping = 1; m_pmd853_memory_mapping = 1;
m_startup_mem_map = 1; m_startup_mem_map = 1;
(this->*update_memory)(); (this->*update_memory)();
if (m_uart)
m_uart->write_cts(0);
} }