pecom: cleanup

This commit is contained in:
Robbbert 2020-07-24 00:02:26 +10:00
parent 388051084e
commit c98148855b
4 changed files with 156 additions and 183 deletions

View File

@ -2,37 +2,54 @@
// copyright-holders:Miodrag Milanovic
/***************************************************************************
Pecom driver by Miodrag Milanovic
Pecom driver by Miodrag Milanovic
08/11/2008 Preliminary driver.
2008-11-08 Preliminary driver.
Need to press capslock twice to get caps to engage - bug?
- All commands to be in UPPERCASE.
- Change background colour: SCR n
- Enter monitor: PROB (B to exit)
- If Capslock is engaged, then Shift doesn't work.
- Control hangs the machine while it is pressed. It doesn't work in the
expected way.
- Don't touch the Shift key while loading a tape because it will corrupt
the data.
- The screen will flash in a crazy epileptic fashion while loading a tape.
Beware!
TODO:
- Cassette: can load its own recordings, but not those from software list
(software-list tapes are slower & wobbly)
- Both machines currently have 32k ram.
- Autorepeat seems a bit fast
****************************************************************************/
#include "emu.h"
#include "includes/pecom.h"
#include "softlist.h"
#include "speaker.h"
/* Address maps */
void pecom_state::pecom64_mem(address_map &map)
void pecom_state::mem_map(address_map &map)
{
map(0x0000, 0x3fff).bankrw("bank1");
map(0x4000, 0x7fff).bankrw("bank2");
map(0x8000, 0xbfff).rom(); // ROM 1
map(0xc000, 0xf3ff).rom(); // ROM 2
map(0x0000, 0x7fff).ram().share("mainram");
map(0x0000, 0x3fff).bankr("bank1");
map(0x8000, 0xefff).rom().region("maincpu",0);
map(0xf000, 0xf7ff).bankrw("bank3"); // CDP1869 / ROM
map(0xf800, 0xffff).bankrw("bank4"); // CDP1869 / ROM
}
void pecom_state::pecom64_io(address_map &map)
void pecom_state::io_map(address_map &map)
{
map(0x01, 0x01).w(FUNC(pecom_state::pecom_bank_w));
map(0x03, 0x03).r(FUNC(pecom_state::pecom_keyboard_r));
map(0x03, 0x07).w(FUNC(pecom_state::pecom_cdp1869_w));
map(0x01, 0x01).w(FUNC(pecom_state::bank_w));
map(0x03, 0x03).r(FUNC(pecom_state::keyboard_r));
map(0x03, 0x07).w(FUNC(pecom_state::cdp1869_w));
}
void pecom_state::cdp1869_page_ram(address_map &map)
{
map(0x000, 0x3ff).mirror(0x400).ram();
}
/* Input ports */
@ -50,12 +67,12 @@ void pecom_state::pecom64_io(address_map &map)
Being keys distributed on four lines, it makes a bit difficult to accurately remap them
on modern keyboards. Hence, we move by default Up/Down/Left/Right to Cursor Keys and
use LEft/Right Ctrl/Alt keys for the remaining keys. Due to the unnatural emulated keyboard
use Left/Right Ctrl/Alt keys for the remaining keys. Due to the unnatural emulated keyboard
mappings, this is another situation where natural keyboard comes very handy! */
INPUT_CHANGED_MEMBER(pecom_state::ef_w)
{
m_cdp1802->set_input_line((int)param, newval);
m_maincpu->set_input_line((int)param, newval);
}
static INPUT_PORTS_START( pecom )
@ -164,8 +181,8 @@ static INPUT_PORTS_START( pecom )
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Del") PORT_CODE(KEYCODE_TAB) PORT_CHAR(UCHAR_MAMEKEY(DEL))
PORT_START("CNT")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Ctrl") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_2) PORT_CHANGED_MEMBER(DEVICE_SELF, pecom_state, ef_w, COSMAC_INPUT_LINE_EF1)
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Shift") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_SHIFT_1)
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Ctrl") PORT_CODE(KEYCODE_LCONTROL) PORT_CHANGED_MEMBER(DEVICE_SELF, pecom_state, ef_w, COSMAC_INPUT_LINE_EF1)
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Caps") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) PORT_TOGGLE PORT_CHANGED_MEMBER(DEVICE_SELF, pecom_state, ef_w, COSMAC_INPUT_LINE_EF3)
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Break") PORT_CODE(KEYCODE_MINUS) PORT_CHANGED_MEMBER(DEVICE_SELF, pecom_state, ef_w, COSMAC_INPUT_LINE_EF4)
INPUT_PORTS_END
@ -174,47 +191,54 @@ INPUT_PORTS_END
void pecom_state::pecom64(machine_config &config)
{
/* basic machine hardware */
CDP1802(config, m_cdp1802, cdp1869_device::DOT_CLK_PAL);
m_cdp1802->set_addrmap(AS_PROGRAM, &pecom_state::pecom64_mem);
m_cdp1802->set_addrmap(AS_IO, &pecom_state::pecom64_io);
m_cdp1802->wait_cb().set_constant(1);
m_cdp1802->clear_cb().set(FUNC(pecom_state::clear_r));
m_cdp1802->ef2_cb().set(FUNC(pecom_state::ef2_r));
m_cdp1802->q_cb().set(FUNC(pecom_state::q_w));
m_cdp1802->sc_cb().set(FUNC(pecom_state::sc_w));
CDP1802(config, m_maincpu, cdp1869_device::DOT_CLK_PAL);
m_maincpu->set_addrmap(AS_PROGRAM, &pecom_state::mem_map);
m_maincpu->set_addrmap(AS_IO, &pecom_state::io_map);
m_maincpu->wait_cb().set_constant(1);
m_maincpu->clear_cb().set(FUNC(pecom_state::clear_r));
m_maincpu->ef2_cb().set(FUNC(pecom_state::ef2_r));
m_maincpu->q_cb().set(FUNC(pecom_state::q_w));
m_maincpu->sc_cb().set(FUNC(pecom_state::sc_w));
// sound and video hardware
pecom_video(config);
SPEAKER(config, "mono").front_center();
CDP1869(config, m_cdp1869, cdp1869_device::DOT_CLK_PAL, &pecom_state::cdp1869_page_ram);
m_cdp1869->add_pal_screen(config, "screen", cdp1869_device::DOT_CLK_PAL);
m_cdp1869->set_color_clock(cdp1869_device::COLOR_CLK_PAL);
m_cdp1869->set_pcb_read_callback(FUNC(pecom_state::pcb_r));
m_cdp1869->set_char_ram_read_callback(FUNC(pecom_state::char_ram_r));
m_cdp1869->set_char_ram_write_callback(FUNC(pecom_state::char_ram_w));
m_cdp1869->pal_ntsc_callback().set_constant(1);
m_cdp1869->prd_callback().set(FUNC(pecom_state::prd_w));
m_cdp1869->add_route(ALL_OUTPUTS, "mono", 0.25);
// devices
CASSETTE(config, m_cassette);
m_cassette->set_default_state(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED);
m_cassette->add_route(ALL_OUTPUTS, "mono", 0.05);
m_cassette->set_interface("pecom_cass");
SOFTWARE_LIST(config, "cass_list").set_original("pecom_cass");
/* internal ram */
RAM(config, RAM_TAG).set_default_size("32K").set_default_value(0x00);
}
/* ROM definition */
ROM_START( pecom32 )
ROM_REGION( 0x10000, CDP1802_TAG, ROMREGION_ERASEFF )
ROM_LOAD( "090786.bin", 0x8000, 0x4000, CRC(b3b1ea23) SHA1(de69f22568161ced801973345fa39d6d207b9e8c) )
ROM_REGION( 0x8000, "maincpu", ROMREGION_ERASEFF )
ROM_LOAD( "090786.bin", 0x0000, 0x4000, CRC(b3b1ea23) SHA1(de69f22568161ced801973345fa39d6d207b9e8c) )
ROM_END
ROM_START( pecom64 )
ROM_REGION( 0x10000, CDP1802_TAG, ROMREGION_ERASEFF )
ROM_REGION( 0x8000, "maincpu", ROMREGION_ERASEFF )
ROM_SYSTEM_BIOS(0, "ver4", "version 4")
ROMX_LOAD( "rom_1_g_24.02.88_l.bin", 0x8000, 0x4000, CRC(9a433b47) SHA1(dadb8c399e0a25a2693e10e42a2d7fc2ea9ad427), ROM_BIOS(0) )
ROMX_LOAD( "rom_2_g_24.02.88_d.bin", 0xc000, 0x4000, CRC(2116cadc) SHA1(03f11055cd221d438a40a41874af8fba0fa116d9), ROM_BIOS(0) )
ROMX_LOAD( "rom_1_g_24.02.88_l.bin", 0x0000, 0x4000, CRC(9a433b47) SHA1(dadb8c399e0a25a2693e10e42a2d7fc2ea9ad427), ROM_BIOS(0) )
ROMX_LOAD( "rom_2_g_24.02.88_d.bin", 0x4000, 0x4000, CRC(2116cadc) SHA1(03f11055cd221d438a40a41874af8fba0fa116d9), ROM_BIOS(0) )
ROM_SYSTEM_BIOS(1, "ver1", "version 1")
ROMX_LOAD( "170887-rom1.bin", 0x8000, 0x4000, CRC(43710fb4) SHA1(f84f75061c9ac3e34af93141ecabd3c955881aa2), ROM_BIOS(1) )
ROMX_LOAD( "170887-rom2.bin", 0xc000, 0x4000, CRC(d0d34f08) SHA1(7baab17d1e68771b8dcef97d0fffc655beabef28), ROM_BIOS(1) )
ROMX_LOAD( "170887-rom1.bin", 0x0000, 0x4000, CRC(43710fb4) SHA1(f84f75061c9ac3e34af93141ecabd3c955881aa2), ROM_BIOS(1) )
ROMX_LOAD( "170887-rom2.bin", 0x4000, 0x4000, CRC(d0d34f08) SHA1(7baab17d1e68771b8dcef97d0fffc655beabef28), ROM_BIOS(1) )
ROM_END
/* Driver */
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
COMP( 1986, pecom32, 0, 0, pecom64, pecom, pecom_state, empty_init, "Ei Nis", "Pecom 32", 0)
COMP( 1987, pecom64, pecom32, 0, pecom64, pecom, pecom_state, empty_init, "Ei Nis", "Pecom 64", 0)
COMP( 1986, pecom32, 0, 0, pecom64, pecom, pecom_state, empty_init, "Ei Nis (Elektronska Industrija Nis)", "Pecom 32", MACHINE_SUPPORTS_SAVE )
COMP( 1987, pecom64, pecom32, 0, pecom64, pecom, pecom_state, empty_init, "Ei Nis (Elektronska Industrija Nis)", "Pecom 64", MACHINE_SUPPORTS_SAVE )

