(MESS) Alphatronic: Can load the user-supplied tape. Sometimes it can load its own tapes.

This commit is contained in:
Robbbert 2013-06-17 12:01:51 +00:00
parent 6fbd776a21
commit 03d31fe618

View File

@ -4,18 +4,23 @@
skeleton driver skeleton driver
z80 + HD46505 as a CRTC z80 + HD46505SP as a CRTC
Has a socket for monochrome (to the standard amber monitor), Other chips: 8251, 8257, 8259
and another for RGB. We emulate this with a configuration switch. Crystals: 16MHz, 17.73447MHz
Floppy format: 2 sides, 40 tracks, 16 sectors, 256 bytes = 320kb.
FDC (unknown) is in a plug-in module.
The Z80 must start at E000, but unlike other designs (Super80 for Has a socket for monochrome (to the standard amber monitor),
example) which causes the ROMs to appear everywhere during boot, and another for RGB. We emulate this with a configuration switch.
this one (it seems) holds the data bus low until E000 is reached.
This kind of boot still needs to be emulated.
This machine has 64k RAM, the ROMs being copied into RAM when The Z80 must start at E000, but unlike other designs (Super80 for
needed. example) which cause the ROMs to appear everywhere during boot,
this one (it seems) holds the data bus low until E000 is reached.
This kind of boot still needs to be emulated.
This machine has 64k RAM, the ROMs being copied into RAM when
needed.
***************************************************************************/ ***************************************************************************/
@ -49,7 +54,7 @@ public:
m_cass(*this, "cassette"), m_cass(*this, "cassette"),
m_beep(*this, "beeper"), m_beep(*this, "beeper"),
m_p_ram(*this, "p_ram"), m_p_ram(*this, "p_ram"),
m_p_videoram(*this, "p_videoram"){ } m_p_videoram(*this, "videoram"){ }
required_device<cpu_device> m_maincpu; required_device<cpu_device> m_maincpu;
required_device<mc6845_device> m_crtc; required_device<mc6845_device> m_crtc;
@ -62,6 +67,8 @@ public:
DECLARE_INPUT_CHANGED_MEMBER(alphatro_break); DECLARE_INPUT_CHANGED_MEMBER(alphatro_break);
DECLARE_READ_LINE_MEMBER(rxdata_callback); DECLARE_READ_LINE_MEMBER(rxdata_callback);
DECLARE_WRITE_LINE_MEMBER(txdata_callback); DECLARE_WRITE_LINE_MEMBER(txdata_callback);
TIMER_DEVICE_CALLBACK_MEMBER(alphatro_c);
TIMER_DEVICE_CALLBACK_MEMBER(alphatro_p);
required_shared_ptr<UINT8> m_p_ram; required_shared_ptr<UINT8> m_p_ram;
required_shared_ptr<UINT8> m_p_videoram; required_shared_ptr<UINT8> m_p_videoram;
@ -75,6 +82,8 @@ public:
private: private:
UINT8 m_timer_bit; UINT8 m_timer_bit;
UINT8 m_cass_data[4];
bool m_cass_state;
virtual void palette_init(); virtual void palette_init();
}; };
@ -105,6 +114,9 @@ WRITE8_MEMBER( alphatro_state::port10_w )
} }
m_cass->change_state( BIT(data, 3) ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR); m_cass->change_state( BIT(data, 3) ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR);
if (BIT(data,2))
m_cass_state = 1;
} }
void alphatro_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) void alphatro_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
@ -128,12 +140,12 @@ void alphatro_state::device_timer(emu_timer &timer, device_timer_id id, int para
READ_LINE_MEMBER( alphatro_state::rxdata_callback ) READ_LINE_MEMBER( alphatro_state::rxdata_callback )
{ {
return (m_cass->input() > -0.1) ? 1 : 0; return (bool)m_cass_data[2];
} }
WRITE_LINE_MEMBER( alphatro_state::txdata_callback ) WRITE_LINE_MEMBER( alphatro_state::txdata_callback )
{ {
m_cass->output( (state) ? 0.8 : -0.8); m_cass_state = state;
} }
void alphatro_state::video_start() void alphatro_state::video_start()
@ -186,7 +198,7 @@ INPUT_CHANGED_MEMBER( alphatro_state::alphatro_break )
static ADDRESS_MAP_START( alphatro_map, AS_PROGRAM, 8, alphatro_state ) static ADDRESS_MAP_START( alphatro_map, AS_PROGRAM, 8, alphatro_state )
AM_RANGE(0x0000, 0xefff) AM_RAM AM_SHARE("p_ram") AM_RANGE(0x0000, 0xefff) AM_RAM AM_SHARE("p_ram")
AM_RANGE(0xf000, 0xffff) AM_RAM AM_SHARE("p_videoram") AM_RANGE(0xf000, 0xffff) AM_RAM AM_SHARE("videoram")
ADDRESS_MAP_END ADDRESS_MAP_END
static ADDRESS_MAP_START( alphatro_io, AS_IO, 8, alphatro_state ) static ADDRESS_MAP_START( alphatro_io, AS_IO, 8, alphatro_state )
@ -353,17 +365,20 @@ void alphatro_state::machine_start()
void alphatro_state::machine_reset() void alphatro_state::machine_reset()
{ {
// do what the IPL does // do what the IPL does
// UINT8* RAM = machine().device<ram_device>("ram")->pointer();
UINT8* ROM = memregion("maincpu")->base(); UINT8* ROM = memregion("maincpu")->base();
m_maincpu->set_pc(0xe000); m_maincpu->set_pc(0xe000);
memcpy(m_p_ram, ROM, 0xf000); // copy BASIC to RAM, which the undumped IPL is supposed to do. memcpy(m_p_ram, ROM, 0xf000); // copy BASIC to RAM, which the undumped IPL is supposed to do.
memcpy(m_p_videoram, ROM+0x1000, 0x1000); memcpy(m_p_videoram, ROM+0x1000, 0x1000);
// membank("bank1")->set_base(RAM);
// probably not correct, exact meaning of port is unknown, vblank/vsync is too slow. // probably not correct, exact meaning of port is unknown, vblank/vsync is too slow.
m_sys_timer->adjust(attotime::from_usec(10),0,attotime::from_usec(10)); m_sys_timer->adjust(attotime::from_usec(10),0,attotime::from_usec(10));
m_serial_timer->adjust(attotime::from_hz(500),0,attotime::from_hz(500)); // USART clock - this is a guesstimate m_serial_timer->adjust(attotime::from_hz(19225),0,attotime::from_hz(19225)); // USART clock - this value loads a real tape
m_timer_bit = 0; m_timer_bit = 0;
m_cass_state = 1;
m_cass_data[0] = 0;
m_cass_data[1] = 0;
m_cass_data[2] = 0;
m_cass_data[3] = 0;
m_beep->set_state(0); m_beep->set_state(0);
m_beep->set_frequency(950); /* piezo-device needs to be measured */ m_beep->set_frequency(950); /* piezo-device needs to be measured */
} }
@ -412,11 +427,34 @@ static const i8251_interface alphatro_usart_interface =
DEVCB_NULL DEVCB_NULL
}; };
TIMER_DEVICE_CALLBACK_MEMBER(alphatro_state::alphatro_c)
{
m_cass_data[3]++;
if (m_cass_state)
m_cass->output(BIT(m_cass_data[3], 0) ? -1.0 : +1.0); // 2400Hz
else
m_cass->output(BIT(m_cass_data[3], 1) ? -1.0 : +1.0); // 1200Hz
}
TIMER_DEVICE_CALLBACK_MEMBER(alphatro_state::alphatro_p)
{
/* cassette - turn 1200/2400Hz to a bit */
m_cass_data[1]++;
UINT8 cass_ws = (m_cass->input() > +0.03) ? 1 : 0;
if (cass_ws != m_cass_data[0])
{
m_cass_data[0] = cass_ws;
m_cass_data[2] = ((m_cass_data[1] < 12) ? 1 : 0);
m_cass_data[1] = 0;
}
}
static const cassette_interface alphatro_cassette_interface = static const cassette_interface alphatro_cassette_interface =
{ {
cassette_default_formats, cassette_default_formats,
NULL, NULL,
//(cassette_state) (CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED),
(cassette_state) (CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED), (cassette_state) (CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED),
"alphatro_cass", "alphatro_cass",
NULL NULL
@ -446,13 +484,14 @@ static MACHINE_CONFIG_START( alphatro, alphatro_state )
MCFG_SOUND_WAVE_ADD(WAVE_TAG, "cassette") MCFG_SOUND_WAVE_ADD(WAVE_TAG, "cassette")
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
/* Devices */ /* Devices */
MCFG_MC6845_ADD("crtc", MC6845, XTAL_12_288MHz / 8, alphatro_crtc6845_interface) // clk unknown MCFG_MC6845_ADD("crtc", MC6845, XTAL_12_288MHz / 8, alphatro_crtc6845_interface) // clk unknown
MCFG_I8251_ADD("usart", alphatro_usart_interface) MCFG_I8251_ADD("usart", alphatro_usart_interface)
MCFG_CASSETTE_ADD("cassette", alphatro_cassette_interface) MCFG_CASSETTE_ADD("cassette", alphatro_cassette_interface)
MCFG_TIMER_DRIVER_ADD_PERIODIC("alphatro_c", alphatro_state, alphatro_c, attotime::from_hz(4800))
MCFG_TIMER_DRIVER_ADD_PERIODIC("alphatro_p", alphatro_state, alphatro_p, attotime::from_hz(40000))
MCFG_RAM_ADD("ram") MCFG_RAM_ADD("ram")
MCFG_RAM_DEFAULT_SIZE("64K") MCFG_RAM_DEFAULT_SIZE("64K")