// license:BSD-3-Clause // copyright-holders:Miodrag Milanovic /*************************************************************************** Pecom driver by Miodrag Milanovic 08/11/2008 Preliminary driver. ****************************************************************************/ #include "emu.h" #include "includes/pecom.h" TIMER_CALLBACK_MEMBER(pecom_state::reset_tick) { m_reset = 1; } void pecom_state::machine_start() { static const char *const keynames[] = { "LINE0", "LINE1", "LINE2", "LINE3", "LINE4", "LINE5", "LINE6", "LINE7", "LINE8", "LINE9", "LINE10", "LINE11", "LINE12", "LINE13", "LINE14", "LINE15", "LINE16", "LINE17", "LINE18", "LINE19", "LINE20", "LINE21", "LINE22", "LINE23", "LINE24","LINE25" }; for ( int i = 0; i < 26; i++ ) { m_io_ports[i] = ioport(keynames[i]); } m_reset_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pecom_state::reset_tick),this)); } void pecom_state::machine_reset() { uint8_t *rom = memregion(CDP1802_TAG)->base(); address_space &space = m_cdp1802->space(AS_PROGRAM); space.unmap_write(0x0000, 0x3fff); space.install_write_bank(0x4000, 0x7fff, "bank2"); space.unmap_write(0xf000, 0xf7ff); space.unmap_write(0xf800, 0xffff); space.install_read_bank (0xf000, 0xf7ff, "bank3"); space.install_read_bank (0xf800, 0xffff, "bank4"); m_bank1->set_base(rom + 0x8000); m_bank2->set_base(m_ram->pointer() + 0x4000); m_bank3->set_base(rom + 0xf000); m_bank4->set_base(rom + 0xf800); m_reset = 0; m_dma = 0; m_reset_timer->adjust(attotime::from_msec(5)); } READ8_MEMBER(pecom_state::pecom_cdp1869_charram_r) { return m_cdp1869->char_ram_r(space, offset); } WRITE8_MEMBER(pecom_state::pecom_cdp1869_charram_w) { return m_cdp1869->char_ram_w(space, offset, data); } READ8_MEMBER(pecom_state::pecom_cdp1869_pageram_r) { return m_cdp1869->page_ram_r(space, offset); } WRITE8_MEMBER(pecom_state::pecom_cdp1869_pageram_w) { return m_cdp1869->page_ram_w(space, offset, data); } WRITE8_MEMBER(pecom_state::pecom_bank_w) { address_space &space2 = m_cdp1802->space(AS_PROGRAM); uint8_t *rom = memregion(CDP1802_TAG)->base(); m_cdp1802->space(AS_PROGRAM).install_write_bank(0x0000, 0x3fff, "bank1"); m_bank1->set_base(m_ram->pointer() + 0x0000); if (data==2) { space2.install_read_handler (0xf000, 0xf7ff, read8_delegate(FUNC(pecom_state::pecom_cdp1869_charram_r),this)); space2.install_write_handler(0xf000, 0xf7ff, write8_delegate(FUNC(pecom_state::pecom_cdp1869_charram_w),this)); space2.install_read_handler (0xf800, 0xffff, read8_delegate(FUNC(pecom_state::pecom_cdp1869_pageram_r),this)); space2.install_write_handler(0xf800, 0xffff, write8_delegate(FUNC(pecom_state::pecom_cdp1869_pageram_w),this)); } else { space2.unmap_write(0xf000, 0xf7ff); space2.unmap_write(0xf800, 0xffff); space2.install_read_bank (0xf000, 0xf7ff, "bank3"); space2.install_read_bank (0xf800, 0xffff, "bank4"); m_bank3->set_base(rom + 0xf000); m_bank4->set_base(rom + 0xf800); } } READ8_MEMBER(pecom_state::pecom_keyboard_r) { /* INP command BUS -> M(R(X)) BUS -> D so on each input, address is also set, 8 lower bits are used as input for keyboard Address is available on address bus during reading of value from port, and that is used to determine keyboard line reading */ uint16_t addr = m_cdp1802->state_int(cosmac_device::COSMAC_R0 + m_cdp1802->state_int(cosmac_device::COSMAC_X)); /* just in case somone is reading non existing ports */ if (addr<0x7cca || addr>0x7ce3) return 0; return m_io_ports[addr - 0x7cca]->read() & 0x03; } /* CDP1802 Interface */ READ_LINE_MEMBER(pecom_state::clear_r) { return m_reset; } READ_LINE_MEMBER(pecom_state::ef2_r) { int shift = BIT(m_io_cnt->read(), 1); double cas = m_cassette->input(); return (cas > 0.0) | shift; } /* static COSMAC_EF_READ( pecom64_ef_r ) { int flags = 0x0f; double valcas = (cassette_device_image(device->machine()));->input() uint8_t val = device->machine().root_device().ioport("CNT")->read(); if ((val & 0x04)==0x04 && pecom_prev_caps_state==0) { pecom_caps_state = (pecom_caps_state==4) ? 0 : 4; // Change CAPS state } pecom_prev_caps_state = val & 0x04; if (valcas!=0.0) { // If there is any cassette signal val = (val & 0x0D); // remove EF2 from SHIFT flags -= EF2; if ( valcas > 0.00) flags += EF2; } flags -= (val & 0x0b) + pecom_caps_state; return flags; } */ WRITE_LINE_MEMBER(pecom_state::q_w) { m_cassette->output(state ? -1.0 : +1.0); } WRITE8_MEMBER(pecom_state::sc_w ) { switch (data) { case COSMAC_STATE_CODE_S0_FETCH: // not connected break; case COSMAC_STATE_CODE_S1_EXECUTE: break; case COSMAC_STATE_CODE_S2_DMA: // DMA acknowledge clears the DMAOUT request m_cdp1802->set_input_line(COSMAC_INPUT_LINE_DMAOUT, CLEAR_LINE); break; case COSMAC_STATE_CODE_S3_INTERRUPT: break; } }