summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/skeleton/pwp14.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/skeleton/pwp14.cpp')
-rw-r--r--src/mame/skeleton/pwp14.cpp264
1 files changed, 264 insertions, 0 deletions
diff --git a/src/mame/skeleton/pwp14.cpp b/src/mame/skeleton/pwp14.cpp
new file mode 100644
index 00000000000..aa1e9e803d2
--- /dev/null
+++ b/src/mame/skeleton/pwp14.cpp
@@ -0,0 +1,264 @@
+// license:BSD-3-Clause
+// copyright-holders:Miodrag Milanovic
+// thanks-to:FozzTexx
+/***************************************************************************
+
+ Smith Corona PWP System 14
+
+ 08/08/2021 Skeleton driver.
+
+ https://twitter.com/FozzTexx/status/1424043157264617478
+
+ XTAL : 7.938 MHz
+ 14.364 MHz
+ 6.000 MHz
+
+ FDC - WD2793A
+ 2 * AM9128 (2048x8 SRAM)
+ NEC D4364 (8192x8 SRAM)
+ 2 * MT4067-12 (64Kx4 DRAM)
+ CRT5037 - SMC 8621
+
+****************************************************************************/
+
+#include "emu.h"
+#include "cpu/z80/z80.h"
+#include "machine/ram.h"
+#include "video/tms9927.h"
+#include "machine/wd_fdc.h"
+#include "imagedev/floppy.h"
+
+#include "emupal.h"
+#include "screen.h"
+
+
+namespace {
+
+class pwp14_state : public driver_device
+{
+public:
+ pwp14_state(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag)
+ , m_maincpu(*this, "maincpu")
+ , m_bank1(*this, "bank1")
+ , m_bank2(*this, "bank2")
+ , m_bank3(*this, "bank3")
+ , m_bank4(*this, "bank4")
+ , m_ram(*this, RAM_TAG)
+ , m_rom(*this, "maincpu")
+ , m_crtc(*this, "crtc")
+ , m_palette(*this, "palette")
+ , m_chargen(*this, "chargen")
+ , m_fdc(*this, "fdc")
+ , m_bank_reg(0)
+ { }
+
+ void pwp14(machine_config &config);
+
+private:
+ virtual void machine_reset() override ATTR_COLD;
+ virtual void machine_start() override ATTR_COLD;
+ uint32_t screen_update_pwp14(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+
+ void pwp14_io(address_map &map) ATTR_COLD;
+ void pwp14_mem(address_map &map) ATTR_COLD;
+ void bankswitch_w(offs_t offset, uint8_t data);
+ void set_bank();
+ u8 typewriter_r(offs_t offset);
+ void ram_memory_w(offs_t offset, uint8_t data);
+
+ required_device<cpu_device> m_maincpu;
+ required_memory_bank m_bank1;
+ required_memory_bank m_bank2;
+ required_memory_bank m_bank3;
+ required_memory_bank m_bank4;
+ required_device<ram_device> m_ram;
+ required_region_ptr<u8> m_rom;
+ required_device<crt5037_device> m_crtc;
+ required_device<palette_device> m_palette;
+ required_region_ptr<uint8_t> m_chargen;
+ required_device<wd2793_device> m_fdc;
+ uint8_t m_bank_reg;
+};
+
+
+void pwp14_state::pwp14_mem(address_map &map)
+{
+ map(0x0000, 0x3fff).bankrw("bank1");
+ map(0x4000, 0x7fff).bankrw("bank2");
+ map(0x8000, 0xbfff).bankrw("bank3");
+ map(0xc000, 0xffff).bankrw("bank4");
+}
+
+void pwp14_state::set_bank()
+{
+ uint8_t *ram = m_ram->pointer();
+ address_space &space = m_maincpu->space(AS_PROGRAM);
+
+ space.install_write_bank(0x0000, 0x3fff, m_bank1);
+ space.install_write_bank(0x4000, 0x7fff, m_bank2);
+ space.install_write_bank(0x8000, 0xbfff, m_bank3);
+ space.install_write_bank(0xc000, 0xffff, m_bank4);
+ if (m_bank_reg & 1) {
+ m_bank1->set_base(ram + 0x0000);
+ } else {
+ space.install_write_handler(0x0000, 0x3fff, write8sm_delegate(*this, FUNC(pwp14_state::ram_memory_w)));
+ m_bank1->set_base(m_rom + 0x0000);
+ }
+ if (m_bank_reg & 2) {
+ m_bank2->set_base(ram + 0x4000);
+ } else {
+ space.install_write_handler(0x4000, 0x7fff, write8sm_delegate(*this, FUNC(pwp14_state::ram_memory_w)));
+ m_bank2->set_base(m_rom + 0x4000);
+ }
+ if (m_bank_reg & 3) {
+ m_bank3->set_base(ram + 0x8000);
+ } else {
+ space.unmap_write(0x8000, 0xbfff);
+ m_bank3->set_base(m_rom + 0x8000);
+ }
+ if (m_bank_reg & 4) {
+ m_bank4->set_base(ram + 0xc000);
+ } else {
+ space.unmap_write(0xc000, 0xffff);
+ m_bank4->set_base(m_rom + 0xc000);
+ }
+}
+
+void pwp14_state::ram_memory_w(offs_t offset, uint8_t data)
+{
+ uint8_t *ram = m_ram->pointer();
+ ram[offset] = data;
+}
+
+void pwp14_state::bankswitch_w(offs_t offset, uint8_t data)
+{
+ m_bank_reg = data;
+ logerror("bankswitch_w %02x at %04X\n", data, m_maincpu->pc());
+ set_bank();
+}
+
+u8 pwp14_state::typewriter_r(offs_t offset)
+{
+ return 0x00;//0xff;
+}
+
+void pwp14_state::pwp14_io(address_map &map)
+{
+ map.unmap_value_high();
+ map.global_mask(0xff);
+ map(0x00, 0x0f).rw("crtc", FUNC(crt5037_device::read), FUNC(crt5037_device::write));
+ map(0x20, 0x23).rw(m_fdc, FUNC(wd2793_device::read), FUNC(wd2793_device::write)); // FDC ???
+ //map(0x40, 0x40) // ???
+ map(0x60, 0x60).rw(FUNC(pwp14_state::typewriter_r), FUNC(pwp14_state::bankswitch_w));
+}
+
+/* Input ports */
+static INPUT_PORTS_START( pwp14 )
+INPUT_PORTS_END
+
+
+void pwp14_state::machine_reset()
+{
+ m_bank_reg = 0;
+ set_bank();
+}
+
+void pwp14_state::machine_start()
+{
+}
+
+uint32_t pwp14_state::screen_update_pwp14(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ rgb_t const *const pen = m_palette->palette()->entry_list_raw();
+ uint8_t *vram = m_ram->pointer() + 0x10000;
+ rectangle cursor;
+ m_crtc->cursor_bounds(cursor);
+
+ for (int y = 0; y < 24; y++)
+ {
+ for (int ra = 0; ra < 8; ra++)
+ {
+ for (int x = 0; x < 80; x++)
+ {
+ uint8_t chr = vram[(y * 80) + x + 0];
+ uint8_t data = m_chargen[(chr << 3) | ra];
+
+ //if (cursor.contains(x * 8, y * 8))
+ // data ^= 0xff;
+
+ // draw 8 pixels of the char
+ for (int i = 0; i < 8; i++)
+ bitmap.pix(y * 8 + ra, x * 8 + i) = pen[BIT(data, 7 - i)];
+ }
+ }
+ }
+
+ return 0;
+}
+
+/* F4 Character Displayer */
+static const gfx_layout pwp14_charlayout =
+{
+ 8, 8, /* 8 x 8 characters */
+ 1024, /* 1024 characters */
+ 1, /* 1 bits per pixel */
+ { 0 }, /* no bitplanes */
+ /* x offsets */
+ { 0, 1, 2, 3, 4, 5, 6, 7 },
+ /* y offsets */
+ { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
+ 8*8 /* every char takes 2 x 8 bytes */
+};
+
+static GFXDECODE_START( gfx_pwp14 )
+ GFXDECODE_ENTRY( "chargen", 0x0000, pwp14_charlayout, 0, 1 )
+GFXDECODE_END
+
+void pwp14_state::pwp14(machine_config &config)
+{
+ /* basic machine hardware */
+ Z80(config, m_maincpu, XTAL(6'000'000)); // Z8400BPS
+ m_maincpu->set_addrmap(AS_PROGRAM, &pwp14_state::pwp14_mem);
+ m_maincpu->set_addrmap(AS_IO, &pwp14_state::pwp14_io);
+
+
+ /* video hardware */
+ screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER, rgb_t::green()));
+ screen.set_refresh_hz(60);
+ screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
+ screen.set_size(640, 480);
+ screen.set_visarea_full();
+ screen.set_screen_update(FUNC(pwp14_state::screen_update_pwp14));
+ screen.set_palette("palette");
+
+ GFXDECODE(config, "gfxdecode", "palette", gfx_pwp14);
+
+ PALETTE(config, "palette", palette_device::MONOCHROME);
+ /* internal ram */
+ RAM(config, m_ram).set_default_size("76K").set_default_value(0x00); // 64K DRAM + 2*2K SRAM (VRAM) + 8K SRAM
+
+ CRT5037(config, m_crtc, 14'364'000 / 8); // unknown clock
+ m_crtc->set_char_width(8);
+ m_crtc->set_screen("screen");
+
+ WD2793(config, m_fdc, XTAL(2'000'000)); // Need proper xtal used
+}
+
+/* ROM definition */
+ROM_START( pwp14 )
+ ROM_REGION( 0x10000, "maincpu", 0 )
+ ROM_LOAD( "750524.bin", 0x0000, 0x8000, CRC(775b0e1a) SHA1(d546ef2bd4e09b2f182ffe0e393895ebad613fcc))
+ ROM_LOAD( "750525.bin", 0x8000, 0x8000, CRC(673e20b5) SHA1(66e3a98cbc5969e6c64a25e39fb0df7f741e6345))
+
+ ROM_REGION(0x2000, "chargen",0)
+ ROM_LOAD( "750504.bin", 0x0000, 0x2000, CRC(b9062df6) SHA1(e79044765093b1d1954254d4a839a9e443d624d6))
+ROM_END
+
+} // anonymous namespace
+
+
+/* Driver */
+
+// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
+COMP( 1986, pwp14, 0, 0, pwp14, pwp14, pwp14_state, empty_init, "Smith Corona", "PWP System 14", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE )