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

@ -4,35 +4,52 @@
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 "emu.h"
#include "includes/pecom.h" #include "includes/pecom.h"
#include "softlist.h"
#include "speaker.h" #include "speaker.h"
/* Address maps */ /* Address maps */
void pecom_state::pecom64_mem(address_map &map) void pecom_state::mem_map(address_map &map)
{ {
map(0x0000, 0x3fff).bankrw("bank1"); map(0x0000, 0x7fff).ram().share("mainram");
map(0x4000, 0x7fff).bankrw("bank2"); map(0x0000, 0x3fff).bankr("bank1");
map(0x8000, 0xbfff).rom(); // ROM 1 map(0x8000, 0xefff).rom().region("maincpu",0);
map(0xc000, 0xf3ff).rom(); // ROM 2
map(0xf000, 0xf7ff).bankrw("bank3"); // CDP1869 / ROM map(0xf000, 0xf7ff).bankrw("bank3"); // CDP1869 / ROM
map(0xf800, 0xffff).bankrw("bank4"); // 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(0x01, 0x01).w(FUNC(pecom_state::bank_w));
map(0x03, 0x03).r(FUNC(pecom_state::pecom_keyboard_r)); map(0x03, 0x03).r(FUNC(pecom_state::keyboard_r));
map(0x03, 0x07).w(FUNC(pecom_state::pecom_cdp1869_w)); 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 */ /* 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 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 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! */ mappings, this is another situation where natural keyboard comes very handy! */
INPUT_CHANGED_MEMBER(pecom_state::ef_w) 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 ) 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_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Del") PORT_CODE(KEYCODE_TAB) PORT_CHAR(UCHAR_MAMEKEY(DEL))
PORT_START("CNT") 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( 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_LCONTROL) PORT_CHAR(UCHAR_SHIFT_1) 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( 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) 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 INPUT_PORTS_END
@ -174,47 +191,54 @@ INPUT_PORTS_END
void pecom_state::pecom64(machine_config &config) void pecom_state::pecom64(machine_config &config)
{ {
/* basic machine hardware */ /* basic machine hardware */
CDP1802(config, m_cdp1802, cdp1869_device::DOT_CLK_PAL); CDP1802(config, m_maincpu, cdp1869_device::DOT_CLK_PAL);
m_cdp1802->set_addrmap(AS_PROGRAM, &pecom_state::pecom64_mem); m_maincpu->set_addrmap(AS_PROGRAM, &pecom_state::mem_map);
m_cdp1802->set_addrmap(AS_IO, &pecom_state::pecom64_io); m_maincpu->set_addrmap(AS_IO, &pecom_state::io_map);
m_cdp1802->wait_cb().set_constant(1); m_maincpu->wait_cb().set_constant(1);
m_cdp1802->clear_cb().set(FUNC(pecom_state::clear_r)); m_maincpu->clear_cb().set(FUNC(pecom_state::clear_r));
m_cdp1802->ef2_cb().set(FUNC(pecom_state::ef2_r)); m_maincpu->ef2_cb().set(FUNC(pecom_state::ef2_r));
m_cdp1802->q_cb().set(FUNC(pecom_state::q_w)); m_maincpu->q_cb().set(FUNC(pecom_state::q_w));
m_cdp1802->sc_cb().set(FUNC(pecom_state::sc_w)); m_maincpu->sc_cb().set(FUNC(pecom_state::sc_w));
// sound and video hardware SPEAKER(config, "mono").front_center();
pecom_video(config);
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 // devices
CASSETTE(config, m_cassette); CASSETTE(config, m_cassette);
m_cassette->set_default_state(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED); 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"); m_cassette->set_interface("pecom_cass");
SOFTWARE_LIST(config, "cass_list").set_original("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 definition */
ROM_START( pecom32 ) ROM_START( pecom32 )
ROM_REGION( 0x10000, CDP1802_TAG, ROMREGION_ERASEFF ) ROM_REGION( 0x8000, "maincpu", ROMREGION_ERASEFF )
ROM_LOAD( "090786.bin", 0x8000, 0x4000, CRC(b3b1ea23) SHA1(de69f22568161ced801973345fa39d6d207b9e8c) ) ROM_LOAD( "090786.bin", 0x0000, 0x4000, CRC(b3b1ea23) SHA1(de69f22568161ced801973345fa39d6d207b9e8c) )
ROM_END ROM_END
ROM_START( pecom64 ) ROM_START( pecom64 )
ROM_REGION( 0x10000, CDP1802_TAG, ROMREGION_ERASEFF ) ROM_REGION( 0x8000, "maincpu", ROMREGION_ERASEFF )
ROM_SYSTEM_BIOS(0, "ver4", "version 4") 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_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", 0xc000, 0x4000, CRC(2116cadc) SHA1(03f11055cd221d438a40a41874af8fba0fa116d9), 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") ROM_SYSTEM_BIOS(1, "ver1", "version 1")
ROMX_LOAD( "170887-rom1.bin", 0x8000, 0x4000, CRC(43710fb4) SHA1(f84f75061c9ac3e34af93141ecabd3c955881aa2), ROM_BIOS(1) ) ROMX_LOAD( "170887-rom1.bin", 0x0000, 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-rom2.bin", 0x4000, 0x4000, CRC(d0d34f08) SHA1(7baab17d1e68771b8dcef97d0fffc655beabef28), ROM_BIOS(1) )
ROM_END ROM_END
/* Driver */ /* Driver */
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ /* 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( 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", "Pecom 64", 0) 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 "cpu/cosmac/cosmac.h"
#include "imagedev/cassette.h" #include "imagedev/cassette.h"
#include "machine/ram.h"
#include "sound/cdp1869.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 class pecom_state : public driver_device
{ {
public: public:
pecom_state(const machine_config &mconfig, device_type type, const char *tag) : pecom_state(const machine_config &mconfig, device_type type, const char *tag)
driver_device(mconfig, type, tag), : driver_device(mconfig, type, tag)
m_cdp1802(*this, CDP1802_TAG), , m_maincpu(*this, "maincpu")
m_cdp1869(*this, CDP1869_TAG), , m_cdp1869(*this, "cdp1869")
m_cassette(*this, "cassette"), , m_cassette(*this, "cassette")
m_ram(*this, RAM_TAG), , m_bank1(*this, "bank1")
m_bank1(*this, "bank1"), , m_bank3(*this, "bank3")
m_bank2(*this, "bank2"), , m_bank4(*this, "bank4")
m_bank3(*this, "bank3"), , m_rom(*this, "maincpu")
m_bank4(*this, "bank4"), , m_ram(*this, "mainram")
m_io_cnt(*this, "CNT"), , m_io_cnt(*this, "CNT")
m_io_ports(*this, "LINE%u", 0U) , m_io_keyboard(*this, "LINE%d", 0U)
{ } { }
DECLARE_INPUT_CHANGED_MEMBER(ef_w); DECLARE_INPUT_CHANGED_MEMBER(ef_w);
void pecom64(machine_config &config); void pecom64(machine_config &config);
protected: private:
uint8_t pecom_cdp1869_charram_r(offs_t offset); uint8_t cdp1869_charram_r(offs_t offset);
void pecom_cdp1869_charram_w(offs_t offset, uint8_t data); void cdp1869_charram_w(offs_t offset, uint8_t data);
uint8_t pecom_cdp1869_pageram_r(offs_t offset); uint8_t cdp1869_pageram_r(offs_t offset);
void pecom_cdp1869_pageram_w(offs_t offset, uint8_t data); void cdp1869_pageram_w(offs_t offset, uint8_t data);
void pecom_bank_w(uint8_t data); void bank_w(uint8_t data);
uint8_t pecom_keyboard_r(); uint8_t keyboard_r();
void pecom_cdp1869_w(offs_t offset, uint8_t data); void cdp1869_w(offs_t offset, uint8_t data);
TIMER_CALLBACK_MEMBER(reset_tick); TIMER_CALLBACK_MEMBER(reset_tick);
DECLARE_READ_LINE_MEMBER(clear_r); DECLARE_READ_LINE_MEMBER(clear_r);
DECLARE_READ_LINE_MEMBER(ef2_r); DECLARE_READ_LINE_MEMBER(ef2_r);
DECLARE_WRITE_LINE_MEMBER(q_w); DECLARE_WRITE_LINE_MEMBER(q_w);
void sc_w(uint8_t data); void sc_w(uint8_t data);
DECLARE_WRITE_LINE_MEMBER(pecom_prd_w); DECLARE_WRITE_LINE_MEMBER(prd_w);
CDP1869_CHAR_RAM_READ_MEMBER(pecom_char_ram_r); CDP1869_CHAR_RAM_READ_MEMBER(char_ram_r);
CDP1869_CHAR_RAM_WRITE_MEMBER(pecom_char_ram_w); CDP1869_CHAR_RAM_WRITE_MEMBER(char_ram_w);
CDP1869_PCB_READ_MEMBER(pecom_pcb_r); CDP1869_PCB_READ_MEMBER(pcb_r);
virtual void machine_start() override; virtual void machine_start() override;
virtual void machine_reset() 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 cdp1869_page_ram(address_map &map);
void pecom64_io(address_map &map); void io_map(address_map &map);
void pecom64_mem(address_map &map); void mem_map(address_map &map);
private:
required_device<cosmac_device> m_cdp1802;
required_device<cdp1869_device> m_cdp1869;
std::unique_ptr<uint8_t[]> m_charram; /* character generator ROM */ std::unique_ptr<uint8_t[]> m_charram; /* character generator ROM */
int m_reset; /* CPU mode */ bool m_reset; /* CPU mode */
int m_dma; /* memory refresh DMA */ bool m_dma; /* memory refresh DMA */
/* timers */ /* timers */
emu_timer *m_reset_timer; /* power on reset timer */ 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<cassette_image_device> m_cassette;
required_device<ram_device> m_ram;
required_memory_bank m_bank1; required_memory_bank m_bank1;
required_memory_bank m_bank2;
required_memory_bank m_bank3; required_memory_bank m_bank3;
required_memory_bank m_bank4; required_memory_bank m_bank4;
required_region_ptr<u8> m_rom;
required_shared_ptr<u8> m_ram;
required_ioport m_io_cnt; required_ioport m_io_cnt;
required_ioport_array<26> m_io_ports; required_ioport_array<26> m_io_keyboard;
}; };
#endif // MAME_INCLUDES_PECOM_H #endif // MAME_INCLUDES_PECOM_H

View File

@ -17,79 +17,65 @@ TIMER_CALLBACK_MEMBER(pecom_state::reset_tick)
m_reset = 1; 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() void pecom_state::machine_reset()
{ {
uint8_t *rom = memregion(CDP1802_TAG)->base(); address_space &space = m_maincpu->space(AS_PROGRAM);
address_space &space = m_cdp1802->space(AS_PROGRAM); m_bank1->set_entry(1);
space.unmap_write(0xf000, 0xffff);
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 (0xf000, 0xf7ff, "bank3");
space.install_read_bank (0xf800, 0xffff, "bank4"); space.install_read_bank (0xf800, 0xffff, "bank4");
m_bank1->set_base(rom + 0x8000); m_bank3->set_base(m_rom + 0x7000);
m_bank2->set_base(m_ram->pointer() + 0x4000); m_bank4->set_base(m_rom + 0x7800);
m_bank3->set_base(rom + 0xf000);
m_bank4->set_base(rom + 0xf800);
m_reset = 0; m_reset = 0;
m_dma = 0; m_dma = 0;
m_reset_timer->adjust(attotime::from_msec(5)); 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); 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); 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); 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); 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); address_space &space = m_maincpu->space(AS_PROGRAM);
uint8_t *rom = memregion(CDP1802_TAG)->base(); m_bank1->set_entry(0);
m_cdp1802->space(AS_PROGRAM).install_write_bank(0x0000, 0x3fff, "bank1");
m_bank1->set_base(m_ram->pointer() + 0x0000);
if (data==2) if (data==2)
{ {
space2.install_read_handler (0xf000, 0xf7ff, read8sm_delegate(*this, FUNC(pecom_state::pecom_cdp1869_charram_r))); space.install_read_handler (0xf000, 0xf7ff, read8sm_delegate(*this, FUNC(pecom_state::cdp1869_charram_r)));
space2.install_write_handler(0xf000, 0xf7ff, write8sm_delegate(*this, FUNC(pecom_state::pecom_cdp1869_charram_w))); space.install_write_handler(0xf000, 0xf7ff, write8sm_delegate(*this, FUNC(pecom_state::cdp1869_charram_w)));
space2.install_read_handler (0xf800, 0xffff, read8sm_delegate(*this, FUNC(pecom_state::pecom_cdp1869_pageram_r))); space.install_read_handler (0xf800, 0xffff, read8sm_delegate(*this, FUNC(pecom_state::cdp1869_pageram_r)));
space2.install_write_handler(0xf800, 0xffff, write8sm_delegate(*this, FUNC(pecom_state::pecom_cdp1869_pageram_w))); space.install_write_handler(0xf800, 0xffff, write8sm_delegate(*this, FUNC(pecom_state::cdp1869_pageram_w)));
} }
else else
{ {
space2.unmap_write(0xf000, 0xf7ff); space.unmap_write(0xf000, 0xffff);
space2.unmap_write(0xf800, 0xffff); space.install_read_bank (0xf000, 0xf7ff, "bank3");
space2.install_read_bank (0xf000, 0xf7ff, "bank3"); space.install_read_bank (0xf800, 0xffff, "bank4");
space2.install_read_bank (0xf800, 0xffff, "bank4"); m_bank3->set_base(m_rom + 0x7000);
m_bank3->set_base(rom + 0xf000); m_bank4->set_base(m_rom + 0x7800);
m_bank4->set_base(rom + 0xf800);
} }
} }
uint8_t pecom_state::pecom_keyboard_r() uint8_t pecom_state::keyboard_r()
{ {
/* /*
INP command BUS -> M(R(X)) BUS -> D 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 Address is available on address bus during reading of value from port, and that is
used to determine keyboard line reading 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 */ /* just in case someone is reading non existing ports */
if (addr<0x7cca || addr>0x7ce3) return 0; if (addr<0x7cca || addr>0x7ce3) return 0;
return m_io_ports[addr - 0x7cca]->read() & 0x03; return m_io_keyboard[addr - 0x7cca]->read();
} }
/* CDP1802 Interface */ /* CDP1802 Interface */
@ -112,10 +98,29 @@ READ_LINE_MEMBER(pecom_state::clear_r)
READ_LINE_MEMBER(pecom_state::ef2_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(); 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; 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 "emu.h"
#include "includes/pecom.h" #include "includes/pecom.h"
#include "sound/wave.h"
#include "speaker.h"
void pecom_state::cdp1869_w(offs_t offset, uint8_t data)
void pecom_state::pecom_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) 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) CDP1869_CHAR_RAM_READ_MEMBER(pecom_state::char_ram_r )
{
map(0x000, 0x3ff).mirror(0x400).ram();
}
CDP1869_CHAR_RAM_READ_MEMBER(pecom_state::pecom_char_ram_r )
{ {
uint8_t column = pmd & 0x7f; uint8_t column = pmd & 0x7f;
uint16_t charaddr = (column << 4) | cma; 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]; 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; uint8_t column = pmd & 0x7f;
uint16_t charaddr = (column << 4) | cma; 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; 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); 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 // every other PRD triggers a DMAOUT request
if (m_dma) if (m_dma)
{ m_maincpu->set_input_line(COSMAC_INPUT_LINE_DMAOUT, HOLD_LINE);
m_cdp1802->set_input_line(COSMAC_INPUT_LINE_DMAOUT, HOLD_LINE);
}
m_dma = !m_dma; 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 */ /* 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 */ /* register for state saving */
save_item(NAME(m_reset)); save_item(NAME(m_reset));
save_item(NAME(m_dma)); 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);
}