mirror of
https://github.com/holub/mame
synced 2025-07-04 17:38:08 +03:00
(nw) amu880: added a cassette interface
This commit is contained in:
parent
55e52efcd1
commit
7080aa92fd
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
|
|
||||||
- keyboard repeat
|
- keyboard repeat
|
||||||
- shift lock is not PORT_TOGGLE, instead RS flipflop
|
- shift lock is not PORT_TOGGLE, instead RS flipflop
|
||||||
@ -18,10 +18,27 @@
|
|||||||
- eprom programmer
|
- eprom programmer
|
||||||
- power off
|
- power off
|
||||||
|
|
||||||
|
Cassette considerations
|
||||||
|
|
||||||
|
- It operates at 4883 baud but may not be fully compatible with real
|
||||||
|
hardware. A partial translation of the available text seems to
|
||||||
|
indicate an overcomplicated and unreliable interface. The one
|
||||||
|
implemented is 100% reliable at the same speed. I've been unable
|
||||||
|
to locate any real recordings to compare against.
|
||||||
|
- To save a range of memory: S name start end
|
||||||
|
- To load it back: L name
|
||||||
|
- To save an unnamed file: S "" start end
|
||||||
|
- To load an unnamed file: L
|
||||||
|
- When loading, if the name doesn't match, there's no message, and no
|
||||||
|
way to determine the name.
|
||||||
|
- For some reason, the system saves the file 3 times. Maybe it was an
|
||||||
|
attempt to guard against the inherent unreliable design.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
#include "includes/huebler.h"
|
#include "includes/huebler.h"
|
||||||
|
#include "sound/wave.h"
|
||||||
|
#include "speaker.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
|
|
||||||
/* Keyboard */
|
/* Keyboard */
|
||||||
@ -103,7 +120,7 @@ void amu880_state::amu880_io(address_map &map)
|
|||||||
map(0x0c, 0x0f).rw(Z80PIO2_TAG, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt));
|
map(0x0c, 0x0f).rw(Z80PIO2_TAG, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt));
|
||||||
map(0x10, 0x13).rw(Z80PIO1_TAG, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt));
|
map(0x10, 0x13).rw(Z80PIO1_TAG, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt));
|
||||||
map(0x14, 0x17).rw(Z80CTC_TAG, FUNC(z80ctc_device::read), FUNC(z80ctc_device::write));
|
map(0x14, 0x17).rw(Z80CTC_TAG, FUNC(z80ctc_device::read), FUNC(z80ctc_device::write));
|
||||||
map(0x18, 0x1b).rw(m_z80sio, FUNC(z80sio0_device::ba_cd_r), FUNC(z80sio0_device::ba_cd_w));
|
map(0x18, 0x1b).rw(m_sio, FUNC(z80sio0_device::ba_cd_r), FUNC(z80sio0_device::ba_cd_w));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Input Ports */
|
/* Input Ports */
|
||||||
@ -252,19 +269,36 @@ WRITE_LINE_MEMBER(amu880_state::ctc_z0_w)
|
|||||||
|
|
||||||
WRITE_LINE_MEMBER(amu880_state::ctc_z2_w)
|
WRITE_LINE_MEMBER(amu880_state::ctc_z2_w)
|
||||||
{
|
{
|
||||||
/* cassette transmit/receive clock */
|
/* cassette clock @ 39kHz */
|
||||||
|
if (state)
|
||||||
|
{
|
||||||
|
m_cnt++;
|
||||||
|
switch (m_cnt & 7) // divide by 8 to get 4883Hz
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
m_cassette->output(m_cassbit ? 1.0 : -1.0);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
m_sio->txca_w(0);
|
||||||
|
m_sio->rxca_w(0);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
m_sio->txca_w(1);
|
||||||
|
m_sio->rxca_w(1);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
m_sio->rxa_w((m_cassette->input() > 0.04) ? 1 : 0);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Z80-SIO Interface */
|
/* Z80-SIO Interface */
|
||||||
|
|
||||||
TIMER_DEVICE_CALLBACK_MEMBER( amu880_state::tape_tick )
|
|
||||||
{
|
|
||||||
m_z80sio->rxa_w(m_cassette->input() < 0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
WRITE_LINE_MEMBER(amu880_state::cassette_w)
|
WRITE_LINE_MEMBER(amu880_state::cassette_w)
|
||||||
{
|
{
|
||||||
m_cassette->output(state ? -1.0 : +1.0);
|
m_cassbit = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Z80 Daisy Chain */
|
/* Z80 Daisy Chain */
|
||||||
@ -329,11 +363,15 @@ void amu880_state::amu880(machine_config &config)
|
|||||||
GFXDECODE(config, "gfxdecode", m_palette, gfx_amu880);
|
GFXDECODE(config, "gfxdecode", m_palette, gfx_amu880);
|
||||||
PALETTE(config, m_palette, palette_device::MONOCHROME);
|
PALETTE(config, m_palette, palette_device::MONOCHROME);
|
||||||
|
|
||||||
|
/* sound hardware */
|
||||||
|
SPEAKER(config, "mono").front_center();
|
||||||
|
WAVE(config, "wave", m_cassette).add_route(ALL_OUTPUTS, "mono", 0.05);
|
||||||
|
|
||||||
/* devices */
|
/* devices */
|
||||||
z80ctc_device& ctc(Z80CTC(config, Z80CTC_TAG, XTAL(10'000'000)/4));
|
z80ctc_device& ctc(Z80CTC(config, Z80CTC_TAG, XTAL(10'000'000)/4));
|
||||||
ctc.intr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
|
ctc.intr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
|
||||||
ctc.zc_callback<0>().set(FUNC(amu880_state::ctc_z0_w));
|
ctc.zc_callback<0>().set(FUNC(amu880_state::ctc_z0_w));
|
||||||
ctc.zc_callback<1>().set(m_z80sio, FUNC(z80dart_device::rxtxcb_w));
|
ctc.zc_callback<1>().set(m_sio, FUNC(z80dart_device::rxtxcb_w));
|
||||||
ctc.zc_callback<2>().set(FUNC(amu880_state::ctc_z2_w));
|
ctc.zc_callback<2>().set(FUNC(amu880_state::ctc_z2_w));
|
||||||
|
|
||||||
z80pio_device& pio1(Z80PIO(config, Z80PIO1_TAG, XTAL(10'000'000)/4));
|
z80pio_device& pio1(Z80PIO(config, Z80PIO1_TAG, XTAL(10'000'000)/4));
|
||||||
@ -342,14 +380,12 @@ void amu880_state::amu880(machine_config &config)
|
|||||||
z80pio_device& pio2(Z80PIO(config, Z80PIO2_TAG, XTAL(10'000'000)/4));
|
z80pio_device& pio2(Z80PIO(config, Z80PIO2_TAG, XTAL(10'000'000)/4));
|
||||||
pio2.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
|
pio2.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
|
||||||
|
|
||||||
Z80SIO0(config, m_z80sio, XTAL(10'000'000)/4); // U856
|
Z80SIO0(config, m_sio, XTAL(10'000'000)/4); // U856
|
||||||
m_z80sio->out_txda_callback().set(FUNC(amu880_state::cassette_w));
|
m_sio->out_txda_callback().set(FUNC(amu880_state::cassette_w));
|
||||||
m_z80sio->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
|
m_sio->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
|
||||||
|
|
||||||
CASSETTE(config, m_cassette);
|
CASSETTE(config, m_cassette);
|
||||||
m_cassette->set_default_state(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_MUTED);
|
m_cassette->set_default_state(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED);
|
||||||
|
|
||||||
TIMER(config, "tape").configure_periodic(FUNC(amu880_state::tape_tick), attotime::from_hz(44100));
|
|
||||||
|
|
||||||
/* internal ram */
|
/* internal ram */
|
||||||
RAM(config, RAM_TAG).set_default_size("64K");
|
RAM(config, RAM_TAG).set_default_size("64K");
|
||||||
|
@ -28,7 +28,7 @@ public:
|
|||||||
: driver_device(mconfig, type, tag)
|
: driver_device(mconfig, type, tag)
|
||||||
, m_maincpu(*this, Z80_TAG)
|
, m_maincpu(*this, Z80_TAG)
|
||||||
, m_cassette(*this, "cassette")
|
, m_cassette(*this, "cassette")
|
||||||
, m_z80sio(*this, Z80SIO_TAG)
|
, m_sio(*this, Z80SIO_TAG)
|
||||||
, m_palette(*this, "palette")
|
, m_palette(*this, "palette")
|
||||||
, m_kb_rom(*this, "keyboard")
|
, m_kb_rom(*this, "keyboard")
|
||||||
, m_char_rom(*this, "chargen")
|
, m_char_rom(*this, "chargen")
|
||||||
@ -44,11 +44,12 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void machine_start() override;
|
virtual void machine_start() override;
|
||||||
|
virtual void machine_reset() override { m_maincpu->set_pc(0xf000); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
required_device<z80_device> m_maincpu;
|
required_device<z80_device> m_maincpu;
|
||||||
required_device<cassette_image_device> m_cassette;
|
required_device<cassette_image_device> m_cassette;
|
||||||
required_device<z80dart_device> m_z80sio;
|
required_device<z80dart_device> m_sio;
|
||||||
required_device<palette_device> m_palette;
|
required_device<palette_device> m_palette;
|
||||||
required_memory_region m_kb_rom;
|
required_memory_region m_kb_rom;
|
||||||
required_memory_region m_char_rom;
|
required_memory_region m_char_rom;
|
||||||
@ -59,7 +60,6 @@ private:
|
|||||||
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||||
|
|
||||||
DECLARE_READ8_MEMBER( keyboard_r );
|
DECLARE_READ8_MEMBER( keyboard_r );
|
||||||
TIMER_DEVICE_CALLBACK_MEMBER( tape_tick );
|
|
||||||
|
|
||||||
void scan_keyboard();
|
void scan_keyboard();
|
||||||
|
|
||||||
@ -77,6 +77,10 @@ private:
|
|||||||
DECLARE_WRITE_LINE_MEMBER(cassette_w);
|
DECLARE_WRITE_LINE_MEMBER(cassette_w);
|
||||||
void amu880_io(address_map &map);
|
void amu880_io(address_map &map);
|
||||||
void amu880_mem(address_map &map);
|
void amu880_mem(address_map &map);
|
||||||
|
|
||||||
|
// cassette variables
|
||||||
|
u8 m_cnt;
|
||||||
|
bool m_cassbit;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user