mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
llc2: cleanup, added cassette
This commit is contained in:
parent
be6924832d
commit
700d95e88f
@ -2,24 +2,21 @@
|
||||
// copyright-holders:Miodrag Milanovic, Robbbert
|
||||
/******************************************************************************
|
||||
|
||||
LLC driver by Miodrag Milanovic
|
||||
LLC2 driver by Miodrag Milanovic
|
||||
|
||||
17/04/2009 Preliminary driver.
|
||||
2009-04-17 Preliminary driver.
|
||||
|
||||
July 2012, updates by Robbbert
|
||||
2012-07-?? Updates by Robbbert
|
||||
|
||||
Very little info available on these computers.
|
||||
The BEL character plays a short tune.
|
||||
In the monitor, it is case sensitive, most commands are uppercase,
|
||||
but some are lowercase.
|
||||
To start Basic, the command is b. To quit basic, use BYE.
|
||||
Inside Basic, it is not case-sensitive.
|
||||
|
||||
LLC2:
|
||||
The BEL character plays a short tune.
|
||||
In the monitor, it is case sensitive, most commands are uppercase,
|
||||
but some are lowercase.
|
||||
To start Basic, the command is b. To quit basic, use BYE.
|
||||
Inside Basic, it is not case-sensitive.
|
||||
|
||||
ToDo:
|
||||
- LLC2: Keyboard is incomplete
|
||||
- Lots of other things
|
||||
ToDo:
|
||||
- Unofficial expansions
|
||||
- Need software
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
@ -31,6 +28,7 @@
|
||||
#include "machine/ram.h"
|
||||
#include "machine/z80ctc.h"
|
||||
#include "machine/z80pio.h"
|
||||
#include "imagedev/cassette.h"
|
||||
#include "sound/spkrdev.h"
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
@ -47,6 +45,10 @@ public:
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_ram(*this, RAM_TAG)
|
||||
, m_p_chargen(*this, "chargen")
|
||||
, m_cass(*this, "cassette")
|
||||
, m_ctc(*this, "ctc")
|
||||
, m_bankr(*this, "bankr%u", 0U)
|
||||
, m_bankw(*this, "bankw%u", 0U)
|
||||
{ }
|
||||
|
||||
void llc2(machine_config &config);
|
||||
@ -56,42 +58,46 @@ public:
|
||||
private:
|
||||
void machine_start() override;
|
||||
void machine_reset() override;
|
||||
void llc2_rom_disable_w(u8 data);
|
||||
void llc2_basic_enable_w(u8 data);
|
||||
u8 llc2_port1_b_r();
|
||||
u8 llc2_port2_a_r();
|
||||
void llc2_port1_b_w(u8 data);
|
||||
u32 screen_update_llc2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void rom_disable_w(u8 data);
|
||||
void basic_enable_w(u8 data);
|
||||
u8 port1b_r();
|
||||
u8 port2a_r();
|
||||
void port1b_w(u8 data);
|
||||
u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
void io_map(address_map &map);
|
||||
void mem_map(address_map &map);
|
||||
|
||||
bool m_rv;
|
||||
required_device<speaker_sound_device> m_speaker;
|
||||
optional_shared_ptr<u8> m_vram;
|
||||
required_shared_ptr<u8> m_vram;
|
||||
required_device<z80_device> m_maincpu;
|
||||
required_device<ram_device> m_ram;
|
||||
required_region_ptr<u8> m_p_chargen;
|
||||
required_device<cassette_image_device> m_cass;
|
||||
required_device<z80ctc_device> m_ctc;
|
||||
required_memory_bank_array<2> m_bankr;
|
||||
required_memory_bank_array<2> m_bankw;
|
||||
};
|
||||
|
||||
/* Address maps */
|
||||
void llc2_state::mem_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x3fff).bankrw("bank1");
|
||||
map(0x4000, 0x5fff).bankrw("bank2");
|
||||
map(0x6000, 0xbfff).bankrw("bank3");
|
||||
map(0xc000, 0xffff).bankrw("bank4");
|
||||
map(0x0000, 0x3fff).bankr("bankr0").bankw("bankw0");
|
||||
map(0x4000, 0x5fff).bankr("bankr1").bankw("bankw1");
|
||||
map(0x6000, 0xbfff).ram();
|
||||
map(0xc000, 0xffff).ram().share("videoram");
|
||||
}
|
||||
|
||||
void llc2_state::io_map(address_map &map)
|
||||
{
|
||||
map.global_mask(0xff);
|
||||
map.unmap_value_high();
|
||||
map(0xE0, 0xE3).w(FUNC(llc2_state::llc2_rom_disable_w));
|
||||
map(0xE4, 0xE7).rw("z80pio2", FUNC(z80pio_device::read), FUNC(z80pio_device::write));
|
||||
map(0xE8, 0xEB).rw("z80pio1", FUNC(z80pio_device::read), FUNC(z80pio_device::write));
|
||||
map(0xEC, 0xEC).w(FUNC(llc2_state::llc2_basic_enable_w));
|
||||
map(0xF8, 0xFB).rw("z80ctc", FUNC(z80ctc_device::read), FUNC(z80ctc_device::write));
|
||||
map(0xE0, 0xE3).w(FUNC(llc2_state::rom_disable_w));
|
||||
map(0xE4, 0xE7).rw("pio2", FUNC(z80pio_device::read), FUNC(z80pio_device::write));
|
||||
map(0xE8, 0xEB).rw("pio1", FUNC(z80pio_device::read), FUNC(z80pio_device::write));
|
||||
map(0xEC, 0xEC).w(FUNC(llc2_state::basic_enable_w));
|
||||
map(0xF8, 0xFB).rw("ctc", FUNC(z80ctc_device::read), FUNC(z80ctc_device::write));
|
||||
}
|
||||
|
||||
/* Input ports */
|
||||
@ -102,74 +108,53 @@ INPUT_PORTS_END
|
||||
/* Driver initialization */
|
||||
void llc2_state::init_llc2()
|
||||
{
|
||||
m_vram.set_target( m_ram->pointer() + 0xc000,m_vram.bytes());
|
||||
u8 *r = m_ram->pointer();
|
||||
u8 *m = memregion("maincpu")->base();
|
||||
|
||||
m_bankr[0]->configure_entry(0, r);
|
||||
m_bankr[0]->configure_entry(1, m);
|
||||
m_bankw[0]->configure_entry(0, r);
|
||||
m_bankr[1]->configure_entry(0, r+0x4000);
|
||||
m_bankr[1]->configure_entry(1, m+0x4000);
|
||||
m_bankw[1]->configure_entry(0, r+0x4000);
|
||||
}
|
||||
|
||||
void llc2_state::machine_reset()
|
||||
{
|
||||
address_space &space = m_maincpu->space(AS_PROGRAM);
|
||||
u8 *ram = m_ram->pointer();
|
||||
|
||||
space.unmap_write(0x0000, 0x3fff);
|
||||
membank("bank1")->set_base(memregion("maincpu")->base());
|
||||
|
||||
space.unmap_write(0x4000, 0x5fff);
|
||||
membank("bank2")->set_base(ram + 0x4000);
|
||||
|
||||
space.unmap_write(0x6000, 0xbfff);
|
||||
membank("bank3")->set_base(ram + 0x6000);
|
||||
|
||||
space.install_write_bank(0xc000, 0xffff, "bank4");
|
||||
membank("bank4")->set_base(ram + 0xc000);
|
||||
m_bankr[0]->set_entry(1);
|
||||
m_bankw[0]->set_entry(0);
|
||||
m_bankr[1]->set_entry(0);
|
||||
m_bankw[1]->set_entry(0);
|
||||
}
|
||||
|
||||
void llc2_state::llc2_rom_disable_w(u8 data)
|
||||
void llc2_state::rom_disable_w(u8 data)
|
||||
{
|
||||
address_space &mem_space = m_maincpu->space(AS_PROGRAM);
|
||||
u8 *ram = m_ram->pointer();
|
||||
|
||||
mem_space.install_write_bank(0x0000, 0xbfff, "bank1");
|
||||
membank("bank1")->set_base(ram);
|
||||
|
||||
mem_space.install_write_bank(0x4000, 0x5fff, "bank2");
|
||||
membank("bank2")->set_base(ram + 0x4000);
|
||||
|
||||
mem_space.install_write_bank(0x6000, 0xbfff, "bank3");
|
||||
membank("bank3")->set_base(ram + 0x6000);
|
||||
|
||||
mem_space.install_write_bank(0xc000, 0xffff, "bank4");
|
||||
membank("bank4")->set_base(ram + 0xc000);
|
||||
|
||||
m_bankr[0]->set_entry(0);
|
||||
}
|
||||
|
||||
void llc2_state::llc2_basic_enable_w(u8 data)
|
||||
void llc2_state::basic_enable_w(u8 data)
|
||||
{
|
||||
address_space &mem_space = m_maincpu->space(AS_PROGRAM);
|
||||
if (BIT(data, 1))
|
||||
{
|
||||
mem_space.unmap_write(0x4000, 0x5fff);
|
||||
membank("bank2")->set_base(memregion("maincpu")->base() + 0x4000);
|
||||
}
|
||||
else
|
||||
{
|
||||
mem_space.install_write_bank(0x4000, 0x5fff, "bank2");
|
||||
membank("bank2")->set_base(m_ram->pointer() + 0x4000);
|
||||
}
|
||||
|
||||
m_bankr[1]->set_entry(BIT(data, 1));
|
||||
}
|
||||
|
||||
u8 llc2_state::llc2_port1_b_r()
|
||||
u8 llc2_state::port1b_r()
|
||||
{
|
||||
return 0;
|
||||
u8 data = 0xfd;
|
||||
|
||||
if (m_cass->input() > 0.03)
|
||||
data |= 0x02;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void llc2_state::llc2_port1_b_w(u8 data)
|
||||
void llc2_state::port1b_w(u8 data)
|
||||
{
|
||||
m_cass->output(BIT(data, 0) ? -1.0 : +1.0);
|
||||
m_speaker->level_w(BIT(data, 6));
|
||||
m_rv = BIT(data, 5);
|
||||
}
|
||||
|
||||
u8 llc2_state::llc2_port2_a_r()
|
||||
u8 llc2_state::port2a_r()
|
||||
{
|
||||
return 0; // bit 2 low or hangs on ^Z^X^C sequence
|
||||
}
|
||||
@ -179,7 +164,7 @@ void llc2_state::machine_start()
|
||||
save_item(NAME(m_rv));
|
||||
}
|
||||
|
||||
u32 llc2_state::screen_update_llc2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
u32 llc2_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
u8 y,ra,chr,gfx,inv, inv1=m_rv ? 0xff : 0;
|
||||
u16 sy=0,ma=0,x;
|
||||
@ -222,15 +207,16 @@ u32 llc2_state::screen_update_llc2(screen_device &screen, bitmap_ind16 &bitmap,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const z80_daisy_config llc2_daisy_chain[] =
|
||||
static const z80_daisy_config daisy_chain[] =
|
||||
{
|
||||
{ "z80pio1" },
|
||||
{ "z80ctc" },
|
||||
{ "ctc" },
|
||||
{ "pio1" },
|
||||
{ "pio2" },
|
||||
{ nullptr }
|
||||
};
|
||||
|
||||
/* F4 Character Displayer */
|
||||
static const gfx_layout llc2_charlayout =
|
||||
static const gfx_layout charlayout =
|
||||
{
|
||||
8, 8, /* 8 x 8 characters */
|
||||
256, /* 256 characters */
|
||||
@ -244,15 +230,15 @@ static const gfx_layout llc2_charlayout =
|
||||
};
|
||||
|
||||
static GFXDECODE_START( gfx_llc2 )
|
||||
GFXDECODE_ENTRY( "chargen", 0x0000, llc2_charlayout, 0, 1 )
|
||||
GFXDECODE_ENTRY( "chargen", 0x0000, charlayout, 0, 1 )
|
||||
GFXDECODE_END
|
||||
|
||||
/* Machine driver */
|
||||
void llc2_state::llc2(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
Z80(config, m_maincpu, XTAL(3'000'000));
|
||||
m_maincpu->set_daisy_config(llc2_daisy_chain);
|
||||
Z80(config, m_maincpu, 12_MHz_XTAL / 4);
|
||||
m_maincpu->set_daisy_config(daisy_chain);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &llc2_state::mem_map);
|
||||
m_maincpu->set_addrmap(AS_IO, &llc2_state::io_map);
|
||||
|
||||
@ -262,7 +248,7 @@ void llc2_state::llc2(machine_config &config)
|
||||
screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
|
||||
screen.set_size(64*8, 32*8);
|
||||
screen.set_visarea(0, 64*8-1, 0, 32*8-1);
|
||||
screen.set_screen_update(FUNC(llc2_state::screen_update_llc2));
|
||||
screen.set_screen_update(FUNC(llc2_state::screen_update));
|
||||
screen.set_palette("palette");
|
||||
|
||||
GFXDECODE(config, "gfxdecode", "palette", gfx_llc2);
|
||||
@ -270,17 +256,28 @@ void llc2_state::llc2(machine_config &config)
|
||||
|
||||
/* sound hardware */
|
||||
SPEAKER(config, "mono").front_center();
|
||||
SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.15);
|
||||
SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.50);
|
||||
|
||||
z80pio_device& pio1(Z80PIO(config, "z80pio1", XTAL(3'000'000)));
|
||||
z80pio_device& pio1(Z80PIO(config, "pio1", 12_MHz_XTAL / 4));
|
||||
pio1.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
|
||||
pio1.in_pa_callback().set(K7659_KEYBOARD_TAG, FUNC(k7659_keyboard_device::read));
|
||||
pio1.in_pb_callback().set(FUNC(llc2_state::llc2_port1_b_r));
|
||||
pio1.out_pb_callback().set(FUNC(llc2_state::llc2_port1_b_w));
|
||||
pio1.in_pb_callback().set(FUNC(llc2_state::port1b_r));
|
||||
pio1.out_pb_callback().set(FUNC(llc2_state::port1b_w));
|
||||
|
||||
z80pio_device& pio2(Z80PIO(config, "z80pio2", XTAL(3'000'000)));
|
||||
pio2.in_pa_callback().set(FUNC(llc2_state::llc2_port2_a_r));
|
||||
z80pio_device& pio2(Z80PIO(config, "pio2", 12_MHz_XTAL / 4));
|
||||
pio2.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
|
||||
pio2.in_pa_callback().set(FUNC(llc2_state::port2a_r));
|
||||
|
||||
Z80CTC(config, "z80ctc", XTAL(3'000'000));
|
||||
Z80CTC(config, m_ctc, 12_MHz_XTAL / 4);
|
||||
m_ctc->intr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
|
||||
m_ctc->set_clk<0>(12_MHz_XTAL / 8);
|
||||
m_ctc->set_clk<1>(12_MHz_XTAL / 8);
|
||||
m_ctc->set_clk<2>(50); // comes from deep in the video section, assumed to be 50Hz
|
||||
m_ctc->zc_callback<2>().set(m_ctc, FUNC(z80ctc_device::trg3));
|
||||
|
||||
CASSETTE(config, m_cass);
|
||||
m_cass->set_default_state(CASSETTE_STOPPED | CASSETTE_SPEAKER_ENABLED | CASSETTE_MOTOR_ENABLED);
|
||||
m_cass->add_route(ALL_OUTPUTS, "mono", 0.05);
|
||||
|
||||
K7659_KEYBOARD(config, K7659_KEYBOARD_TAG, 0);
|
||||
|
||||
@ -291,11 +288,11 @@ void llc2_state::llc2(machine_config &config)
|
||||
/* ROM definition */
|
||||
ROM_START( llc2 )
|
||||
ROM_REGION( 0x6000, "maincpu", ROMREGION_ERASEFF )
|
||||
ROM_LOAD( "scchmon_91.bin", 0x0000, 0x1000, CRC(218d8236) SHA1(b8297272cc79751afc2eb8688d99b40691346dcb) )
|
||||
ROM_LOAD( "scchmon_91.d35", 0x0000, 0x1000, CRC(218d8236) SHA1(b8297272cc79751afc2eb8688d99b40691346dcb) )
|
||||
ROM_LOAD( "gsbasic.bin", 0x4000, 0x2000, CRC(78a5f388) SHA1(e7b475b98dce36b24540ad11eb89046ddb4f02af) )
|
||||
|
||||
ROM_REGION( 0x0800, "chargen", 0 )
|
||||
ROM_LOAD ("llc2font.bin", 0x0000, 0x0800, CRC(ce53e55d) SHA1(da23d93f14a8a1f8d82bb72470a96b0bfd81ed1b) )
|
||||
ROM_LOAD ("llc2font.d17", 0x0000, 0x0800, CRC(ce53e55d) SHA1(da23d93f14a8a1f8d82bb72470a96b0bfd81ed1b) )
|
||||
ROM_END
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user