View File

@ -7,80 +7,69 @@
#include "cpu/cosmac/cosmac.h"
#include "imagedev/cassette.h"
#include "machine/ram.h"
#include "sound/cdp1869.h"
#define SCREEN_TAG "screen"
#define CDP1802_TAG "cdp1802"
#define CDP1869_TAG "cdp1869"
#define PECOM_CHAR_RAM_SIZE 0x800
class pecom_state : public driver_device
{
public:
pecom_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_cdp1802(*this, CDP1802_TAG),
m_cdp1869(*this, CDP1869_TAG),
m_cassette(*this, "cassette"),
m_ram(*this, RAM_TAG),
m_bank1(*this, "bank1"),
m_bank2(*this, "bank2"),
m_bank3(*this, "bank3"),
m_bank4(*this, "bank4"),
m_io_cnt(*this, "CNT"),
m_io_ports(*this, "LINE%u", 0U)
pecom_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_cdp1869(*this, "cdp1869")
, m_cassette(*this, "cassette")
, m_bank1(*this, "bank1")
, m_bank3(*this, "bank3")
, m_bank4(*this, "bank4")
, m_rom(*this, "maincpu")
, m_ram(*this, "mainram")
, m_io_cnt(*this, "CNT")
, m_io_keyboard(*this, "LINE%d", 0U)
{ }
DECLARE_INPUT_CHANGED_MEMBER(ef_w);
void pecom64(machine_config &config);
protected:
uint8_t pecom_cdp1869_charram_r(offs_t offset);
void pecom_cdp1869_charram_w(offs_t offset, uint8_t data);
uint8_t pecom_cdp1869_pageram_r(offs_t offset);
void pecom_cdp1869_pageram_w(offs_t offset, uint8_t data);
void pecom_bank_w(uint8_t data);
uint8_t pecom_keyboard_r();
void pecom_cdp1869_w(offs_t offset, uint8_t data);
private:
uint8_t cdp1869_charram_r(offs_t offset);
void cdp1869_charram_w(offs_t offset, uint8_t data);
uint8_t cdp1869_pageram_r(offs_t offset);
void cdp1869_pageram_w(offs_t offset, uint8_t data);
void bank_w(uint8_t data);
uint8_t keyboard_r();
void cdp1869_w(offs_t offset, uint8_t data);
TIMER_CALLBACK_MEMBER(reset_tick);
DECLARE_READ_LINE_MEMBER(clear_r);
DECLARE_READ_LINE_MEMBER(ef2_r);
DECLARE_WRITE_LINE_MEMBER(q_w);
void sc_w(uint8_t data);
DECLARE_WRITE_LINE_MEMBER(pecom_prd_w);
CDP1869_CHAR_RAM_READ_MEMBER(pecom_char_ram_r);
CDP1869_CHAR_RAM_WRITE_MEMBER(pecom_char_ram_w);
CDP1869_PCB_READ_MEMBER(pecom_pcb_r);
DECLARE_WRITE_LINE_MEMBER(prd_w);
CDP1869_CHAR_RAM_READ_MEMBER(char_ram_r);
CDP1869_CHAR_RAM_WRITE_MEMBER(char_ram_w);
CDP1869_PCB_READ_MEMBER(pcb_r);
virtual void machine_start() override;
virtual void machine_reset() override;
virtual void video_start() override;
void pecom_video(machine_config &config);
void cdp1869_page_ram(address_map &map);
void pecom64_io(address_map &map);
void pecom64_mem(address_map &map);
private:
required_device<cosmac_device> m_cdp1802;
required_device<cdp1869_device> m_cdp1869;
void io_map(address_map &map);
void mem_map(address_map &map);
std::unique_ptr<uint8_t[]> m_charram; /* character generator ROM */
int m_reset; /* CPU mode */
int m_dma; /* memory refresh DMA */
bool m_reset; /* CPU mode */
bool m_dma; /* memory refresh DMA */
/* timers */
emu_timer *m_reset_timer; /* power on reset timer */
required_device<cosmac_device> m_maincpu;
required_device<cdp1869_device> m_cdp1869;
required_device<cassette_image_device> m_cassette;
required_device<ram_device> m_ram;
required_memory_bank m_bank1;
required_memory_bank m_bank2;
required_memory_bank m_bank3;
required_memory_bank m_bank4;
required_region_ptr<u8> m_rom;
required_shared_ptr<u8> m_ram;
required_ioport m_io_cnt;
required_ioport_array<26> m_io_ports;
required_ioport_array<26> m_io_keyboard;
};
#endif // MAME_INCLUDES_PECOM_H

