// license:BSD-3-Clause // copyright-holders:Miodrag Milanovic /*************************************************************************** PP-01 driver by Miodrag Milanovic 08/09/2008 Preliminary driver. ****************************************************************************/ #include "emu.h" #include "includes/pp01.h" void pp01_state::video_write_mode_w(uint8_t data) { m_video_write_mode = data & 0x0f; } void pp01_state::video_w(uint8_t block,uint16_t offset,uint8_t data,uint8_t part) { uint16_t addroffset = part ? 0x1000 : 0x0000; uint8_t *ram = m_ram->pointer(); if (BIT(m_video_write_mode,3)) { // Copy mode if(BIT(m_video_write_mode,0)) ram[0x6000+offset+addroffset] = data; else ram[0x6000+offset+addroffset] = 0; if(BIT(m_video_write_mode,1)) ram[0xa000+offset+addroffset] = data; else ram[0xa000+offset+addroffset] = 0; if(BIT(m_video_write_mode,2)) ram[0xe000+offset+addroffset] = data; else ram[0xe000+offset+addroffset] = 0; } else { if (block==0) ram[0x6000+offset+addroffset] = data; else if (block==1) ram[0xa000+offset+addroffset] = data; else if (block==2) ram[0xe000+offset+addroffset] = data; } } void pp01_state::video_r_1_w(offs_t offset, uint8_t data) { video_w(0,offset,data,0); } void pp01_state::video_g_1_w(offs_t offset, uint8_t data) { video_w(1,offset,data,0); } void pp01_state::video_b_1_w(offs_t offset, uint8_t data) { video_w(2,offset,data,0); } void pp01_state::video_r_2_w(offs_t offset, uint8_t data) { video_w(0,offset,data,1); } void pp01_state::video_g_2_w(offs_t offset, uint8_t data) { video_w(1,offset,data,1); } void pp01_state::video_b_2_w(offs_t offset, uint8_t data) { video_w(2,offset,data,1); } void pp01_state::set_memory(uint8_t block, uint8_t data) { uint8_t *mem = memregion("maincpu")->base(); address_space &space = m_maincpu->space(AS_PROGRAM); uint16_t startaddr = block*0x1000; uint16_t endaddr = startaddr+0xfff; if (data>=0xE0 && data<=0xEF) { // This is RAM space.install_read_bank (startaddr, endaddr, m_bank[block]); switch(data) { case 0xe6 : space.install_write_handler(startaddr, endaddr, write8sm_delegate(*this, FUNC(pp01_state::video_r_1_w))); break; case 0xe7: space.install_write_handler(startaddr, endaddr, write8sm_delegate(*this, FUNC(pp01_state::video_r_2_w))); break; case 0xea: space.install_write_handler(startaddr, endaddr, write8sm_delegate(*this, FUNC(pp01_state::video_g_1_w))); break; case 0xeb: space.install_write_handler(startaddr, endaddr, write8sm_delegate(*this, FUNC(pp01_state::video_g_2_w))); break; case 0xee: space.install_write_handler(startaddr, endaddr, write8sm_delegate(*this, FUNC(pp01_state::video_b_1_w))); break; case 0xef: space.install_write_handler(startaddr, endaddr, write8sm_delegate(*this, FUNC(pp01_state::video_b_2_w))); break; default: space.install_write_bank(startaddr, endaddr, m_bank[block]); break; } m_bank[block]->set_base(m_ram->pointer() + (data & 0x0F)* 0x1000); } else if (data>=0xFC) { space.install_read_bank (startaddr, endaddr, m_bank[block]); space.unmap_write(startaddr, endaddr); m_bank[block]->set_base(mem + (data & 0x03)* 0x1000); } else { logerror("%02x %02x\n",block,data); space.unmap_readwrite (startaddr, endaddr); } } void pp01_state::machine_reset() { int i; memset(m_memory_block,0xff,16); for(i=0;i<16;i++) { m_memory_block[i] = 0xff; set_memory(i, 0xff); } m_uart->write_cts(0); } void pp01_state::mem_block_w(offs_t offset, uint8_t data) { m_memory_block[offset] = data; set_memory(offset, data); } uint8_t pp01_state::mem_block_r(offs_t offset) { return m_memory_block[offset]; } void pp01_state::machine_start() { save_item(NAME(m_video_scroll)); save_item(NAME(m_memory_block)); save_item(NAME(m_video_write_mode)); save_item(NAME(m_key_line)); save_item(NAME(m_txe)); save_item(NAME(m_txd)); save_item(NAME(m_rts)); save_item(NAME(m_casspol)); save_item(NAME(m_cass_data)); } TIMER_DEVICE_CALLBACK_MEMBER( pp01_state::kansas_r ) { if (m_rts) { m_cass_data[1] = m_cass_data[2] = m_cass_data[3] = 0; m_casspol = 1; return; } m_cass_data[1]++; m_cass_data[2]++; uint8_t cass_ws = (m_cass->input() > +0.04) ? 1 : 0; if (cass_ws != m_cass_data[0]) { m_cass_data[0] = cass_ws; if (m_cass_data[1] > 13) m_casspol ^= 1; m_cass_data[1] = 0; m_cass_data[2] = 0; m_uart->write_rxd(m_casspol); } if ((m_cass_data[2] & 7)==2) { m_cass_data[3]++; m_uart->write_rxc(BIT(m_cass_data[3], 0)); } } WRITE_LINE_MEMBER(pp01_state::z2_w) { // incoming 1200Hz m_uart->write_txc(state); if (!m_txe) m_cass->output((m_txd ^ state) ? -1.0 : 1.0); } uint8_t pp01_state::ppi1_porta_r() { return m_video_scroll; } void pp01_state::ppi1_porta_w(uint8_t data) { m_video_scroll = data; } uint8_t pp01_state::ppi1_portb_r() { return m_io_keyboard[m_key_line]->read() | m_io_keyboard[16]->read(); } void pp01_state::ppi1_portb_w(uint8_t data) { //logerror("pp01_8255_portb_w %02x\n",data); } void pp01_state::ppi1_portc_w(uint8_t data) { if (BIT(data, 4)) m_key_line = data & 0x0f; else m_speaker->level_w(BIT(data, 0)); } uint8_t pp01_state::ppi1_portc_r() { return 0xff; }