// license:BSD-3-Clause // copyright-holders:Miodrag Milanovic /*************************************************************************** Specialist machine driver by Miodrag Milanovic 20/03/2008 Cassette support 15/03/2008 Preliminary driver. ****************************************************************************/ #include "emu.h" #include "includes/special.h" /* Driver initialization */ void special_state::init_special() { /* set initialy ROM to be visible on first bank */ uint8_t *RAM = m_region_maincpu->base(); memset(RAM,0x0000,0x3000); // make first page empty by default m_bank1->configure_entries(1, 2, RAM, 0x0000); m_bank1->configure_entries(0, 2, RAM, 0xc000); } READ8_MEMBER( special_state::specialist_8255_porta_r ) { for (int i = 0; i < 8; i++) if (m_io_line[i]->read() != 0xff) return (1 << i) ^ 0xff; return 0xff; } READ8_MEMBER( special_state::specialist_8255_portb_r ) { uint8_t dat = 0xff; for (int i = 0; i < 8; i++) if (!BIT(m_specialist_8255_porta, i)) dat &= m_io_line[i]->read(); for (int i = 0; i < 4; i++) if (!BIT(m_specialist_8255_portc, i)) dat &= m_io_line[8 + i]->read(); // shift key if (BIT(~m_io_line[12]->read(), 0)) dat &= 0xfd; // cassette if (m_cassette->input() > 0.01) dat &= 0xfe; // strobe if a key is pressed if (dat < 0xfc) dat &= 0x7f; return dat; } READ8_MEMBER( special_state::specimx_8255_portb_r ) { uint8_t dat = 0xff; for (int i = 0; i < 8; i++) if (!BIT(m_specialist_8255_porta, i)) dat &= m_io_line[i]->read(); for (int i = 0; i < 4; i++) if (!BIT(m_specialist_8255_portc, i)) dat &= m_io_line[8 + i]->read(); // shift key if (BIT(~m_io_line[12]->read(), 0)) dat &= 0xfd; // cassette if (m_cassette->input() > 0.01) dat &= 0xfe; return dat; } READ8_MEMBER( special_state::specialist_8255_portc_r ) { for (int i = 0; i < 4; i++) if (m_io_line[8 + i]->read() != 0xff) return (1 << i) ^ 0x0f; return 0x0f; } WRITE8_MEMBER( special_state::specialist_8255_porta_w ) { m_specialist_8255_porta = data; } WRITE8_MEMBER( special_state::specialist_8255_portb_w ) { m_specialist_8255_portb = data; } WRITE8_MEMBER( special_state::specialist_8255_portc_w ) { m_specialist_8255_portc = data; m_cassette->output(BIT(data, 7) ? 1 : -1); m_dac->write(BIT(data, 5)); //beeper } void special_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { switch (id) { case TIMER_RESET: m_bank1->set_entry(0); break; case TIMER_PIT8253_GATES: { m_pit->write_gate0(0); m_pit->write_gate1(0); m_pit->write_gate2(0); break; } default: assert_always(false, "Unknown id in special_state::device_timer"); } } MACHINE_RESET_MEMBER(special_state,special) { timer_set(attotime::from_usec(10), TIMER_RESET); m_bank1->set_entry(1); } /* Specialist MX */ WRITE8_MEMBER( special_state::video_memory_w ) { m_ram->pointer()[0x9000 + offset] = data; m_specimx_colorram[offset] = m_specimx_color; } WRITE8_MEMBER( special_state::specimx_video_color_w ) { m_specimx_color = data; } READ8_MEMBER( special_state::specimx_video_color_r ) { return m_specimx_color; } void special_state::specimx_set_bank(offs_t i, uint8_t data) { address_space &space = m_maincpu->space(AS_PROGRAM); uint8_t *ram = m_ram->pointer(); space.install_write_bank(0xc000, 0xffbf, "bank3"); space.install_write_bank(0xffc0, 0xffdf, "bank4"); m_bank4->set_base(ram + 0xffc0); switch(i) { case 0 : space.install_write_bank(0x0000, 0x8fff, "bank1"); space.install_write_handler(0x9000, 0xbfff, write8_delegate(FUNC(special_state::video_memory_w), this)); m_bank1->set_base(ram); m_bank2->set_base(ram + 0x9000); m_bank3->set_base(ram + 0xc000); break; case 1 : space.install_write_bank(0x0000, 0x8fff, "bank1"); space.install_write_bank(0x9000, 0xbfff, "bank2"); m_bank1->set_base(ram + 0x10000); m_bank2->set_base(ram + 0x19000); m_bank3->set_base(ram + 0x1c000); break; case 2 : space.unmap_write(0x0000, 0x8fff); space.unmap_write(0x9000, 0xbfff); m_bank1->set_base(m_region_maincpu->base() + 0x10000); m_bank2->set_base(m_region_maincpu->base() + 0x19000); if (data & 0x80) m_bank3->set_base(ram + 0x1c000); else m_bank3->set_base(ram + 0xc000); break; } } WRITE8_MEMBER( special_state::specimx_select_bank ) { specimx_set_bank(offset, data); } MACHINE_START_MEMBER(special_state,specimx) { m_drive = 0; } MACHINE_RESET_MEMBER(special_state,specimx) { specimx_set_bank(2, 0); // Initiali load ROM disk timer_set(attotime::zero, TIMER_PIT8253_GATES); } READ8_MEMBER( special_state::specimx_disk_ctrl_r ) { return 0xff; } WRITE_LINE_MEMBER( special_state::fdc_drq ) { /* Clears HALT state of CPU when data is ready to read */ if(state) { m_maincpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE); } } WRITE8_MEMBER( special_state::specimx_disk_ctrl_w ) { floppy_image_device *floppy = nullptr; floppy_connector *con = m_fdd[m_drive & 1].target(); if(con) floppy = con->get_device(); m_fdc->set_floppy(floppy); floppy->mon_w(0); switch(offset) { case 0 : m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); break; case 2 : floppy->ss_w(data & 1); break; case 3 : m_drive = data & 1; break; } } /* Erik */ void special_state::erik_set_bank() { uint8_t bank1 = m_RR_register & 3; uint8_t bank2 = (m_RR_register >> 2) & 3; uint8_t bank3 = (m_RR_register >> 4) & 3; uint8_t bank4 = (m_RR_register >> 6) & 3; uint8_t *mem = m_region_maincpu->base(); uint8_t *ram = m_ram->pointer(); address_space &space = m_maincpu->space(AS_PROGRAM); space.install_write_bank(0x0000, 0x3fff, "bank1"); space.install_write_bank(0x4000, 0x8fff, "bank2"); space.install_write_bank(0x9000, 0xbfff, "bank3"); space.install_write_bank(0xc000, 0xefff, "bank4"); space.install_write_bank(0xf000, 0xf7ff, "bank5"); space.install_write_bank(0xf800, 0xffff, "bank6"); switch(bank1) { case 1: case 2: case 3: m_bank1->set_base(ram + 0x10000*(bank1-1)); break; case 0: space.unmap_write(0x0000, 0x3fff); m_bank1->set_base(mem + 0x10000); break; } switch(bank2) { case 1: case 2: case 3: m_bank2->set_base(ram + 0x10000*(bank2-1) + 0x4000); break; case 0: space.unmap_write(0x4000, 0x8fff); m_bank2->set_base(mem + 0x14000); break; } switch(bank3) { case 1: case 2: case 3: m_bank3->set_base(ram + 0x10000*(bank3-1) + 0x9000); break; case 0: space.unmap_write(0x9000, 0xbfff); m_bank3->set_base(mem + 0x19000); break; } switch(bank4) { case 1: case 2: case 3: m_bank4->set_base(ram + 0x10000*(bank4-1) + 0x0c000); m_bank5->set_base(ram + 0x10000*(bank4-1) + 0x0f000); m_bank6->set_base(ram + 0x10000*(bank4-1) + 0x0f800); break; case 0: space.unmap_write(0xc000, 0xefff); m_bank4->set_base(mem + 0x1c000); space.unmap_write(0xf000, 0xf7ff); space.nop_read(0xf000, 0xf7ff); space.install_readwrite_handler(0xf800, 0xf803, 0, 0x7fc, 0, read8_delegate(FUNC(i8255_device::read), (i8255_device*)m_ppi), write8_delegate(FUNC(i8255_device::write), (i8255_device*)m_ppi)); break; } } void special_state::init_erik() { m_erik_color_1 = 0; m_erik_color_2 = 0; m_erik_background = 0; } MACHINE_RESET_MEMBER(special_state,erik) { m_RR_register = 0x00; m_RC_register = 0x00; erik_set_bank(); } READ8_MEMBER( special_state::erik_rr_reg_r ) { return m_RR_register; } WRITE8_MEMBER( special_state::erik_rr_reg_w ) { m_RR_register = data; erik_set_bank(); } READ8_MEMBER( special_state::erik_rc_reg_r ) { return m_RC_register; } WRITE8_MEMBER( special_state::erik_rc_reg_w ) { m_RC_register = data; m_erik_color_1 = m_RC_register & 7; m_erik_color_2 = (m_RC_register >> 3) & 7; m_erik_background = BIT(m_RC_register, 6) + BIT(m_RC_register, 7) * 4; } READ8_MEMBER( special_state::erik_disk_reg_r ) { return 0xff; } WRITE8_MEMBER( special_state::erik_disk_reg_w ) { /* wd17xx_set_side (m_fdc,data & 1); wd17xx_set_drive(m_fdc,(data >> 1) & 1); wd17xx_dden_w(m_fdc, BIT(data, 2)); floppy_mon_w(floppy_get_device(machine(), BIT(data, 1)), 0); floppy_mon_w(floppy_get_device(machine(), BIT(data, 1) ^ 1), 1); floppy_drive_set_ready_state(floppy_get_device(machine(), BIT(data, 1)), 1, 1);*/ }