View File

@ -17,79 +17,65 @@ TIMER_CALLBACK_MEMBER(pecom_state::reset_tick)
m_reset = 1;
}
void pecom_state::machine_start()
{
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);
address_space &space = m_maincpu->space(AS_PROGRAM);
m_bank1->set_entry(1);
space.unmap_write(0x0000, 0x3fff);
space.install_write_bank(0x4000, 0x7fff, "bank2");
space.unmap_write(0xf000, 0xf7ff);
space.unmap_write(0xf800, 0xffff);
space.unmap_write(0xf000, 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_bank3->set_base(m_rom + 0x7000);
m_bank4->set_base(m_rom + 0x7800);
m_reset = 0;
m_dma = 0;
m_reset_timer->adjust(attotime::from_msec(5));
}
uint8_t pecom_state::pecom_cdp1869_charram_r(offs_t offset)
uint8_t pecom_state::cdp1869_charram_r(offs_t offset)
{
return m_cdp1869->char_ram_r(offset);
}
void pecom_state::pecom_cdp1869_charram_w(offs_t offset, uint8_t data)
void pecom_state::cdp1869_charram_w(offs_t offset, uint8_t data)
{
return m_cdp1869->char_ram_w(offset, data);
}
uint8_t pecom_state::pecom_cdp1869_pageram_r(offs_t offset)
uint8_t pecom_state::cdp1869_pageram_r(offs_t offset)
{
return m_cdp1869->page_ram_r(offset);
}
void pecom_state::pecom_cdp1869_pageram_w(offs_t offset, uint8_t data)
void pecom_state::cdp1869_pageram_w(offs_t offset, uint8_t data)
{
return m_cdp1869->page_ram_w(offset, data);
}
void pecom_state::pecom_bank_w(uint8_t data)
void pecom_state::bank_w(uint8_t data)
{
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);
address_space &space = m_maincpu->space(AS_PROGRAM);
m_bank1->set_entry(0);
if (data==2)
{
space2.install_read_handler (0xf000, 0xf7ff, read8sm_delegate(*this, FUNC(pecom_state::pecom_cdp1869_charram_r)));
space2.install_write_handler(0xf000, 0xf7ff, write8sm_delegate(*this, FUNC(pecom_state::pecom_cdp1869_charram_w)));
space2.install_read_handler (0xf800, 0xffff, read8sm_delegate(*this, FUNC(pecom_state::pecom_cdp1869_pageram_r)));
space2.install_write_handler(0xf800, 0xffff, write8sm_delegate(*this, FUNC(pecom_state::pecom_cdp1869_pageram_w)));
space.install_read_handler (0xf000, 0xf7ff, read8sm_delegate(*this, FUNC(pecom_state::cdp1869_charram_r)));
space.install_write_handler(0xf000, 0xf7ff, write8sm_delegate(*this, FUNC(pecom_state::cdp1869_charram_w)));
space.install_read_handler (0xf800, 0xffff, read8sm_delegate(*this, FUNC(pecom_state::cdp1869_pageram_r)));
space.install_write_handler(0xf800, 0xffff, write8sm_delegate(*this, FUNC(pecom_state::cdp1869_pageram_w)));
}
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);
space.unmap_write(0xf000, 0xffff);
space.install_read_bank (0xf000, 0xf7ff, "bank3");
space.install_read_bank (0xf800, 0xffff, "bank4");
m_bank3->set_base(m_rom + 0x7000);
m_bank4->set_base(m_rom + 0x7800);
}
}
uint8_t pecom_state::pecom_keyboard_r()
uint8_t pecom_state::keyboard_r()
{
/*
INP command BUS -> M(R(X)) BUS -> D
@ -97,10 +83,10 @@ uint8_t pecom_state::pecom_keyboard_r()
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));
uint16_t addr = m_maincpu->state_int(cosmac_device::COSMAC_R0 + m_maincpu->state_int(cosmac_device::COSMAC_X));
/* just in case someone is reading non existing ports */
if (addr<0x7cca || addr>0x7ce3) return 0;
return m_io_ports[addr - 0x7cca]->read() & 0x03;
return m_io_keyboard[addr - 0x7cca]->read();
}
/* CDP1802 Interface */
@ -112,10 +98,29 @@ READ_LINE_MEMBER(pecom_state::clear_r)
READ_LINE_MEMBER(pecom_state::ef2_r)
{
int shift = BIT(m_io_cnt->read(), 1);
bool shift = BIT(m_io_cnt->read(), 1);
double cas = m_cassette->input();
return (cas > 0.0) | shift;
return (cas < -0.02) | shift; // touching shift kills cassette load
}
WRITE_LINE_MEMBER(pecom_state::q_w)
{
m_cassette->output(state ? -1.0 : +1.0);
}
void pecom_state::sc_w(uint8_t data)
{
switch (data)
{
case COSMAC_STATE_CODE_S2_DMA:
// DMA acknowledge clears the DMAOUT request
m_maincpu->set_input_line(COSMAC_INPUT_LINE_DMAOUT, CLEAR_LINE);
break;
default:
break;
}
}
/*
@ -140,28 +145,4 @@ static COSMAC_EF_READ( pecom64_ef_r )
return flags;
}
*/
WRITE_LINE_MEMBER(pecom_state::q_w)
{
m_cassette->output(state ? -1.0 : +1.0);
}
void pecom_state::sc_w(uint8_t data)
{
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;
}
}

