diff options
author | Robbbert <Robbbert@users.noreply.github.com> | 2020-07-10 02:41:24 +1000 |
---|---|---|
committer | Robbbert <Robbbert@users.noreply.github.com> | 2020-07-10 02:41:24 +1000 |
commit | 700d95e88f665f7ba0029ccb31684206432d92ee (patch) | |
tree | daf5cc0b15123465e19a5480cdf616cf3ba55a7f /src/mame | |
parent | be6924832da5675e8aa4f7cb3f901e4d9e2d4300 (diff) |
llc2: cleanup, added cassette
Diffstat (limited to 'src/mame')
-rw-r--r-- | src/mame/drivers/llc2.cpp | 189 |
1 files changed, 93 insertions, 96 deletions
diff --git a/src/mame/drivers/llc2.cpp b/src/mame/drivers/llc2.cpp index bd0b6d896c0..b22de1b0774 100644 --- a/src/mame/drivers/llc2.cpp +++ b/src/mame/drivers/llc2.cpp @@ -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, "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)); - z80pio_device& pio2(Z80PIO(config, "z80pio2", XTAL(3'000'000))); - pio2.in_pa_callback().set(FUNC(llc2_state::llc2_port2_a_r)); + 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)); - Z80CTC(config, "z80ctc", XTAL(3'000'000)); + 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 |