View File

@ -11,13 +11,10 @@
#include "emu.h"
#include "includes/pecom.h"
#include "sound/wave.h"
#include "speaker.h"
void pecom_state::pecom_cdp1869_w(offs_t offset, uint8_t data)
void pecom_state::cdp1869_w(offs_t offset, uint8_t data)
{
uint16_t ma = m_cdp1802->get_memory_address();
uint16_t ma = m_maincpu->get_memory_address();
switch (offset + 3)
{
@ -43,12 +40,7 @@ void pecom_state::pecom_cdp1869_w(offs_t offset, uint8_t data)
}
}
void pecom_state::cdp1869_page_ram(address_map &map)
{
map(0x000, 0x3ff).mirror(0x400).ram();
}
CDP1869_CHAR_RAM_READ_MEMBER(pecom_state::pecom_char_ram_r )
CDP1869_CHAR_RAM_READ_MEMBER(pecom_state::char_ram_r )
{
uint8_t column = pmd & 0x7f;
uint16_t charaddr = (column << 4) | cma;
@ -56,7 +48,7 @@ CDP1869_CHAR_RAM_READ_MEMBER(pecom_state::pecom_char_ram_r )
return m_charram[charaddr];
}
CDP1869_CHAR_RAM_WRITE_MEMBER(pecom_state::pecom_char_ram_w )
CDP1869_CHAR_RAM_WRITE_MEMBER(pecom_state::char_ram_w )
{
uint8_t column = pmd & 0x7f;
uint16_t charaddr = (column << 4) | cma;
@ -64,45 +56,32 @@ CDP1869_CHAR_RAM_WRITE_MEMBER(pecom_state::pecom_char_ram_w )
m_charram[charaddr] = data;
}
CDP1869_PCB_READ_MEMBER(pecom_state::pecom_pcb_r )
CDP1869_PCB_READ_MEMBER(pecom_state::pcb_r )
{
return BIT(pmd, 7);
}
WRITE_LINE_MEMBER(pecom_state::pecom_prd_w)
WRITE_LINE_MEMBER(pecom_state::prd_w)
{
// every other PRD triggers a DMAOUT request
if (m_dma)
{
m_cdp1802->set_input_line(COSMAC_INPUT_LINE_DMAOUT, HOLD_LINE);
}
m_maincpu->set_input_line(COSMAC_INPUT_LINE_DMAOUT, HOLD_LINE);
m_dma = !m_dma;
}
void pecom_state::video_start()
void pecom_state::machine_start()
{
m_bank1->configure_entry(0, m_ram);
m_bank1->configure_entry(1, m_rom);
/* allocate memory */
m_charram = std::make_unique<uint8_t[]>(PECOM_CHAR_RAM_SIZE);
m_charram = std::make_unique<uint8_t[]>(0x0800);
/* register for state saving */
save_item(NAME(m_reset));
save_item(NAME(m_dma));
save_pointer(NAME(m_charram), PECOM_CHAR_RAM_SIZE);
save_pointer(NAME(m_charram), 0x0800);
m_reset_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pecom_state::reset_tick),this));
}
void pecom_state::pecom_video(machine_config &config)
{
SPEAKER(config, "mono").front_center();
CDP1869(config, m_cdp1869, cdp1869_device::DOT_CLK_PAL, &pecom_state::cdp1869_page_ram);
m_cdp1869->add_pal_screen(config, SCREEN_TAG, cdp1869_device::DOT_CLK_PAL);
m_cdp1869->set_color_clock(cdp1869_device::COLOR_CLK_PAL);
m_cdp1869->set_pcb_read_callback(FUNC(pecom_state::pecom_pcb_r));
m_cdp1869->set_char_ram_read_callback(FUNC(pecom_state::pecom_char_ram_r));
m_cdp1869->set_char_ram_write_callback(FUNC(pecom_state::pecom_char_ram_w));
m_cdp1869->pal_ntsc_callback().set_constant(1);
m_cdp1869->prd_callback().set(FUNC(pecom_state::pecom_prd_w));
m_cdp1869->add_route(ALL_OUTPUTS, "mono", 0.25);
WAVE(config, "wave", "cassette").add_route(ALL_OUTPUTS, "mono", 0.25);
}