From 5cee6e47b627d16fabe77f7ceb785226e1d5098e Mon Sep 17 00:00:00 2001 From: Robbbert Date: Tue, 5 Jul 2022 00:44:26 +1000 Subject: Moved AU & NZ computers into a project --- src/mame/appliedtech/mbee.cpp | 1194 ------------------------------------ src/mame/appliedtech/mbee.h | 212 ------- src/mame/appliedtech/mbee_m.cpp | 792 ------------------------ src/mame/appliedtech/mbee_v.cpp | 408 ------------ src/mame/ausnz/amust.cpp | 550 +++++++++++++++++ src/mame/ausnz/applix.cpp | 1181 +++++++++++++++++++++++++++++++++++ src/mame/ausnz/aussiebyte.cpp | 619 +++++++++++++++++++ src/mame/ausnz/aussiebyte.h | 157 +++++ src/mame/ausnz/aussiebyte_v.cpp | 196 ++++++ src/mame/ausnz/binbug.cpp | 294 +++++++++ src/mame/ausnz/d6800.cpp | 434 +++++++++++++ src/mame/ausnz/datum.cpp | 233 +++++++ src/mame/ausnz/dg680.cpp | 337 ++++++++++ src/mame/ausnz/dmax8000.cpp | 211 +++++++ src/mame/ausnz/eacc.cpp | 302 +++++++++ src/mame/ausnz/eti660.cpp | 411 +++++++++++++ src/mame/ausnz/excali64.cpp | 694 +++++++++++++++++++++ src/mame/ausnz/labtam.cpp | 114 ++++ src/mame/ausnz/magnum.cpp | 337 ++++++++++ src/mame/ausnz/mbee.cpp | 1194 ++++++++++++++++++++++++++++++++++++ src/mame/ausnz/mbee.h | 212 +++++++ src/mame/ausnz/mbee_m.cpp | 792 ++++++++++++++++++++++++ src/mame/ausnz/mbee_v.cpp | 408 ++++++++++++ src/mame/ausnz/pipbug.cpp | 248 ++++++++ src/mame/ausnz/poly.cpp | 449 ++++++++++++++ src/mame/ausnz/poly.h | 187 ++++++ src/mame/ausnz/poly_m.cpp | 259 ++++++++ src/mame/ausnz/proteus.cpp | 433 +++++++++++++ src/mame/ausnz/pulsar.cpp | 278 +++++++++ src/mame/ausnz/super80.cpp | 995 ++++++++++++++++++++++++++++++ src/mame/ausnz/super80.h | 188 ++++++ src/mame/ausnz/super80_m.cpp | 284 +++++++++ src/mame/ausnz/super80_v.cpp | 420 +++++++++++++ src/mame/ausnz/tec1.cpp | 410 +++++++++++++ src/mame/dicksmith/super80.cpp | 995 ------------------------------ src/mame/dicksmith/super80.h | 188 ------ src/mame/dicksmith/super80_m.cpp | 284 --------- src/mame/dicksmith/super80_v.cpp | 420 ------------- src/mame/dulmont/magnum.cpp | 337 ---------- src/mame/labtam/labtam.cpp | 114 ---- src/mame/mame.lst | 40 +- src/mame/mess.flt | 64 +- src/mame/poly/poly.cpp | 449 -------------- src/mame/poly/poly.h | 187 ------ src/mame/poly/poly_m.cpp | 259 -------- src/mame/poly/proteus.cpp | 433 ------------- src/mame/skeleton/amust.cpp | 550 ----------------- src/mame/skeleton/applix.cpp | 1181 ----------------------------------- src/mame/skeleton/aussiebyte.cpp | 619 ------------------- src/mame/skeleton/aussiebyte.h | 157 ----- src/mame/skeleton/aussiebyte_v.cpp | 196 ------ src/mame/skeleton/binbug.cpp | 294 --------- src/mame/skeleton/d6800.cpp | 434 ------------- src/mame/skeleton/dg680.cpp | 337 ---------- src/mame/skeleton/dmax8000.cpp | 211 ------- src/mame/skeleton/eacc.cpp | 302 --------- src/mame/skeleton/eti660.cpp | 411 ------------- src/mame/skeleton/excali64.cpp | 694 --------------------- src/mame/skeleton/pipbug.cpp | 248 -------- src/mame/skeleton/pulsar.cpp | 278 --------- src/mame/trainer/datum.cpp | 233 ------- src/mame/trainer/tec1.cpp | 410 ------------- 62 files changed, 12879 insertions(+), 12879 deletions(-) delete mode 100644 src/mame/appliedtech/mbee.cpp delete mode 100644 src/mame/appliedtech/mbee.h delete mode 100644 src/mame/appliedtech/mbee_m.cpp delete mode 100644 src/mame/appliedtech/mbee_v.cpp create mode 100644 src/mame/ausnz/amust.cpp create mode 100644 src/mame/ausnz/applix.cpp create mode 100644 src/mame/ausnz/aussiebyte.cpp create mode 100644 src/mame/ausnz/aussiebyte.h create mode 100644 src/mame/ausnz/aussiebyte_v.cpp create mode 100644 src/mame/ausnz/binbug.cpp create mode 100644 src/mame/ausnz/d6800.cpp create mode 100644 src/mame/ausnz/datum.cpp create mode 100644 src/mame/ausnz/dg680.cpp create mode 100644 src/mame/ausnz/dmax8000.cpp create mode 100644 src/mame/ausnz/eacc.cpp create mode 100644 src/mame/ausnz/eti660.cpp create mode 100644 src/mame/ausnz/excali64.cpp create mode 100644 src/mame/ausnz/labtam.cpp create mode 100644 src/mame/ausnz/magnum.cpp create mode 100644 src/mame/ausnz/mbee.cpp create mode 100644 src/mame/ausnz/mbee.h create mode 100644 src/mame/ausnz/mbee_m.cpp create mode 100644 src/mame/ausnz/mbee_v.cpp create mode 100644 src/mame/ausnz/pipbug.cpp create mode 100644 src/mame/ausnz/poly.cpp create mode 100644 src/mame/ausnz/poly.h create mode 100644 src/mame/ausnz/poly_m.cpp create mode 100644 src/mame/ausnz/proteus.cpp create mode 100644 src/mame/ausnz/pulsar.cpp create mode 100644 src/mame/ausnz/super80.cpp create mode 100644 src/mame/ausnz/super80.h create mode 100644 src/mame/ausnz/super80_m.cpp create mode 100644 src/mame/ausnz/super80_v.cpp create mode 100644 src/mame/ausnz/tec1.cpp delete mode 100644 src/mame/dicksmith/super80.cpp delete mode 100644 src/mame/dicksmith/super80.h delete mode 100644 src/mame/dicksmith/super80_m.cpp delete mode 100644 src/mame/dicksmith/super80_v.cpp delete mode 100644 src/mame/dulmont/magnum.cpp delete mode 100644 src/mame/labtam/labtam.cpp delete mode 100644 src/mame/poly/poly.cpp delete mode 100644 src/mame/poly/poly.h delete mode 100644 src/mame/poly/poly_m.cpp delete mode 100644 src/mame/poly/proteus.cpp delete mode 100644 src/mame/skeleton/amust.cpp delete mode 100644 src/mame/skeleton/applix.cpp delete mode 100644 src/mame/skeleton/aussiebyte.cpp delete mode 100644 src/mame/skeleton/aussiebyte.h delete mode 100644 src/mame/skeleton/aussiebyte_v.cpp delete mode 100644 src/mame/skeleton/binbug.cpp delete mode 100644 src/mame/skeleton/d6800.cpp delete mode 100644 src/mame/skeleton/dg680.cpp delete mode 100644 src/mame/skeleton/dmax8000.cpp delete mode 100644 src/mame/skeleton/eacc.cpp delete mode 100644 src/mame/skeleton/eti660.cpp delete mode 100644 src/mame/skeleton/excali64.cpp delete mode 100644 src/mame/skeleton/pipbug.cpp delete mode 100644 src/mame/skeleton/pulsar.cpp delete mode 100644 src/mame/trainer/datum.cpp delete mode 100644 src/mame/trainer/tec1.cpp diff --git a/src/mame/appliedtech/mbee.cpp b/src/mame/appliedtech/mbee.cpp deleted file mode 100644 index 7c864a175fd..00000000000 --- a/src/mame/appliedtech/mbee.cpp +++ /dev/null @@ -1,1194 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Robbbert -/*************************************************************************** - -Driver completely rewritten by Robbbert, in a process begun on 2009-02-24. -Assistance/advice was gratefully received from: - E.J.Wordsworth (owner of Microbee Systems), nama, ChickenMan, - and the author of the "ubee512" emulator. - -Previous driver was written by Juergen Buchmueller, Jan 2000 with assistance -from Brett Selwood and Andrew Davies. - - - Keyboard notes are in video/microbee.cpp - - 256tc: The 1.31 rom version which appears to fit the 256TC is actually - part of the Z80 emulation in the Matilda model. If you fit this rom into a real - 256TC, the floppy disk will not be detected. - - The unemulated Matilda is a IBM XT clone fitted with a NEC V40, and has the - ability to emulate the 256TC as mentioned above. - - The Premium Plus was a limited-edition kit from Microbee Systems, but we don't - have any technical info or schematic as yet. It starts up, keyboard works, disks - work much the same as a 128k or 256tc. It has 1024k of RAM. - The kit itself has an extra custom FPGA CPU board with memory-card slot, but there's - no info on it yet. We just emulate the Z80 portion. - - ICs on schematics, pcbs, and manuals which never made it into production machines: - - Z80SCC; - - SN76489A; - - 2651A; - - B & C roms on disk-based machines. - - Floppy formats: - - All disks are the standard CPCEMU 'dsk' format. - - Types are 9/13cm 40/80 track (single or double sided) - - 13cm has been specified as QD to prevent a nasty crash if an 80-track disk was mounted - - The tracks/sector layout is the same regardless of size - - Although certain models came with particular drives as standard, users could add - the other size if they wished. We support both sizes on any model. - - Early machines have 'standard' video (128 hires characters). - Later machines had the option of 'premium' video which - provides thousands of hires characters, enough to simulate - bit-mapped graphics. - - Commands to call up built-in roms (depends on the model): - NET - Jump to E000, usually the Telcom communications program. - This rom can be replaced with the Dreamdisk Chip-8 rom. - Note that Telcom 3.21 is 8k, it uses a rombank switch - (by reading port 0A) to swap between the two halves. - See Telcom notes below. - - MEM - same as NET. - - EDASM - Jump to C000, usually the Editor/Assembler package. - - MENU - Do a rombank switch to bank 5 and jump to C000 to start the Shell - - PAK n - Do a rombank switch (write to port 0A) to bank "n" and jump to C000. - - These early colour computers have a PROM to create the foreground palette. - - Notes about the printer: - - Older models default to a 1200 baud serial printer, which we do not support. - - You need to change it to parallel by entering OUTL#1 while in Basic. - - After you mount/create a printfile, you can LPRINT and LLIST in Basic, - or by using the printing option in other apps. - - Notes about Telcom: - - On the older models, Telcom is called up by entering NET from within Basic. Models - from the pc85 onwards have it as a menu option. - - To exit, press Enter without any input. Disk versions, enter CPM or press ^C. - - After being used, version 3 and up will enable the use of OUT#7 in Basic, which - changes the screen to 80x24. Enter OUT#0 to revert to normal. - - Most versions of Telcom can have their parameters adjusted directly from Basic, - without needing to enter the Telcom program. - - Most versions of Telcom have an optional clock. In older models firstly select VS - from the MAME config menu, then enter NET CLOCK to enable it. NET TIME hhmm to set - the time (24hour format). NET CLOCKD is supposed to remove the status line, but it - doesn't, although the clock stops updating. NET CLOCK and NET CLOCKD are toggles. - - Telcom 1.2 (used in mbeeic) has a bug. If you enter NET CLOCK, the status line is - filled with inverse K. You can fix this from Basic by doing NET CLOCK 3 times. - - Notes about Disk System - - Ports 44 to 47 are for standard connection to FD2793. - - Port 48 is used for drive/side/density select on write, and intrq/drq on read. - intrq and drq are OR'd together, then gated to bit 7 of the data bus whenever - port 48 is activated on read. There are no interrupts used. - - The 256TC can boot from the B drive if you hold down Shift and hit F1 at the menu. - - How to use the config switch for PIO B7: - - Teleterm: Must use RTC. Anything else makes teleterm go crazy. - - 256TC, 128, 128p: Doesn't seem to matter, leave at the default. - - Standard: Has no effect, best left at "Tied High" - - Other rom-based models: "VS" to make the Telcom clock work, or "Tied high". - - 56k: not sure yet, leave as "Tied high" until more is known. - -*************************************************************************** - - TODO/not working: - - Old CRTC-based keyboard: - - Paste drops many characters. - - Typing can drop the occasional character. - - mbee -bios 1 is unusable due to keyboard issues. - - FDC: (TODO: see if these bugs still exist) - - B drive doesn't work with most disks. - - some disks cause MAME to freeze. - - - 128k: Simply Write has no keyboard. - - - 256tc: the Intro disk doesn't work - - - 256tc, Teleterm: Keyboard CPU inbuilt ROM needs to be dumped. - - 128k, 64k: PALs need to be dumped for the bankswitching. - - - Mouse: a few programs support the use of a serial mouse which interfaced - directly to the Z80PIO. However there's little info to be found. - PIO B3 to ground activates the mouse pointer in Shell v3.01. - - - Hard drive (10MB) & controller - -*******************************************************************************/ - -#include "emu.h" -#include "mbee.h" -#include "formats/mbee_cas.h" -#include "sound/sn76496.h" -#include "softlist_dev.h" -#include "speaker.h" - -void mbee_state::mbee_mem(address_map &map) -{ - map.unmap_value_high(); - map(0x0000, 0x7fff).ram(); - map(0x8000, 0xbfff).rom().region("maincpu",0); - map(0xc000, 0xdfff).r(FUNC(mbee_state::pak_r)); - map(0xe000, 0xefff).r(FUNC(mbee_state::net_r)); - map(0xf000, 0xf7ff).rw(FUNC(mbee_state::video_low_r), FUNC(mbee_state::video_low_w)); - map(0xf800, 0xffff).rw(FUNC(mbee_state::video_high_r), FUNC(mbee_state::video_high_w)); -} - -void mbee_state::mbeeic_mem(address_map &map) -{ - map(0x0000, 0x7fff).ram(); - map(0x8000, 0xbfff).rom().region("maincpu",0); - map(0xc000, 0xdfff).r(FUNC(mbee_state::pak_r)); - map(0xe000, 0xefff).r(FUNC(mbee_state::net_r)); - map(0xf000, 0xf7ff).rw(FUNC(mbee_state::video_low_r), FUNC(mbee_state::video_low_w)); - map(0xf800, 0xffff).rw(FUNC(mbee_state::video_high_r), FUNC(mbee_state::video_high_w)); -} - -void mbee_state::mbeeppc_mem(address_map &map) -{ - map(0x0000, 0x7fff).ram(); - map(0x8000, 0x9fff).bankr("basic"); - map(0xa000, 0xbfff).rom().region("maincpu",0); - map(0xc000, 0xdfff).r(FUNC(mbee_state::pak_r)); - map(0xe000, 0xefff).r(FUNC(mbee_state::net_r)); - map(0xf000, 0xf7ff).rw(FUNC(mbee_state::video_low_r), FUNC(mbee_state::video_low_w)); - map(0xf800, 0xffff).rw(FUNC(mbee_state::video_high_r), FUNC(mbee_state::video_high_w)); -} - -void mbee_state::mbeett_mem(address_map &map) -{ - map(0x0000, 0x7fff).ram(); - map(0x8000, 0x9fff).rom().region("maincpu",0); - map(0xa000, 0xbfff).ram(); - map(0xc000, 0xdfff).r(FUNC(mbee_state::pak_r)); - map(0xe000, 0xefff).r(FUNC(mbee_state::net_r)); - map(0xf000, 0xf7ff).rw(FUNC(mbee_state::video_low_r), FUNC(mbee_state::video_low_w)); - map(0xf800, 0xffff).rw(FUNC(mbee_state::video_high_r), FUNC(mbee_state::video_high_w)); -} - -void mbee_state::mbee56_mem(address_map &map) -{ - map(0x0000, 0xdfff).ram(); - map(0xe000, 0xefff).rom().region("maincpu",0); - map(0xf000, 0xf7ff).rw(FUNC(mbee_state::video_low_r), FUNC(mbee_state::video_low_w)); - map(0xf800, 0xffff).rw(FUNC(mbee_state::video_high_r), FUNC(mbee_state::video_high_w)); -} - -void mbee_state::mbee256_mem(address_map &map) -{ - map(0x0000, 0x0fff).bankr("bankr0").bankw("bankw0"); - map(0x1000, 0x1fff).bankr("bankr1").bankw("bankw1"); - map(0x2000, 0x2fff).bankr("bankr2").bankw("bankw2"); - map(0x3000, 0x3fff).bankr("bankr3").bankw("bankw3"); - map(0x4000, 0x4fff).bankr("bankr4").bankw("bankw4"); - map(0x5000, 0x5fff).bankr("bankr5").bankw("bankw5"); - map(0x6000, 0x6fff).bankr("bankr6").bankw("bankw6"); - map(0x7000, 0x7fff).bankr("bankr7").bankw("bankw7"); - map(0x8000, 0x8fff).bankr("bankr8").bankw("bankw8"); - map(0x9000, 0x9fff).bankr("bankr9").bankw("bankw9"); - map(0xa000, 0xafff).bankr("bankr10").bankw("bankw10"); - map(0xb000, 0xbfff).bankr("bankr11").bankw("bankw11"); - map(0xc000, 0xcfff).bankr("bankr12").bankw("bankw12"); - map(0xd000, 0xdfff).bankr("bankr13").bankw("bankw13"); - map(0xe000, 0xefff).bankr("bankr14").bankw("bankw14"); - map(0xf000, 0xffff).bankr("bankr15").bankw("bankw15"); -} - -void mbee_state::mbee_io(address_map &map) -{ - map.global_mask(0xff); - map.unmap_value_high(); - map(0x00, 0x03).mirror(0x10).rw(m_pio, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt)); - map(0x0b, 0x0b).mirror(0x10).w(FUNC(mbee_state::port0b_w)); - map(0x0c, 0x0c).mirror(0x10).r(m_crtc, FUNC(mc6845_device::status_r)).w(FUNC(mbee_state::m6545_index_w)); - map(0x0d, 0x0d).mirror(0x10).r(m_crtc, FUNC(mc6845_device::register_r)).w(FUNC(mbee_state::m6545_data_w)); -} - -void mbee_state::mbeeic_io(address_map &map) -{ - map.unmap_value_high(); - map(0x0000, 0x0003).mirror(0xff10).rw(m_pio, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt)); - map(0x0008, 0x0008).mirror(0xff10).rw(FUNC(mbee_state::port08_r), FUNC(mbee_state::port08_w)); - map(0x0009, 0x0009).mirror(0xff00).nopw(); - map(0x000a, 0x000a).select(0xff10).rw(FUNC(mbee_state::telcom_r), FUNC(mbee_state::port0a_w)); - map(0x000b, 0x000b).mirror(0xff10).w(FUNC(mbee_state::port0b_w)); - map(0x000c, 0x000c).mirror(0xff10).r(m_crtc, FUNC(mc6845_device::status_r)).w(FUNC(mbee_state::m6545_index_w)); - map(0x000d, 0x000d).mirror(0xff10).r(m_crtc, FUNC(mc6845_device::register_r)).w(FUNC(mbee_state::m6545_data_w)); -} - -void mbee_state::mbeeppc_io(address_map &map) -{ - map.unmap_value_high(); - map(0x0000, 0x0003).mirror(0xff10).rw(m_pio, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt)); - map(0x0008, 0x0008).mirror(0xff10).rw(FUNC(mbee_state::port08_r), FUNC(mbee_state::port08_w)); - map(0x0009, 0x0009).mirror(0xff00).nopw(); - map(0x000a, 0x000a).select(0xff10).rw(FUNC(mbee_state::telcom_r), FUNC(mbee_state::port0a_w)); - map(0x000b, 0x000b).mirror(0xff10).w(FUNC(mbee_state::port0b_w)); - map(0x000c, 0x000c).mirror(0xff00).r(m_crtc, FUNC(mc6845_device::status_r)).w(FUNC(mbee_state::m6545_index_w)); - map(0x000d, 0x000d).mirror(0xff10).r(m_crtc, FUNC(mc6845_device::register_r)).w(FUNC(mbee_state::m6545_data_w)); - map(0x001c, 0x001c).mirror(0xff00).rw(FUNC(mbee_state::port1c_r), FUNC(mbee_state::port1c_w)); -} - -void mbee_state::mbeett_io(address_map &map) -{ - map.unmap_value_high(); - map(0x0000, 0x0003).mirror(0xff00).rw(m_pio, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt)); - map(0x0004, 0x0004).mirror(0xff00).w(FUNC(mbee_state::port04_w)); - map(0x0006, 0x0006).mirror(0xff00).w(FUNC(mbee_state::port06_w)); - map(0x0007, 0x0007).mirror(0xff00).r(FUNC(mbee_state::port07_r)); - map(0x0008, 0x0008).mirror(0xff00).rw(FUNC(mbee_state::port08_r), FUNC(mbee_state::port08_w)); - map(0x000a, 0x000a).select(0xff10).rw(FUNC(mbee_state::telcom_r), FUNC(mbee_state::port0a_w)); - map(0x000b, 0x000b).mirror(0xff00).w(FUNC(mbee_state::port0b_w)); - map(0x000c, 0x000c).mirror(0xff00).r(m_crtc, FUNC(mc6845_device::status_r)).w(FUNC(mbee_state::m6545_index_w)); - map(0x000d, 0x000d).mirror(0xff00).r(m_crtc, FUNC(mc6845_device::register_r)).w(FUNC(mbee_state::m6545_data_w)); - map(0x0018, 0x001b).mirror(0xff00).r(FUNC(mbee_state::port18_r)); - map(0x001c, 0x001f).mirror(0xff00).rw(FUNC(mbee_state::port1c_r), FUNC(mbee_state::port1c_w)); - map(0x0009, 0x0009).select(0xff00).r(FUNC(mbee_state::speed_r)); - map(0x0068, 0x006f).mirror(0xff00).noprw(); // swallow i/o to SCC which was never fitted to production machines -} - -void mbee_state::mbee56_io(address_map &map) -{ - map.global_mask(0xff); - map.unmap_value_high(); - map(0x00, 0x03).rw(m_pio, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt)); - map(0x08, 0x08).rw(FUNC(mbee_state::port08_r), FUNC(mbee_state::port08_w)); - map(0x09, 0x09).nopw(); - map(0x0b, 0x0b).w(FUNC(mbee_state::port0b_w)); - map(0x0c, 0x0c).r(m_crtc, FUNC(mc6845_device::status_r)).w(FUNC(mbee_state::m6545_index_w)); - map(0x0d, 0x0d).r(m_crtc, FUNC(mc6845_device::register_r)).w(FUNC(mbee_state::m6545_data_w)); - map(0x44, 0x47).rw(m_fdc, FUNC(wd2793_device::read), FUNC(wd2793_device::write)); - map(0x48, 0x4f).rw(FUNC(mbee_state::fdc_status_r), FUNC(mbee_state::fdc_motor_w)); -} - -void mbee_state::mbee128_io(address_map &map) -{ - map.global_mask(0xff); - map.unmap_value_high(); - map(0x00, 0x03).rw(m_pio, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt)); - map(0x04, 0x04).w(FUNC(mbee_state::port04_w)); - map(0x06, 0x06).w(FUNC(mbee_state::port06_w)); - map(0x07, 0x07).r(FUNC(mbee_state::port07_r)); - map(0x08, 0x08).rw(FUNC(mbee_state::port08_r), FUNC(mbee_state::port08_w)); - map(0x09, 0x09).nopw(); - map(0x0b, 0x0b).w(FUNC(mbee_state::port0b_w)); - map(0x0c, 0x0c).r(m_crtc, FUNC(mc6845_device::status_r)).w(FUNC(mbee_state::m6545_index_w)); - map(0x0d, 0x0d).r(m_crtc, FUNC(mc6845_device::register_r)).w(FUNC(mbee_state::m6545_data_w)); - map(0x1c, 0x1f).rw(FUNC(mbee_state::port1c_r), FUNC(mbee_state::port1c_w)); - map(0x44, 0x47).rw(m_fdc, FUNC(wd2793_device::read), FUNC(wd2793_device::write)); - map(0x48, 0x4f).rw(FUNC(mbee_state::fdc_status_r), FUNC(mbee_state::fdc_motor_w)); - map(0x50, 0x57).w(FUNC(mbee_state::port50_w)); -} - -void mbee_state::mbee128p_io(address_map &map) -{ - map.global_mask(0xff); - map.unmap_value_high(); - mbee128_io(map); - map(0x10, 0x13).w("sn1", FUNC(sn76489a_device::write)); -} - -void mbee_state::mbee256_io(address_map &map) -{ - map.unmap_value_high(); - map(0x0000, 0x0003).mirror(0xff00).rw(m_pio, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt)); - map(0x0004, 0x0004).mirror(0xff00).w(FUNC(mbee_state::port04_w)); - map(0x0006, 0x0006).mirror(0xff00).w(FUNC(mbee_state::port06_w)); - map(0x0007, 0x0007).mirror(0xff00).r(FUNC(mbee_state::port07_r)); - map(0x0008, 0x0008).mirror(0xff00).rw(FUNC(mbee_state::port08_r), FUNC(mbee_state::port08_w)); - map(0x0009, 0x0009).select(0xff00).r(FUNC(mbee_state::speed_r)); - map(0x0009, 0x0009).mirror(0xff00).nopw(); - map(0x000b, 0x000b).mirror(0xff00).w(FUNC(mbee_state::port0b_w)); - map(0x000c, 0x000c).mirror(0xff00).r(m_crtc, FUNC(mc6845_device::status_r)).w(FUNC(mbee_state::m6545_index_w)); - map(0x000d, 0x000d).mirror(0xff00).r(m_crtc, FUNC(mc6845_device::register_r)).w(FUNC(mbee_state::m6545_data_w)); - map(0x0010, 0x0013).mirror(0xff00).w("sn1", FUNC(sn76489a_device::write)); - map(0x0018, 0x001b).mirror(0xff00).r(FUNC(mbee_state::port18_r)); - map(0x001c, 0x001f).mirror(0xff00).rw(FUNC(mbee_state::port1c_r), FUNC(mbee_state::port1c_w)); - map(0x0044, 0x0047).mirror(0xff00).rw(m_fdc, FUNC(wd2793_device::read), FUNC(wd2793_device::write)); - map(0x0048, 0x004f).mirror(0xff00).rw(FUNC(mbee_state::fdc_status_r), FUNC(mbee_state::fdc_motor_w)); - map(0x0050, 0x0057).mirror(0xff00).w(FUNC(mbee_state::port50_w)); - // map(0x0058, 0x005f).mirror(0xff00); External options: floppy drive, hard drive and keyboard - // map(0x0060, 0x0067).mirror(0xff00); Reserved for file server selection (unused) - // map(0x0068, 0x006f).mirror(0xff00); Reserved for 8530 SCC (never used) -} - -static INPUT_PORTS_START( oldkb ) - PORT_START("X.0") /* IN0 KEY ROW 0 [000] */ - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("@") PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR('@') PORT_CHAR('`') - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') PORT_CHAR(0x01) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') PORT_CHAR(0x02) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') PORT_CHAR(0x03) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') PORT_CHAR(0x04) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') PORT_CHAR(0x05) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') PORT_CHAR(0x06) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') PORT_CHAR(0x07) - - PORT_START("X.1") /* IN1 KEY ROW 1 [080] */ - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') PORT_CHAR(0x08) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') PORT_CHAR(0x09) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') PORT_CHAR(0x0a) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') PORT_CHAR(0x0b) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') PORT_CHAR(0x0c) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') PORT_CHAR(0x0d) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') PORT_CHAR(0x0e) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') PORT_CHAR(0x0f) - - PORT_START("X.2") /* IN2 KEY ROW 2 [100] */ - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') PORT_CHAR(0x10) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') PORT_CHAR(0x11) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') PORT_CHAR(0x12) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') PORT_CHAR(0x13) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') PORT_CHAR(0x14) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') PORT_CHAR(0x15) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') PORT_CHAR(0x16) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') PORT_CHAR(0x17) - - PORT_START("X.3") /* IN3 KEY ROW 3 [180] */ - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') PORT_CHAR(0x18) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') PORT_CHAR(0x19) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') PORT_CHAR(0x1a) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("[") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') PORT_CHAR(0x1b) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("\\") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') PORT_CHAR(0x1c) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("]") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') PORT_CHAR(0x1d) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("^") PORT_CODE(KEYCODE_TILDE) PORT_CHAR('^') PORT_CHAR('~') PORT_CHAR(0x1e) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Delete") PORT_CODE(KEYCODE_DEL) PORT_CHAR(8) PORT_CHAR(0x5f) PORT_CHAR(0x1f) // port_char not working - hijacked - - PORT_START("X.4") /* IN4 KEY ROW 4 [200] */ - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0') - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("1 !") PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("2 \"") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('\"') - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("3 #") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("4 $") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("5 %") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("6 &") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("7 '") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'') - - PORT_START("X.5") /* IN5 KEY ROW 5 [280] */ - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("8 (") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("9 )") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(": *") PORT_CODE(KEYCODE_COLON) PORT_CHAR(':') PORT_CHAR('*') - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("; +") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(';') PORT_CHAR('+') - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(", <") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("- =") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('=') - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(". >") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("/ ?") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') - - PORT_START("X.6") /* IN6 KEY ROW 6 [300] */ - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Escape") PORT_CODE(KEYCODE_ESC) PORT_CHAR(27) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Backspace") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tab") PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Linefeed") PORT_CODE(KEYCODE_HOME) PORT_CHAR(10) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Enter") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Lock") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Break") PORT_CODE(KEYCODE_END) PORT_CHAR(3) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') - - PORT_START("X.7") /* IN7 KEY ROW 7 [380] */ - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("(Up)") PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Ctrl") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_SHIFT_2) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("(Down)") PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("(Left)") PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED ) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED ) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("(Right)") PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) -INPUT_PORTS_END - -static INPUT_PORTS_START( mbee ) - - PORT_INCLUDE( oldkb ) - - // Autorun on quickload - PORT_START("CONFIG") - PORT_CONFNAME( 0x01, 0x01, "Autorun on Quickload") - PORT_CONFSETTING( 0x00, DEF_STR(No)) - PORT_CONFSETTING( 0x01, DEF_STR(Yes)) - // monochrome monitor could be used - PORT_CONFNAME( 0x30, 0x00, "Monitor type") - PORT_CONFSETTING( 0x00, "Colour") - PORT_CONFSETTING( 0x10, "Green") - PORT_CONFSETTING( 0x20, "Amber") - PORT_CONFSETTING( 0x30, "White") - // Wire links on motherboard - PORT_CONFNAME( 0xc0, 0x00, "PIO B7") - PORT_CONFSETTING( 0x00, "VS") // sync pulse to enable telcom clock - PORT_CONFSETTING( 0x40, "RTC") // optional board usually not fitted - PORT_CONFSETTING( 0x80, "Tied high") // default resistor to vcc - PORT_CONFSETTING( 0xc0, "Reserved for net") -INPUT_PORTS_END - -static INPUT_PORTS_START( mbee128 ) - - PORT_INCLUDE( oldkb ) - - // Autorun on quickload - PORT_START("CONFIG") - PORT_CONFNAME( 0x01, 0x01, "Autorun on Quickload") - PORT_CONFSETTING( 0x00, DEF_STR(No)) - PORT_CONFSETTING( 0x01, DEF_STR(Yes)) - // monochrome monitor could be used - PORT_CONFNAME( 0x30, 0x00, "Monitor type") - PORT_CONFSETTING( 0x00, "Colour") - PORT_CONFSETTING( 0x10, "Green") - PORT_CONFSETTING( 0x20, "Amber") - PORT_CONFSETTING( 0x30, "White") - // Wire links on motherboard - PORT_CONFNAME( 0xc0, 0x80, "PIO B7") - PORT_CONFSETTING( 0x00, "VS") // sync pulse to enable telcom clock - PORT_CONFSETTING( 0x40, "RTC") // RTC IRQ for clock - PORT_CONFSETTING( 0x80, "Tied high") // default resistor to vcc - PORT_CONFSETTING( 0xc0, "Reserved for net") -INPUT_PORTS_END - -static INPUT_PORTS_START( mbee256 ) - PORT_START("Y.0") /* IN0 KEY ROW 0 [+00] */ - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F1") PORT_CODE(KEYCODE_F1) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Escape") PORT_CODE(KEYCODE_ESC) PORT_CHAR(27) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tab") PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Break") PORT_CODE(KEYCODE_END) PORT_CHAR(3) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("0 (num)") PORT_CODE(KEYCODE_0_PAD) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("DEL (num)") PORT_CODE(KEYCODE_DEL_PAD) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') - - PORT_START("Y.1") /* IN1 KEY ROW 1 [+08] */ - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F2") PORT_CODE(KEYCODE_F2) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("1 !") PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') PORT_CHAR(0x11) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') PORT_CHAR(0x01) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Lock") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Linefeed") PORT_CODE(KEYCODE_HOME) PORT_CHAR(10) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Insert") PORT_CODE(KEYCODE_INSERT) - - PORT_START("Y.2") /* IN2 KEY ROW 2 [+10] */ - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F3") PORT_CODE(KEYCODE_F3) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("2 @") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') PORT_CHAR(0x17) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') PORT_CHAR(0x13) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("+ (num)") PORT_CODE(KEYCODE_PLUS_PAD) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("2 (num)") PORT_CODE(KEYCODE_2_PAD) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("3 (num)") PORT_CODE(KEYCODE_3_PAD) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') PORT_CHAR(0x1a) - - PORT_START("Y.3") /* IN3 KEY ROW 3 [+18] */ - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F4") PORT_CODE(KEYCODE_F4) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("3 #") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') PORT_CHAR(0x05) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') PORT_CHAR(0x04) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("- (num)") PORT_CODE(KEYCODE_MINUS_PAD) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("5 (num)") PORT_CODE(KEYCODE_5_PAD) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("6 (num)") PORT_CODE(KEYCODE_6_PAD) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') PORT_CHAR(0x18) - - PORT_START("Y.4") /* IN4 KEY ROW 4 [+20] */ - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F5") PORT_CODE(KEYCODE_F5) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("4 $") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') PORT_CHAR(0x12) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') PORT_CHAR(0x06) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("* (num)") PORT_CODE(KEYCODE_ASTERISK) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("8 (num)") PORT_CODE(KEYCODE_8_PAD) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("9 (num)") PORT_CODE(KEYCODE_9_PAD) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') PORT_CHAR(0x03) - - PORT_START("Y.5") /* IN5 KEY ROW 5 [+28] */ - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F6") PORT_CODE(KEYCODE_F6) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("5 %") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') PORT_CHAR(0x14) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') PORT_CHAR(0x07) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("7 (num)") PORT_CODE(KEYCODE_7_PAD) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("1 (num)") PORT_CODE(KEYCODE_1_PAD) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("4 (num)") PORT_CODE(KEYCODE_4_PAD) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') PORT_CHAR(0x16) - - PORT_START("Y.6") /* IN6 KEY ROW 6 [+30] */ - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F7") PORT_CODE(KEYCODE_F7) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("6 &") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') PORT_CHAR(0x19) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') PORT_CHAR(0x08) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("/ (num)") PORT_CODE(KEYCODE_SLASH_PAD) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("(Down)") PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("(Right)") PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') PORT_CHAR(0x02) - - PORT_START("Y.7") /* IN7 KEY ROW 7 [+38] */ - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F8") PORT_CODE(KEYCODE_F8) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("7 &") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') PORT_CHAR(0x15) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') PORT_CHAR(0x0a) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("(Left)") PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') PORT_CHAR(0x0e) - - PORT_START("Y.8") /* IN0 KEY ROW 0 [+40] */ - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F9") PORT_CODE(KEYCODE_F9) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("8 *") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') PORT_CHAR(0x09) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') PORT_CHAR(0x0b) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("(Up)") PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') PORT_CHAR(0x0d) - - PORT_START("Y.9") /* IN1 KEY ROW 1 [+48] */ - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F10") PORT_CODE(KEYCODE_F10) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("9 (") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') PORT_CHAR(0x0f) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') PORT_CHAR(0x0c) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Backspace") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Enter") PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(13) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(", <") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') - - PORT_START("Y.10") /* IN2 KEY ROW 2 [+50] */ - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F11") PORT_CODE(KEYCODE_F11) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("0 )") PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') PORT_CHAR(0x10) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("; :") PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Delete") PORT_CODE(KEYCODE_DEL) PORT_CHAR(127) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("` ~") PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~') - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("\\ |") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') PORT_CHAR(0x1c) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(". >") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') - - PORT_START("Y.11") /* IN3 KEY ROW 3 [+58] */ - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F12") PORT_CODE(KEYCODE_F12) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("-") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("[ {") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') PORT_CHAR(0x1b) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("\' \"") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('\"') - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("= +") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("] }") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') PORT_CHAR(0x1d) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("/ ?") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') - - PORT_START("Y.12") /* IN4 KEY ROW 4 [+60] */ - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) - - PORT_START("Y.13") /* IN5 KEY ROW 5 [+68] */ - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Ctrl") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_SHIFT_2) - - PORT_START("Y.14") /* IN6 KEY ROW 6 [+70] */ - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Alt") PORT_CODE(KEYCODE_LALT) PORT_CODE(KEYCODE_RALT) - - // Autorun on quickload - PORT_START("CONFIG") - PORT_CONFNAME( 0x01, 0x01, "Autorun on Quickload") - PORT_CONFSETTING( 0x00, DEF_STR(No)) - PORT_CONFSETTING( 0x01, DEF_STR(Yes)) - // Wire links on motherboard - PORT_CONFNAME( 0xc0, 0x80, "PIO B7") - PORT_CONFSETTING( 0x00, "VS") // sync pulse to enable telcom clock - PORT_CONFSETTING( 0x40, "RTC") // RTC IRQ must be used on teleterm - PORT_CONFSETTING( 0x80, "Tied high") // default resistor to vcc - PORT_CONFSETTING( 0xc0, "Reserved for net") -INPUT_PORTS_END - -static const z80_daisy_config mbee_daisy_chain[] = -{ - { "z80pio" }, - { nullptr } -}; - -/**************************** F4 CHARACTER DISPLAYER */ -static const gfx_layout charlayout = -{ - 8,16, /* 8 x 16 characters */ - RGN_FRAC(1,1), - 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, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8 }, - 8*16 /* every char takes 16 bytes */ -}; - -static GFXDECODE_START( gfx_mono ) - GFXDECODE_ENTRY( "chargen", 0x0000, charlayout, 96, 1 ) -GFXDECODE_END - -static GFXDECODE_START( gfx_standard ) - GFXDECODE_ENTRY( "chargen", 0x0000, charlayout, 0, 48 ) -GFXDECODE_END - -static GFXDECODE_START( gfx_premium ) - GFXDECODE_ENTRY( "chargen", 0x0000, charlayout, 0, 8 ) -GFXDECODE_END - -static void mbee_floppies(device_slot_interface &device) -{ - device.option_add("35dd", FLOPPY_35_DD); - device.option_add("525qd", FLOPPY_525_QD); -} - - -void mbee_state::remove_carts(machine_config &config) -{ - config.device_remove("cart_list"); - config.device_remove("optrom1"); - config.device_remove("optrom2"); - config.device_remove("optrom3"); - config.device_remove("optrom4"); - config.device_remove("optrom5"); - config.device_remove("optrom6"); - config.device_remove("optrom7"); -} - -void mbee_state::remove_quick(machine_config &config) -{ - config.device_remove("cass_list"); - config.device_remove("quickload"); - config.device_remove("quik_list"); -} - -void mbee_state::mbee(machine_config &config) -{ - /* basic machine hardware */ - Z80(config, m_maincpu, 12_MHz_XTAL / 6); /* 2 MHz */ - m_maincpu->set_addrmap(AS_PROGRAM, &mbee_state::mbee_mem); - m_maincpu->set_addrmap(AS_IO, &mbee_state::mbee_io); - m_maincpu->set_daisy_config(mbee_daisy_chain); - - Z80PIO(config, m_pio, 12_MHz_XTAL / 6); - m_pio->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); - m_pio->out_pa_callback().set("cent_data_out", FUNC(output_latch_device::write)); - m_pio->out_ardy_callback().set(FUNC(mbee_state::pio_ardy)); - m_pio->in_pb_callback().set(FUNC(mbee_state::pio_port_b_r)); - m_pio->out_pb_callback().set(FUNC(mbee_state::pio_port_b_w)); - - SCREEN(config, m_screen, SCREEN_TYPE_RASTER); - m_screen->set_refresh_hz(50); - m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(250)); /* not accurate */ - m_screen->set_size(64*8, 19*16); /* need at least 17 lines for NET */ - m_screen->set_visarea(0*8, 64*8-1, 0, 19*16-1); - m_screen->set_screen_update(FUNC(mbee_state::screen_update_mbee)); - - GFXDECODE(config, "gfxdecode", m_palette, gfx_mono); - - PALETTE(config, m_palette, FUNC(mbee_state::standard_palette), 100); - - /* sound hardware */ - SPEAKER(config, "mono").front_center(); - SPEAKER_SOUND(config, "speaker").add_route(ALL_OUTPUTS, "mono", 0.50); - - /* devices */ - SY6545_1(config, m_crtc, 12_MHz_XTAL / 8); - m_crtc->set_screen(m_screen); - m_crtc->set_show_border_area(false); - m_crtc->set_char_width(8); - m_crtc->set_update_row_callback(FUNC(mbee_state::crtc_update_row)); - m_crtc->set_on_update_addr_change_callback(FUNC(mbee_state::crtc_update_addr)); - m_crtc->out_vsync_callback().set(FUNC(mbee_state::crtc_vs)); - - quickload_image_device &quickload(QUICKLOAD(config, "quickload", "mwb,com,bee,bin", attotime::from_seconds(3))); - quickload.set_load_callback(FUNC(mbee_state::quickload_cb)); - quickload.set_interface("mbee_quik"); - - CENTRONICS(config, m_centronics, centronics_devices, nullptr); - m_centronics->ack_handler().set(m_pio, FUNC(z80pio_device::strobe_a)); - - OUTPUT_LATCH(config, m_cent_data_out); - m_centronics->set_output_latch(*m_cent_data_out); - - CASSETTE(config, m_cassette); - m_cassette->set_formats(mbee_cassette_formats); - 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("mbee_cass"); - - generic_slot_device &optrom1(GENERIC_SOCKET(config, "optrom1", generic_plain_slot, "mbee_net", "mbn")); // net - optrom1.set_device_load(FUNC(mbee_state::pak_load<1U>)); - optrom1.set_device_unload(FUNC(mbee_state::pak_unload<1U>)); - generic_slot_device &optrom2(GENERIC_SOCKET(config, "optrom2", generic_plain_slot, "mbee_pak", "mbp")); // edasm - optrom2.set_device_load(FUNC(mbee_state::pak_load<2U>)); - optrom2.set_device_unload(FUNC(mbee_state::pak_unload<2U>)); - - SOFTWARE_LIST(config, "cass_list").set_original("mbee_cass").set_filter("1"); - SOFTWARE_LIST(config, "quik_list").set_original("mbee_quik").set_filter("1"); - SOFTWARE_LIST(config, "cart_list").set_original("mbee_cart").set_filter("1"); -} - - -void mbee_state::mbeeic(machine_config &config) -{ - /* basic machine hardware */ - Z80(config, m_maincpu, 13.5_MHz_XTAL / 4); /* 3.37500 MHz */ - m_maincpu->set_addrmap(AS_PROGRAM, &mbee_state::mbeeic_mem); - m_maincpu->set_addrmap(AS_IO, &mbee_state::mbeeic_io); - m_maincpu->set_daisy_config(mbee_daisy_chain); - - Z80PIO(config, m_pio, 13.5_MHz_XTAL / 4); - m_pio->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); - m_pio->out_pa_callback().set("cent_data_out", FUNC(output_latch_device::write)); - m_pio->out_ardy_callback().set(FUNC(mbee_state::pio_ardy)); - m_pio->in_pb_callback().set(FUNC(mbee_state::pio_port_b_r)); - m_pio->out_pb_callback().set(FUNC(mbee_state::pio_port_b_w)); - - SCREEN(config, m_screen, SCREEN_TYPE_RASTER); - m_screen->set_refresh_hz(50); - m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(250)); /* not accurate */ - m_screen->set_size(80*8, 310); - m_screen->set_visarea(0, 80*8-1, 0, 19*16-1); - m_screen->set_screen_update(FUNC(mbee_state::screen_update_mbee)); - - GFXDECODE(config, "gfxdecode", m_palette, gfx_standard); - - PALETTE(config, m_palette, FUNC(mbee_state::standard_palette), 100); - - /* sound hardware */ - SPEAKER(config, "mono").front_center(); - SPEAKER_SOUND(config, "speaker").add_route(ALL_OUTPUTS, "mono", 0.50); - - /* devices */ - SY6545_1(config, m_crtc, 13.5_MHz_XTAL / 8); - m_crtc->set_screen(m_screen); - m_crtc->set_show_border_area(false); - m_crtc->set_char_width(8); - m_crtc->set_update_row_callback(FUNC(mbee_state::crtc_update_row)); - m_crtc->set_on_update_addr_change_callback(FUNC(mbee_state::crtc_update_addr)); - m_crtc->out_vsync_callback().set(FUNC(mbee_state::crtc_vs)); - - quickload_image_device &quickload(QUICKLOAD(config, "quickload", "mwb,com,bee,bin", attotime::from_seconds(3))); - quickload.set_load_callback(FUNC(mbee_state::quickload_cb)); - quickload.set_interface("mbee_quik"); - - CENTRONICS(config, m_centronics, centronics_devices, "printer"); - m_centronics->ack_handler().set(m_pio, FUNC(z80pio_device::strobe_a)); - - OUTPUT_LATCH(config, m_cent_data_out); - m_centronics->set_output_latch(*m_cent_data_out); - - CASSETTE(config, m_cassette); - m_cassette->set_formats(mbee_cassette_formats); - 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("mbee_cass"); - - generic_slot_device &optrom1(GENERIC_SOCKET(config, "optrom1", generic_plain_slot, "mbee_net", "mbn")); // net - optrom1.set_device_load(FUNC(mbee_state::pak_load<1U>)); - optrom1.set_device_unload(FUNC(mbee_state::pak_unload<1U>)); - generic_slot_device &optrom2(GENERIC_SOCKET(config, "optrom2", generic_plain_slot, "mbee_pak", "mbp")); // pak0 - optrom2.set_device_load(FUNC(mbee_state::pak_load<2U>)); - optrom2.set_device_unload(FUNC(mbee_state::pak_unload<2U>)); - generic_slot_device &optrom3(GENERIC_SOCKET(config, "optrom3", generic_plain_slot, "mbee_pak", "mbp")); // pak1 - optrom3.set_device_load(FUNC(mbee_state::pak_load<3U>)); - optrom3.set_device_unload(FUNC(mbee_state::pak_unload<3U>)); - generic_slot_device &optrom4(GENERIC_SOCKET(config, "optrom4", generic_plain_slot, "mbee_pak", "mbp")); // pak2 - optrom4.set_device_load(FUNC(mbee_state::pak_load<4U>)); - optrom4.set_device_unload(FUNC(mbee_state::pak_unload<4U>)); - generic_slot_device &optrom5(GENERIC_SOCKET(config, "optrom5", generic_plain_slot, "mbee_pak", "mbp")); // pak3 - optrom5.set_device_load(FUNC(mbee_state::pak_load<5U>)); - optrom5.set_device_unload(FUNC(mbee_state::pak_unload<5U>)); - generic_slot_device &optrom6(GENERIC_SOCKET(config, "optrom6", generic_plain_slot, "mbee_pak", "mbp")); // pak4 - optrom6.set_device_load(FUNC(mbee_state::pak_load<6U>)); - optrom6.set_device_unload(FUNC(mbee_state::pak_unload<6U>)); - generic_slot_device &optrom7(GENERIC_SOCKET(config, "optrom7", generic_plain_slot, "mbee_pak", "mbp")); // pak5 - optrom7.set_device_load(FUNC(mbee_state::pak_load<7U>)); - optrom7.set_device_unload(FUNC(mbee_state::pak_unload<7U>)); - - SOFTWARE_LIST(config, "cass_list").set_original("mbee_cass").set_filter("2"); - SOFTWARE_LIST(config, "quik_list").set_original("mbee_quik").set_filter("2"); - SOFTWARE_LIST(config, "cart_list").set_original("mbee_cart").set_filter("2"); -} - -void mbee_state::mbeepc85(machine_config &config) -{ - mbeeic(config); - SOFTWARE_LIST(config.replace(), "cart_list").set_original("mbee_cart").set_filter("3"); -} - -void mbee_state::mbeeppc(machine_config &config) -{ - mbeepc85(config); - - m_maincpu->set_addrmap(AS_PROGRAM, &mbee_state::mbeeppc_mem); - m_maincpu->set_addrmap(AS_IO, &mbee_state::mbeeppc_io); - subdevice("gfxdecode")->set_info(gfx_premium); - m_palette->set_init(FUNC(mbee_state::premium_palette)); - - MC146818(config, m_rtc, 32.768_kHz_XTAL); - m_rtc->irq().set(FUNC(mbee_state::rtc_irq_w)); -} - -void mbee_state::mbee56(machine_config &config) -{ - mbeeic(config); - m_maincpu->set_addrmap(AS_PROGRAM, &mbee_state::mbee56_mem); - m_maincpu->set_addrmap(AS_IO, &mbee_state::mbee56_io); - - WD2793(config, m_fdc, 4_MHz_XTAL / 2); - m_fdc->intrq_wr_callback().set(FUNC(mbee_state::fdc_intrq_w)); - m_fdc->drq_wr_callback().set(FUNC(mbee_state::fdc_drq_w)); - m_fdc->enmf_rd_callback().set_constant(0); - FLOPPY_CONNECTOR(config, m_floppy0, mbee_floppies, "35dd", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, m_floppy1, mbee_floppies, "35dd", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); - - SOFTWARE_LIST(config, "flop_list").set_original("mbee_flop").set_filter("1"); - remove_carts(config); - remove_quick(config); -} - -void mbee_state::mbee128(machine_config &config) -{ - mbee56(config); - m_maincpu->set_addrmap(AS_PROGRAM, &mbee_state::mbee256_mem); - m_maincpu->set_addrmap(AS_IO, &mbee_state::mbee128_io); - - MC146818(config, m_rtc, 32.768_kHz_XTAL); - m_rtc->irq().set(FUNC(mbee_state::rtc_irq_w)); - - SOFTWARE_LIST(config.replace(), "flop_list").set_original("mbee_flop").set_filter("2"); -} - -void mbee_state::mbee128p(machine_config &config) -{ - mbeeppc(config); - m_maincpu->set_addrmap(AS_PROGRAM, &mbee_state::mbee256_mem); - m_maincpu->set_addrmap(AS_IO, &mbee_state::mbee128p_io); - - WD2793(config, m_fdc, 4_MHz_XTAL / 2); - m_fdc->intrq_wr_callback().set(FUNC(mbee_state::fdc_intrq_w)); - m_fdc->drq_wr_callback().set(FUNC(mbee_state::fdc_drq_w)); - m_fdc->enmf_rd_callback().set_constant(0); - FLOPPY_CONNECTOR(config, m_floppy0, mbee_floppies, "35dd", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, m_floppy1, mbee_floppies, "35dd", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); - - SN76489A(config, "sn1", 13.5_MHz_XTAL / 4).add_route(ALL_OUTPUTS, "mono", 0.50); - - SOFTWARE_LIST(config, "flop_list").set_original("mbee_flop").set_filter("3"); - remove_carts(config); - remove_quick(config); -} - -void mbee_state::mbeepp(machine_config &config) -{ - mbee128p(config); - SOFTWARE_LIST(config.replace(), "flop_list").set_original("mbee_flop").set_filter("2,3"); -} - -void mbee_state::mbee256(machine_config &config) -{ - mbee128p(config); - m_maincpu->set_addrmap(AS_PROGRAM, &mbee_state::mbee256_mem); - m_maincpu->set_addrmap(AS_IO, &mbee_state::mbee256_io); - - TIMER(config, "newkb_timer").configure_periodic(FUNC(mbee_state::newkb_timer), attotime::from_hz(50)); - - SOFTWARE_LIST(config.replace(), "flop_list").set_original("mbee_flop").set_filter("4"); -} - -void mbee_state::mbeett(machine_config &config) -{ - mbeeppc(config); - m_maincpu->set_addrmap(AS_PROGRAM, &mbee_state::mbeett_mem); - m_maincpu->set_addrmap(AS_IO, &mbee_state::mbeett_io); - TIMER(config, "newkb_timer").configure_periodic(FUNC(mbee_state::newkb_timer), attotime::from_hz(50)); - remove_quick(config); - config.device_remove("optrom3"); - config.device_remove("optrom4"); - config.device_remove("optrom5"); - config.device_remove("optrom6"); - config.device_remove("optrom7"); - SOFTWARE_LIST(config.replace(), "cart_list").set_original("mbee_cart").set_filter("TT"); -} - -// This represents the Series 1: Kit computer, 16K, 32K, 16K Plus, and 32K plus. -ROM_START( mbee ) - ROM_REGION( 0x6000, "maincpu", 0 ) - ROM_SYSTEM_BIOS( 0, "510", "Basic 5.10" ) - ROMX_LOAD("bas510a.ic25", 0x0000, 0x1000, CRC(2ca47c36) SHA1(f36fd0afb3f1df26edc67919e78000b762b6cbcb), ROM_BIOS(0) ) - ROMX_LOAD("bas510b.ic27", 0x1000, 0x1000, CRC(a07a0c51) SHA1(dcbdd9df78b4b6b2972de2e4050dabb8ae9c3f5a), ROM_BIOS(0) ) - ROMX_LOAD("bas510c.ic28", 0x2000, 0x1000, CRC(906ac00f) SHA1(9b46458e5755e2c16cdb191a6a70df6de9fe0271), ROM_BIOS(0) ) - ROMX_LOAD("bas510d.ic30", 0x3000, 0x1000, CRC(61727323) SHA1(c0fea9fd0e25beb9faa7424db8efd07cf8d26c1b), ROM_BIOS(0) ) - ROM_SYSTEM_BIOS( 1, "500", "Basic 5.00" ) - ROMX_LOAD("bas500a.ic25", 0x0000, 0x1000, CRC(5fabd317) SHA1(a91bb6a802da17bc02e720e68b8bdd80261b5039), ROM_BIOS(1) ) - ROMX_LOAD("bas500b.ic27", 0x1000, 0x1000, CRC(0aaf5d04) SHA1(f871a2991d4a487596ec637e237fc0d9656f4a64), ROM_BIOS(1) ) - ROMX_LOAD("bas500c.ic28", 0x2000, 0x1000, CRC(ab7d79b8) SHA1(75f71b63dcd81946afce7e2c4d83c6f3ba5c2bc3), ROM_BIOS(1) ) - ROMX_LOAD("bas500d.ic30", 0x3000, 0x1000, CRC(19f83c4e) SHA1(3ca985bb6b31d39e9cd42ea0a4baeb266c1b5e86), ROM_BIOS(1) ) - - // first 0x800 for normal chars, 2nd 0x800 for small chars. Some roms don't have small chars so normal ones loaded twice. - ROM_REGION( 0x1000, "chargen", 0 ) - ROM_LOAD("charrom.ic13", 0x0000, 0x0800, CRC(b149737b) SHA1(a3cd4f5d0d3c71137cd1f0f650db83333a2e3597) ) - ROM_RELOAD( 0x0800, 0x0800 ) - - ROM_REGION( 0x0020, "proms", 0 ) - ROM_LOAD_OPTIONAL( "82s123.ic16", 0x0000, 0x0020, CRC(79fa1e9d) SHA1(0454051697b23e4561744466fb31e7a133d02246) ) // video switching prom, not needed for emulation purposes -ROM_END - -// This represents the Series 1: IC (Integrated Computer), and the Series 2: Experimenter, the Educator, and the Personal Communicator -ROM_START( mbeeic ) - ROM_REGION( 0x4000, "maincpu", 0 ) - ROM_SYSTEM_BIOS( 0, "522e", "Basic 5.22e" ) - ROMX_LOAD("bas522e.ic5", 0x0000, 0x2000, CRC(7896a696) SHA1(a158f7803296766160e1f258dfc46134735a9477), ROM_BIOS(0) ) - ROMX_LOAD("bas522e.ic10", 0x2000, 0x2000, CRC(b21d9679) SHA1(332844433763331e9483409cd7da3f90ac58259d), ROM_BIOS(0) ) - ROM_SYSTEM_BIOS( 1, "522d", "Basic 5.22d" ) - ROMX_LOAD("bas522d.ic5", 0x0000, 0x2000, CRC(7896a696) SHA1(a158f7803296766160e1f258dfc46134735a9477), ROM_BIOS(1) ) - ROMX_LOAD("bas522d.ic10", 0x2000, 0x2000, CRC(523a38ff) SHA1(a5383067bc712123849710d8b69cbd879d17a61f), ROM_BIOS(1) ) - - ROM_REGION( 0x1000, "netdef", ROMREGION_ERASEFF ) - ROM_LOAD_OPTIONAL( "telcom10.mbn", 0x0000, 0x1000, CRC(d1617e4f) SHA1(c73dc4dcf4c69419842fa4b52aa92e86924a2e2b) ) // net - - /* PAK option roms */ - ROM_REGION( 0x20000, "pakdef", ROMREGION_ERASEFF ) - ROM_LOAD_OPTIONAL("wbee12.mbp", 0x0000, 0x2000, CRC(0fc21cb5) SHA1(33b3995988fc51ddef1568e160dfe699867adbd5) ) // pak0 - ROM_LOAD_OPTIONAL("help1.mbp", 0x2000, 0x2000, CRC(d34fae54) SHA1(5ed30636f48e9d208ce2da367ba4425782a5bce3) ) // pak1 - - ROM_REGION( 0x1000, "chargen", 0 ) - ROM_LOAD("charrom.bin", 0x0000, 0x1000, CRC(1f9fcee4) SHA1(e57ac94e03638075dde68a0a8c834a4f84ba47b0) ) - - ROM_REGION( 0x0040, "proms", 0 ) - ROM_LOAD( "82s123.ic7", 0x0000, 0x0020, CRC(61b9c16c) SHA1(0ee72377831c21339360c376f7248861d476dc20) ) - ROM_LOAD_OPTIONAL( "82s123.ic16", 0x0020, 0x0020, CRC(79fa1e9d) SHA1(0454051697b23e4561744466fb31e7a133d02246) ) // video switching prom, not needed for emulation purposes -ROM_END - -// This represents the Series 3: 16K Educator, and the 32K Communicator -ROM_START( mbeepc ) - ROM_REGION( 0x4000, "maincpu", 0 ) - ROM_SYSTEM_BIOS( 0, "522e", "Basic 5.22e" ) - ROMX_LOAD("bas522e.ic5", 0x0000, 0x2000, CRC(7896a696) SHA1(a158f7803296766160e1f258dfc46134735a9477), ROM_BIOS(0) ) - ROMX_LOAD("bas522e.ic10", 0x2000, 0x2000, CRC(b21d9679) SHA1(332844433763331e9483409cd7da3f90ac58259d), ROM_BIOS(0) ) - ROM_SYSTEM_BIOS( 1, "524e", "Basic 5.24e" ) - ROMX_LOAD("bas524e.ic5", 0x0000, 0x2000, CRC(ec9c7a60) SHA1(a4021bcedc8da8c0eb0bda036a1d457619a175b0), ROM_BIOS(1) ) - ROMX_LOAD("bas524e.ic10", 0x2000, 0x2000, CRC(9621cfc8) SHA1(81ab332d366466ae84cff2e8b8596dd86c6b6f63), ROM_BIOS(1) ) - - ROM_REGION( 0x1000, "netdef", ROMREGION_ERASEFF ) - ROM_LOAD_OPTIONAL( "telcom10.mbn", 0x0000, 0x1000, CRC(d1617e4f) SHA1(c73dc4dcf4c69419842fa4b52aa92e86924a2e2b) ) // net - - /* PAK option roms */ - ROM_REGION( 0x20000, "pakdef", ROMREGION_ERASEFF ) - ROM_LOAD_OPTIONAL("wbee12.mbp", 0x0000, 0x2000, CRC(0fc21cb5) SHA1(33b3995988fc51ddef1568e160dfe699867adbd5) ) // pak0 - ROM_LOAD_OPTIONAL("help1.mbp", 0x2000, 0x2000, CRC(d34fae54) SHA1(5ed30636f48e9d208ce2da367ba4425782a5bce3) ) // pak1 - - ROM_REGION( 0x1000, "chargen", 0 ) - ROM_LOAD("charrom.bin", 0x0000, 0x1000, CRC(1f9fcee4) SHA1(e57ac94e03638075dde68a0a8c834a4f84ba47b0) ) - - ROM_REGION( 0x0040, "proms", 0 ) - ROM_LOAD( "82s123.ic7", 0x0000, 0x0020, CRC(61b9c16c) SHA1(0ee72377831c21339360c376f7248861d476dc20) ) - ROM_LOAD_OPTIONAL( "82s123.ic16", 0x0020, 0x0020, CRC(79fa1e9d) SHA1(0454051697b23e4561744466fb31e7a133d02246) ) // video switching prom, not needed for emulation purposes -ROM_END - -ROM_START( mbeepc85 ) // The PC85 with the earlier menu - ROM_REGION( 0x4000, "maincpu", 0 ) - ROM_LOAD("bas525a.rom", 0x0000, 0x2000, CRC(a6e02afe) SHA1(0495308c7e1d84b5989a3af6d3b881f4580b2641) ) - ROM_LOAD("bas525b.rom", 0x2000, 0x2000, CRC(245dd36b) SHA1(dd288f3e6737627f50d3d2a49df3e57c423d3118) ) - - ROM_REGION( 0x2000, "netdef", ROMREGION_ERASEFF ) - ROM_LOAD_OPTIONAL("telcom321a.mbn", 0x0000, 0x2000, CRC(36852a11) SHA1(c45b8d03629e86231c6b256a7435abd87d8872a4) ) - - // PAK option roms - Wordbee must be in slot 0 and Shell must be in slot 5. - ROM_REGION( 0x20000, "pakdef", ROMREGION_ERASEFF ) - ROM_LOAD("wbee13r3.mbp", 0x0000, 0x2000, CRC(d7c58b7b) SHA1(5af1b8d21a0f21534ed1833ae919dbbc6ca973e2) ) // 0 - ROM_LOAD("help2.mbp", 0x2000, 0x2000, CRC(a4f1fa90) SHA1(1456abc6ed0501a3b15a99b4302750843293ae5f) ) // 1 - ROM_LOAD("shell.mbp", 0xa000, 0x2000, CRC(5a2c7cd6) SHA1(8edc086710cb558f2146d660eddc8a18ba6a141c) ) // 5 - - ROM_REGION( 0x1000, "chargen", 0 ) - ROM_LOAD("charrom.bin", 0x0000, 0x1000, CRC(1f9fcee4) SHA1(e57ac94e03638075dde68a0a8c834a4f84ba47b0) ) - - ROM_REGION( 0x0040, "proms", 0 ) - ROM_LOAD( "82s123.ic7", 0x0000, 0x0020, CRC(61b9c16c) SHA1(0ee72377831c21339360c376f7248861d476dc20) ) - ROM_LOAD_OPTIONAL( "82s123.ic16", 0x0020, 0x0020, CRC(79fa1e9d) SHA1(0454051697b23e4561744466fb31e7a133d02246) ) // video switching prom, not needed for emulation purposes -ROM_END - -ROM_START( mbeepc85b ) // The PC85 with the later menu - ROM_REGION( 0x4000, "maincpu", 0 ) - ROM_LOAD("bas525a.rom", 0x0000, 0x2000, CRC(a6e02afe) SHA1(0495308c7e1d84b5989a3af6d3b881f4580b2641) ) - ROM_LOAD("bas525b.rom", 0x2000, 0x2000, CRC(245dd36b) SHA1(dd288f3e6737627f50d3d2a49df3e57c423d3118) ) - - ROM_REGION( 0x2000, "netdef", ROMREGION_ERASEFF ) - ROM_LOAD_OPTIONAL("telcom321a.mbn", 0x0000, 0x2000, CRC(36852a11) SHA1(c45b8d03629e86231c6b256a7435abd87d8872a4) ) - - // PAK option roms - Wordbee must be in slot 0 and Shell must be in slot 5. - ROM_REGION( 0x20000, "pakdef", ROMREGION_ERASEFF ) - ROM_LOAD("wbee13r3.mbp", 0x0000, 0x2000, CRC(d7c58b7b) SHA1(5af1b8d21a0f21534ed1833ae919dbbc6ca973e2) ) // 0 - ROM_LOAD("help2.mbp", 0x2000, 0x2000, CRC(a4f1fa90) SHA1(1456abc6ed0501a3b15a99b4302750843293ae5f) ) // 1 - ROM_LOAD("busy.mbp", 0x4000, 0x2000, CRC(56255f60) SHA1(fd2e37209fd49290be6875bc460cfc05392938ba) ) // 2 - ROM_CONTINUE( 0x14000, 0x2000 ) - ROM_LOAD("graphics.mbp", 0x6000, 0x2000, CRC(9e9d327c) SHA1(aebf60ed153004380b9f271f2212376910a6cef9) ) // 3 - ROM_CONTINUE( 0x16000, 0x2000 ) - ROM_LOAD("viatel23.mbp", 0x8000, 0x2000, CRC(2da2411f) SHA1(d3cfa978165feef0a96e28197f6a762aa6604799) ) // 4 - ROM_LOAD("shell-b.mbp", 0xa000, 0x2000, CRC(17bf2d58) SHA1(ae22a5fc5783f37066ba5555497e40945272ca3d) ) // 5 - - ROM_REGION( 0x1000, "chargen", 0 ) - ROM_LOAD("charrom.bin", 0x0000, 0x1000, CRC(1f9fcee4) SHA1(e57ac94e03638075dde68a0a8c834a4f84ba47b0) ) - - ROM_REGION( 0x0040, "proms", 0 ) - ROM_LOAD( "82s123.ic7", 0x0000, 0x0020, CRC(61b9c16c) SHA1(0ee72377831c21339360c376f7248861d476dc20) ) - ROM_LOAD_OPTIONAL( "82s123.ic16", 0x0020, 0x0020, CRC(79fa1e9d) SHA1(0454051697b23e4561744466fb31e7a133d02246) ) // video switching prom, not needed for emulation purposes -ROM_END - -ROM_START( mbeepc85s ) // The Swedish version of the PC85, with custom localised software paks - ROM_REGION( 0x4000, "maincpu", 0 ) - ROM_LOAD("bas524a.rom", 0x0000, 0x2000, CRC(ec9c7a60) SHA1(a4021bcedc8da8c0eb0bda036a1d457619a175b0) ) - ROM_LOAD("bas524b.rom", 0x2000, 0x2000, CRC(17d3eac7) SHA1(d40d376cc5e751d257d951909a34445e70506c7b) ) - - ROM_REGION( 0x2000, "netdef", ROMREGION_ERASEFF ) - ROM_LOAD_OPTIONAL("telcom321s.mbp", 0x0000, 0x2000, CRC(00f8fde1) SHA1(eb881bbab90c85fd6e29540decd25e884c67f738) ) - - // PAK roms - These are not optional and will only work in the correct slots. - ROM_REGION( 0x20000, "pakdef", ROMREGION_ERASEFF ) - ROM_LOAD("wbee20s.mbp", 0x0000, 0x2000, CRC(6a0fe57f) SHA1(a101b588b1872e19382b9e9ea50fabb0fd060aa6) ) // 0 - ROM_LOAD("db-s.mbp", 0x2000, 0x2000, CRC(e2094771) SHA1(62d7fb66c91d2bd24523bc84e4f005cf2c4480bb) ) // 1 - ROM_LOAD("kalk-s.mbp", 0x4000, 0x2000, CRC(08dd71ee) SHA1(c9d506d8bb56f602c3481b253d4cac226f545d98) ) // 2 - ROM_LOAD("bg-s.mbp", 0x6000, 0x2000, CRC(5aa4813e) SHA1(a8638e9046bfb9d5a98c878322295ce408bd879d) ) // 3 - ROM_LOAD("vtex11s.mbp", 0x8000, 0x2000, CRC(67592b3f) SHA1(7f1d23ded34781ccda5f36b4a4fa118a8c0e44ec) ) // 4 - ROM_LOAD("shell-s.mbp", 0xa000, 0x2000, CRC(bdf1768f) SHA1(4385351d07288cf94947ac63131eeed98572caa1) ) // 5 - - ROM_REGION( 0x1000, "chargen", 0 ) - ROM_LOAD("charrom-s.bin", 0x0000, 0x1000, CRC(1bcbf083) SHA1(6438649b8b5fc20dd772ec7195e69a5bbe016b09) ) - - ROM_REGION( 0x0040, "proms", 0 ) - ROM_LOAD( "82s123.ic7", 0x0000, 0x0020, CRC(61b9c16c) SHA1(0ee72377831c21339360c376f7248861d476dc20) ) - ROM_LOAD_OPTIONAL( "82s123.ic16", 0x0020, 0x0020, CRC(79fa1e9d) SHA1(0454051697b23e4561744466fb31e7a133d02246) ) // video switching prom, not needed for emulation purposes -ROM_END - -ROM_START( mbeett ) // The Teleterm - ROM_REGION( 0x2000, "maincpu", 0 ) - ROM_LOAD("kernel_106.rom", 0x0000, 0x2000, CRC(5ab9cb1d) SHA1(a1fb971622f85c4d866b91cb4bec6d75757e8c5f) ) - - ROM_REGION( 0x2000, "netdef", ROMREGION_ERASEFF ) - ROM_LOAD("wm_106.mbn", 0x0000, 0x2000, CRC(77e0b355) SHA1(1db6769cd6b12e1c335c83f17f8c139986c87758) ) - - ROM_REGION( 0x20000, "pakdef", ROMREGION_ERASEFF ) - ROM_LOAD("tv_470311.mbp", 0x2000, 0x2000, CRC(2c4c2dcb) SHA1(77cd75166a389cb2d1d8abf00b1ddd077ce98354) ) // 1 - ROM_CONTINUE( 0x12000, 0x2000 ) - ROM_LOAD("tw_103.mbp", 0x4000, 0x2000, CRC(881edb4b) SHA1(f6e30a12b1537bd55b69d1319799b150e80a471b) ) // 2 - ROM_CONTINUE( 0x14000, 0x2000 ) - ROM_LOAD("oside_107.mbp", 0x6000, 0x2000, CRC(05d99aba) SHA1(4f88d63025f99bcc54d6f2abc20a699c97384f68) ) // 3 - ROM_CONTINUE( 0x16000, 0x1000 ) - ROM_LOAD("test_105.mbp", 0x8000, 0x2000, CRC(b69aa618) SHA1(49de8cbad59f549c7ad9f8efc9beee0cfcd901fe) ) // 4 - - ROM_REGION( 0x1000, "chargen", 0 ) - ROM_LOAD("charrom.bin", 0x0000, 0x1000, CRC(1f9fcee4) SHA1(e57ac94e03638075dde68a0a8c834a4f84ba47b0) ) -ROM_END - -ROM_START( mbeeppc ) // The Premium PC85 - ROM_REGION( 0x2000, "maincpu", 0 ) - ROM_LOAD("bas529b.rom", 0x0000, 0x2000, CRC(a1bd986b) SHA1(5d79f210c9042db5aefc85a0bdf45210cb9e9899) ) - - ROM_REGION( 0x4000, "basicrom", 0 ) - ROM_LOAD("bas529a.rom", 0x0000, 0x4000, CRC(fe8242e1) SHA1(ff790edf4fcc7a134d451dbad7779157b07f6abf) ) - - ROM_REGION( 0x2000, "netdef", ROMREGION_ERASEFF ) - ROM_LOAD_OPTIONAL("telco321.rom", 0x0000, 0x2000, CRC(36852a11) SHA1(c45b8d03629e86231c6b256a7435abd87d8872a4) ) - - /* PAK option roms - Wordbee must be in slot 0 and Shell must be in slot 5. */ - ROM_REGION( 0x20000, "pakdef", ROMREGION_ERASEFF ) - ROM_LOAD("wbee13r3.mbp", 0x0000, 0x2000, CRC(d7c58b7b) SHA1(5af1b8d21a0f21534ed1833ae919dbbc6ca973e2) ) // 0 - ROM_LOAD("help2.mbp", 0x2000, 0x2000, CRC(a4f1fa90) SHA1(1456abc6ed0501a3b15a99b4302750843293ae5f) ) // 1 - ROM_LOAD("busy-p.mbp", 0x4000, 0x2000, CRC(f2897427) SHA1(b4c351bdac72d89589980be6d654f9b931bcba6b) ) // 2 - ROM_CONTINUE( 0x14000, 0x2000 ) - ROM_LOAD("graphics.mbp", 0x6000, 0x2000, CRC(9e9d327c) SHA1(aebf60ed153004380b9f271f2212376910a6cef9) ) // 3 - ROM_CONTINUE( 0x16000, 0x2000 ) - ROM_LOAD("vtex235.mbp", 0x8000, 0x2000, CRC(8c30ecb2) SHA1(cf068462d7def885bdb5d3a265851b88c727c0d7) ) // 4 - ROM_LOAD("ppcshell.mbp", 0xa000, 0x2000, CRC(1e793555) SHA1(ddeaa081ec4408e80e3fb192865d87daa035c701) ) // 5 - - ROM_REGION( 0x1000, "chargen", 0 ) - ROM_LOAD("charrom.bin", 0x0000, 0x1000, CRC(1f9fcee4) SHA1(e57ac94e03638075dde68a0a8c834a4f84ba47b0) ) -ROM_END - -// This represents the Series 1: 64K, and 64K Plus -ROM_START( mbee56 ) - ROM_REGION( 0x1000, "maincpu", 0 ) - ROM_LOAD("56kb.rom", 0x0000, 0x1000, CRC(28211224) SHA1(b6056339402a6b2677b0e6c57bd9b78a62d20e4f) ) - - ROM_REGION( 0x1000, "chargen", 0 ) - ROM_LOAD("charrom.bin", 0x0000, 0x1000, CRC(1f9fcee4) SHA1(e57ac94e03638075dde68a0a8c834a4f84ba47b0) ) - - ROM_REGION( 0x0040, "proms", 0 ) - ROM_LOAD( "82s123.ic7", 0x0000, 0x0020, CRC(61b9c16c) SHA1(0ee72377831c21339360c376f7248861d476dc20) ) - ROM_LOAD_OPTIONAL( "82s123.ic16", 0x0020, 0x0020, CRC(79fa1e9d) SHA1(0454051697b23e4561744466fb31e7a133d02246) ) // video switching prom, not needed for emulation purposes -ROM_END - -// This represents the Series 3: 64K CIAB (Computer-in-a-Book), and the standard 128K Small Business Computer -ROM_START( mbee128 ) - ROM_REGION( 0x8000, "maincpu", 0 ) - ROM_LOAD("bn54.bin", 0x0000, 0x2000, CRC(995c53db) SHA1(46e1a5cfd5795b8cf528bacf9dc79398ff7d64af) ) - //ROM_SYSTEM_BIOS( 1, "bn55", "bn55" ) - //ROMX_LOAD("bn55.rom", 0x0000, 0x2000, CRC(ca2c1073) SHA1(355d90d181de899cc7af892df96305fead9c81b4), ROM_BIOS(1) ) // not working - meant for standard CIAB - - ROM_REGION( 0x1000, "chargen", 0 ) - ROM_LOAD("charrom.bin", 0x0000, 0x1000, CRC(1f9fcee4) SHA1(e57ac94e03638075dde68a0a8c834a4f84ba47b0) ) - - ROM_REGION( 0x4000, "pals", 0 ) // undumped; using prom from 256tc for now - ROM_LOAD( "silver.u39", 0x0000, 0x4000, BAD_DUMP CRC(c34aab64) SHA1(781fe648488dec90185760f8e081e488b73b68bf) ) - - ROM_REGION( 0x0040, "proms", 0 ) - ROM_LOAD( "82s123.ic7", 0x0000, 0x0020, CRC(61b9c16c) SHA1(0ee72377831c21339360c376f7248861d476dc20) ) - ROM_LOAD_OPTIONAL( "82s123.ic16", 0x0020, 0x0020, CRC(79fa1e9d) SHA1(0454051697b23e4561744466fb31e7a133d02246) ) // video switching prom, not needed for emulation purposes -ROM_END - -// This represents the 64K Premium CIAB, the 128K Premium Small Business Computer, and the 128K Overdrive -ROM_START( mbee128p ) - ROM_REGION( 0x8000, "maincpu", 0 ) - ROM_SYSTEM_BIOS( 0, "bn60", "Version 2.03" ) - ROMX_LOAD("bn60.rom", 0x0000, 0x2000, CRC(ed15d4ee) SHA1(3ea42b63d42b9a4c5402676dee8912ad1f906bda), ROM_BIOS(0) ) - ROM_SYSTEM_BIOS( 1, "bn59", "Version 2.02" ) - ROMX_LOAD("bn59.rom", 0x0000, 0x2000, CRC(97384116) SHA1(87f2c4ab1a1f2964ba4f2bb60e62dc9c163831ba), ROM_BIOS(1) ) - ROM_SYSTEM_BIOS( 2, "bn58", "Version 2.01" ) - ROMX_LOAD("bn58.rom", 0x0000, 0x2000, CRC(2f3757a6) SHA1(37158da0e8609fea50382f6b941fe473eaaf20cf), ROM_BIOS(2) ) - ROM_SYSTEM_BIOS( 3, "bn56", "bn56" ) - ROMX_LOAD("bn56.rom", 0x0000, 0x2000, CRC(3f76769d) SHA1(cfae2069d739c26fe39f734d9f705a3c965d1e6f), ROM_BIOS(3) ) - ROM_SYSTEM_BIOS( 4, "bn54", "bn54" ) - ROMX_LOAD("bn54.rom", 0x0000, 0x2000, CRC(995c53db) SHA1(46e1a5cfd5795b8cf528bacf9dc79398ff7d64af), ROM_BIOS(4) ) - ROM_SYSTEM_BIOS( 5, "bn54s", "bn54_Swedish" ) - ROMX_LOAD("bn54_swedish.rom", 0x0000, 0x2000, CRC(694179a6) SHA1(1d465330845cd7878c236a0c84a85b5512ccfd65), ROM_BIOS(5) ) - ROM_SYSTEM_BIOS( 6, "bn56s", "bn56_Swedish" ) - ROMX_LOAD("bn56_swedish.rom", 0x0000, 0x2000, CRC(dad4a515) SHA1(9c1e0faaccd8d2062bb3b99c8600b515ed460479), ROM_BIOS(6) ) - ROM_SYSTEM_BIOS( 7, "hd18", "Hard Disk System" ) - ROMX_LOAD("hd18.rom", 0x0000, 0x2000, CRC(ed53ace7) SHA1(534e2e00cc527197c76b3c106b3c9ff7f1328487), ROM_BIOS(7) ) - - ROM_REGION( 0x4000, "pals", 0 ) // undumped; using prom from 256tc for now - ROM_LOAD( "silver.u39", 0x0000, 0x4000, BAD_DUMP CRC(c34aab64) SHA1(781fe648488dec90185760f8e081e488b73b68bf) ) - - ROM_REGION( 0x1000, "chargen", 0 ) - ROM_LOAD("charrom.bin", 0x0000, 0x1000, CRC(1f9fcee4) SHA1(e57ac94e03638075dde68a0a8c834a4f84ba47b0) ) -ROM_END - -ROM_START( mbee256 ) // The 256K Telecomputer - ROM_REGION( 0x4000, "maincpu", 0 ) - ROM_SYSTEM_BIOS( 0, "1.20", "Version 1.20" ) - ROMX_LOAD("256tc_boot_1.20.u38", 0x0000, 0x4000, CRC(fe8d6a84) SHA1(a037a1b90b18a2180e9f5f216b829fcd480449a4), ROM_BIOS(0) ) - ROM_SYSTEM_BIOS( 1, "1.15", "Version 1.15" ) - ROMX_LOAD("256tc_boot_1.15.u38", 0x0000, 0x4000, CRC(1902062d) SHA1(e4a1c0b3f4996e313da0bac0edb6d34e3270723e), ROM_BIOS(1) ) - - ROM_REGION( 0x4000, "pals", 0 ) - ROM_LOAD( "silver.u39", 0x0000, 0x4000, CRC(c34aab64) SHA1(781fe648488dec90185760f8e081e488b73b68bf) ) - - ROM_REGION( 0x2000, "chargen", 0 ) - ROM_LOAD("char256.u53", 0x0000, 0x2000, CRC(9372af3c) SHA1(a63591822c0504de2fed52e88d64e1dbd6124b74) ) -ROM_END - -// Premium Plus - Note: The bios rom is the only one confirmed to be in the machine. IC position numbers are unknown. -// No technical information has been released. -ROM_START( mbeepp ) // Premium Plus - ROM_REGION( 0x4000, "maincpu", 0 ) - ROM_LOAD( "pp.bin", 0x0000, 0x4000, CRC(33292300) SHA1(8ba32123ef1b3beffa797855a1de0ea2078d652a) ) // ver 1.0 - - ROM_REGION( 0x4000, "pals", 0 ) - ROM_LOAD( "silver.u39", 0x0000, 0x4000, BAD_DUMP CRC(c34aab64) SHA1(781fe648488dec90185760f8e081e488b73b68bf) ) - - ROM_REGION( 0x2000, "chargen", 0 ) - ROM_LOAD("char256.u53", 0x0000, 0x2000, BAD_DUMP CRC(9372af3c) SHA1(a63591822c0504de2fed52e88d64e1dbd6124b74) ) -ROM_END - -/*************************************************************************** - - Game driver(s) - -***************************************************************************/ - -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME -COMP( 1982, mbee, 0, 0, mbee, mbee, mbee_state, init_mbee, "Applied Technology", "Microbee 16k Standard", MACHINE_SUPPORTS_SAVE ) -COMP( 1983, mbeeic, mbee, 0, mbeeic, mbee, mbee_state, init_mbeeic, "Applied Technology", "Microbee 32k IC", MACHINE_SUPPORTS_SAVE ) -COMP( 1983, mbee56, mbee, 0, mbee56, mbee, mbee_state, init_mbee56, "Applied Technology", "Microbee 64k", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) -COMP( 1984, mbeepc, mbee, 0, mbeeic, mbee, mbee_state, init_mbeeic, "Applied Technology", "Microbee 32k Communicator", MACHINE_SUPPORTS_SAVE ) -COMP( 1984, mbee128, mbee, 0, mbee128, mbee128, mbee_state, init_mbee128, "Applied Technology", "Microbee 128k Standard", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) -COMP( 1985, mbeepc85, mbee, 0, mbeepc85, mbee, mbee_state, init_mbeeic, "Applied Technology", "Microbee PC85", MACHINE_SUPPORTS_SAVE ) -COMP( 1985, mbeepc85s, mbee, 0, mbeepc85, mbee, mbee_state, init_mbeeic, "Applied Technology", "Microbee PC85 (Swedish)", MACHINE_SUPPORTS_SAVE ) -COMP( 1985, mbeepc85b, mbee, 0, mbeepc85, mbee, mbee_state, init_mbeeic, "Microbee Systems", "Microbee PC85 (New version)", MACHINE_SUPPORTS_SAVE ) -COMP( 1986, mbeeppc, mbee, 0, mbeeppc, mbee, mbee_state, init_mbeeppc, "Microbee Systems", "Microbee Premium PC85", MACHINE_SUPPORTS_SAVE ) -COMP( 1986, mbeett, mbee, 0, mbeett, mbee256, mbee_state, init_mbeett, "Microbee Systems", "Microbee Teleterm", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) -COMP( 1986, mbee128p, mbee, 0, mbee128p, mbee128, mbee_state, init_mbee128p, "Microbee Systems", "Microbee 128k Premium", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) -COMP( 1987, mbee256, mbee, 0, mbee256, mbee256, mbee_state, init_mbee256, "Microbee Systems", "Microbee 256TC", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) -COMP( 2012, mbeepp, mbee, 0, mbeepp, mbee128, mbee_state, init_mbeepp, "Microbee Systems", "Microbee Premium Plus+", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/appliedtech/mbee.h b/src/mame/appliedtech/mbee.h deleted file mode 100644 index 8cb40b3d5e0..00000000000 --- a/src/mame/appliedtech/mbee.h +++ /dev/null @@ -1,212 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Robbbert -/***************************************************************************** - * - * includes/mbee.h - * - ****************************************************************************/ -#ifndef MAME_INCLUDES_MBEE_H -#define MAME_INCLUDES_MBEE_H - -#pragma once - -#include "bus/centronics/ctronics.h" -#include "bus/generic/carts.h" -#include "bus/generic/slot.h" - -#include "cpu/z80/z80.h" -#include "machine/z80daisy.h" - -#include "imagedev/cassette.h" -#include "imagedev/floppy.h" -#include "imagedev/snapquik.h" - -#include "machine/buffer.h" -#include "machine/mc146818.h" -#include "machine/wd_fdc.h" -#include "machine/z80pio.h" - -#include "sound/spkrdev.h" - -#include "video/mc6845.h" - -#include "machine/timer.h" -#include "emupal.h" -#include "screen.h" - - -class mbee_state : public driver_device -{ -public: - mbee_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_palette(*this, "palette") - , m_maincpu(*this, "maincpu") - , m_pio(*this, "z80pio") - , m_cassette(*this, "cassette") - , m_speaker(*this, "speaker") - , m_centronics(*this, "centronics") - , m_cent_data_out(*this, "cent_data_out") - , m_crtc(*this, "crtc") - , m_fdc(*this, "fdc") - , m_floppy0(*this, "fdc:0") - , m_floppy1(*this, "fdc:1") - , m_rtc(*this, "rtc") - , m_pakdef(*this, "pakdef") - , m_netdef(*this, "netdef") - , m_p_pakdef(*this, "pakdef") - , m_p_netdef(*this, "netdef") - , m_basic(*this, "basic") - , m_io_x7(*this, "X.7") - , m_io_oldkb(*this, "X.%u", 0U) - , m_io_newkb(*this, "Y.%u", 0U) - , m_io_config(*this, "CONFIG") - , m_screen(*this, "screen") - , m_bankr(*this, "bankr%d", 0U) - , m_bankw(*this, "bankw%d", 0U) - , m_pak(*this, "optrom%u", 0U) // "rom" causes issues - { - for (u8 n : m_pak_extended) - m_pak_extended[n] = 0; - } - - void mbee56(machine_config &config); - void mbeeppc(machine_config &config); - void mbee128(machine_config &config); - void mbee256(machine_config &config); - void mbee(machine_config &config); - void mbeett(machine_config &config); - void mbeeic(machine_config &config); - void mbeepc85(machine_config &config); - void mbee128p(machine_config &config); - void mbeepp(machine_config &config); - void remove_carts(machine_config &config); - void remove_quick(machine_config &config); - - void init_mbee() { m_features = 0x00; } - void init_mbeett() { m_features = 0x0d; } - void init_mbeeppc() { m_features = 0x09; } - void init_mbeepp() { m_features = 0x39; } - void init_mbeeic() { m_features = 0x01; } - void init_mbee56() { m_features = 0x03; } - void init_mbee128() { m_features = 0x11; } - void init_mbee128p() { m_features = 0x19; } - void init_mbee256() { m_features = 0x2d; } - -private: - void port04_w(u8 data); - void port06_w(u8 data); - u8 port07_r(); - u8 port08_r(); - void port08_w(u8 data); - void port0a_w(u8 data); - void port0b_w(u8 data); - u8 port18_r(); - u8 port1c_r(); - void port1c_w(u8 data); - void port50_w(u8 data); - u8 telcom_r(offs_t); - u8 speed_r(offs_t); - void m6545_index_w(u8 data); - void m6545_data_w(u8 data); - u8 video_low_r(offs_t offset); - u8 video_high_r(offs_t offset); - void video_low_w(offs_t offset, u8 data); - void video_high_w(offs_t offset, u8 data); - void pio_port_b_w(u8 data); - u8 pio_port_b_r(); - DECLARE_WRITE_LINE_MEMBER(pio_ardy); - DECLARE_WRITE_LINE_MEMBER(crtc_vs); - u8 fdc_status_r(); - u8 pak_r(offs_t); - u8 net_r(offs_t); - void fdc_motor_w(u8 data); - void standard_palette(palette_device &palette) const; - void premium_palette(palette_device &palette) const; - uint32_t screen_update_mbee(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - TIMER_DEVICE_CALLBACK_MEMBER(newkb_timer); - image_init_result load_cart(device_image_interface &image, generic_slot_device *slot, u8); - void unload_cart(u8); - DECLARE_QUICKLOAD_LOAD_MEMBER(quickload_cb); - template DECLARE_DEVICE_IMAGE_LOAD_MEMBER(pak_load) { return load_cart(image, m_pak[T], T); } - template DECLARE_DEVICE_IMAGE_UNLOAD_MEMBER(pak_unload) { unload_cart(T); } - WRITE_LINE_MEMBER(rtc_irq_w); - WRITE_LINE_MEMBER(fdc_intrq_w); - WRITE_LINE_MEMBER(fdc_drq_w); - MC6845_UPDATE_ROW(crtc_update_row); - MC6845_ON_UPDATE_ADDR_CHANGED(crtc_update_addr); - void machine_start() override; - void machine_reset() override; - - required_device m_palette; - void mbee128_io(address_map &map); - void mbee128p_io(address_map &map); - void mbee256_io(address_map &map); - void mbee256_mem(address_map &map); - void mbee56_io(address_map &map); - void mbee56_mem(address_map &map); - void mbee_io(address_map &map); - void mbee_mem(address_map &map); - void mbeeic_io(address_map &map); - void mbeeic_mem(address_map &map); - void mbeeppc_io(address_map &map); - void mbeeppc_mem(address_map &map); - void mbeett_io(address_map &map); - void mbeett_mem(address_map &map); - - u8 m_features = 0; - u16 m_size = 0; - u32 m_ramsize = 0; - bool m_b7_rtc = false; - bool m_b7_vs = false; - bool m_b2 = false; - u8 m_framecnt = 0; - u8 m_08 = 0; - u8 m_09 = 0; - u8 m_0a = 0; - u8 m_0b = 0; - u8 m_1c = 0; - u8 m_newkb_was_pressed[15] = { }; - u8 m_newkb_q[20] = { }; - u8 m_newkb_q_pos = 0; - u8 m_sy6545_reg[32] = { }; - u8 m_sy6545_ind = 0; - u8 m_fdc_rq = 0; - u8 m_bank_array[33] = { }; - bool m_pak_extended[10] = { }; - std::unique_ptr m_dummy; // black hole for writes to rom - std::unique_ptr m_ram; // main banked-switch ram, 128/256/pp - std::unique_ptr m_vram; // video ram, all models - std::unique_ptr m_pram; // pcg ram, all models - std::unique_ptr m_cram; // colour ram, all except mbee - std::unique_ptr m_aram; // attribute ram, ppc/128/256/pp/tt - void setup_banks(u8 data, bool first_time, u8 b_mask); - void oldkb_scan(uint16_t param); - void oldkb_matrix_r(uint16_t offs); - required_device m_maincpu; - required_device m_pio; - required_device m_cassette; - required_device m_speaker; - required_device m_centronics; - required_device m_cent_data_out; - required_device m_crtc; - optional_device m_fdc; - optional_device m_floppy0; - optional_device m_floppy1; - optional_device m_rtc; - optional_memory_region m_pakdef; - optional_memory_region m_netdef; - optional_region_ptr m_p_pakdef; - optional_region_ptr m_p_netdef; - optional_memory_bank m_basic; - optional_ioport m_io_x7; - optional_ioport_array<8> m_io_oldkb; - optional_ioport_array<15> m_io_newkb; - required_ioport m_io_config; - required_device m_screen; - optional_memory_bank_array<16> m_bankr; - optional_memory_bank_array<16> m_bankw; - optional_device_array m_pak; -}; - -#endif // MAME_INCLUDES_MBEE_H diff --git a/src/mame/appliedtech/mbee_m.cpp b/src/mame/appliedtech/mbee_m.cpp deleted file mode 100644 index b26b127d645..00000000000 --- a/src/mame/appliedtech/mbee_m.cpp +++ /dev/null @@ -1,792 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Robbbert -/*************************************************************************** - -Microbee machine driver -Originally written by Juergen Buchmueller, Jan 2000 - -Rewritten by Robbbert (see notes in driver file). - -****************************************************************************/ - -#include "emu.h" -#include "mbee.h" - -#include "z80bin.h" - - -/*********************************************************** - - PIO - -************************************************************/ - -WRITE_LINE_MEMBER( mbee_state::pio_ardy ) -{ - m_centronics->write_strobe((state) ? 0 : 1); -} - -void mbee_state::pio_port_b_w(u8 data) -{ -/* PIO port B - d5..d2 not emulated - d7 interrupt from network or rtc or vsync or not used (see config switch) - d6 speaker - d5 rs232 output (1=mark) - d4 rs232 input (0=mark) - d3 rs232 CTS (0=clear to send) - d2 rs232 clock or DTR - d1 cass out and (on new keyboard) keyboard irq - d0 cass in */ - - m_cassette->output(BIT(data, 1) ? -1.0 : +1.0); - m_speaker->level_w(BIT(data, 6)); -} - -u8 mbee_state::pio_port_b_r() -{ - u8 data = 0; - - if (m_cassette->input() > 0.03) - data |= 1; - - data |= 8; // CTS held high via resistor. If low, the disk-based models think a mouse is plugged in. - - switch (m_io_config->read() & 0xc0) - { - case 0x00: - data |= (u8)m_b7_vs << 7; - break; - case 0x40: - data |= (u8)m_b7_rtc << 7; - break; - case 0x80: - data |= 0x80; - break; - } - data |= (u8)m_b2 << 1; // key pressed on new keyboard - - return data; -} - -/************************************************************************************* - - Floppy Disk - - The callback is quite simple, no interrupts are used. - If either IRQ or DRQ activate, they set bit 7 of inport 0x48. - -*************************************************************************************/ - -WRITE_LINE_MEMBER( mbee_state::fdc_intrq_w ) -{ - m_fdc_rq = (m_fdc_rq & 2) | state; -} - -WRITE_LINE_MEMBER( mbee_state::fdc_drq_w ) -{ - m_fdc_rq = (m_fdc_rq & 1) | (state << 1); -} - -u8 mbee_state::fdc_status_r() -{ -/* d7 indicate if IRQ or DRQ is occurring (1=happening) - d6..d0 not used */ - - return m_fdc_rq ? 0xff : 0x7f; -} - -void mbee_state::fdc_motor_w(u8 data) -{ -/* d7..d4 not used - d3 density (1=MFM) - d2 side (1=side 1) - d1..d0 drive select (0 to 3) */ - - floppy_image_device *floppy = nullptr; - floppy = m_floppy0->get_device(); - floppy->mon_w(0); // motor on always - floppy = m_floppy1->get_device(); - floppy->mon_w(0); // motor on always - - if ((data&3)==0) - floppy = m_floppy0->get_device(); - else - if ((data&3)==1) - floppy = m_floppy1->get_device(); - - m_fdc->set_floppy(floppy); - m_fdc->dden_w(!BIT(data, 3)); // /Q output of ic29 - - if (floppy) - { - floppy->ss_w(BIT(data, 2)); // inverted on the board - } -} - -/*********************************************************** - - 256TC Keyboard - -************************************************************/ - - -TIMER_DEVICE_CALLBACK_MEMBER( mbee_state::newkb_timer ) -{ - /* Keyboard scanner is a Mostek M3870 chip. Its speed of operation is determined by a 15k resistor on - pin 2 (XTL2) and is therefore 2MHz. If a key change is detected (up or down), the /strobe - line activates, sending a high to bit 1 of port 2 (one of the pio input lines). The next read of - port 18 will clear this line, and read the key scancode. It will also signal the 3870 that the key - data has been read, on pin 38 (/extint). The 3870 can cache up to 9 keys. With no rom dump - available, the following is a guess. - - The 3870 (MK3870) 8-bit microcontroller is a single chip implementation of Fairchild F8 (Mostek 3850). - It includes up to 4 KB of mask-programmable ROM, 64 bytes of scratchpad RAM and up to 64 bytes - of executable RAM. The MCU also integrates 32-bit I/O and a programmable timer. */ - - if (!BIT(m_features, 2)) - return; - - u8 i, j, pressed; - - // find what has changed - for (i = 0; i < 15; i++) - { - pressed = m_io_newkb[i]->read(); - if (pressed != m_newkb_was_pressed[i]) - { - // get scankey value - for (j = 0; j < 8; j++) - { - if (BIT(pressed^m_newkb_was_pressed[i], j)) - { - // put it in the queue - u8 code = (i << 3) | j | (BIT(pressed, j) ? 0x80 : 0); - m_newkb_q[m_newkb_q_pos] = code; - if (m_newkb_q_pos < (std::size(m_newkb_q)-1)) - m_newkb_q_pos++; - } - } - m_newkb_was_pressed[i] = pressed; - } - } - - // if anything queued, cause an interrupt - if (m_newkb_q_pos) - m_b2 = 1; // set irq - - if (m_b2) - m_pio->port_b_write(pio_port_b_r()); -} - -u8 mbee_state::port18_r() -{ - u8 i, data = m_newkb_q[0]; // get oldest key - - if (m_newkb_q_pos) - { - for (i = 0; i < m_newkb_q_pos; i++) m_newkb_q[i] = m_newkb_q[i+1]; // ripple queue - m_newkb_q[m_newkb_q_pos] = 0; - m_newkb_q_pos--; - } - - m_b2 = 0; // clear irq - m_pio->port_b_write(pio_port_b_r()); - return data; -} - - -/*********************************************************** - - 256TC Change CPU speed - -************************************************************/ - -u8 mbee_state::speed_r(offs_t offset) -{ - m_maincpu->set_unscaled_clock(BIT(offset, 8, 2) ? 6750000 : 3375000); - return 0xff; -} - - -/*********************************************************** - - 256TC Real Time Clock - -************************************************************/ - -void mbee_state::port04_w(u8 data) // address -{ - m_rtc->write(0, data); -} - -void mbee_state::port06_w(u8 data) // write -{ - m_rtc->write(1, data); -} - -u8 mbee_state::port07_r() // read -{ - return m_rtc->read(1); -} - -// See it work: Run mbeett, choose RTC in the config switches, run the F3 test, press Esc. -WRITE_LINE_MEMBER( mbee_state::rtc_irq_w ) -{ - m_b7_rtc = state; // inverted by IC15 (pins 8,9,10) then again by mame - - if ((m_io_config->read() & 0xc0) == 0x40) // RTC selected in config menu - m_pio->port_b_write(pio_port_b_r()); -} - - -/*********************************************************** - - 256TC Memory Banking - - Selection of ROM, RAM, and video access by the CPU is controlled by U39, - a PAL14L8. When read as an ordinary rom it is 16k in size. The dumper has - arranged the pins as (bit0,1,..) (input = 1,23,2,3,4,5,6,7,8,9,10,11,14,13) - and (output = 22,21,20,19,18,17,16,15). The prom is also used to control - the refresh required by the dynamic rams, however we ignore this function. - - b_mask = total dynamic ram (1=64k; 3=128k; 7=256k or more) - - Certain software (such as the PJB system) constantly switch banks around, - causing slowness. Therefore this function only changes the banks that need - changing, leaving the others as is. - -************************************************************/ - -void mbee_state::setup_banks(u8 data, bool first_time, u8 b_mask) -{ - b_mask &= 7; - u32 dbank = m_ramsize / 0x1000; - u8 extra_bits = (data & 0xc0) & (dbank - 1); - data &= 0x3f; // (bits 0-5 are referred to as S0-S5) - address_space &mem = m_maincpu->space(AS_PROGRAM); - u8 *prom = memregion("pals")->base(); - u8 b_data = bitswap<8>(data, 7,5,3,2,4,6,1,0) & 0x3b; // arrange data bits to S0,S1,-,S4,S2,S3 - u8 b_bank, b_byte, b_byte_t, b_addr, p_bank = 1; - uint16_t b_vid; - - if (first_time || (b_data != m_bank_array[0])) // if same data as last time, leave now - { - m_bank_array[0] = b_data; - - for (b_bank = 0; b_bank < 16; b_bank++) - { - b_vid = b_bank << 12; - b_addr = bitswap<8>(b_bank, 7,4,5,3,1,2,6,0) & 0x1f; // arrange address bits to A12,-,A14,A13,A15 - - // Calculate read-bank - b_byte_t = prom[b_addr | (b_data << 8) | 0x82]; // read-bank (RDS and MREQ are low, RFSH is high) - b_byte = bitswap<8>(b_byte_t, 7,5,0,3,6,2,1,4); // rearrange so that bits 0-2 are rambank, bit 3 = rom select, bit 4 = video select, others not used - - if (first_time || (b_byte != m_bank_array[p_bank])) - { - m_bank_array[p_bank] = b_byte; - - if (!BIT(data, 5)) - b_byte &= 0xfb; // U42/1 - S17 only valid if S5 is on - - if (!BIT(b_byte, 4)) - { - // select video - mem.install_read_handler (b_vid, b_vid + 0x7ff, read8sm_delegate(*this, FUNC(mbee_state::video_low_r))); - mem.install_read_handler (b_vid + 0x800, b_vid + 0xfff, read8sm_delegate(*this, FUNC(mbee_state::video_high_r))); - } - else - { - mem.install_read_bank( b_vid, b_vid+0xfff, m_bankr[b_bank] ); - - if (!BIT(b_byte, 3)) - m_bankr[b_bank]->set_entry(dbank + (b_bank & 3)); // read from rom - else - m_bankr[b_bank]->set_entry(extra_bits + (b_bank & 7) + ((b_byte & b_mask) << 3)); // ram - } - } - p_bank++; - - // Calculate write-bank - b_byte_t = prom[b_addr | (b_data << 8) | 0xc0]; // write-bank (XWR and MREQ are low, RFSH is high) - b_byte = bitswap<8>(b_byte_t, 7,5,0,3,6,2,1,4); // rearrange so that bits 0-2 are rambank, bit 3 = rom select, bit 4 = video select, others not used - - if (first_time || (b_byte != m_bank_array[p_bank])) - { - m_bank_array[p_bank] = b_byte; - - if (!BIT(data, 5)) - b_byte &= 0xfb; // U42/1 - S17 only valid if S5 is on - - if (!BIT(b_byte, 4)) - { - // select video - mem.install_write_handler (b_vid, b_vid + 0x7ff, write8sm_delegate(*this, FUNC(mbee_state::video_low_w))); - mem.install_write_handler (b_vid + 0x800, b_vid + 0xfff, write8sm_delegate(*this, FUNC(mbee_state::video_high_w))); - } - else - { - mem.install_write_bank( b_vid, b_vid+0xfff, m_bankw[b_bank] ); - - //if (!BIT(b_byte, 3)) - //m_bankw[b_bank]->set_entry(dbank); // write to rom dummy area - //else - m_bankw[b_bank]->set_entry(extra_bits + (b_bank & 7) + ((b_byte & b_mask) << 3)); // ram - } - } - p_bank++; - } - } -} - -void mbee_state::port50_w(u8 data) -{ - u8 mask = ((m_ramsize / 0x8000) - 1) & 7; - setup_banks(data, 0, mask); -} - -/*********************************************************** - - 128k Memory Banking - - The only difference to the 256TC is that bit 5 switches - between rom2 and rom3. Since neither of these is dumped, - this bit is not emulated. If it was, this scheme is used: - - Low - rom2 occupies C000-FFFF - High - ram = C000-DFFF, rom3 = E000-FFFF. - -************************************************************/ - - -/*********************************************************** - - ROM Banking on older models - - Set A to 0 or 1 then read the port to switch between the - halves of the Telcom ROM. - - Output the PAK number to choose an optional PAK ROM. - - The bios will support 256 PAKs, although normally only - 6 are available in hardware. Each PAK is normally a 8K - ROM. If 16K ROMs are used, the 2nd half becomes PAK+8, - thus 16 PAKs in total. This is used in the PC85 models. - -************************************************************/ - -void mbee_state::port0a_w(u8 data) -{ - m_0a = data & 15; -} - -// Banking of Telcom rom -// Some boards use bits 8 and 9, but there are no roms big enough in existence. -u8 mbee_state::telcom_r(offs_t offset) -{ - m_09 = BIT(offset, 8); - return m_09; -} - -u8 mbee_state::pak_r(offs_t offset) -{ - u8 data = (m_0a & 7)+2; - - if (m_pak[data] && m_pak[data]->exists()) - { - if (BIT(m_0a, 3)) - { - if (m_pak_extended[data]) - return m_pak[data]->read_rom(0x2000 | offset); - else - return 0xff; - } - else - return m_pak[data]->read_rom(offset); - } - else - { - m_pak_extended[data] = false; - if (m_pakdef) - return m_p_pakdef[(m_0a<<13)|offset]; - else - return 0xff; - } -} - -u8 mbee_state::net_r(offs_t offset) -{ - if (m_pak[1] && m_pak[1]->exists()) - { - if (m_09 && m_pak_extended[1]) - return m_pak[1]->read_rom(0x1000 | offset); - else - return m_pak[1]->read_rom(offset); - } - else - { - m_pak_extended[1] = false; - if (m_netdef) - return m_p_netdef[(m_09<<12)|offset]; - else - return 0xff; - } -} - -/*********************************************************** - - Machine - -************************************************************/ - -/* - On reset or power on, a circuit forces rom 8000-8FFF to appear at 0000-0FFF, while ram is disabled. - It gets set back to normal on the first attempt to write to memory. (/WR line goes active). -*/ - -void mbee_state::machine_start() -{ - save_item(NAME(m_ramsize)); - save_item(NAME(m_features)); - save_item(NAME(m_size)); - save_item(NAME(m_b7_rtc)); - save_item(NAME(m_b7_vs)); - save_item(NAME(m_b2)); - save_item(NAME(m_framecnt)); // not important - save_item(NAME(m_08)); - save_item(NAME(m_09)); - save_item(NAME(m_0a)); - save_item(NAME(m_0b)); - save_item(NAME(m_1c)); - save_item(NAME(m_newkb_was_pressed)); - save_item(NAME(m_newkb_q)); - save_item(NAME(m_newkb_q_pos)); - save_item(NAME(m_sy6545_reg)); - save_item(NAME(m_sy6545_ind)); - save_item(NAME(m_fdc_rq)); - save_item(NAME(m_bank_array)); - - m_b2 = 0; - - // banking of the BASIC roms - if (m_basic) - { - u8 *b = memregion("basicrom")->base(); - m_basic->configure_entries(0, 2, b, 0x2000); - } - - // videoram - m_vram = make_unique_clear(0x0800); - save_pointer(NAME(m_vram), 0x0800); - - // colour - if (BIT(m_features, 0)) - { - m_cram = make_unique_clear(0x0800); - save_pointer(NAME(m_cram), 0x0800); - } - - // minimal main ram - if (BIT(m_features, 1)) - m_size = 0xE000; - else - m_size = 0x8000; - - // premium - if (BIT(m_features, 3)) - { - m_aram = make_unique_clear(0x0800); - save_pointer(NAME(m_aram), 0x0800); - m_pram = make_unique_clear(0x8800); - save_pointer(NAME(m_pram), 0x8800); - } - else - { - m_pram = make_unique_clear(0x1000); - save_pointer(NAME(m_pram), 0x1000); - } - - // Banked systems - u8 b = BIT(m_features, 4, 2); - if (b) - { - m_ramsize = 0x20000; // 128k - if (b == 2) - m_ramsize = 0x40000; // 256k - else - if (b == 3) - m_ramsize = 0x100000; // 1MB for PP - - m_ram = make_unique_clear(m_ramsize); - save_pointer(NAME(m_ram), m_ramsize); - m_dummy = std::make_unique(0x1000); // don't save this - - u8 *r = m_ram.get(); - u8 *d = m_dummy.get(); - u8 *m = memregion("maincpu")->base(); - - u32 banks = m_ramsize / 0x1000; - - for (u8 b_bank = 0; b_bank < 16; b_bank++) - { - m_bankr[b_bank]->configure_entries(0, banks, r, 0x1000); // RAM banks - m_bankr[b_bank]->configure_entries(banks, 4, m, 0x1000); // rom - m_bankw[b_bank]->configure_entries(0, banks, r, 0x1000); // RAM banks - m_bankw[b_bank]->configure_entry(banks, d); // dummy rom - } - } - - // set pak index to true for 16k roms - if (m_pakdef) - for (u8 i = 8; i < 14; i++) - if (!(m_pak[i-8] && m_pak[i-8]->exists())) - if (m_p_pakdef[(i<<13)] != 0xff) - m_pak_extended[(i & 7)+2] = true; - - // set net index to true for 8k roms - if (m_netdef && (m_netdef->bytes() > 0x1000)) - if (!(m_pak[1] && m_pak[1]->exists())) - m_pak_extended[1] = true; -} - -void mbee_state::machine_reset() -{ - m_fdc_rq = 0; - m_08 = 0; - m_09 = 0; - m_0a = 0; - m_0b = 0; - m_1c = 0; - - // set default chars - memcpy(m_pram.get(), memregion("chargen")->base(), 0x800); - - if (m_basic) - m_basic->set_entry(0); - - m_maincpu->set_pc(m_size); - - // init new kbd - if (BIT(m_features, 2)) - m_newkb_q_pos = 0; - - // set banks to default - if (BIT(m_features, 4, 2) == 1) - setup_banks(0, 1, 3); - else - if (BIT(m_features, 4, 2) == 2) - setup_banks(0, 1, 7); - else - if (BIT(m_features, 4, 2) == 3) - setup_banks(0, 1, 31); -} - - -/* m_features: -bit 0 : (colour fitted) 1 = yes -bit 1 : (initial pc value / size of main ram) 1=0xE000, 0=0x8000 -bit 2 : (keyboard type) 1 = new keyboard -bit 3 : (core type) 1 = premium -bit 4,5 : (banking main ram) 0x10 = 128k; 0x20 = 256k -*/ - -/*********************************************************** - - Quickload - - This loads the standard BIN format, as well - as BEE, COM and MWB files. - -************************************************************/ - -QUICKLOAD_LOAD_MEMBER(mbee_state::quickload_cb) -{ - address_space &space = m_maincpu->space(AS_PROGRAM); - bool autorun = BIT(m_io_config->read(), 0); - if (image.is_filetype("bin")) - { - uint16_t execute_address, start_addr, end_addr; - - /* load the binary into memory */ - if (z80bin_load_file(image, space, execute_address, start_addr, end_addr) != image_init_result::PASS) - return image_init_result::FAIL; - - /* is this file executable? */ - if (execute_address != 0xffff) - { - space.write_word(0xa6, execute_address); /* fix the EXEC command */ - - if (autorun) - { - space.write_word(0xa2, execute_address); /* fix warm-start vector to get around some copy-protections */ - m_maincpu->set_pc(execute_address); - } - else - { - space.write_word(0xa2, 0x8517); - } - } - - return image_init_result::PASS; - } - - uint16_t i, j; - u8 data; - - size_t quickload_size = image.length(); - if (image.is_filetype("mwb")) - { - /* mwb files - standard basic files */ - for (i = 0; i < quickload_size; i++) - { - j = 0x8c0 + i; - - if (image.fread(&data, 1) != 1) - { - image.message("Unexpected EOF"); - return image_init_result::FAIL; - } - - if ((j < m_size) || (j > 0xefff)) - space.write_byte(j, data); - else - { - image.message("Not enough memory in this microbee"); - return image_init_result::FAIL; - } - } - - if (autorun) - { - space.write_word(0xa2,0x801e); /* fix warm-start vector to get around some copy-protections */ - m_maincpu->set_pc(0x801e); - } - else - space.write_word(0xa2,0x8517); - } - else - if (image.is_filetype("com")) - { - /* com files - most com files are just machine-language games with a wrapper and don't need cp/m to be present */ - for (i = 0; i < quickload_size; i++) - { - j = 0x100 + i; - - if (image.fread(&data, 1) != 1) - { - image.message("Unexpected EOF"); - return image_init_result::FAIL; - } - - if ((j < m_size) || (j > 0xefff)) - space.write_byte(j, data); - else - { - image.message("Not enough memory in this microbee"); - return image_init_result::FAIL; - } - } - - if (autorun) - m_maincpu->set_pc(0x100); - } - else - if (image.is_filetype("bee")) - { - /* bee files - machine-language games that start at 0900 */ - for (i = 0; i < quickload_size; i++) - { - j = 0x900 + i; - - if (image.fread(&data, 1) != 1) - { - image.message("Unexpected EOF"); - return image_init_result::FAIL; - } - - if ((j < m_size) || (j > 0xefff)) - space.write_byte(j, data); - else - { - image.message("Not enough memory in this microbee"); - return image_init_result::FAIL; - } - } - - if (autorun) - m_maincpu->set_pc(0x900); - } - - return image_init_result::PASS; -} - -// Index usage: 0 = not used; 1 = net rom; 2-7 = pak roms -image_init_result mbee_state::load_cart(device_image_interface &image, generic_slot_device *slot, u8 pak_index) -{ - u32 size = slot->common_get_size("rom"); - - if (pak_index > 1) - { - // "mbp" roms - if ((size == 0) || (size > 0x4000)) - { - image.seterror(image_error::INVALIDIMAGE, "Unsupported ROM size"); - return image_init_result::FAIL; - } - - m_pak_extended[pak_index] = (size > 0x2000) ? true : false; - - slot->rom_alloc(m_pak_extended[pak_index] ? 0x4000 : 0x2000, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE); // we alloc the amount for a real rom - slot->common_load_rom(slot->get_rom_base(), size, "rom"); - - // Validate the rom - logerror ("Rom header = %02X %02X %02X\n", slot->read_rom(0), slot->read_rom(1), slot->read_rom(2)); - if ((slot->read_rom(0) != 0xc3) || ((slot->read_rom(2) & 0xe0) != 0xc0)) - { - image.seterror(image_error::INVALIDIMAGE, "Not a PAK rom"); - slot->call_unload(); - return image_init_result::FAIL; - } - } - else - { - // "mbn" roms - if ((size == 0) || (size > 0x2000)) - { - image.seterror(image_error::INVALIDIMAGE, "Unsupported ROM size"); - return image_init_result::FAIL; - } - m_pak_extended[pak_index] = (size > 0x1000) ? true : false; - - slot->rom_alloc(m_pak_extended[pak_index] ? 0x2000 : 0x1000, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE); - slot->common_load_rom(slot->get_rom_base(), size, "rom"); - - // Validate the rom - logerror ("Rom header = %02X %02X %02X\n", slot->read_rom(0), slot->read_rom(1), slot->read_rom(2)); - if (!image.loaded_through_softlist()) // need to let pascal through without testing - { - if ((slot->read_rom(0) != 0xc3) || ((slot->read_rom(2) & 0xf0) != 0xe0)) - { - image.seterror(image_error::INVALIDIMAGE, "Not a NET rom"); - slot->call_unload(); - return image_init_result::FAIL; - } - } - } - - return image_init_result::PASS; -} - -void mbee_state::unload_cart(u8 pak_index) -{ - if (pak_index > 1) - { - if (m_pakdef) - m_pak_extended[pak_index] = (m_p_pakdef[((pak_index+8)<<13)] == 0xff) ? false : true; - else - m_pak_extended[pak_index] = false; - } - else - m_pak_extended[pak_index] = (m_netdef && (m_netdef->bytes() > 0x1000)) ? true : false; -} - diff --git a/src/mame/appliedtech/mbee_v.cpp b/src/mame/appliedtech/mbee_v.cpp deleted file mode 100644 index fafe7a2ca6a..00000000000 --- a/src/mame/appliedtech/mbee_v.cpp +++ /dev/null @@ -1,408 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Robbbert -/*************************************************************************** -Microbee video hardware -Originally written by Juergen Buchmueller, Dec 1999 - -Rewritten by Robbbert (see notes in driver file). - -Operation of old keyboard: - The design is taken from the SY6545 Application Note AN3. As the CRTC - renders the picture, the MA lines also scan the keyboard. When a keydown - is detected, the lightpen pin is activated, which sets bit 6 of the status - register. The CPU continuously monitors this register. Once bit 6 is set, - the CPU needs to determine which key is pressed. It firstly clears bit 6, - then sets port 0B to 1. This prevents the CRTC from scanning the keyboard - and causing interference. Next, the CPU writes an address to regs 18,19 and - then instigates the transparent access. This checks one keyboard row, which - if the pressed key is found, will once again set bit 6. If not found, the - next row will be checked. Once found, the CPU clears bit 6 and port 0B, then - works out the ascii key code of the pressed key. - -Tests of old keyboard. Start mbeeic. -1. Load ASTEROIDS PLUS, stay in attract mode, hold down spacebar, - it should only fire bullets. If it sometimes starts turning, - thrusting or using the shield, then there is a problem. - -2. Load SCAVENGER and make sure it doesn't go to the next level - until you find the Exit. - -3. At the Basic prompt, type in EDASM press enter. At the memory size - prompt press enter. Now, make sure the keyboard works properly. - -See drivers\mbee.cpp for any issues. - -****************************************************************************/ - - -#include "emu.h" -#include "mbee.h" - -WRITE_LINE_MEMBER( mbee_state::crtc_vs ) -{ - m_b7_vs = state; - if ((m_io_config->read() & 0xc0) == 0) // VS selected in config menu - m_pio->port_b_write(pio_port_b_r()); -} - - -/*********************************************************** - - Handlers of video, colour, and attribute RAM - -************************************************************/ - - -u8 mbee_state::video_low_r(offs_t offset) -{ - if ((m_1c & 0x9f) == 0x90) - return m_aram[offset]; - else - if (m_0b) - return m_pram[offset]; - else - return m_vram[offset]; -} - -void mbee_state::video_low_w(offs_t offset, u8 data) -{ - if (BIT(m_1c, 4)) - { - // non-premium attribute writes are discarded - if (BIT(m_1c, 7)) - m_aram[offset] = data; - } - else - m_vram[offset] = data; -} - -u8 mbee_state::video_high_r(offs_t offset) -{ - if (BIT(m_08, 6) && BIT(m_features, 0)) - return m_cram[offset]; - else - return m_pram[(((m_1c & 15) + 1) << 11) | offset]; -} - -void mbee_state::video_high_w(offs_t offset, u8 data) -{ - if (BIT(m_08, 6) && (m_0b==0) && BIT(m_features, 0)) - m_cram[offset] = data; - else - m_pram[(((m_1c & 15) + 1) << 11) | offset] = data; -} - -void mbee_state::port0b_w(u8 data) -{ - m_0b = BIT(data, 0); -} - -u8 mbee_state::port08_r() -{ - return m_08; -} - -void mbee_state::port08_w(u8 data) -{ - m_08 = data & 0x4e; -} - -u8 mbee_state::port1c_r() -{ - return m_1c; -} - -void mbee_state::port1c_w(u8 data) -{ -/* d7 extended graphics (1=allow attributes and pcg banks) - d5 bankswitch basic rom - d4 select attribute ram - d3..d0 select videoram bank */ - - if (BIT(m_features, 3) && BIT(data, 7)) - m_1c = data; - else - m_1c = data & 0x30; - - if (m_basic) - m_basic->set_entry(BIT(data, 5)); -} - - -/*********************************************************** - - CRTC-driven keyboard - -************************************************************/ - - -void mbee_state::oldkb_matrix_r(u16 offs) -{ - if (!BIT(m_features, 2)) - { - u8 port = BIT(offs, 7, 3); - u8 bit = BIT(offs, 4, 3); - u8 extra = 0; - u8 data = m_io_oldkb[port]->read(); - bool keydown = BIT(data, bit); - - // This adds premium-style cursor keys to the old keyboard. - // They are used by the pc85 menu. Premium keyboards already - // have these keys fitted. - if (!keydown && !BIT(m_features, 3)) - { - if ((port == 0) || (port == 2) || (port == 3)) - extra = m_io_x7->read(); - else if (port == 7) - extra = data; - - if (extra) - { - if (BIT(extra, 0)) // cursor up - { - if( port == 7 && bit == 1 ) keydown = 1; - if( port == 0 && bit == 5 ) keydown = 1; // control E - } - else if (BIT(extra, 2)) // cursor down - { - if( port == 7 && bit == 1 ) keydown = 1; - if( port == 3 && bit == 0 ) keydown = 1; // control X - } - else if (BIT(extra, 3)) // cursor left - { - if( port == 7 && bit == 1 ) keydown = 1; - if( port == 2 && bit == 3 ) keydown = 1; // control S - } - else if (BIT(extra, 6)) // cursor right - { - if( port == 7 && bit == 1 ) keydown = 1; - if( port == 0 && bit == 4 ) keydown = 1; // control D - } - } - } - - if( keydown ) - m_crtc->assert_light_pen_input(offs); //lpen_strobe - } -} - - -void mbee_state::oldkb_scan( u16 param ) -{ - if (m_0b) return; // IC5 (pins 11,12,13) - if (param & 15) return; // only scan once per row instead of 16 times - oldkb_matrix_r(param); -} - - -/*********************************************************** - - CRTC registers - -************************************************************/ - -void mbee_state::m6545_index_w(u8 data) -{ - data &= 0x1f; - m_sy6545_ind = data; - m_crtc->address_w(data); -} - -void mbee_state::m6545_data_w(u8 data) -{ - static const u8 sy6545_mask[32]={0xff,0xff,0xff,0x0f,0x7f,0x1f,0x7f,0x7f,3,0x1f,0x7f,0x1f,0x3f,0xff,0x3f,0xff,0,0,0x3f,0xff}; - - switch( m_sy6545_ind ) - { - case 12: - data &= 0x3f; // select alternate character set - if( m_sy6545_reg[12] != data ) - memcpy(m_pram.get(), memregion("chargen")->base() + (((data & 0x30) == 0x20) << 11), 0x800); - break; - } - m_sy6545_reg[m_sy6545_ind] = data & sy6545_mask[m_sy6545_ind]; /* save data in register */ - m_crtc->register_w(data); -} - - - - -/*********************************************************** - - Video - -************************************************************/ - -u32 mbee_state::screen_update_mbee(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - m_framecnt++; - m_crtc->screen_update(screen, bitmap, cliprect); - return 0; -} - - -MC6845_ON_UPDATE_ADDR_CHANGED( mbee_state::crtc_update_addr ) -{ -// parameters passed are address, strobe -// not used on 256TC - - if (strobe) - oldkb_matrix_r(address); -} - - -MC6845_UPDATE_ROW( mbee_state::crtc_update_row ) -{ - if (!de) - return; - - const rgb_t *palette = m_palette->palette()->entry_list_raw(); - - // colours - u8 colourm = BIT(m_08, 1, 3); - u8 monopal = BIT(m_io_config->read(), 4, 2); - // if colour chosen on mono bee, default to amber - if ((monopal==0) && !BIT(m_features, 0)) - monopal = 2; - - u32 *p = &bitmap.pix(y); - u8 inv, attr=0, gfx, fg=96+monopal, bg=96, col=0; - u16 mem, x, chr; - - for (x = 0; x < x_count; x++) // for each character - { - inv = (x == cursor_x) ? 0xff : 0; - mem = (ma + x) & 0x7ff; - chr = m_vram[mem]; - - if (BIT(m_1c, 7)) // premium graphics enabled? - { - attr = m_aram[mem]; - - if (BIT(chr, 7)) - chr += ((attr & 15) << 7); // bump chr to its particular pcg definition - - if (BIT(attr, 6)) - inv ^= 0xff; // inverse attribute - - if (BIT(attr, 7) & BIT(m_framecnt, 4)) // flashing attribute - chr = 0x20; - } - - oldkb_scan(x+ma); - - /* get pattern of pixels for that character scanline */ - gfx = m_pram[(chr<<4) | ra] ^ inv; - - // get colours - if (monopal==0) - { - col = m_cram[mem]; // read a byte of colour - - if (BIT(m_features, 3)) // premium - { - fg = col & 15; - bg = col >> 4; - } - else - { - fg = (col & 0x1f) | 64; - bg = ((col & 0xe0) >> 2) | colourm; - } - } - - /* Display a scanline of a character (8 pixels) */ - *p++ = palette[BIT(gfx, 7) ? fg : bg]; - *p++ = palette[BIT(gfx, 6) ? fg : bg]; - *p++ = palette[BIT(gfx, 5) ? fg : bg]; - *p++ = palette[BIT(gfx, 4) ? fg : bg]; - *p++ = palette[BIT(gfx, 3) ? fg : bg]; - *p++ = palette[BIT(gfx, 2) ? fg : bg]; - *p++ = palette[BIT(gfx, 1) ? fg : bg]; - *p++ = palette[BIT(gfx, 0) ? fg : bg]; - } -} - - -/***************************************************************************************************** - - Palette - - Standard Palette: The 8 bits from the colour RAM are divided into 5 bits for foreground, and 3 - bits for background. The 5 foreground bits pass through a PAL, which has 6 outputs. A write to - port 8 produces 3 more background lines, giving 6 in total. These 12 lines travel to a pair of - 74LS157 switching chips, where the foreground or background lines are selected by the absence or - or presence of a pixel. The 6 chosen lines pass through a 7407 then are merged to the final 3 RGB - lines. Each pair is merged like this: - VCC --- 330 ohm --- primary colour line + out to monitor ---- 120 ohm --- secondary colour line - -*****************************************************************************************************/ - -void mbee_state::standard_palette(palette_device &palette) const -{ - constexpr u8 bglevel[] = { 0, 0x54, 0xa0, 0xff }; - constexpr u8 fglevel[] = { 0, 0xa0, 0xff, 0xff }; - - // set up background colours (00-63) - u8 i = 0; - for (u8 b : bglevel) - { - for (u8 g : bglevel) - { - for (u8 r : bglevel) - { - u8 const k = bitswap<8>(i, 7, 6, 5, 3, 1, 4, 2, 0); - palette.set_pen_color(k, rgb_t(r, g, b)); - i++; - } - } - } - - // set up foreground palette (64-95) by reading the prom - u8 const *const color_prom = memregion("proms")->base(); - for (i = 0; i < 32; i++) - { - u8 const k = color_prom[i]; - u8 const r = fglevel[(BIT(k, 2))|(BIT(k, 5)<<1)]; - u8 const g = fglevel[(BIT(k, 1))|(BIT(k, 4)<<1)]; - u8 const b = fglevel[(BIT(k, 0))|(BIT(k, 3)<<1)]; - palette.set_pen_color(i|64, rgb_t(r, g, b)); - } - - // monochrome palette - palette.set_pen_color(96, rgb_t(0x00, 0x00, 0x00)); // black - palette.set_pen_color(97, rgb_t(0x00, 0xff, 0x00)); // green - palette.set_pen_color(98, rgb_t(0xf7, 0xaa, 0x00)); // amber - palette.set_pen_color(99, rgb_t(0xff, 0xff, 0xff)); // white -} - - -void mbee_state::premium_palette(palette_device &palette) const -{ - // set up 8 low intensity colours - for (u8 i = 0; i < 7; i++) - { - u8 const r = BIT(i, 0) ? 0xc0 : 0; - u8 const g = BIT(i, 1) ? 0xc0 : 0; - u8 const b = BIT(i, 2) ? 0xc0 : 0; - palette.set_pen_color(i, rgb_t(r, g, b)); - } - - // colour 8 is dark grey, rather than black - palette.set_pen_color(8, rgb_t(96, 96, 96)); - - // set up 8 high intensity colours - for (u8 i = 9; i < 16; i++) - { - u8 const r = BIT(i, 0) ? 0xff : 0; - u8 const g = BIT(i, 1) ? 0xff : 0; - u8 const b = BIT(i, 2) ? 0xff : 0; - palette.set_pen_color(i, rgb_t(r, g, b)); - } - - // monochrome palette - palette.set_pen_color(96, rgb_t(0x00, 0x00, 0x00)); // black - palette.set_pen_color(97, rgb_t(0x00, 0xff, 0x00)); // green - palette.set_pen_color(98, rgb_t(0xf7, 0xaa, 0x00)); // amber - palette.set_pen_color(99, rgb_t(0xff, 0xff, 0xff)); // white -} diff --git a/src/mame/ausnz/amust.cpp b/src/mame/ausnz/amust.cpp new file mode 100644 index 00000000000..b2f1e6fd22f --- /dev/null +++ b/src/mame/ausnz/amust.cpp @@ -0,0 +1,550 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert +/***************************************************************************************** + +Amust Compak - also known as Amust Executive 816. + +2014-03-21 Skeleton driver. [Robbbert] + +An unusual-looking CP/M computer. The screen is a tiny CRT not much bigger +than a modern smartphone. + +Z-80A @ 4MHz; 64KB dynamic RAM (8x 4164); 2KB video ram (6116); 2x 13cm drives; +80 track DD with data capacity of 790KB; in a lockable Samsonite briefcase. + +There are no manuals or schematics known to exist. +The entire driver is guesswork. +The board has LH0080 (Z80A), 2x 8251, 2x 8255, 8253, uPD765A and a HD46505SP-2. +There is a piezo beeper. There are 3 crystals, X1 = 4.9152 (serial chips), +X2 = 16 (CPU), X3 = 14.31818 MHz (Video). +There are numerous jumpers, all of which perform unknown functions. + +The keyboard is a plug-in unit, same idea as Kaypro and Zorba. It has these +chips: INS8035N-6, F74145, 74LS373N, SN75451BP, 2716 rom with label KBD-3. +Crystal: 3.579545 MHz + +The main rom is identical between the 2 halves, except that the initial +crtc parameters are slightly different. I've chosen to ignore the first +half. (perhaps 50/60 Hz selectable by jumper?) + +Preliminary I/O ports +--------------------- +00-01 uart 1 +02-03 uart 2 +04-07 ppi 1 +08-0b ppi 2 +0d-0f crtc +10-11 fdc +14-17 pit + +PIT. +Having the PIT on ports 14-17 seems to make sense. It sets counters 1 and 2 +to mode 3, binary, initial count = 0x80. Counter 0 not used? + + +Floppy Parameters: +------------------ +Double Density +Two Side +80 track +1024 byte sectors +5 sectors/track +800k capacity +128 directory entries +2k block size +Skew 1,3,5,2,4 + + +Monitor Commands: +----------------- +B = Boot from floppy +(YES! Most useless monitor ever) + + +ToDo: +- Everything +- Floppy issues: + - The loop to read a sector has no escape. The interrupt handler (which can't be found) + needs to take another path when the sector is complete. + - The loop uses "ini" to read a byte, but this doesn't clear DRQ, so memory rapidly fills + up with garbage, mostly FF. +- Keyboard controller needs to be emulated. +- If booting straight to CP/M, the load message should be in the middle of the screen. +- Looks like port 5 has a row of function keys or similar. Need to be added. + + +*******************************************************************************************/ + +#include "emu.h" + +#include "bus/rs232/rs232.h" +#include "cpu/z80/z80.h" +#include "imagedev/floppy.h" +#include "machine/clock.h" +#include "machine/i8251.h" +#include "machine/i8255.h" +#include "machine/pit8253.h" +#include "machine/timer.h" +#include "machine/upd765.h" +#include "sound/beep.h" +#include "video/mc6845.h" + +#include "emupal.h" +#include "screen.h" +#include "speaker.h" + + +namespace { + +class amust_state : public driver_device +{ +public: + amust_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_palette(*this, "palette") + , m_maincpu(*this, "maincpu") + , m_rom(*this, "maincpu") + , m_ram(*this, "mainram") + , m_bank1(*this, "bank1") + , m_p_chargen(*this, "chargen") + , m_beep(*this, "beeper") + , m_fdc (*this, "fdc") + , m_floppy0(*this, "fdc:0") + , m_floppy1(*this, "fdc:1") + , m_beep_timer(*this, "beep_timer") + { } + + void amust(machine_config &config); + +private: + u8 port04_r(); + void port04_w(u8 data); + u8 port05_r(); + u8 port06_r(); + void port06_w(u8 data); + u8 port08_r(); + void port08_w(u8 data); + u8 port09_r(); + u8 port0a_r(); + void port0a_w(u8 data); + void port0d_w(u8 data); + DECLARE_WRITE_LINE_MEMBER(hsync_w); + DECLARE_WRITE_LINE_MEMBER(vsync_w); + DECLARE_WRITE_LINE_MEMBER(drq_w); + DECLARE_WRITE_LINE_MEMBER(intrq_w); + void kbd_put(u8 data); + MC6845_UPDATE_ROW(crtc_update_row); + TIMER_DEVICE_CALLBACK_MEMBER(beep_timer); + + void io_map(address_map &map); + void mem_map(address_map &map); + void machine_reset() override; + void machine_start() override; + void do_int(); + + u8 m_port04 = 0U; + u8 m_port06 = 0U; + u8 m_port08 = 0U; + u8 m_port09 = 0U; + u8 m_port0a = 0U; + u8 m_term_data = 0U; + bool m_drq = 0; + //bool m_intrq = 0; + bool m_hsync = 0; + bool m_vsync = 0; + std::unique_ptr m_vram; + memory_passthrough_handler m_rom_shadow_tap; + required_device m_palette; + required_device m_maincpu; + required_region_ptr m_rom; + required_shared_ptr m_ram; + required_memory_bank m_bank1; + required_region_ptr m_p_chargen; + required_device m_beep; + required_device m_fdc; + required_device m_floppy0; + required_device m_floppy1; + required_device m_beep_timer; +}; + +TIMER_DEVICE_CALLBACK_MEMBER(amust_state::beep_timer) +{ + m_beep->set_state(0); +} + +//void amust_state::port00_w(u8 data) +//{ +// membank("bankr0")->set_entry(BIT(data, 6)); +// m_fdc->dden_w(BIT(data, 5)); +// floppy_image_device *floppy = nullptr; +// if (BIT(data, 0)) floppy = m_floppy0->get_device(); +// m_fdc->set_floppy(floppy); +// if (floppy) +// floppy->ss_w(BIT(data, 4)); +//} + +void amust_state::mem_map(address_map &map) +{ + map(0x0000, 0xffff).ram().share("mainram"); + map(0xf800, 0xffff).bankr("bank1"); +} + +void amust_state::io_map(address_map &map) +{ + map.unmap_value_high(); + map.global_mask(0xff); + map(0x00, 0x01).rw("uart1", FUNC(i8251_device::read), FUNC(i8251_device::write)); + map(0x02, 0x03).rw("uart2", FUNC(i8251_device::read), FUNC(i8251_device::write)); + map(0x04, 0x07).rw("ppi1", FUNC(i8255_device::read), FUNC(i8255_device::write)); + map(0x08, 0x0b).rw("ppi2", FUNC(i8255_device::read), FUNC(i8255_device::write)); + map(0x0d, 0x0d).nopr().w(FUNC(amust_state::port0d_w)); + map(0x0e, 0x0e).rw("crtc", FUNC(mc6845_device::status_r), FUNC(mc6845_device::address_w)); + map(0x0f, 0x0f).rw("crtc", FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w)); + map(0x10, 0x11).m(m_fdc, FUNC(upd765a_device::map)); + map(0x14, 0x17).rw("pit", FUNC(pit8253_device::read), FUNC(pit8253_device::write)); +} + +static void amust_floppies(device_slot_interface &device) +{ + device.option_add("525qd", FLOPPY_525_QD); +} + +/* Input ports */ +static INPUT_PORTS_START( amust ) + PORT_START("P9") + // bits 6,7 not used? + // bit 5 - fdc intrq + PORT_DIPNAME( 0x01, 0x01, "Bit0" ) // code @ FC99 + PORT_DIPSETTING( 0x01, DEF_STR( On ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPNAME( 0x02, 0x02, "Bit1" ) + PORT_DIPSETTING( 0x02, DEF_STR( On ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPNAME( 0x04, 0x04, "Bit2" ) + PORT_DIPSETTING( 0x04, DEF_STR( On ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPNAME( 0x08, 0x08, "Bit3" ) + PORT_DIPSETTING( 0x08, DEF_STR( On ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPNAME( 0x10, 0x10, "Boot to Monitor" ) // code @ F895 + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x10, DEF_STR( On ) ) +INPUT_PORTS_END + +void amust_state::do_int() +{ + bool sync = m_hsync | m_vsync; + + if ((BIT(m_port0a, 3) && sync) // when writing to the screen, only do it during blanking + || (BIT(m_port0a, 5) && m_drq)) // when reading from floppy, only do it when DRQ is high. + { + //printf("%X,%X,%X ",m_port0a,sync,m_drq); + m_maincpu->set_input_line_and_vector(INPUT_LINE_IRQ0, ASSERT_LINE, 0x00); // Z80 + } + else + m_maincpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE); +} + +WRITE_LINE_MEMBER( amust_state::drq_w ) +{ + m_drq = state; + do_int(); + m_fdc->tc_w(1); +} + +WRITE_LINE_MEMBER( amust_state::intrq_w ) +{ + m_port09 = (m_port09 & 0xdf) | (state ? 0x20 : 0); +} + +WRITE_LINE_MEMBER( amust_state::hsync_w ) +{ + m_hsync = state; + do_int(); +} + +WRITE_LINE_MEMBER( amust_state::vsync_w ) +{ + m_vsync = state; + do_int(); +} + +u8 amust_state::port04_r() +{ + return m_port04; +} + +void amust_state::port04_w(u8 data) +{ + m_port04 = data; +} + +u8 amust_state::port05_r() +{ + return 0; +} + +u8 amust_state::port06_r() +{ + return m_port06; +} + +// BIT 5 low while writing to screen +void amust_state::port06_w(u8 data) +{ + m_port06 = data; +} + +u8 amust_state::port08_r() +{ + return m_port08; +} + +// lower 8 bits of video address +void amust_state::port08_w(u8 data) +{ + m_port08 = data; +} + +/* +d0 - something to do with type of disk +d1 - +d2 - +d3 - +d4 - H = go to monitor; L = boot from disk +d5 - status of fdc intrq; loops till NZ +d6 - +d7 - +*/ +u8 amust_state::port09_r() +{ + logerror("%s\n",machine().describe_context()); + return (ioport("P9")->read() & 0x1f) | m_port09; +} + +u8 amust_state::port0a_r() +{ + return m_port0a; +} + +/* Bits 7,6,5,3 something to do +with selecting which device causes interrupt? +50, 58 = video sync +70 disk +D0 ? +Bit 4 low = beeper. +Lower 3 bits = upper part of video address */ +void amust_state::port0a_w(u8 data) +{ + m_port0a = data; + + if (!BIT(data, 4)) + { + m_beep->set_state(1); + m_beep_timer->adjust(attotime::from_msec(150)); + } + floppy_image_device *floppy = m_floppy0->get_device(); + m_fdc->set_floppy(floppy); + if (floppy) + { + floppy->mon_w(0); + + //floppy->ss_w(0); // side 0? hopefully fdc does this + } +} + +void amust_state::port0d_w(u8 data) +{ + uint16_t video_address = m_port08 | ((m_port0a & 7) << 8); + m_vram[video_address] = data; +} + +/* F4 Character Displayer */ +static const gfx_layout charlayout = +{ + 8, 8, /* 8 x 8 characters */ + 256, /* 256 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 8 bytes */ +}; + +static GFXDECODE_START( gfx_amust ) + GFXDECODE_ENTRY( "chargen", 0x0000, charlayout, 0, 1 ) +GFXDECODE_END + +MC6845_UPDATE_ROW( amust_state::crtc_update_row ) +{ + rgb_t const *const palette = m_palette->palette()->entry_list_raw(); + u32 *p = &bitmap.pix(y); + + for (u16 x = 0; x < x_count; x++) + { + u8 inv = (x == cursor_x) ? 0xff : 0; + u16 mem = (ma + x) & 0x7ff; + u8 chr = m_vram[mem]; + u8 gfx; + if (ra < 8) + gfx = m_p_chargen[(chr<<3) | ra] ^ inv; + else + gfx = inv; + + /* Display a scanline of a character (8 pixels) */ + *p++ = palette[BIT(gfx, 7)]; + *p++ = palette[BIT(gfx, 6)]; + *p++ = palette[BIT(gfx, 5)]; + *p++ = palette[BIT(gfx, 4)]; + *p++ = palette[BIT(gfx, 3)]; + *p++ = palette[BIT(gfx, 2)]; + *p++ = palette[BIT(gfx, 1)]; + *p++ = palette[BIT(gfx, 0)]; + } +} + +void amust_state::machine_reset() +{ + m_bank1->set_entry(1); + m_port04 = 0; + m_port06 = 0; + m_port08 = 0; + m_port09 = 0; + m_port0a = 0; + m_hsync = false; + m_vsync = false; + m_drq = false; + m_fdc->set_ready_line_connected(1); // always ready for minifloppy; controlled by fdc for 20cm + m_fdc->set_unscaled_clock(4000000); // 4MHz for minifloppy; 8MHz for 20cm + + address_space &program = m_maincpu->space(AS_PROGRAM); + program.install_rom(0x0000, 0x07ff, m_rom); // do it here for F3 + m_rom_shadow_tap.remove(); + m_rom_shadow_tap = program.install_read_tap( + 0xf800, 0xffff, + "rom_shadow_r", + [this] (offs_t offset, u8 &data, u8 mem_mask) + { + if (!machine().side_effects_disabled()) + { + // delete this tap + m_rom_shadow_tap.remove(); + + // reinstall RAM over the ROM shadow + m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram); + } + }, + &m_rom_shadow_tap); +} + +void amust_state::machine_start() +{ + m_vram = make_unique_clear(0x800); + save_pointer(NAME(m_vram), 0x800); + save_item(NAME(m_port04)); + save_item(NAME(m_port06)); + save_item(NAME(m_port08)); + save_item(NAME(m_port09)); + save_item(NAME(m_port0a)); + save_item(NAME(m_term_data)); + save_item(NAME(m_drq)); + //save_item(NAME(m_intrq)); + save_item(NAME(m_hsync)); + save_item(NAME(m_vsync)); + m_bank1->configure_entry(0, m_ram+0xf800); + m_bank1->configure_entry(1, m_rom); +} + +void amust_state::amust(machine_config &config) +{ + /* basic machine hardware */ + Z80(config, m_maincpu, XTAL(16'000'000) / 4); + m_maincpu->set_addrmap(AS_PROGRAM, &amust_state::mem_map); + m_maincpu->set_addrmap(AS_IO, &amust_state::io_map); + + /* video hardware */ + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER, rgb_t::green())); + screen.set_refresh_hz(50); + screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */ + screen.set_size(640, 480); + screen.set_visarea(0, 640-1, 0, 480-1); + screen.set_screen_update("crtc", FUNC(mc6845_device::screen_update)); + PALETTE(config, m_palette, palette_device::MONOCHROME); + GFXDECODE(config, "gfxdecode", m_palette, gfx_amust); + + /* sound hardware */ + SPEAKER(config, "mono").front_center(); + BEEP(config, m_beep, 800).add_route(ALL_OUTPUTS, "mono", 0.50); + TIMER(config, m_beep_timer).configure_generic(FUNC(amust_state::beep_timer)); + + /* Devices */ + hd6845s_device &crtc(HD6845S(config, "crtc", XTAL(14'318'181) / 8)); + crtc.set_screen("screen"); + crtc.set_show_border_area(false); + crtc.set_char_width(8); + crtc.set_update_row_callback(FUNC(amust_state::crtc_update_row)); + crtc.out_hsync_callback().set(FUNC(amust_state::hsync_w)); + crtc.out_vsync_callback().set(FUNC(amust_state::vsync_w)); + + UPD765A(config, m_fdc, 8'000'000, true, true); + m_fdc->drq_wr_callback().set(FUNC(amust_state::drq_w)); + m_fdc->intrq_wr_callback().set(FUNC(amust_state::intrq_w)); + FLOPPY_CONNECTOR(config, "fdc:0", amust_floppies, "525qd", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, "fdc:1", amust_floppies, "525qd", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); + + clock_device &uart_clock(CLOCK(config, "uart_clock", 153600)); + uart_clock.signal_handler().set("uart1", FUNC(i8251_device::write_txc)); + uart_clock.signal_handler().append("uart1", FUNC(i8251_device::write_rxc)); + + i8251_device &uart1(I8251(config, "uart1", 0)); + uart1.txd_handler().set("rs232", FUNC(rs232_port_device::write_txd)); + uart1.dtr_handler().set("rs232", FUNC(rs232_port_device::write_dtr)); + uart1.rts_handler().set("rs232", FUNC(rs232_port_device::write_rts)); + + rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, "keyboard")); + rs232.rxd_handler().set("uart1", FUNC(i8251_device::write_rxd)); + rs232.cts_handler().set("uart1", FUNC(i8251_device::write_cts)); + rs232.dsr_handler().set("uart1", FUNC(i8251_device::write_dsr)); + + I8251(config, "uart2", 0); + //uart2.txd_handler().set("rs232", FUNC(rs232_port_device::write_txd)); + //uart2.dtr_handler().set("rs232", FUNC(rs232_port_device::write_dtr)); + //uart2.rts_handler().set("rs232", FUNC(rs232_port_device::write_rts)); + + PIT8253(config, "pit", 0); + + i8255_device &ppi1(I8255A(config, "ppi1")); + ppi1.in_pa_callback().set(FUNC(amust_state::port04_r)); + ppi1.out_pa_callback().set(FUNC(amust_state::port04_w)); + ppi1.in_pb_callback().set(FUNC(amust_state::port05_r)); + ppi1.in_pc_callback().set(FUNC(amust_state::port06_r)); + ppi1.out_pc_callback().set(FUNC(amust_state::port06_w)); + + i8255_device &ppi2(I8255A(config, "ppi2")); + ppi2.in_pa_callback().set(FUNC(amust_state::port08_r)); + ppi2.out_pa_callback().set(FUNC(amust_state::port08_w)); + ppi2.in_pb_callback().set(FUNC(amust_state::port09_r)); + ppi2.in_pc_callback().set(FUNC(amust_state::port0a_r)); + ppi2.out_pc_callback().set(FUNC(amust_state::port0a_w)); +} + +/* ROM definition */ +ROM_START( amust ) + ROM_REGION( 0x1000, "maincpu", 0 ) + ROM_LOAD( "mon_h.ic25", 0x0000, 0x1000, CRC(10dceac6) SHA1(1ef80039063f7a6455563d59f1bcc23e09eca369) ) + + ROM_REGION( 0x800, "chargen", 0 ) + ROM_LOAD( "cg4.ic74", 0x000, 0x800, CRC(52e7b9d8) SHA1(cc6d457634eb688ccef471f72bddf0424e64b045) ) + + ROM_REGION( 0x800, "keyboard", 0 ) + ROM_LOAD( "kbd_3.rom", 0x000, 0x800, CRC(d9441b35) SHA1(ce250ab1e892a13fd75182703f259855388c6bf4) ) +ROM_END + +} // anonymous namespace + +/* Driver */ + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1983, amust, 0, 0, amust, amust, amust_state, empty_init, "Amust", "Amust Executive 816", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/ausnz/applix.cpp b/src/mame/ausnz/applix.cpp new file mode 100644 index 00000000000..b1fed2a8d84 --- /dev/null +++ b/src/mame/ausnz/applix.cpp @@ -0,0 +1,1181 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert +/*************************************************************************** + + Applix 1616 computer + + See for docs: http://psiphi.server101.com/applix/ + + First revealed to the world in December 1986 issue of Electronics Today + International (ETI) an Australian electronics magazine which is now defunct. + + The main articles appeared in ETI February/March/April 1987, followed by + other articles in various issues after that. + + Current Status: + After 60 seconds, boots to the ramdisk. You can enter commands. + If you have a floppy mounted, it will boot from the disk. + + The system could support 1 or 2 5.25 or 3.5 floppy drives, although 3.5 + was the recommended hardware. Format is similar to the PC 720kb, except + it has 5 sectors of 1024 bytes, giving 800kb total. We only support the + 3.5-sized disks. + + TODO: + - Cassette interface (coded but not working) + - Use kbtro device (tried and failed) + - Optional SCSI controller NCR5380 and hard drive (max 40mb) + - Joystick + - Audio: it could be better + - DAC output is used to compare against analog inputs; core doesn't permit + audio outputs to be used for non-speaker purposes. + - Bios 5 crashes MAME after scrolling about half a screen + +****************************************************************************/ + +#include "emu.h" + +#include "bus/centronics/ctronics.h" +#include "bus/rs232/rs232.h" +#include "cpu/m68000/m68000.h" +#include "cpu/mcs51/mcs51.h" +#include "cpu/z80/z80.h" +#include "imagedev/cassette.h" +#include "imagedev/floppy.h" +#include "machine/6522via.h" +#include "machine/timer.h" +#include "machine/wd_fdc.h" +#include "machine/z80scc.h" +#include "sound/dac.h" +#include "video/mc6845.h" + +#include "emupal.h" +#include "screen.h" +#include "softlist_dev.h" +#include "speaker.h" + +#include "formats/applix_dsk.h" + + + +class applix_state : public driver_device +{ +public: + applix_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_base(*this, "base") + , m_maincpu(*this, "maincpu") + , m_crtc(*this, "crtc") + , m_via(*this, "via6522") + , m_centronics(*this, "centronics") + , m_cent_data_out(*this, "cent_data_out") + , m_fdc(*this, "fdc") + , m_floppy0(*this, "fdc:0") + , m_floppy1(*this, "fdc:1") + , m_ldac(*this, "ldac") + , m_rdac(*this, "rdac") + , m_cass(*this, "cassette") + , m_io_dsw(*this, "DSW") + , m_io_fdc(*this, "FDC") + , m_io_k0f(*this, "K0f") + , m_io_k300(*this, "K30_0") + , m_io_k301(*this, "K30_1") + , m_io_k310(*this, "K31_0") + , m_io_k311(*this, "K31_1") + , m_io_k320(*this, "K32_0") + , m_io_k321(*this, "K32_1") + , m_io_k330(*this, "K33_0") + , m_io_k331(*this, "K33_1") + , m_io_k340(*this, "K34_0") + , m_io_k341(*this, "K34_1") + , m_io_k350(*this, "K35_0") + , m_io_k351(*this, "K35_1") + , m_io_k360(*this, "K36_0") + , m_io_k361(*this, "K36_1") + , m_io_k370(*this, "K37_0") + , m_io_k371(*this, "K37_1") + , m_io_k380(*this, "K38_0") + , m_io_k390(*this, "K39_0") + , m_io_k3a0(*this, "K3a_0") + , m_io_k3b0(*this, "K3b_0") + , m_io_k0b(*this, "K0b") + , m_expansion(*this, "expansion") + , m_palette(*this, "palette") + { } + + void applix(machine_config &config); + + void init_applix(); + +private: + virtual void machine_reset() override; + virtual void machine_start() override; + u16 applix_inputs_r(); + void palette_w(offs_t offset, u16 data, u16 mem_mask = ~0); + void analog_latch_w(u16 data); + void dac_latch_w(u16 data); + void video_latch_w(offs_t offset, u16 data, u16 mem_mask = ~0); + u8 applix_pb_r(); + void applix_pa_w(u8 data); + void applix_pb_w(u8 data); + DECLARE_WRITE_LINE_MEMBER(vsync_w); + u8 port00_r(); + u8 port08_r(); + u8 port10_r(); + u8 port18_r(); + u8 port20_r(); + u8 port60_r(); + void port08_w(u8 data); + void port10_w(u8 data); + void port18_w(offs_t offset, u8 data); + void port20_w(u8 data); + void port60_w(u8 data); + u16 fdc_data_r(); + u16 fdc_stat_r(offs_t offset); + void fdc_data_w(u16 data); + void fdc_cmd_w(u16 data); + static void floppy_formats(format_registration &fr); + u8 internal_data_read(offs_t offset); + void internal_data_write(offs_t offset, u8 data); + u8 p1_read(); + void p1_write(u8 data); + u8 p2_read(); + void p2_write(u8 data); + u8 p3_read(); + void p3_write(u8 data); + TIMER_DEVICE_CALLBACK_MEMBER(cass_timer); + + MC6845_UPDATE_ROW(crtc_update_row); + MC6845_BEGIN_UPDATE(crtc_update_border); + void applix_palette(palette_device &palette) const; + + u8 m_video_latch = 0U; + u8 m_pa = 0U; + u8 m_palette_latch[4]{}; + required_shared_ptr m_base; + + void main_mem(address_map &map); + void keytronic_pc3270_io(address_map &map); + void keytronic_pc3270_program(address_map &map); + void sub_io(address_map &map); + void sub_mem(address_map &map); + + u8 m_pb = 0U; + u8 m_analog_latch = 0U; + u8 m_dac_latch = 0U; + u8 m_port08 = 0U; + u8 m_data_to_fdc = 0U; + u8 m_data_from_fdc = 0U; + bool m_data = 0; + bool m_data_or_cmd = 0; + bool m_buffer_empty = 0; + bool m_fdc_cmd = 0; + u8 m_clock_count = 0U; + bool m_cp = 0; + u8 m_p1 = 0U; + u8 m_p1_data = 0U; + u8 m_p2 = 0U; + u8 m_p3 = 0U; + u16 m_last_write_addr = 0U; + u8 m_cass_data[4]{}; + required_device m_maincpu; + required_device m_crtc; + required_device m_via; + required_device m_centronics; + required_device m_cent_data_out; + required_device m_fdc; + required_device m_floppy0; + required_device m_floppy1; + required_device m_ldac; + required_device m_rdac; + required_device m_cass; + required_ioport m_io_dsw; + required_ioport m_io_fdc; + required_ioport m_io_k0f; + required_ioport m_io_k300; + required_ioport m_io_k301; + required_ioport m_io_k310; + required_ioport m_io_k311; + required_ioport m_io_k320; + required_ioport m_io_k321; + required_ioport m_io_k330; + required_ioport m_io_k331; + required_ioport m_io_k340; + required_ioport m_io_k341; + required_ioport m_io_k350; + required_ioport m_io_k351; + required_ioport m_io_k360; + required_ioport m_io_k361; + required_ioport m_io_k370; + required_ioport m_io_k371; + required_ioport m_io_k380; + required_ioport m_io_k390; + required_ioport m_io_k3a0; + required_ioport m_io_k3b0; + required_ioport m_io_k0b; + required_shared_ptr m_expansion; + + required_device m_palette; +}; + +/* +d0,1,2 = joystick +d3 = cassette LED, low=on +d4,5,6 = audio select +d7 = cassette relay, low=on +*/ +void applix_state::analog_latch_w(u16 data) +{ + data &= 0xff; + if (data != m_analog_latch) + { + m_cass->change_state( + (BIT(data,7)) ? CASSETTE_MOTOR_DISABLED : CASSETTE_MOTOR_ENABLED, CASSETTE_MASK_MOTOR); + + m_analog_latch = data; + } +} + +void applix_state::dac_latch_w(u16 data) +{ + data &= 0xff; + m_dac_latch = data; + + if ((m_analog_latch & 0x70) == 0) // right + m_rdac->write(m_dac_latch); + else + if ((m_analog_latch & 0x70) == 0x10) // left + m_ldac->write(m_dac_latch); +} + +//cent = odd, video = even +void applix_state::palette_w(offs_t offset, u16 data, u16 mem_mask) +{ + offset >>= 4; + if (ACCESSING_BITS_0_7) + { + m_cent_data_out->write(data); + } + else + m_palette_latch[offset] = (data >> 8) & 15; +} + +void applix_state::video_latch_w(offs_t offset, u16 data, u16 mem_mask) +{ + if (ACCESSING_BITS_0_7) + m_video_latch = data; +} + +/* +d0 = dac output + external signal = analog input +d1 = cassette in +d2,3 = joystick in +d4-7 = SW2 dipswitch block +*/ +u16 applix_state::applix_inputs_r() +{ + return m_io_dsw->read() | m_cass_data[2]; +} + +u8 applix_state::applix_pb_r() +{ + return m_pb; +} + +/* +d0 = /(in) printer busy signal +d1 = /(out) printer strobe +d2 = /(out) enable cassette write IRQ +d3 = (out) H = 640 video mode +d4 = /(out) enable cassette read IRQ +d5 = /(out) clear cass IRQ and output line +d6 = /(out) reset keyboard by pulling kbd clock low +d7 = /(out) reset keyboard flipflop +*/ +void applix_state::applix_pa_w(u8 data) +{ + // Reset flipflop counter + if (!BIT(data, 7)) + m_clock_count = 0; + + // Reset keyboard + if (!BIT(data, 6)) + { + m_p3 = 0xff; + m_last_write_addr = 0; + } + m_cass->output(BIT(data, 5) ? -1.0 : +1.0); + + // high-to-low of PA5 when reading cassette - /PRE on IC32b + if (BIT(m_pa, 5) && !BIT(data, 5) && !BIT(data, 4)) + m_maincpu->set_input_line(M68K_IRQ_4, CLEAR_LINE); + + // low-to-high of PA2 when writing cassette - /PRE on IC49 + if (!BIT(m_pa, 2) && BIT(data, 2)) + m_maincpu->set_input_line(M68K_IRQ_4, CLEAR_LINE); + + m_centronics->write_strobe(BIT(data, 1)); + + m_pa = data; +} + +/* +d0-6 = user +d7 = square wave output for cassette IRQ +*/ +void applix_state::applix_pb_w(u8 data) +{ + // low-to-high of PB7 when writing cassette - CLK on IC49 + if (!BIT(m_pb, 7) && BIT(data, 7)) + if (!BIT(m_pa, 2)) + m_maincpu->set_input_line(M68K_IRQ_4, ASSERT_LINE); + + m_pb = data; +} + +/* +d0 = H if 68000 sent a command +d1 = H if 68000 sent a byte +d2 = H if 68000 has read last byte +d3 = test switch +*/ +u8 applix_state::port00_r() +{ + return (u8)m_data_or_cmd | ((u8)m_data << 1) | ((u8)m_buffer_empty << 2) | m_io_fdc->read(); +} + +/* +d0 = /RDY +d1 = /DISC CHANGE +d2 = DS0 +d3 = DS1 +d4 = MOTORON +d5 = SIDE +d6 = BANK +d7 = MAP +*/ +u8 applix_state::port08_r() +{ + return m_port08 | 3; +} + +/* +d0 = /INUSE +d1 = /EJECT +d2-7 same as for port08_r +*/ +void applix_state::port08_w(u8 data) +{ + m_port08 = data; + membank("bank1")->set_entry(BIT(data, 6)); + + floppy_image_device *floppy = nullptr; + if (BIT(data, 2)) floppy = m_floppy0->get_device(); + if (BIT(data, 3)) floppy = m_floppy1->get_device(); + + m_fdc->set_floppy(floppy); + + if (floppy) + { + floppy->mon_w(0); + floppy->ss_w(BIT(data, 5)); + } +} + +u8 applix_state::port10_r() +{ + return 0; +} + +void applix_state::port10_w(u8 data) +{ +} + +u8 applix_state::port18_r() +{ + m_data = 0; + return m_data_to_fdc; +} + +void applix_state::port18_w(offs_t offset, u8 data) +{ + m_data_from_fdc = data; + m_buffer_empty = 0; + m_fdc_cmd = BIT(offset, 2); +} + +u8 applix_state::port20_r() +{ + return 0; +} + +void applix_state::port20_w(u8 data) +{ +} + +u8 applix_state::port60_r() +{ + return 0; +} + +void applix_state::port60_w(u8 data) +{ +} + +u16 applix_state::fdc_stat_r(offs_t offset) +{ + u8 data = 0; + switch (offset) + { + case 0: data = (u8)m_buffer_empty^1; break; + case 1: data = (u8)m_data^1; break; + default: data = (u8)m_fdc_cmd; // case 2 + } + return data << 7; +} + +u16 applix_state::fdc_data_r() +{ + m_buffer_empty = 1; + return m_data_from_fdc; +} + +void applix_state::fdc_data_w(u16 data) +{ + m_data_to_fdc = data; + m_data = 1; + m_data_or_cmd = 0; +} + +void applix_state::fdc_cmd_w(u16 data) +{ + m_data_to_fdc = data; + m_data = 1; + m_data_or_cmd = 1; +} + +void applix_state::main_mem(address_map &map) +{ + map.unmap_value_high(); + map.global_mask(0xffffff); + map(0x000000, 0x3fffff).ram().share("expansion"); // Expansion + map(0x400000, 0x47ffff).ram().mirror(0x80000).share("base"); // Main ram + map(0x500000, 0x51ffff).rom().region("maincpu", 0); + map(0x600000, 0x60007f).w(FUNC(applix_state::palette_w)); + map(0x600080, 0x6000ff).w(FUNC(applix_state::dac_latch_w)); + map(0x600100, 0x60017f).w(FUNC(applix_state::video_latch_w)); //video latch (=border colour, high nybble; video base, low nybble) (odd) + map(0x600180, 0x6001ff).w(FUNC(applix_state::analog_latch_w)); + map(0x700000, 0x700007).mirror(0x78).rw("scc", FUNC(scc8530_device::ab_dc_r), FUNC(scc8530_device::ab_dc_w)).umask16(0xff00).cswidth(16); + map(0x700080, 0x7000ff).r(FUNC(applix_state::applix_inputs_r)); + map(0x700100, 0x70011f).mirror(0x60).m(m_via, FUNC(via6522_device::map)).umask16(0xff00).cswidth(16); + map(0x700180, 0x700180).mirror(0x7c).rw(m_crtc, FUNC(mc6845_device::status_r), FUNC(mc6845_device::address_w)).cswidth(16); + map(0x700182, 0x700182).mirror(0x7c).rw(m_crtc, FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w)).cswidth(16); + map(0xffffc0, 0xffffc1).rw(FUNC(applix_state::fdc_data_r), FUNC(applix_state::fdc_data_w)); + //map(0xffffc2, 0xffffc3).rw(FUNC(applix_state::fdc_int_r) , FUNC(applix_state::fdc_int_w)); // optional + map(0xffffc8, 0xffffcd).r(FUNC(applix_state::fdc_stat_r)); + map(0xffffd0, 0xffffd1).w(FUNC(applix_state::fdc_cmd_w)); + //600000, 6FFFFF io ports and latches + //700000, 7FFFFF peripheral chips and devices + //800000, FFC000 optional roms + //FFFFC0, FFFFFF disk controller board +} + +void applix_state::sub_mem(address_map &map) +{ + map(0x0000, 0x5fff).rom(); + map(0x6000, 0x7fff).ram(); + map(0x8000, 0xffff).bankrw("bank1"); +} + +void applix_state::sub_io(address_map &map) +{ + map.global_mask(0xff); + map(0x00, 0x07).r(FUNC(applix_state::port00_r)); //PORTR + map(0x08, 0x0f).rw(FUNC(applix_state::port08_r), FUNC(applix_state::port08_w)); //Disk select + map(0x10, 0x17).rw(FUNC(applix_state::port10_r), FUNC(applix_state::port10_w)); //IRQ + map(0x18, 0x1f).rw(FUNC(applix_state::port18_r), FUNC(applix_state::port18_w)); //data&command + map(0x20, 0x27).mirror(0x18).rw(FUNC(applix_state::port20_r), FUNC(applix_state::port20_w)); //SCSI NCR5380 + map(0x40, 0x43).mirror(0x1c).rw(m_fdc, FUNC(wd1772_device::read), FUNC(wd1772_device::write)); //FDC + map(0x60, 0x63).mirror(0x1c).rw(FUNC(applix_state::port60_r), FUNC(applix_state::port60_w)); //anotherZ80SCC +} + +void applix_state::keytronic_pc3270_program(address_map &map) +{ + map(0x0000, 0x0fff).rom().region("kbdcpu", 0); +} + +void applix_state::keytronic_pc3270_io(address_map &map) +{ + map(0x0000, 0xffff).rw(FUNC(applix_state::internal_data_read), FUNC(applix_state::internal_data_write)); +} + +// io priorities: +// 4 cassette +// 3 scc +// 2 via + +/* Input ports */ +static INPUT_PORTS_START( applix ) + PORT_START( "K0f" ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') /* 06 */ + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') /* 05 */ + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') /* 14 */ + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') /* 13 */ + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') /* 22 */ + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') /* 21 */ + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F7 (IRMA)") /* 41 */ + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?6a?") /* 6a */ + + PORT_START( "K30_0" ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') /* 31 */ + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') /* 32 */ + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') /* 30 */ + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') /* 2f */ + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') /* 2e */ + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') /* 33 */ + PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START( "K30_1" ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) /* 58 */ + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) /* 59 */ + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) /* 5a */ + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) /* 5b */ + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) /* 5c */ + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) /* 5d */ + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?6b?") /* 6b */ + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F8 (IRMA)") /* 42 */ + + PORT_START( "K31_0" ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') /* 07 */ + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') /* 08 */ + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') /* 15 */ + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') /* 16 */ + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') /* 23 */ + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') /* 24 */ + PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START( "K31_1" ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) /* 37 */ + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) /* 5f */ + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LSHIFT) PORT_NAME("LShift") PORT_CHAR(UCHAR_SHIFT_1) /* 2a */ + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("<") /* 70 */ + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') /* 2c */ + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') /* 2d */ + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?6c?") /* 6c */ + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F9 (IRMA)") /* 43 */ + + PORT_START( "K32_0" ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') /* 0a */ + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') /* 09 */ + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') /* 18 */ + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') /* 17 */ + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') /* 26 */ + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') /* 25 */ + PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START( "K32_1" ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) /* 57 */ + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F10) PORT_CHAR(UCHAR_MAMEKEY(F10)) /* 1d */ + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) /* 71 */ + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LALT) PORT_NAME("LAlt") /* 38 */ + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') /* 39 */ + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RALT) PORT_NAME("RAlt") /* 38 */ + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?69?") /* 69 */ + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F6 (IRMA)") /* 40 */ + + PORT_START( "K33_0" ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2_PAD) PORT_CODE(KEYCODE_DOWN) PORT_NAME("KP 2") /* 50 */ + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1_PAD) PORT_CODE(KEYCODE_END) PORT_NAME("KP 1") /* 4f */ + PORT_BIT( 0x0c, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Down") /* 55 */ + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Enter") /* 75 */ + PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START( "K33_1" ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') /* 02 */ + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~') /* 29 */ + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') /* 10 */ + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) /* 0f */ + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') /* 1e */ + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CAPSLOCK) PORT_NAME("Caps") /* 3a */ + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?68?") /* 68 */ + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F5 (IRMA)") /* 3f */ + + PORT_START( "K34_0" ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') /* 35 */ + PORT_BIT( 0x0c, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_MAMEKEY(RSHIFT)) /* 36 */ + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Left") /* 56 */ + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') /* 34 */ + PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START( "K34_1" ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') /* 02 */ + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') /* 03 */ + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') /* 11 */ + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') /* 12 */ + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') /* 1f */ + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') /* 20 */ + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?67?") /* 67 */ + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F4 (IRMA)") /* 3e */ + + PORT_START( "K35_0" ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') /* 0b */ + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') /* 0c */ + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') /* 19 */ + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') /* 1a */ + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') /* 27 */ + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"') /* 28 */ + PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START( "K35_1" ) + PORT_BIT( 0x3f, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?66?") /* 66 */ + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F3 (IRMA)") /* 3d */ + + PORT_START( "K36_0" ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) /* 0e */ + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') /* 0d */ + PORT_BIT( 0x14, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) /* 1c */ + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') /* 2b */ + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') /* 1b */ + PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START( "K36_1" ) + PORT_BIT( 0x7f, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F2 (IRMA)") /* 3c */ + + PORT_START( "K37_0" ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("PA1") /* 7b */ + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("|<--") /* 7e */ + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("/a\\") /* 7a */ + PORT_BIT( 0x30, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_PLUS_PAD) PORT_NAME("KP +") /* 4e */ + PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START( "K37_1" ) + PORT_BIT( 0x3f, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?64?") /* 64 */ + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F1 (IRMA)") /* 3b */ + + PORT_START( "K38_0" ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SysReq") /* 54 */ + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) /*PORT_CODE(KEYCODE_SCRLOCK)*/ PORT_NAME("ScrLock") /* 46 */ + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("-->|") /* 7c */ + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9_PAD) PORT_CODE(KEYCODE_PGUP) PORT_NAME("KP 9") /* 49 */ + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS_PAD) PORT_NAME("KP -") /* 4a */ + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6_PAD) PORT_CODE(KEYCODE_RIGHT) PORT_NAME("KP 6") /* 4d */ + PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START( "K39_0" ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ESC) PORT_NAME("Esc") /* 01 */ + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_NUMLOCK) PORT_NAME("NumLock") /* 45 */ + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7_PAD) PORT_CODE(KEYCODE_HOME) PORT_NAME("KP 7") /* 47 */ + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8_PAD) PORT_CODE(KEYCODE_UP) PORT_NAME("KP 8") /* 48 */ + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4_PAD) PORT_CODE(KEYCODE_LEFT) PORT_NAME("KP 4") /* 4b */ + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("KP 5") /* 4c */ + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?76?") /* 76 */ + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?63?") /* 63 */ + + PORT_START( "K3a_0" ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("PrtSc *") /* 6f */ + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("PA2") /* 7f */ + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Right") /* 7d */ + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("/a") /* 79 */ + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Center") /* 77 */ + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?6e?") /* 6e */ + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?62?") /* 62 */ + + PORT_START( "K3b_0" ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3_PAD) PORT_CODE(KEYCODE_PGDN) PORT_NAME("KP 3") /* 51 */ + PORT_BIT( 0x06, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0_PAD) PORT_CODE(KEYCODE_INSERT) PORT_NAME("KP 0") /* 52 */ + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DEL_PAD) PORT_CODE(KEYCODE_DEL) PORT_NAME("KP .") /* 53 */ + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Up") /* 78 */ + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?6d?") /* 6d */ + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F10 (IRMA)") /* 44 */ + + PORT_START( "K0b" ) + PORT_DIPNAME( 0x01, 0x01, "Protocol selection" ) + PORT_DIPSETTING( 0x00, "Enhanced XT, AT and PS/2 models" ) + PORT_DIPSETTING( 0x01, "Standard PC and XT" ) + PORT_DIPNAME( 0x02, 0x00, "IRMA/Native scan code set" ) + PORT_DIPSETTING( 0x00, "Native scan code set" ) + PORT_DIPSETTING( 0x02, "IRMA Emulation" ) + PORT_DIPNAME( 0x04, 0x04, "Enhanced 101/Native scan code set" ) + PORT_DIPSETTING( 0x00, "Native scan code set" ) + PORT_DIPSETTING( 0x04, "Enhanced 101 scan code set" ) + PORT_DIPNAME( 0x08, 0x08, "Enable E0" ) + PORT_DIPSETTING( 0x00, "Enable E0" ) + PORT_DIPSETTING( 0x08, "Disable E0" ) + PORT_DIPNAME( 0x10, 0x10, "Code tables" ) + PORT_DIPSETTING( 0x00, "U.S. code tables" ) + PORT_DIPSETTING( 0x10, "International code tables" ) + PORT_BIT( 0x60, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_DIPNAME( 0x80, 0x80, "Key click" ) + PORT_DIPSETTING( 0x00, "No key click" ) + PORT_DIPSETTING( 0x80, "Key click" ) + + PORT_START("DSW") + PORT_BIT( 0xf, 0, IPT_UNUSED ) + PORT_DIPNAME( 0x10, 0x00, "Switch 0") PORT_DIPLOCATION("SW2:1") + PORT_DIPSETTING( 0x10, DEF_STR(Off)) + PORT_DIPSETTING( 0x00, DEF_STR(On)) + PORT_DIPNAME( 0x20, 0x00, "Switch 1") PORT_DIPLOCATION("SW2:2") + PORT_DIPSETTING( 0x20, DEF_STR(Off)) + PORT_DIPSETTING( 0x00, DEF_STR(On)) + PORT_DIPNAME( 0x40, 0x00, "Switch 2") PORT_DIPLOCATION("SW2:3") + PORT_DIPSETTING( 0x40, DEF_STR(Off)) + PORT_DIPSETTING( 0x00, DEF_STR(On)) + PORT_DIPNAME( 0x80, 0x80, "Switch 3") PORT_DIPLOCATION("SW2:4") + PORT_DIPSETTING( 0x80, DEF_STR(Off)) + PORT_DIPSETTING( 0x00, DEF_STR(On)) + + PORT_START("FDC") + PORT_BIT( 0xf7, 0, IPT_UNUSED ) + PORT_DIPNAME( 0x08, 0x08, "FDC Test") PORT_DIPLOCATION("SW3:1") + PORT_DIPSETTING( 0x08, DEF_STR(Off)) + PORT_DIPSETTING( 0x00, DEF_STR(On)) +INPUT_PORTS_END + + +void applix_state::machine_reset() +{ + u8* ROM = memregion("maincpu")->base(); + memcpy(m_expansion, ROM, 8); + membank("bank1")->set_entry(0); + m_p3 = 0xff; + m_last_write_addr = 0; + m_maincpu->reset(); +} + +void applix_state::floppy_formats(format_registration &fr) +{ + fr.add_mfm_containers(); + fr.add(FLOPPY_APPLIX_FORMAT); +} + +static void applix_floppies(device_slot_interface &device) +{ + device.option_add("35dd", FLOPPY_35_DD); +} + + +void applix_state::applix_palette(palette_device &palette) const +{ + // shades need to be verified - the names on the right are from the manual + constexpr rgb_t colors[16] = { + { 0x00, 0x00, 0x00 }, // 0 Black + { 0x40, 0x40, 0x40 }, // 1 Dark Grey + { 0x00, 0x00, 0x80 }, // 2 Dark Blue + { 0x00, 0x00, 0xff }, // 3 Mid Blue + { 0x00, 0x80, 0x00 }, // 4 Dark Green + { 0x00, 0xff, 0x00 }, // 5 Green + { 0x00, 0xff, 0xff }, // 6 Blue Grey + { 0x00, 0x7f, 0x7f }, // 7 Light Blue + { 0x7f, 0x00, 0x00 }, // 8 Dark Red + { 0xff, 0x00, 0x00 }, // 9 Red + { 0x7f, 0x00, 0x7f }, // 10 Dark Violet + { 0xff, 0x00, 0xff }, // 11 Violet + { 0x7f, 0x7f, 0x00 }, // 12 Brown + { 0xff, 0xff, 0x00 }, // 13 Yellow + { 0xbf, 0xbf, 0xbf }, // 14 Light Grey + { 0xff, 0xff, 0xff } }; // 15 White + + palette.set_pen_colors(0, colors); +} + + +void applix_state::machine_start() +{ + std::fill(std::begin(m_palette_latch), std::end(m_palette_latch), 0); + + save_item(NAME(m_video_latch)); + save_item(NAME(m_pa)); + save_item(NAME(m_palette_latch)); + save_item(NAME(m_pb)); + save_item(NAME(m_analog_latch)); + save_item(NAME(m_dac_latch)); + save_item(NAME(m_port08)); + save_item(NAME(m_data_to_fdc)); + save_item(NAME(m_data_from_fdc)); + save_item(NAME(m_data)); + save_item(NAME(m_data_or_cmd)); + save_item(NAME(m_buffer_empty)); + save_item(NAME(m_fdc_cmd)); + save_item(NAME(m_clock_count)); + save_item(NAME(m_cp)); + save_item(NAME(m_p1)); + save_item(NAME(m_p1_data)); + save_item(NAME(m_p2)); + save_item(NAME(m_p3)); + save_item(NAME(m_last_write_addr)); + save_item(NAME(m_cass_data)); +} + +MC6845_UPDATE_ROW( applix_state::crtc_update_row ) +{ + if (!de) + return; + // The display is bitmapped. 2 modes are supported here, 320x200x16 and 640x200x4. + // There is a monochrome mode, but no info found as yet. + // The 6845 cursor signal is not used at all. + rgb_t const *const palette = m_palette->palette()->entry_list_raw(); + u32 const vidbase = (m_video_latch & 15) << 14 | (ra & 7) << 12; + u32 *p = &bitmap.pix(y + vbp, hbp); + + for (u16 x = 0; x < x_count; x++) + { + u32 const mem = vidbase | ((ma + x) & 0xfff); + u16 chr = m_base[mem]; + + if (BIT(m_pa, 3)) + { + // 640 x 200 x 4of16 mode + for (int i = 0; i < 8; i++) + { + *p++ = palette[m_palette_latch[chr>>14]]; + chr <<= 2; + } + } + else + { + // 320 x 200 x 16 mode + for (int i = 0; i < 4; i++) + { + *p++ = palette[chr>>12]; + *p++ = palette[chr>>12]; + chr <<= 4; + } + } + } +} + +MC6845_BEGIN_UPDATE( applix_state::crtc_update_border ) +{ + bitmap.fill(m_palette->pen(m_video_latch >> 4), cliprect); +} + +WRITE_LINE_MEMBER( applix_state::vsync_w ) +{ + m_via->write_ca2(state); +} + +TIMER_DEVICE_CALLBACK_MEMBER(applix_state::cass_timer) +{ + /* cassette - turn 2500/5000Hz to a bit */ + m_cass_data[1]++; + u8 cass_ws = (m_cass->input() > +0.03) ? 1 : 0; + + if (cass_ws != m_cass_data[0]) + { + m_cass_data[0] = cass_ws; + m_cass_data[2] = ((m_cass_data[1] < 12) ? 2 : 0); + m_cass_data[1] = 0; + // low-to-high transition when reading cassette - CLK on IC32b + if ((cass_ws) && !BIT(m_pa, 4)) + m_maincpu->set_input_line(M68K_IRQ_4, ASSERT_LINE); + } +} + +void applix_state::applix(machine_config &config) +{ + /* basic machine hardware */ + M68000(config, m_maincpu, 30_MHz_XTAL / 4); // MC68000-P10 @ 7.5 MHz + m_maincpu->set_addrmap(AS_PROGRAM, &applix_state::main_mem); + + z80_device &subcpu(Z80(config, "subcpu", 16_MHz_XTAL / 2)); // Z80H + subcpu.set_addrmap(AS_PROGRAM, &applix_state::sub_mem); + subcpu.set_addrmap(AS_IO, &applix_state::sub_io); + + i8051_device &kbdcpu(I8051(config, "kbdcpu", 11060250)); + kbdcpu.set_addrmap(AS_PROGRAM, &applix_state::keytronic_pc3270_program); + kbdcpu.set_addrmap(AS_IO, &applix_state::keytronic_pc3270_io); + kbdcpu.port_in_cb<1>().set(FUNC(applix_state::p1_read)); + kbdcpu.port_out_cb<1>().set(FUNC(applix_state::p1_write)); + kbdcpu.port_in_cb<2>().set(FUNC(applix_state::p2_read)); + kbdcpu.port_out_cb<2>().set(FUNC(applix_state::p2_write)); + kbdcpu.port_in_cb<3>().set(FUNC(applix_state::p3_read)); + kbdcpu.port_out_cb<3>().set(FUNC(applix_state::p3_write)); + + /* video hardware */ + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); + screen.set_refresh_hz(50); + screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */ + screen.set_size(640, 200); + screen.set_visarea_full(); + screen.set_screen_update("crtc", FUNC(mc6845_device::screen_update)); + PALETTE(config, m_palette, FUNC(applix_state::applix_palette), 16); + + /* sound hardware */ + SPEAKER(config, "lspeaker").front_left(); + SPEAKER(config, "rspeaker").front_right(); + DAC0800(config, "ldac", 0).add_route(ALL_OUTPUTS, "lspeaker", 1.0); // 74ls374.u20 + dac0800.u21 + 4052.u23 + DAC0800(config, "rdac", 0).add_route(ALL_OUTPUTS, "rspeaker", 1.0); // 74ls374.u20 + dac0800.u21 + 4052.u23 + + /* Devices */ + MC6845(config, m_crtc, 30_MHz_XTAL / 16); // MC6545 @ 1.875 MHz + m_crtc->set_screen("screen"); + m_crtc->set_show_border_area(true); + m_crtc->set_char_width(8); + m_crtc->set_update_row_callback(FUNC(applix_state::crtc_update_row)); + m_crtc->set_begin_update_callback(FUNC(applix_state::crtc_update_border)); + m_crtc->out_vsync_callback().set(FUNC(applix_state::vsync_w)); + + MOS6522(config, m_via, 30_MHz_XTAL / 4 / 10); // VIA uses 68000 E clock + m_via->readpb_handler().set(FUNC(applix_state::applix_pb_r)); + // in CB1 kbd clk + // in CA2 vsync + // in CB2 kdb data + m_via->writepa_handler().set(FUNC(applix_state::applix_pa_w)); + m_via->writepb_handler().set(FUNC(applix_state::applix_pb_w)); + m_via->irq_handler().set_inputline("maincpu", M68K_IRQ_2); + + CENTRONICS(config, m_centronics, centronics_devices, "printer"); + m_centronics->ack_handler().set(m_via, FUNC(via6522_device::write_ca1)); + m_centronics->busy_handler().set(m_via, FUNC(via6522_device::write_pa0)); + + OUTPUT_LATCH(config, m_cent_data_out); + m_centronics->set_output_latch(*m_cent_data_out); + + CASSETTE(config, m_cass); + m_cass->set_default_state(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED); + m_cass->add_route(ALL_OUTPUTS, "lspeaker", 0.10); + + WD1772(config, m_fdc, 16_MHz_XTAL / 2); //connected to Z80H clock pin + FLOPPY_CONNECTOR(config, "fdc:0", applix_floppies, "35dd", applix_state::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, "fdc:1", applix_floppies, "35dd", applix_state::floppy_formats).enable_sound(true); + TIMER(config, "applix_c").configure_periodic(FUNC(applix_state::cass_timer), attotime::from_hz(100000)); + + scc8530_device &scc(SCC8530N(config, "scc", 30_MHz_XTAL / 8)); + scc.out_txda_callback().set("serial_a", FUNC(rs232_port_device::write_txd)); + scc.out_rtsa_callback().set("serial_a", FUNC(rs232_port_device::write_rts)); + scc.out_dtra_callback().set("serial_a", FUNC(rs232_port_device::write_dtr)); + scc.out_txdb_callback().set("serial_b", FUNC(rs232_port_device::write_txd)); + scc.out_rtsb_callback().set("serial_b", FUNC(rs232_port_device::write_rts)); + scc.out_dtrb_callback().set("serial_b", FUNC(rs232_port_device::write_dtr)); + scc.out_int_callback().set_inputline("maincpu", M68K_IRQ_3); + + rs232_port_device &serial_a(RS232_PORT(config, "serial_a", default_rs232_devices, nullptr)); + serial_a.rxd_handler().set("scc", FUNC(scc8530_device::rxa_w)); + serial_a.cts_handler().set("scc", FUNC(scc8530_device::ctsa_w)); + serial_a.cts_handler().set("scc", FUNC(scc8530_device::dcda_w)); + + rs232_port_device &serial_b(RS232_PORT(config, "serial_b", default_rs232_devices, nullptr)); + serial_b.rxd_handler().set("scc", FUNC(scc8530_device::rxb_w)); + serial_b.cts_handler().set("scc", FUNC(scc8530_device::ctsb_w)); + serial_b.cts_handler().set("scc", FUNC(scc8530_device::dcdb_w)); + + SOFTWARE_LIST(config, "flop_list").set_original("applix_flop"); +} + +/* ROM definition */ +ROM_START( applix ) + ROM_REGION16_BE(0x20000, "maincpu", 0) + ROM_SYSTEM_BIOS(0, "v4.5a", "V4.5a") + ROMX_LOAD( "1616osl.45a", 0x00000, 0x10000, CRC(9dfb3224) SHA1(5223833a357f90b147f25826c01713269fc1945f), ROM_SKIP(1) | ROM_BIOS(0) ) + ROMX_LOAD( "1616osh.45a", 0x00001, 0x10000, CRC(951bd441) SHA1(e0a38c8d0d38d84955c1de3f6a7d56ce06b063f6), ROM_SKIP(1) | ROM_BIOS(0) ) + ROM_SYSTEM_BIOS(1, "v4.4a", "V4.4a") + ROMX_LOAD( "1616osl.44a", 0x00000, 0x10000, CRC(4a1a90d3) SHA1(4df504bbf6fc5dad76c29e9657bfa556500420a6), ROM_SKIP(1) | ROM_BIOS(1) ) + ROMX_LOAD( "1616osh.44a", 0x00001, 0x10000, CRC(ef619994) SHA1(ff16fe9e2c99a1ffc855baf89278a97a2a2e881a), ROM_SKIP(1) | ROM_BIOS(1) ) + ROM_SYSTEM_BIOS(2, "v4.3a", "V4.3a") + ROMX_LOAD( "1616osl.43a", 0x00000, 0x10000, CRC(c09b9ff8) SHA1(c46f2a98470d2d09cf9f9eec0f4096ab762407b5), ROM_SKIP(1) | ROM_BIOS(2) ) + ROMX_LOAD( "1616osh.43a", 0x00001, 0x10000, CRC(071a2505) SHA1(42c4cc6e3e78b6a5320f9d9c858fc9f4e6220857), ROM_SKIP(1) | ROM_BIOS(2) ) + ROM_SYSTEM_BIOS(3, "v4.0c", "V4.0c") + ROMX_LOAD( "1616osl.40c", 0x00000, 0x10000, CRC(6a517b5d) SHA1(e0f4eba0cb8d273ba681b9d2c6d4b1beff9ef325), ROM_SKIP(1) | ROM_BIOS(3) ) + ROMX_LOAD( "1616osh.40c", 0x00001, 0x10000, CRC(7851651f) SHA1(d7d329aa7fe9f4418de0cdf813b61e70243e0e77), ROM_SKIP(1) | ROM_BIOS(3) ) + ROM_SYSTEM_BIOS(4, "v3.0b", "V3.0b") + ROMX_LOAD( "1616osl.30b", 0x00000, 0x10000, CRC(fb9198c3) SHA1(e0e7a1dd176c1cbed063df1c405821c261d48f3a), ROM_SKIP(1) | ROM_BIOS(4) ) + ROMX_LOAD( "1616osh.30b", 0x00001, 0x10000, CRC(a279e1d7) SHA1(3451b2cae87a9ccee5f579fd1d49cf52d9f97b83), ROM_SKIP(1) | ROM_BIOS(4) ) + ROM_SYSTEM_BIOS(5, "v2.4a", "V2.4a") + ROMX_LOAD( "1616osl.24a", 0x00000, 0x08000, CRC(b155830b) SHA1(b32db6a06c8a3c544210ba9faba7c49497c504fb), ROM_SKIP(1) | ROM_BIOS(5) ) + ROMX_LOAD( "1616osh.24a", 0x00001, 0x08000, CRC(6d9fc0e0) SHA1(07111f46386494ed3f426c1e50308f0209587f06), ROM_SKIP(1) | ROM_BIOS(5) ) + + ROM_REGION(0x18000, "subcpu", 0) + ROM_LOAD( "1616ssdv.022", 0x0000, 0x8000, CRC(6d8e413a) SHA1(fc27d92c34f231345a387b06670f36f8c1705856) ) + + ROM_REGION(0x20000, "user1", 0) + ROM_LOAD( "ssdcromv.22", 0x0000, 0x8000, CRC(c85c47fb) SHA1(6f0bb3753fc0d74ee5901d71d05a74ec6a4a1d05) ) + ROM_LOAD( "ssddromv.14a", 0x8000, 0x8000, CRC(8fe2db78) SHA1(487484003aba4d8960101ced6a689dc81676235d) ) + + ROM_REGION(0x2000, "kbdcpu", 0) + ROM_LOAD( "14166.bin", 0x0000, 0x2000, CRC(1aea1b53) SHA1(b75b6d4509036406052157bc34159f7039cdc72e) ) +ROM_END + + +void applix_state::init_applix() +{ + u8 *RAM = memregion("subcpu")->base(); + membank("bank1")->configure_entries(0, 2, &RAM[0x8000], 0x8000); +} + + +/* Driver */ + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1986, applix, 0, 0, applix, applix, applix_state, init_applix, "Applix Pty Ltd", "Applix 1616", MACHINE_SUPPORTS_SAVE ) + + + +/**************************************************** KEYBOARD MODULE *****************************************/ + +u8 applix_state::internal_data_read(offs_t offset) +{ + m_via->write_cb2( BIT(offset, 8) ); // data + bool cp = !BIT(offset, 9); // clock pulses //TODO tidy this up with real flipflops + if (cp != m_cp) + { + m_cp = cp; + if (cp) + m_clock_count++; + } + if (m_clock_count > 1) + m_via->write_cb1( cp ); + + return 0xff; +} + + +void applix_state::internal_data_write(offs_t offset, u8 data) +{ + /* Check for low->high transition on AD8 */ + if ( ! ( m_last_write_addr & 0x0100 ) && ( offset & 0x0100 ) ) + { + switch (m_p1) + { + case 0x0e: + break; + case 0x0f: + m_p1_data = m_io_k0f->read(); + break; + case 0x30: + m_p1_data = m_io_k300->read(); + break; + case 0x31: + m_p1_data = m_io_k310->read(); + break; + case 0x32: + m_p1_data = m_io_k320->read(); + break; + case 0x33: + m_p1_data = m_io_k330->read(); + break; + case 0x34: + m_p1_data = m_io_k340->read(); + break; + case 0x35: + m_p1_data = m_io_k350->read(); + break; + case 0x36: + m_p1_data = m_io_k360->read(); + break; + case 0x37: + m_p1_data = m_io_k370->read() | (m_io_k360->read() & 0x01); + break; + case 0x38: + m_p1_data = m_io_k380->read(); + break; + case 0x39: + m_p1_data = m_io_k390->read(); + break; + case 0x3a: + m_p1_data = m_io_k3a0->read(); + break; + case 0x3b: + m_p1_data = m_io_k3b0->read(); + break; + } + } + + /* Check for low->high transition on AD9 */ + if ( ! ( m_last_write_addr & 0x0200 ) && ( offset & 0x0200 ) ) + { + switch (m_p1) + { + case 0x0b: + m_p1_data = m_io_k0b->read(); + break; + case 0x30: + m_p1_data = m_io_k301->read(); + break; + case 0x31: + m_p1_data = m_io_k311->read(); + break; + case 0x32: + m_p1_data = m_io_k321->read(); + break; + case 0x33: + m_p1_data = m_io_k331->read(); + break; + case 0x34: + m_p1_data = m_io_k341->read(); + break; + case 0x35: + m_p1_data = m_io_k351->read(); + break; + case 0x36: + m_p1_data = m_io_k361->read(); + break; + case 0x37: + m_p1_data = m_io_k371->read(); + break; + case 0x38: + m_p1_data = 0xff; + break; + case 0x39: + m_p1_data = 0xff; + break; + case 0x3a: + m_p1_data = 0xff; + break; + } + } + + m_last_write_addr = offset; +} + + +u8 applix_state::p1_read() +{ + return m_p1 & m_p1_data; +} + + +void applix_state::p1_write(u8 data) +{ + m_p1 = data; +} + + +u8 applix_state::p2_read() +{ + return m_p2; +} + + +void applix_state::p2_write(u8 data) +{ + m_p2 = data; +} + + +u8 applix_state::p3_read() +{ + u8 data = m_p3; + + data &= ~0x14; + + /* -INT0 signal */ + data |= 4; + + /* T0 signal */ + data |= 0; + + return data; +} + + +void applix_state::p3_write(u8 data) +{ + m_p3 = data; +} diff --git a/src/mame/ausnz/aussiebyte.cpp b/src/mame/ausnz/aussiebyte.cpp new file mode 100644 index 00000000000..3d452580ed7 --- /dev/null +++ b/src/mame/ausnz/aussiebyte.cpp @@ -0,0 +1,619 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert +/************************************************************************************************* + + The Aussie Byte II Single-Board Computer, created by SME Systems, Melbourne, Australia. + Also known as the Knight 2000 Microcomputer. + + Status: + Boots up from floppy. + Output to serial terminal and to 6545 are working. Serial keyboard works. + + Developed in conjunction with members of the MSPP. Written in July, 2015. + + ToDo: + - CRT8002 attributes controller + - Graphics + - Hard drive controllers and drives + - Test Centronics printer + - PIO connections + + Note of MAME restrictions: + - Votrax doesn't sound anything like the real thing + - WD1001/WD1002 device is not emulated + - CRT8002 device is not emulated + +**************************************************************************************************/ + +/*********************************************************** + + Includes + +************************************************************/ +#include "emu.h" +#include "aussiebyte.h" + +#include "screen.h" +#include "softlist_dev.h" +#include "speaker.h" + + +/*********************************************************** + + Address Maps + +************************************************************/ + +void aussiebyte_state::mem_map(address_map &map) +{ + map(0x0000, 0x3fff).bankr("bankr0").bankw("bankw0"); + map(0x4000, 0x7fff).bankrw("bank1"); + map(0x8000, 0xbfff).bankrw("bank2"); + map(0xc000, 0xffff).ram(); +} + +void aussiebyte_state::io_map(address_map &map) +{ + map.global_mask(0xff); + map.unmap_value_high(); + map(0x00, 0x03).rw("sio1", FUNC(z80sio_device::ba_cd_r), FUNC(z80sio_device::ba_cd_w)); + map(0x04, 0x07).rw(m_pio1, FUNC(z80pio_device::read), FUNC(z80pio_device::write)); + map(0x08, 0x0b).rw(m_ctc, FUNC(z80ctc_device::read), FUNC(z80ctc_device::write)); + map(0x0c, 0x0f).noprw(); // winchester interface + map(0x10, 0x13).rw(m_fdc, FUNC(wd2797_device::read), FUNC(wd2797_device::write)); + map(0x14, 0x14).rw(m_dma, FUNC(z80dma_device::read), FUNC(z80dma_device::write)); + map(0x15, 0x15).w(FUNC(aussiebyte_state::port15_w)); // boot rom disable + map(0x16, 0x16).w(FUNC(aussiebyte_state::port16_w)); // fdd select + map(0x17, 0x17).w(FUNC(aussiebyte_state::port17_w)); // DMA mux + map(0x18, 0x18).w(FUNC(aussiebyte_state::port18_w)); // fdc select + map(0x19, 0x19).r(FUNC(aussiebyte_state::port19_r)); // info port + map(0x1a, 0x1a).w(FUNC(aussiebyte_state::port1a_w)); // membank + map(0x1b, 0x1b).w(FUNC(aussiebyte_state::port1b_w)); // winchester control + map(0x1c, 0x1f).w(FUNC(aussiebyte_state::port1c_w)); // gpebh select + map(0x20, 0x23).rw(m_pio2, FUNC(z80pio_device::read), FUNC(z80pio_device::write)); + map(0x24, 0x27).rw("sio2", FUNC(z80sio_device::ba_cd_r), FUNC(z80sio_device::ba_cd_w)); + map(0x28, 0x28).r(FUNC(aussiebyte_state::port28_r)).w(m_votrax, FUNC(votrax_sc01_device::write)); + map(0x2c, 0x2c).w(m_votrax, FUNC(votrax_sc01_device::inflection_w)); + map(0x30, 0x30).w(FUNC(aussiebyte_state::address_w)); + map(0x31, 0x31).r(m_crtc, FUNC(mc6845_device::status_r)); + map(0x32, 0x32).w(FUNC(aussiebyte_state::register_w)); + map(0x33, 0x33).r(FUNC(aussiebyte_state::port33_r)); + map(0x34, 0x34).w(FUNC(aussiebyte_state::port34_w)); // video control + map(0x35, 0x35).w(FUNC(aussiebyte_state::port35_w)); // data to vram and aram + map(0x36, 0x36).r(FUNC(aussiebyte_state::port36_r)); // data from vram and aram + map(0x37, 0x37).r(FUNC(aussiebyte_state::port37_r)); // read dispen flag + map(0x40, 0x4f).rw(FUNC(aussiebyte_state::rtc_r), FUNC(aussiebyte_state::rtc_w)); +} + +/*********************************************************** + + Keyboard + +************************************************************/ +static INPUT_PORTS_START( aussiebyte ) +INPUT_PORTS_END + +/*********************************************************** + + I/O Ports + +************************************************************/ +void aussiebyte_state::port15_w(u8 data) +{ + m_bankr0->set_entry(m_port15); // point at ram + m_port15 = true; +} + +/* FDD select +0 Drive Select bit O +1 Drive Select bit 1 +2 Drive Select bit 2 +3 Drive Select bit 3 + - These bits connect to a 74LS145 binary to BCD converter. + - Drives 0 to 3 are 5.25 inch, 4 to 7 are 8 inch, 9 and 0 are not used. + - Currently we only support drive 0. +4 Side Select to Disk Drives. +5 Disable 5.25 inch floppy spindle motors. +6 Unused. +7 Enable write precompensation on WD2797 controller. */ +void aussiebyte_state::port16_w(u8 data) +{ + floppy_image_device *m_floppy = nullptr; + if ((data & 15) == 0) + m_floppy = m_floppy0->get_device(); + else + if ((data & 15) == 1) + m_floppy = m_floppy1->get_device(); + + m_fdc->set_floppy(m_floppy); + + if (m_floppy) + { + m_floppy->mon_w(BIT(data, 5)); + m_floppy->ss_w(BIT(data, 4)); + } +} + +/* DMA select +0 - FDC +1 - SIO Ch A +2 - SIO Ch B +3 - Winchester bus +4 - SIO Ch C +5 - SIO Ch D +6 - Ext ready 1 +7 - Ext ready 2 */ +void aussiebyte_state::port17_w(u8 data) +{ + m_port17 = data & 7; + m_dma->rdy_w(BIT(m_port17_rdy, data)); +} + +/* FDC params +2 EXC: WD2797 clock frequency. H = 5.25"; L = 8" +3 WIEN: WD2797 Double density select. */ +void aussiebyte_state::port18_w(u8 data) +{ + m_fdc->set_unscaled_clock(BIT(data, 2) ? 1e6 : 2e6); + m_fdc->dden_w(BIT(data, 3)); +} + +u8 aussiebyte_state::port19_r() +{ + return m_port19; +} + +// Memory banking +void aussiebyte_state::port1a_w(u8 data) +{ + data &= 7; + switch (data) + { + case 0: + case 1: + case 2: + case 3: + case 4: + m_port1a = data*3+1; + if (m_port15) + m_bankr0->set_entry(data*3+1); + m_bankw0->set_entry(data*3+1); + m_bank1->set_entry(data*3+2); + m_bank2->set_entry(data*3+3); + break; + case 5: + m_port1a = 1; + if (m_port15) + m_bankr0->set_entry(1); + m_bankw0->set_entry(1); + m_bank1->set_entry(2); + m_bank2->set_entry(13); + break; + case 6: + m_port1a = 14; + if (m_port15) + m_bankr0->set_entry(14); + m_bankw0->set_entry(14); + m_bank1->set_entry(15); + //m_bank2->set_entry(0); // open bus + break; + case 7: + m_port1a = 1; + if (m_port15) + m_bankr0->set_entry(1); + m_bankw0->set_entry(1); + m_bank1->set_entry(4); + m_bank2->set_entry(13); + break; + } +} + +// Winchester control +void aussiebyte_state::port1b_w(u8 data) +{ +} + +// GPEHB control +void aussiebyte_state::port1c_w(u8 data) +{ +} + +void aussiebyte_state::port20_w(u8 data) +{ + m_speaker->level_w(BIT(data, 7)); + m_rtc->cs_w(BIT(data, 0)); + m_rtc->hold_w(BIT(data, 0)); +} + +u8 aussiebyte_state::port28_r() +{ + return m_port28; +} + +/*********************************************************** + + RTC + +************************************************************/ +u8 aussiebyte_state::rtc_r(offs_t offset) +{ + m_rtc->read_w(1); + m_rtc->address_w(offset); + u8 data = m_rtc->data_r(); + m_rtc->read_w(0); + return data; +} + +void aussiebyte_state::rtc_w(offs_t offset, u8 data) +{ + m_rtc->address_w(offset); + m_rtc->data_w(data); + m_rtc->write_w(1); + m_rtc->write_w(0); +} + +/*********************************************************** + + DMA + +************************************************************/ +u8 aussiebyte_state::memory_read_byte(offs_t offset) +{ + address_space& prog_space = m_maincpu->space(AS_PROGRAM); + return prog_space.read_byte(offset); +} + +void aussiebyte_state::memory_write_byte(offs_t offset, u8 data) +{ + address_space& prog_space = m_maincpu->space(AS_PROGRAM); + prog_space.write_byte(offset, data); +} + +u8 aussiebyte_state::io_read_byte(offs_t offset) +{ + address_space& prog_space = m_maincpu->space(AS_IO); + return prog_space.read_byte(offset); +} + +void aussiebyte_state::io_write_byte(offs_t offset, u8 data) +{ + address_space& prog_space = m_maincpu->space(AS_IO); + prog_space.write_byte(offset, data); +} + +WRITE_LINE_MEMBER( aussiebyte_state::busreq_w ) +{ +// since our Z80 has no support for BUSACK, we assume it is granted immediately + m_maincpu->set_input_line(Z80_INPUT_LINE_BUSRQ, state); + m_dma->bai_w(state); // tell dma that bus has been granted +} + +/*********************************************************** + + DMA selector + +************************************************************/ +WRITE_LINE_MEMBER( aussiebyte_state::sio1_rdya_w ) +{ + m_port17_rdy = (m_port17_rdy & 0xfd) | (u8)(state << 1); + if (m_port17 == 1) + m_dma->rdy_w(state); +} + +WRITE_LINE_MEMBER( aussiebyte_state::sio1_rdyb_w ) +{ + m_port17_rdy = (m_port17_rdy & 0xfb) | (u8)(state << 2); + if (m_port17 == 2) + m_dma->rdy_w(state); +} + +WRITE_LINE_MEMBER( aussiebyte_state::sio2_rdya_w ) +{ + m_port17_rdy = (m_port17_rdy & 0xef) | (u8)(state << 4); + if (m_port17 == 4) + m_dma->rdy_w(state); +} + +WRITE_LINE_MEMBER( aussiebyte_state::sio2_rdyb_w ) +{ + m_port17_rdy = (m_port17_rdy & 0xdf) | (u8)(state << 5); + if (m_port17 == 5) + m_dma->rdy_w(state); +} + + +/*********************************************************** + + Video + +************************************************************/ + +/* F4 Character Displayer */ +static const gfx_layout crt8002_charlayout = +{ + 8, 12, /* 7 x 11 characters */ + 128, /* 128 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, 9*8, 10*8, 11*8 }, + 8*16 /* every char takes 16 bytes */ +}; + +static GFXDECODE_START( gfx_crt8002 ) + GFXDECODE_ENTRY( "chargen", 0x0000, crt8002_charlayout, 0, 1 ) +GFXDECODE_END + +/*************************************************************** + + Daisy Chain + +****************************************************************/ + +static const z80_daisy_config daisy_chain_intf[] = +{ + { "dma" }, + { "pio2" }, + { "sio1" }, + { "sio2" }, + { "pio1" }, + { "ctc" }, + { nullptr } +}; + + +/*********************************************************** + + Floppy Disk + +************************************************************/ + +WRITE_LINE_MEMBER( aussiebyte_state::fdc_intrq_w ) +{ + u8 data = (m_port19 & 0xbf) | (state ? 0x40 : 0); + m_port19 = data; +} + +WRITE_LINE_MEMBER( aussiebyte_state::fdc_drq_w ) +{ + u8 data = (m_port19 & 0x7f) | (state ? 0x80 : 0); + m_port19 = data; + state ^= 1; // inverter on pin38 of fdc + m_port17_rdy = (m_port17_rdy & 0xfe) | (u8)state; + if (m_port17 == 0) + m_dma->rdy_w(state); +} + +static void aussiebyte_floppies(device_slot_interface &device) +{ + device.option_add("525qd", FLOPPY_525_QD); +} + + +/*********************************************************** + + Quickload + + This loads a .COM file to address 0x100 then jumps + there. Sometimes .COM has been renamed to .CPM to + prevent windows going ballistic. These can be loaded + as well. + +************************************************************/ + +QUICKLOAD_LOAD_MEMBER(aussiebyte_state::quickload_cb) +{ + address_space& prog_space = m_maincpu->space(AS_PROGRAM); + + if (image.length() >= 0xfd00) + return image_init_result::FAIL; + + /* RAM must be banked in */ + m_port15 = true; // disable boot rom + m_port1a = 4; + m_bankr0->set_entry(m_port1a); /* enable correct program bank */ + m_bankw0->set_entry(m_port1a); + + /* Avoid loading a program if CP/M-80 is not in memory */ + if ((prog_space.read_byte(0) != 0xc3) || (prog_space.read_byte(5) != 0xc3)) + { + machine_reset(); + return image_init_result::FAIL; + } + + /* Load image to the TPA (Transient Program Area) */ + u16 quickload_size = image.length(); + for (u16 i = 0; i < quickload_size; i++) + { + u8 data; + if (image.fread( &data, 1) != 1) + return image_init_result::FAIL; + prog_space.write_byte(i+0x100, data); + } + + /* clear out command tail */ + prog_space.write_byte(0x80, 0); prog_space.write_byte(0x81, 0); + + /* Roughly set SP basing on the BDOS position */ + m_maincpu->set_state_int(Z80_SP, 256 * prog_space.read_byte(7) - 0x400); + m_maincpu->set_pc(0x100); // start program + + return image_init_result::PASS; +} + +/*********************************************************** + + Machine Driver + +************************************************************/ +void aussiebyte_state::machine_reset() +{ + m_port15 = false; + m_port17 = 0; + m_port17_rdy = 0; + m_port1a = 1; + m_alpha_address = 0; + m_graph_address = 0; + m_bankr0->set_entry(16); // point at rom + m_bankw0->set_entry(1); // always write to ram + m_bank1->set_entry(2); + m_bank2->set_entry(3); + m_maincpu->reset(); +} + +void aussiebyte_state::machine_start() +{ + m_vram = std::make_unique(0x10000); + m_aram = std::make_unique(0x800); + m_ram = make_unique_clear(0x40000); + save_pointer(NAME(m_vram), 0x10000); + save_pointer(NAME(m_aram), 0x800); + save_pointer(NAME(m_ram), 0x40000); + save_item(NAME(m_port15)); + save_item(NAME(m_port17)); + save_item(NAME(m_port17_rdy)); + save_item(NAME(m_port19)); + save_item(NAME(m_port1a)); + save_item(NAME(m_port28)); + save_item(NAME(m_port34)); + save_item(NAME(m_port35)); + save_item(NAME(m_video_index)); + save_item(NAME(m_cnt)); + save_item(NAME(m_alpha_address)); + save_item(NAME(m_graph_address)); + save_item(NAME(m_centronics_busy)); + + // Main ram is divided into 16k blocks (0-15). The boot rom is block number 16. + // For convenience, bank 0 is permanently assigned to C000-FFFF + + m_bankr0->configure_entries(0, 16, m_p_mram, 0x4000); + m_bankw0->configure_entries(0, 16, m_p_mram, 0x4000); + m_bank1->configure_entries(0, 16, m_p_mram, 0x4000); + m_bank2->configure_entries(0, 16, m_p_mram, 0x4000); + m_bankr0->configure_entry(16, memregion("roms")->base()); + + m_cnt = 0; +} + + +void aussiebyte_state::aussiebyte(machine_config &config) +{ + /* basic machine hardware */ + Z80(config, m_maincpu, 16_MHz_XTAL / 4); + m_maincpu->set_addrmap(AS_PROGRAM, &aussiebyte_state::mem_map); + m_maincpu->set_addrmap(AS_IO, &aussiebyte_state::io_map); + m_maincpu->set_daisy_config(daisy_chain_intf); + + /* video hardware */ + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); + screen.set_raw(16_MHz_XTAL, 952, 0, 640, 336, 0, 288); + screen.set_screen_update("crtc", FUNC(sy6545_1_device::screen_update)); + + GFXDECODE(config, "gfxdecode", "palette", gfx_crt8002); + PALETTE(config, m_palette, palette_device::MONOCHROME); + + /* sound hardware */ + SPEAKER(config, "mono").front_center(); + SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.50); + VOTRAX_SC01(config, m_votrax, 720000); // 720kHz? needs verify + m_votrax->ar_callback().set([this] (bool state) { m_port28 = state ? 0 : 1; }); + m_votrax->add_route(ALL_OUTPUTS, "mono", 1.00); + + /* devices */ + CENTRONICS(config, m_centronics, centronics_devices, "printer"); + m_centronics->set_data_input_buffer("cent_data_in"); + m_centronics->busy_handler().set([this] (bool state) { m_centronics_busy = state; }); + INPUT_BUFFER(config, "cent_data_in"); + output_latch_device ¢_data_out(OUTPUT_LATCH(config, "cent_data_out")); + m_centronics->set_output_latch(cent_data_out); + + Z80CTC(config, m_ctc, 16_MHz_XTAL / 4); + m_ctc->intr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); + m_ctc->set_clk<0>(4.9152_MHz_XTAL / 4); + m_ctc->set_clk<1>(4.9152_MHz_XTAL / 4); + m_ctc->set_clk<2>(4.9152_MHz_XTAL / 4); + m_ctc->zc_callback<0>().set("sio1", FUNC(z80sio_device::rxca_w)); + m_ctc->zc_callback<0>().append("sio1", FUNC(z80sio_device::txca_w)); + m_ctc->zc_callback<1>().set("sio1", FUNC(z80sio_device::rxtxcb_w)); + m_ctc->zc_callback<1>().append("sio2", FUNC(z80sio_device::rxca_w)); + m_ctc->zc_callback<1>().append("sio2", FUNC(z80sio_device::txca_w)); + m_ctc->zc_callback<2>().set("ctc", FUNC(z80ctc_device::trg3)); + m_ctc->zc_callback<2>().append("sio2", FUNC(z80sio_device::rxtxcb_w)); + + Z80DMA(config, m_dma, 16_MHz_XTAL / 4); + m_dma->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); + m_dma->out_busreq_callback().set(FUNC(aussiebyte_state::busreq_w)); + // BAO, not used + m_dma->in_mreq_callback().set(FUNC(aussiebyte_state::memory_read_byte)); + m_dma->out_mreq_callback().set(FUNC(aussiebyte_state::memory_write_byte)); + m_dma->in_iorq_callback().set(FUNC(aussiebyte_state::io_read_byte)); + m_dma->out_iorq_callback().set(FUNC(aussiebyte_state::io_write_byte)); + + Z80PIO(config, m_pio1, 16_MHz_XTAL / 4); + m_pio1->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); + m_pio1->out_pa_callback().set("cent_data_out", FUNC(output_latch_device::write)); + m_pio1->in_pb_callback().set("cent_data_in", FUNC(input_buffer_device::read)); + m_pio1->out_ardy_callback().set(m_centronics, FUNC(centronics_device::write_strobe)).invert(); + + Z80PIO(config, m_pio2, 16_MHz_XTAL / 4); + m_pio2->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); + m_pio2->out_pa_callback().set(FUNC(aussiebyte_state::port20_w)); + + z80sio_device& sio1(Z80SIO(config, "sio1", 16_MHz_XTAL / 4)); + sio1.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); + sio1.out_wrdya_callback().set(FUNC(aussiebyte_state::sio1_rdya_w)); + sio1.out_wrdyb_callback().set(FUNC(aussiebyte_state::sio1_rdyb_w)); + + z80sio_device& sio2(Z80SIO(config, "sio2", 16_MHz_XTAL / 4)); + sio2.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); + sio2.out_wrdya_callback().set(FUNC(aussiebyte_state::sio2_rdya_w)); + sio2.out_wrdyb_callback().set(FUNC(aussiebyte_state::sio2_rdyb_w)); + sio2.out_txda_callback().set("rs232", FUNC(rs232_port_device::write_txd)); + sio2.out_dtra_callback().set("rs232", FUNC(rs232_port_device::write_dtr)); + sio2.out_rtsa_callback().set("rs232", FUNC(rs232_port_device::write_rts)); + + RS232_PORT(config, m_rs232, default_rs232_devices, "keyboard"); + m_rs232->rxd_handler().set("sio2", FUNC(z80sio_device::rxa_w)); + + WD2797(config, m_fdc, 16_MHz_XTAL / 16); + m_fdc->intrq_wr_callback().set(FUNC(aussiebyte_state::fdc_intrq_w)); + m_fdc->drq_wr_callback().set(FUNC(aussiebyte_state::fdc_drq_w)); + FLOPPY_CONNECTOR(config, "fdc:0", aussiebyte_floppies, "525qd", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, "fdc:1", aussiebyte_floppies, "525qd", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); + + /* devices */ + SY6545_1(config, m_crtc, 16_MHz_XTAL / 8); + m_crtc->set_screen("screen"); + m_crtc->set_show_border_area(false); + m_crtc->set_char_width(8); + m_crtc->set_update_row_callback(FUNC(aussiebyte_state::crtc_update_row)); + m_crtc->set_on_update_addr_change_callback(FUNC(aussiebyte_state::crtc_update_addr)); + + MSM5832(config, m_rtc, 32.768_kHz_XTAL); + + /* quickload */ + QUICKLOAD(config, "quickload", "com,cpm", attotime::from_seconds(3)).set_load_callback(FUNC(aussiebyte_state::quickload_cb)); + + SOFTWARE_LIST(config, "flop_list").set_original("aussiebyte"); +} + + +/*********************************************************** + + Game driver + +************************************************************/ + + +ROM_START(aussieby) + ROM_REGION(0x4000, "roms", 0) // Size of bank 16 + ROM_LOAD( "knight_boot_0000.u27", 0x0000, 0x1000, CRC(1f200437) SHA1(80d1d208088b325c16a6824e2da605fb2b00c2ce) ) + + ROM_REGION(0x800, "chargen", 0) + ROM_LOAD( "8002.bin", 0x0000, 0x0800, CRC(fdd6eb13) SHA1(a094d416e66bdab916e72238112a6265a75ca690) ) +ROM_END + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1984, aussieby, 0, 0, aussiebyte, aussiebyte, aussiebyte_state, empty_init, "SME Systems", "Aussie Byte II", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/ausnz/aussiebyte.h b/src/mame/ausnz/aussiebyte.h new file mode 100644 index 00000000000..046307795b2 --- /dev/null +++ b/src/mame/ausnz/aussiebyte.h @@ -0,0 +1,157 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert +#ifndef MAME_INCLUDES_AUSSIEBYTE_H +#define MAME_INCLUDES_AUSSIEBYTE_H + +#pragma once + +/*********************************************************** + + Includes + +************************************************************/ +#include "bus/centronics/ctronics.h" +#include "bus/rs232/rs232.h" + +#include "cpu/z80/z80.h" +#include "machine/z80daisy.h" + +#include "imagedev/floppy.h" +#include "machine/msm5832.h" +#include "machine/wd_fdc.h" +#include "machine/z80ctc.h" +#include "machine/z80sio.h" +#include "machine/z80dma.h" +#include "machine/z80pio.h" + +#include "sound/spkrdev.h" +#include "sound/votrax.h" + +#include "video/mc6845.h" + +#include "imagedev/snapquik.h" + +#include "emupal.h" + + + +/*********************************************************** + + Class + +************************************************************/ +class aussiebyte_state : public driver_device +{ +public: + aussiebyte_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_palette(*this, "palette") + , m_maincpu(*this, "maincpu") + , m_bankr0(*this, "bankr0") + , m_bankw0(*this, "bankw0") + , m_bank1(*this, "bank1") + , m_bank2(*this, "bank2") + , m_p_chargen(*this, "chargen") + , m_p_mram(*this, "mram", 0x40000, ENDIANNESS_LITTLE) + , m_p_videoram(*this, "vram", 0x10000, ENDIANNESS_LITTLE) + , m_p_attribram(*this, "aram", 0x800, ENDIANNESS_LITTLE) + , m_ctc(*this, "ctc") + , m_dma(*this, "dma") + , m_pio1(*this, "pio1") + , m_pio2(*this, "pio2") + , m_centronics(*this, "centronics") + , m_rs232(*this, "rs232") + , m_fdc(*this, "fdc") + , m_floppy0(*this, "fdc:0") + , m_floppy1(*this, "fdc:1") + , m_crtc(*this, "crtc") + , m_speaker(*this, "speaker") + , m_votrax(*this, "votrax") + , m_rtc(*this, "rtc") + { } + + void aussiebyte(machine_config &config); + + DECLARE_QUICKLOAD_LOAD_MEMBER(quickload_cb); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + +private: + u8 memory_read_byte(offs_t offset); + void memory_write_byte(offs_t offset, u8 data); + u8 io_read_byte(offs_t offset); + void io_write_byte(offs_t offset, u8 data); + void port15_w(u8 data); + void port16_w(u8 data); + void port17_w(u8 data); + void port18_w(u8 data); + u8 port19_r(); + void port1a_w(u8 data); + void port1b_w(u8 data); + void port1c_w(u8 data); + void port20_w(u8 data); + u8 port28_r(); + u8 port33_r(); + void port34_w(u8 data); + void port35_w(u8 data); + u8 port36_r(); + u8 port37_r(); + u8 rtc_r(offs_t offset); + void rtc_w(offs_t offset, u8 data); + DECLARE_WRITE_LINE_MEMBER(fdc_intrq_w); + DECLARE_WRITE_LINE_MEMBER(fdc_drq_w); + DECLARE_WRITE_LINE_MEMBER(busreq_w); + DECLARE_WRITE_LINE_MEMBER(sio1_rdya_w); + DECLARE_WRITE_LINE_MEMBER(sio1_rdyb_w); + DECLARE_WRITE_LINE_MEMBER(sio2_rdya_w); + DECLARE_WRITE_LINE_MEMBER(sio2_rdyb_w); + void address_w(u8 data); + void register_w(u8 data); + MC6845_UPDATE_ROW(crtc_update_row); + MC6845_ON_UPDATE_ADDR_CHANGED(crtc_update_addr); + + void io_map(address_map &map); + void mem_map(address_map &map); + + u8 crt8002(u8 ac_ra, u8 ac_chr, u8 ac_attr, u16 ac_cnt, bool ac_curs); + bool m_port15 = false; // rom switched in (0), out (1) + u8 m_port17 = 0U; + u8 m_port17_rdy = 0U; + u8 m_port19 = 0U; + u8 m_port1a = 0U; // bank to switch to when write to port 15 happens + u8 m_port28 = 0U; + u8 m_port34 = 0U; + u8 m_port35 = 0U; // byte to be written to vram or aram + u8 m_video_index = 0U; + u16 m_cnt = 0U; + u16 m_alpha_address = 0U; + u16 m_graph_address = 0U; + bool m_centronics_busy = false; + std::unique_ptr m_vram; // video ram, 64k dynamic + std::unique_ptr m_aram; // attribute ram, 2k static + std::unique_ptr m_ram; // main ram, 256k dynamic + required_device m_palette; + required_device m_maincpu; + required_memory_bank m_bankr0, m_bankw0, m_bank1, m_bank2; + required_region_ptr m_p_chargen; + memory_share_creator m_p_mram; + memory_share_creator m_p_videoram; + memory_share_creator m_p_attribram; + required_device m_ctc; + required_device m_dma; + required_device m_pio1; + required_device m_pio2; + required_device m_centronics; + required_device m_rs232; + required_device m_fdc; + required_device m_floppy0; + optional_device m_floppy1; + required_device m_crtc; + required_device m_speaker; + required_device m_votrax; + required_device m_rtc; +}; + +#endif // MAME_INCLUDES_AUSSIEBYTE_H diff --git a/src/mame/ausnz/aussiebyte_v.cpp b/src/mame/ausnz/aussiebyte_v.cpp new file mode 100644 index 00000000000..9348d7c96a3 --- /dev/null +++ b/src/mame/ausnz/aussiebyte_v.cpp @@ -0,0 +1,196 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert +/*********************************************************** + + Video + Graphics not working properly. + Mode 0 - lores (wide, chunky) + Mode 1 - external, *should* be ok + Mode 2 - thin graphics, not explained well enough to code + Mode 3 - alphanumeric, works + + + +************************************************************/ +#include "emu.h" +#include "aussiebyte.h" +/*********************************************************** + + I/O Ports + +************************************************************/ + +// dummy read port, forces requested action to happen +u8 aussiebyte_state::port33_r() +{ + return 0xff; +} + +/* +Video control - needs to be fully understood +d0, d1, d2, d3 - can replace RA0-3 in graphics mode +d4 - GS - unknown +d5 - /SRRD - controls write of data to either vram or aram (1=vram, 0=aram) +d6 - /VWR - 0 = enable write vdata to vram, read from aram to vdata ; 1 = enable write to aram from vdata +d7 - OE on port 35 +*/ +void aussiebyte_state::port34_w(u8 data) +{ + m_port34 = data; +} + +void aussiebyte_state::port35_w(u8 data) +{ + m_port35 = data; +} + +u8 aussiebyte_state::port36_r() +{ + if (BIT(m_port34, 5)) + { + if (BIT(m_aram[m_alpha_address & 0x7ff], 7)) + return m_vram[m_alpha_address]; + else + return m_vram[m_graph_address]; + } + else + return m_aram[m_alpha_address & 0x7ff]; +} + +u8 aussiebyte_state::port37_r() +{ + return m_crtc->de_r() ? 0xff : 0xfe; +} + + +/*********************************************************** + + Video + +************************************************************/ +MC6845_ON_UPDATE_ADDR_CHANGED( aussiebyte_state::crtc_update_addr ) +{ +/* not sure what goes in here - parameters passed are device, address, strobe */ +// m_video_address = address;// & 0x7ff; +} + +void aussiebyte_state::address_w(u8 data) +{ + m_crtc->address_w(data); + + m_video_index = data & 0x1f; + + if (m_video_index == 31) + { + m_alpha_address++; + m_alpha_address &= 0x3fff; + m_graph_address = (m_alpha_address << 4) | (m_port34 & 15); + + if (BIT(m_port34, 5)) + { + if (BIT(m_aram[m_alpha_address & 0x7ff], 7)) + m_vram[m_alpha_address] = m_port35; + else + m_vram[m_graph_address] = m_port35; + } + else + m_aram[m_alpha_address & 0x7ff] = m_port35; + } +} + +void aussiebyte_state::register_w(u8 data) +{ + m_crtc->register_w(data); + u16 temp = m_alpha_address; + + // Get transparent address + if (m_video_index == 18) + m_alpha_address = (data << 8 ) | (temp & 0xff); + else + if (m_video_index == 19) + m_alpha_address = data | (temp & 0xff00); +} + +u8 aussiebyte_state::crt8002(u8 ac_ra, u8 ac_chr, u8 ac_attr, u16 ac_cnt, bool ac_curs) +{ + u8 gfx = 0; + switch (ac_attr & 3) + { + case 0: // lores gfx + switch (ac_ra) + { + case 0: + case 1: + case 2: + gfx = (BIT(ac_chr, 7) ? 0xf8 : 0) | (BIT(ac_chr, 3) ? 7 : 0); + break; + case 3: + case 4: + case 5: + gfx = (BIT(ac_chr, 6) ? 0xf8 : 0) | (BIT(ac_chr, 2) ? 7 : 0); + break; + case 6: + case 7: + case 8: + gfx = (BIT(ac_chr, 5) ? 0xf8 : 0) | (BIT(ac_chr, 1) ? 7 : 0); + break; + default: + gfx = (BIT(ac_chr, 4) ? 0xf8 : 0) | (BIT(ac_chr, 0) ? 7 : 0); + break; + } + break; + case 1: // external mode + gfx = bitswap<8>(ac_chr, 0,1,2,3,4,5,6,7); + break; + case 2: // thin gfx + break; + case 3: // alpha + gfx = m_p_chargen[((ac_chr & 0x7f)<<4) | ac_ra]; + break; + } + + if (BIT(ac_attr, 3) & (ac_ra == 11)) // underline + gfx = 0xff; + if (BIT(ac_attr, 2) & ((ac_ra == 5) | (ac_ra == 6))) // strike-through + gfx = 0xff; + if (BIT(ac_attr, 6) & BIT(ac_cnt, 13)) // flash + gfx = 0; + if (BIT(ac_attr, 5)) // blank + gfx = 0; + if (ac_curs && BIT(ac_cnt, 14)) // cursor + gfx ^= 0xff; + if (BIT(ac_attr, 4)) // reverse video + gfx ^= 0xff; + return gfx; +} + +MC6845_UPDATE_ROW( aussiebyte_state::crtc_update_row ) +{ + rgb_t const *const palette = m_palette->palette()->entry_list_raw(); + u32 *p = &bitmap.pix(y); + ra &= 15; + m_cnt++; + + for (u16 x = 0; x < x_count; x++) + { + u16 mem = ma + x; + u8 attr = m_aram[mem & 0x7ff]; + u8 chr; + if (BIT(attr, 7)) + chr = m_vram[mem & 0x3fff]; // alpha + else + chr = m_vram[(mem << 4) | ra]; // gfx + + u8 gfx = crt8002(ra, chr, attr, m_cnt, (x==cursor_x)); + + /* Display a scanline of a character (8 pixels) */ + *p++ = palette[BIT(gfx, 7)]; + *p++ = palette[BIT(gfx, 6)]; + *p++ = palette[BIT(gfx, 5)]; + *p++ = palette[BIT(gfx, 4)]; + *p++ = palette[BIT(gfx, 3)]; + *p++ = palette[BIT(gfx, 2)]; + *p++ = palette[BIT(gfx, 1)]; + *p++ = palette[BIT(gfx, 0)]; + } +} diff --git a/src/mame/ausnz/binbug.cpp b/src/mame/ausnz/binbug.cpp new file mode 100644 index 00000000000..300af799dd4 --- /dev/null +++ b/src/mame/ausnz/binbug.cpp @@ -0,0 +1,294 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert +/*************************************************************************** + + BINBUG + + 2013-01-14 Driver created + + All input must be in uppercase. + + Commands: + A - See and alter memory + B - Set breakpoint (2 permitted) + C - Clear breakpoint + D - cassette save + G - Go to address, run + L - cassette load + S - See and alter registers + + BINBUG is an alternate bios to PIPBUG, however it uses its own + video output. Method of output is through a DG640 board. + + Keyboard input, like PIPBUG, is via a serial device. + The baud rate is 300, 8N1. + + The SENSE and FLAG lines are used for 300 baud cassette, in + conjunction with unknown hardware. + + There are 3 versions of BINBUG: + + - 3.6 300 baud tape routines, 300 baud keyboard, memory-mapped VDU + + - 4.4 300 baud keyboard, ACOS tape system, advanced video routines + + - 5.2 ACOS tape system, 1200 baud terminal + + + ToDo: + - Need dumps of 4.4 and 5.2. + +****************************************************************************/ + +#include "emu.h" +#include "bus/rs232/keyboard.h" +#include "cpu/s2650/s2650.h" +#include "imagedev/cassette.h" +#include "imagedev/snapquik.h" +#include "machine/clock.h" +#include "machine/timer.h" +#include "bus/s100/s100.h" +#include "bus/s100/dg640.h" +#include "speaker.h" + + +class binbug_state : public driver_device +{ +public: + binbug_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_cass(*this, "cassette") + , m_rs232(*this, "keyboard") + , m_clock(*this, "cass_clock") + , m_s100(*this, "s100") + { } + + void binbug(machine_config &config); + +private: + u8 mem_r(offs_t offset); + void mem_w(offs_t offset, u8 data); + DECLARE_WRITE_LINE_MEMBER(kansas_w); + DECLARE_READ_LINE_MEMBER(serial_r); + DECLARE_WRITE_LINE_MEMBER(serial_w); + DECLARE_QUICKLOAD_LOAD_MEMBER(quickload_cb); + TIMER_DEVICE_CALLBACK_MEMBER(kansas_r); + + u8 m_cass_data[4]{}; + bool m_cassold = 0, m_cassinbit = 0, m_cassoutbit = 0; + + void mem_map(address_map &map); + void machine_start() override; + + required_device m_maincpu; + required_device m_cass; + required_device m_rs232; + required_device m_clock; + required_device m_s100; +}; + +WRITE_LINE_MEMBER( binbug_state::kansas_w ) +{ + if ((m_cass->get_state() & CASSETTE_MASK_UISTATE) != CASSETTE_RECORD) + return; + + u8 twobit = m_cass_data[3] & 15; + + if (state) + { + if (twobit == 0) + m_cassold = m_cassoutbit; + + if (m_cassold) + m_cass->output(BIT(m_cass_data[3], 0) ? -1.0 : +1.0); // 2400Hz + else + m_cass->output(BIT(m_cass_data[3], 1) ? -1.0 : +1.0); // 1200Hz + + m_cass_data[3]++; + } +} + +TIMER_DEVICE_CALLBACK_MEMBER( binbug_state::kansas_r ) +{ + // no tape - set to idle + m_cass_data[1]++; + if (m_cass_data[1] > 32) + { + m_cass_data[1] = 32; + m_cassinbit = 1; + } + + if ((m_cass->get_state() & CASSETTE_MASK_UISTATE) != CASSETTE_PLAY) + return; + + /* cassette - turn 1200/2400Hz to a bit */ + u8 cass_ws = (m_cass->input() > +0.04) ? 1 : 0; + + if (cass_ws != m_cass_data[0]) + { + m_cass_data[0] = cass_ws; + m_cassinbit = (m_cass_data[1] < 12) ? 1 : 0; + m_cass_data[1] = 0; + } +} + +READ_LINE_MEMBER( binbug_state::serial_r ) +{ + return m_rs232->rxd_r() & m_cassinbit; +} + +WRITE_LINE_MEMBER( binbug_state::serial_w ) +{ + m_cassoutbit = state; +} + +u8 binbug_state::mem_r(offs_t offset) +{ + return m_s100->smemr_r(offset + 0x7800); +} + +void binbug_state::mem_w(offs_t offset, u8 data) +{ + m_s100->mwrt_w(offset + 0x7800, data); +} + +void binbug_state::machine_start() +{ + save_item(NAME(m_cass_data)); + save_item(NAME(m_cassold)); + save_item(NAME(m_cassinbit)); + save_item(NAME(m_cassoutbit)); +} + +void binbug_state::mem_map(address_map &map) +{ + map.unmap_value_high(); + map(0x0000, 0x03ff).rom(); + map(0x0400, 0x77ff).ram(); + map(0x7800, 0x7fff).rw(FUNC(binbug_state::mem_r),FUNC(binbug_state::mem_w)); +} + + +/* Input ports */ +static INPUT_PORTS_START( binbug ) +INPUT_PORTS_END + + +QUICKLOAD_LOAD_MEMBER(binbug_state::quickload_cb) +{ + address_space &space = m_maincpu->space(AS_PROGRAM); + int i; + int quick_addr = 0x440; + int exec_addr; + int quick_length; + std::vector quick_data; + int read_; + image_init_result result = image_init_result::FAIL; + + quick_length = image.length(); + if (quick_length < 0x0444) + { + image.seterror(image_error::INVALIDIMAGE, "File too short"); + image.message(" File too short"); + } + else if (quick_length > 0x8000) + { + image.seterror(image_error::INVALIDIMAGE, "File too long"); + image.message(" File too long"); + } + else + { + quick_data.resize(quick_length); + read_ = image.fread( &quick_data[0], quick_length); + if (read_ != quick_length) + { + image.seterror(image_error::INVALIDIMAGE, "Cannot read the file"); + image.message(" Cannot read the file"); + } + else if (quick_data[0] != 0xc4) + { + image.seterror(image_error::INVALIDIMAGE, "Invalid header"); + image.message(" Invalid header"); + } + else + { + exec_addr = quick_data[1] * 256 + quick_data[2]; + + if (exec_addr >= quick_length) + { + image.seterror(image_error::INVALIDIMAGE, "Exec address beyond end of file"); + image.message(" Exec address beyond end of file"); + } + else + { + for (i = quick_addr; i < read_; i++) + space.write_byte(i, quick_data[i]); + + /* display a message about the loaded quickload */ + image.message(" Quickload: size=%04X : exec=%04X",quick_length,exec_addr); + + // Start the quickload + m_maincpu->set_state_int(S2650_PC, exec_addr); + + result = image_init_result::PASS; + } + } + } + + return result; +} + +static DEVICE_INPUT_DEFAULTS_START( keyboard ) + DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_300 ) + DEVICE_INPUT_DEFAULTS( "RS232_DATABITS", 0xff, RS232_DATABITS_8 ) + DEVICE_INPUT_DEFAULTS( "RS232_PARITY", 0xff, RS232_PARITY_NONE ) + DEVICE_INPUT_DEFAULTS( "RS232_STOPBITS", 0xff, RS232_STOPBITS_1 ) +DEVICE_INPUT_DEFAULTS_END + +static void binbug_s100_devices(device_slot_interface &device) +{ + device.option_add("dg640", S100_DG640); +} + +void binbug_state::binbug(machine_config &config) +{ + SPEAKER(config, "mono").front_center(); + + /* Cassette */ + CASSETTE(config, m_cass); + m_cass->set_default_state(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED); + m_cass->add_route(ALL_OUTPUTS, "mono", 0.05); + TIMER(config, "kansas_r").configure_periodic(FUNC(binbug_state::kansas_r), attotime::from_hz(40000)); + + CLOCK(config, m_clock, 4'800); // 300 baud x 16(divider) = 4800 + m_clock->signal_handler().set(FUNC(binbug_state::kansas_w)); + + /* basic machine hardware */ + s2650_device &maincpu(S2650(config, m_maincpu, XTAL(1'000'000))); + maincpu.set_addrmap(AS_PROGRAM, &binbug_state::mem_map); + maincpu.sense_handler().set(FUNC(binbug_state::serial_r)); + maincpu.flag_handler().set(FUNC(binbug_state::serial_w)); + + /* Keyboard */ + RS232_PORT(config, m_rs232, default_rs232_devices, "keyboard").set_option_device_input_defaults("keyboard", DEVICE_INPUT_DEFAULTS_NAME(keyboard)); + + /* quickload */ + QUICKLOAD(config, "quickload", "pgm", attotime::from_seconds(1)).set_load_callback(FUNC(binbug_state::quickload_cb)); + + S100_BUS(config, m_s100, 0); + S100_SLOT(config, "s100:1", binbug_s100_devices, "dg640"); +} + + +/* ROM definition */ +ROM_START( binbug ) + ROM_REGION( 0x0400, "maincpu", ROMREGION_ERASEFF ) + ROM_LOAD( "binbug.rom", 0x0000, 0x0400, CRC(2cb1ac6e) SHA1(a969883fc767484d6b0fa103cfa4b4129b90441b) ) +ROM_END + +/* Driver */ + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1980, binbug, pipbug, 0, binbug, binbug, binbug_state, empty_init, "MicroByte", "BINBUG 3.6", MACHINE_SUPPORTS_SAVE ) + diff --git a/src/mame/ausnz/d6800.cpp b/src/mame/ausnz/d6800.cpp new file mode 100644 index 00000000000..a0981b8ad48 --- /dev/null +++ b/src/mame/ausnz/d6800.cpp @@ -0,0 +1,434 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert +/******************************************************************************** + + The Dream 6800 is a CHIP-8 computer roughly modelled on the Cosmac VIP. + It was described in Electronics Australia magazine in 4 articles starting + in May 1979. It has 1k of ROM and 1k of RAM. The video consists of 64x32 + pixels. The keyboard is a hexcode 4x4 matrix, plus a Function key. + + Designed by Michael Bauer, of the Division of Computing and Mathematics + at Deakin University, Australia. + + NOTE that the display only updates after each 4 digits is entered, and + you can't see what you type as you change bytes. This is by design. + + The cassette has no checksum, header or blocks. It is simply a stream + of pulses. The successful loading of a tape is therefore a matter of luck. + + To modify memory, press RST, then enter the 4-digit address (nothing happens + until the 4th digit is pressed), then press FN, then 0, then the 2 digit data. + It will enter the data (you won't see anything), then the address will increment. + Enter the data for this new address. If you want to skip this address, press FN. + When you're done, press RST. NOTE!!! Do NOT change any of these addresses: + 0000,0001,0006-007F, or the system may crash. It's recommended to start all + your programs at 0200. + + Function keys: + FN 0 - Modify memory - see above paragraph. + + FN 1 - Tape load. You must have entered the start address at 0002, and + the end address+1 at 0004 (big-endian). + + FN 2 - Tape save. You must have entered the start address at 0002, and + the end address+1 at 0004 (big-endian). + + FN 3 - Run. To use, press RST, then enter the 4-digit start address + (nothing happens until the 4th digit is pressed), then FN, then 3. + + All CHIP-8 programs load at 0200 (max size 4k), and exec address + is C000. + + Information and programs can be found at http://chip8.com/?page=78 + + Due to the way the keyboard is scanned, Natural Keyboard/Paste is not possible. + +**********************************************************************************/ + + +#include "emu.h" +#include "cpu/m6800/m6800.h" +#include "imagedev/cassette.h" +#include "imagedev/snapquik.h" +#include "machine/6821pia.h" +#include "machine/timer.h" +#include "sound/beep.h" +#include "emupal.h" +#include "screen.h" +#include "softlist_dev.h" +#include "speaker.h" + + +class d6800_state : public driver_device +{ +public: + d6800_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_cass(*this, "cassette") + , m_pia(*this, "pia") + , m_beeper(*this, "beeper") + , m_videoram(*this, "videoram") + , m_io_keyboard(*this, "X%u", 0U) + , m_io_shift(*this, "SHIFT") + { } + + + void d6800(machine_config &config); + + DECLARE_INPUT_CHANGED_MEMBER(reset_button); + +private: + uint8_t d6800_cassette_r(); + void d6800_cassette_w(uint8_t data); + uint8_t d6800_keyboard_r(); + void d6800_keyboard_w(uint8_t data); + DECLARE_WRITE_LINE_MEMBER( d6800_screen_w ); + uint32_t screen_update_d6800(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + INTERRUPT_GEN_MEMBER(rtc_interrupt); + TIMER_DEVICE_CALLBACK_MEMBER(kansas_w); + TIMER_DEVICE_CALLBACK_MEMBER(kansas_r); + DECLARE_QUICKLOAD_LOAD_MEMBER(quickload_cb); + + void d6800_map(address_map &map); + + bool m_cb2 = 0; + bool m_cassold = 0; + uint8_t m_cass_data[4]{}; + uint8_t m_portb = 0U; + virtual void machine_start() override; + virtual void machine_reset() override; + required_device m_maincpu; + required_device m_cass; + required_device m_pia; + required_device m_beeper; + required_shared_ptr m_videoram; + required_ioport_array<4> m_io_keyboard; + required_ioport m_io_shift; +}; + + +/* Memory Maps */ + +void d6800_state::d6800_map(address_map &map) +{ + map(0x0000, 0x00ff).ram(); + map(0x0100, 0x01ff).ram().share("videoram"); + map(0x0200, 0x17ff).ram(); + //map(0x1800, 0x1fff).rom().region("maincpu",0x800); // for dreamsoft_1, if we can find a good copy + map(0x8010, 0x8013).rw(m_pia, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); + map(0xc000, 0xc7ff).mirror(0x3800).rom().region("maincpu",0); +} + +/* Input Ports */ + +static INPUT_PORTS_START( d6800 ) + PORT_START("X0") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_NAME("0") // ee + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_NAME("1") // ed + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_UP) PORT_NAME("2") // eb + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_NAME("3") // e7 + PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("X1") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_LEFT) PORT_NAME("4") // de + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_NAME("5") // dd + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_RIGHT) PORT_NAME("6") // db + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_NAME("7") // d7 + PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("X2") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_DOWN) PORT_NAME("8") // be + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_NAME("9") // bd + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_NAME("A") // bb + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_NAME("B") // b7 + PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("X3") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_NAME("C") // 7e + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_NAME("D") // 7d + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_NAME("E") // 7b + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_NAME("F") // 77 + PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("SHIFT") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("FN") PORT_CODE(KEYCODE_LSHIFT) + + PORT_START("RESET") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RST") PORT_CODE(KEYCODE_LALT) PORT_CHANGED_MEMBER(DEVICE_SELF, d6800_state, reset_button, 0) + + PORT_START("VS") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_CUSTOM) PORT_VBLANK("screen") +INPUT_PORTS_END + +INPUT_CHANGED_MEMBER(d6800_state::reset_button) +{ + // RESET button wired to POR on the mc6875, which activates the Reset output pin which in turn connects to the CPU's Reset pin. + if (newval) + m_pia->reset(); + m_maincpu->set_input_line(INPUT_LINE_RESET, newval ? ASSERT_LINE : CLEAR_LINE); +} + +/* Video */ +uint32_t d6800_state::screen_update_d6800(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + uint8_t gfx=0; + + for (uint8_t y = 0; y < 32; y++) + { + uint16_t *p = &bitmap.pix(y); + + for (uint8_t x = 0; x < 8; x++) + { + if (m_cb2) + gfx = m_videoram[x | (y<<3)]; + + *p++ = BIT(gfx, 7); + *p++ = BIT(gfx, 6); + *p++ = BIT(gfx, 5); + *p++ = BIT(gfx, 4); + *p++ = BIT(gfx, 3); + *p++ = BIT(gfx, 2); + *p++ = BIT(gfx, 1); + *p++ = BIT(gfx, 0); + } + } + return 0; +} + +/* NE556 */ + +TIMER_DEVICE_CALLBACK_MEMBER(d6800_state::kansas_w) +{ + m_cass_data[3]++; + + if (BIT(m_portb, 0) != m_cassold) + { + m_cass_data[3] = 0; + m_cassold = BIT(m_portb, 0); + } + + if (BIT(m_portb, 0)) + m_cass->output(BIT(m_cass_data[3], 0) ? -1.0 : +1.0); // 2400Hz + else + m_cass->output(BIT(m_cass_data[3], 1) ? -1.0 : +1.0); // 1200Hz +} + +/* PIA6821 Interface */ + +TIMER_DEVICE_CALLBACK_MEMBER(d6800_state::kansas_r) +{ + uint8_t data = m_io_keyboard[0]->read() & m_io_keyboard[1]->read() & m_io_keyboard[2]->read() & m_io_keyboard[3]->read(); + int ca1 = (data == 255) ? 0 : 1; + int ca2 = m_io_shift->read(); + + m_pia->ca1_w(ca1); + m_pia->ca2_w(ca2); + + /* cassette - turn 1200/2400Hz to a bit */ + m_cass_data[1]++; + uint8_t cass_ws = (m_cass->input() > +0.03) ? 1 : 0; + + if (cass_ws != m_cass_data[0]) + { + m_cass_data[0] = cass_ws; + m_cass_data[2] = ((m_cass_data[1] < 12) ? 128 : 0); + m_cass_data[1] = 0; + } +} + + +WRITE_LINE_MEMBER( d6800_state::d6800_screen_w ) +{ + m_cb2 = state; + m_maincpu->set_unscaled_clock(state ? 589744 : 1e6); // effective clock is ~590kHz while screen is on +} + +uint8_t d6800_state::d6800_cassette_r() +{ + /* + Cassette circuit consists of a 741 op-amp, a 74121 oneshot, and a 74LS74. + When a pulse arrives, the oneshot is set. After a preset time, it triggers + and the 74LS74 compares this pulse to the output of the 741. Therefore it + knows if the tone is 1200 or 2400 Hz. Input to PIA is bit 7. + */ + + return m_cass_data[2] | m_portb; +} + +void d6800_state::d6800_cassette_w(uint8_t data) +{ + /* + A NE556 runs at either 1200 or 2400 Hz, depending on the state of bit 0. + This output drives the speaker and the output signal to the cassette player. + Bit 6 enables the speaker. Also the speaker is silenced when cassette operations + are in progress (DMA/CB2 line low). + */ + + m_beeper->set_clock(BIT(data, 0) ? 2400 : 1200); + m_beeper->set_state(BIT(data, 6) & (m_cb2 ? 1 : 0)); + + m_portb = data & 0x7f; +} + +uint8_t d6800_state::d6800_keyboard_r() +{ + /* + This system reads the key matrix one way, then swaps the input and output + lines around and reads it another way. This isolates the key that was pressed. + */ + + u8 y = 8; + for (u8 i = 0; i < 4; i++) + { + u8 data = m_io_keyboard[i]->read() & 15; + y <<= 1; + if (data < 15) + for (u8 j = 0; j < 4; j++) + if (!BIT(data, j)) + return data | (0xf0 - y); + } + + return 0xff; +} + +void d6800_state::d6800_keyboard_w(uint8_t data) +{ + /* + + bit description + + PA0 keyboard column 0 + PA1 keyboard column 1 + PA2 keyboard column 2 + PA3 keyboard column 3 + PA4 keyboard row 0 + PA5 keyboard row 1 + PA6 keyboard row 2 + PA7 keyboard row 3 + + */ + +} + +INTERRUPT_GEN_MEMBER(d6800_state::rtc_interrupt) +{ + m_pia->cb1_w(1); + m_pia->cb1_w(0); +} + +/* Machine Initialization */ + +void d6800_state::machine_start() +{ + save_item(NAME(m_cb2)); + save_item(NAME(m_cassold)); + save_item(NAME(m_cass_data)); + save_item(NAME(m_portb)); +} + +void d6800_state::machine_reset() +{ + m_beeper->set_state(0); + m_cass_data[0] = 0; + m_cass_data[1] = 0; + m_cass_data[2] = 128; + m_cass_data[3] = 0; +} + +/* Machine Drivers */ + +QUICKLOAD_LOAD_MEMBER(d6800_state::quickload_cb) +{ + address_space &space = m_maincpu->space(AS_PROGRAM); + u8 ch; + u16 quick_addr = 0x200; + u16 exec_addr = 0xc000; + u32 quick_length = image.length(); + if (quick_length > 0xe00) + { + image.seterror(image_error::INVALIDIMAGE, "File exceeds 3584 bytes"); + image.message(" File exceeds 3584 bytes"); + return image_init_result::FAIL; + } + + for (u32 i = 0; i < quick_length; i++) + { + image.fread(&ch, 1); + space.write_byte(i + quick_addr, ch); + } + + if (image.is_filetype("bin")) + exec_addr = quick_addr; + + /* display a message about the loaded quickload */ + image.message(" Quickload: size=%04X : start=%04X : end=%04X : exec=%04X",quick_length,quick_addr,quick_addr+quick_length,exec_addr); + + // Start the quickload + m_maincpu->set_pc(exec_addr); + + return image_init_result::PASS; +} + +void d6800_state::d6800(machine_config &config) +{ + /* basic machine hardware */ + M6800(config, m_maincpu, XTAL(4'000'000)/4); + m_maincpu->set_addrmap(AS_PROGRAM, &d6800_state::d6800_map); + m_maincpu->set_vblank_int("screen", FUNC(d6800_state::rtc_interrupt)); + + /* video hardware */ + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); + screen.set_refresh_hz(50); + screen.set_size(64, 32); + screen.set_visarea_full(); + screen.set_screen_update(FUNC(d6800_state::screen_update_d6800)); + screen.set_vblank_time(ATTOSECONDS_IN_USEC(300)); // verified + screen.set_palette("palette"); + + PALETTE(config, "palette", palette_device::MONOCHROME); + + /* sound hardware */ + SPEAKER(config, "mono").front_center(); + BEEP(config, "beeper", 1200).add_route(ALL_OUTPUTS, "mono", 0.50); + + /* devices */ + PIA6821(config, m_pia, 0); + m_pia->readpa_handler().set(FUNC(d6800_state::d6800_keyboard_r)); + m_pia->readpb_handler().set(FUNC(d6800_state::d6800_cassette_r)); + m_pia->writepa_handler().set(FUNC(d6800_state::d6800_keyboard_w)); + m_pia->writepb_handler().set(FUNC(d6800_state::d6800_cassette_w)); + m_pia->cb2_handler().set(FUNC(d6800_state::d6800_screen_w)); + m_pia->irqa_handler().set_inputline("maincpu", M6800_IRQ_LINE); + m_pia->irqb_handler().set_inputline("maincpu", M6800_IRQ_LINE); + + CASSETTE(config, m_cass); + m_cass->set_default_state(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED); + m_cass->add_route(ALL_OUTPUTS, "mono", 0.05); + + TIMER(config, "kansas_w").configure_periodic(FUNC(d6800_state::kansas_w), attotime::from_hz(4800)); + TIMER(config, "kansas_r").configure_periodic(FUNC(d6800_state::kansas_r), attotime::from_hz(40000)); + + /* quickload */ + quickload_image_device &quickload(QUICKLOAD(config, "quickload", "bin,c8", attotime::from_seconds(2))); + quickload.set_load_callback(FUNC(d6800_state::quickload_cb)); + quickload.set_interface("chip8quik"); + SOFTWARE_LIST(config, "quik_list").set_original("chip8_quik").set_filter("D"); +} + +/* ROMs */ + +ROM_START( d6800 ) + ROM_REGION( 0x1000, "maincpu", ROMREGION_ERASEFF ) + ROM_SYSTEM_BIOS(0, "0", "Original") // "chipos" + ROMX_LOAD( "d6800.bin", 0x0000, 0x0400, CRC(3f97ca2e) SHA1(60f26e57a058262b30befceceab4363a5d65d877), ROM_BIOS(0) ) + ROM_RELOAD( 0x0400, 0x0400 ) + //ROMX_LOAD( "d6800d1.bin", 0x0800, 0x0800, BAD_DUMP CRC(e552cae3) SHA1(0b90504922d46b9c46278924768c45b1b276709f), ROM_BIOS(0) ) // need a good dump, this one is broken + ROM_SYSTEM_BIOS(1, "d2", "Dreamsoft2") + ROMX_LOAD( "d6800d2.bin", 0x0000, 0x0800, CRC(ded5712f) SHA1(f594f313a74d7135c9fdd0bcb0093fc5771a9b7d), ROM_BIOS(1) ) + ROM_SYSTEM_BIOS(2, "d2m", "Dreamsoft2m") + ROMX_LOAD( "d6800d2m.bin", 0x0000, 0x0800, CRC(eec8e56f) SHA1(f587ccbc0872f2982d61120d033f481a862b902b), ROM_BIOS(2) ) +ROM_END + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1979, d6800, 0, 0, d6800, d6800, d6800_state, empty_init, "Michael Bauer", "Dream 6800", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/ausnz/datum.cpp b/src/mame/ausnz/datum.cpp new file mode 100644 index 00000000000..e8763504aca --- /dev/null +++ b/src/mame/ausnz/datum.cpp @@ -0,0 +1,233 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert +/********************************************************************************************** + +Gammatron Datum (1982) + +2016-10-28. + +Described in Electronics Australia magazine in 1982/1983. + +- The ROM was keyed in by hand from a printout, so is therefore considered a bad dump. +- It has routines for adc, dac, cassette, but there's no hardware to support these. +- The basic machine is fully emulated as per the schematic. + +Memory Map: +0000-007F = RAM inside the cpu +1000-13FF = RAM (2x 2114) +3E00-3E01 = ADC (in monitor as EQU but not further referenced) not in schematic +3F00-3F01 = 10-bit DAC (supported in monitor with routines for the user) not in schematic +4000-4001 = ACIA (in monitor for cassette usage, but schematic shows it for rs232) + Schematic has no provision of baud clocks +5000-5003 = PIA2 for expansion, monitor does not use it at all. +6000-6003 = PIA1 for keyboard and display +7000-77FF = ROM + +Note about the acia6850: The monitor sends it a master reset, then ignores it thereafter. + None of the pins are connected to anything - including the clocks. + It's up to the owner to write a TTY interface, and wire it up. + +Sample program to paste in: Pick-up-sticks (Nim) All inputs are in HEX. +1. Paste this in +2. Enter number of sticks to begin with (2 digits) +3. Enter max number of sticks to be removed per turn (1 digit) +4. Your turn - remove some sticks +5. After a pause, player's turn. +6. Keep doing steps 4 and 5 till you lose (it says 10b3 3F) +7. When tested, the game seems buggy - prepare to lose sooner than expected + +1000M +BD^71^07^CE^00^10^86^7E^A7^01^A7^05^BD^71^5E^B7^12^00^BD^72^7D^97^10^BD^71^5E^ +B7^12^01^BD^72^7D^97^11^CE^12^00^BD^72^4D^B7^12^00^BD^71^5E^B7^12^02^BD^72^7D^ +97^15^BD^71^5E^B7^12^03^27^08^7C^12^02^B1^12^02^2B^18^CE^00^10^86^06^97^12^ +86^15^97^13^8D^61^CE^00^10^86^7F^A7^02^A7^03^20^D8^B6^12^00^B0^12^03^B7^12^00^ +BD^72^6E^D7^10^97^11^8D^44^B6^12^00^4A^27^3C^7F^12^05^7C^12^02^7C^12^05^ +B0^12^02^2E^F8^7A^12^05^5F^FB^12^02^7A^12^05^26^F8^B6^12^00^10^16^5A^ +26^02^C6^01^B6^12^00^10^B7^12^00^BD^72^6E^D7^10^97^11^B6^12^00^81^01^27^04^ +7E^10^36^3F^3F^86^80^B7^12^04^BD^71^DD^7A^12^04^26^F8^39^ +Z1000G + + +*******************************************************************************************/ + +#include "emu.h" +#include "cpu/m6800/m6800.h" +#include "machine/6821pia.h" +#include "machine/6850acia.h" +#include "bus/rs232/rs232.h" +#include "video/pwm.h" +#include "datum.lh" + + +class datum_state : public driver_device +{ +public: + datum_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_pia1(*this, "pia1") + , m_pia2(*this, "pia2") + , m_acia(*this, "acia") + , m_maincpu(*this, "maincpu") + , m_display(*this, "display") + , m_io_keyboard(*this, "X%u", 0U) + { } + + void datum(machine_config &config); + DECLARE_INPUT_CHANGED_MEMBER(trigger_reset); + DECLARE_INPUT_CHANGED_MEMBER(trigger_nmi); + +private: + uint8_t pa_r(); + void pa_w(uint8_t data); + void pb_w(uint8_t data); + void datum_mem(address_map &map); + uint8_t m_digit = 0U; + uint8_t m_seg = 0U; + virtual void machine_start() override; + virtual void machine_reset() override; + required_device m_pia1; + required_device m_pia2; + required_device m_acia; + required_device m_maincpu; + required_device m_display; + required_ioport_array<4> m_io_keyboard; +}; + + +void datum_state::datum_mem(address_map &map) +{ + map.unmap_value_high(); + map(0x1000, 0x13ff).mirror(0x8c00).ram(); // main ram 2x 2114 + map(0x4000, 0x4001).mirror(0x8ffe).rw(m_acia, FUNC(acia6850_device::read), FUNC(acia6850_device::write)); + map(0x5000, 0x5003).mirror(0x8ffc).rw(m_pia2, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); + map(0x6000, 0x6003).mirror(0x8ffc).rw(m_pia1, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); + map(0x7000, 0x77ff).mirror(0x8800).rom().region("roms", 0); +} + + +/* Input ports */ +static INPUT_PORTS_START( datum ) + PORT_START("X0") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('E') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('F') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("2F") PORT_CODE(KEYCODE_S) PORT_CHAR('S') // "Second Function" i.e Shift-lock + PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("X1") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("M/R") PORT_CODE(KEYCODE_M) PORT_CHAR('M') // "Memory / Registers" + PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("X2") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("I/D") PORT_CODE(KEYCODE_UP) PORT_CHAR('^') // "Increment / Decrement" + PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("X3") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("G/S") PORT_CODE(KEYCODE_G) PORT_CHAR('G') // "Goto / Single-step" + PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("SPECIAL") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Reset") PORT_CODE(KEYCODE_F3) PORT_CHANGED_MEMBER(DEVICE_SELF, datum_state, trigger_reset, 0) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Escape") PORT_CODE(KEYCODE_ESC) PORT_CHAR('Z') PORT_CHANGED_MEMBER(DEVICE_SELF, datum_state, trigger_nmi, 0) +INPUT_PORTS_END + +INPUT_CHANGED_MEMBER( datum_state::trigger_reset ) +{ + m_maincpu->set_input_line(INPUT_LINE_RESET, newval ? CLEAR_LINE : ASSERT_LINE); +} + +INPUT_CHANGED_MEMBER( datum_state::trigger_nmi ) +{ + m_maincpu->set_input_line(INPUT_LINE_NMI, newval ? CLEAR_LINE : ASSERT_LINE); +} + + +void datum_state::machine_start() +{ + save_item(NAME(m_digit)); + save_item(NAME(m_seg)); +} + +void datum_state::machine_reset() +{ + m_digit = 0; + m_seg = 0; +} + +// read keyboard +uint8_t datum_state::pa_r() +{ + if (m_digit < 4) + return m_io_keyboard[m_digit]->read(); + + return 0xff; +} + +// write display segments +void datum_state::pa_w(uint8_t data) +{ + m_seg = bitswap<8>(~data, 7, 0, 5, 6, 4, 2, 1, 3); + m_display->matrix(1<(data, 7, 6, 5, 4, 0, 1, 2, 3) & 15; + m_display->matrix(1<set_addrmap(AS_PROGRAM, &datum_state::datum_mem); + + /* video hardware */ + config.set_default_layout(layout_datum); + PWM_DISPLAY(config, m_display).set_size(10, 7); + m_display->set_segmask(0x3f0, 0x7f); + + /* Devices */ + PIA6821(config, m_pia1, 0); // keyboard & display + m_pia1->readpa_handler().set(FUNC(datum_state::pa_r)); + m_pia1->writepa_handler().set(FUNC(datum_state::pa_w)); + m_pia1->writepb_handler().set(FUNC(datum_state::pb_w)); + m_pia1->irqa_handler().set_inputline("maincpu", M6802_IRQ_LINE); + m_pia1->irqb_handler().set_inputline("maincpu", M6802_IRQ_LINE); + + PIA6821(config, m_pia2, 0); // expansion + m_pia2->irqa_handler().set_inputline("maincpu", M6802_IRQ_LINE); + m_pia2->irqb_handler().set_inputline("maincpu", M6802_IRQ_LINE); + + ACIA6850(config, m_acia, 0); // rs232 + m_acia->txd_handler().set("rs232", FUNC(rs232_port_device::write_txd)); + m_acia->rts_handler().set("rs232", FUNC(rs232_port_device::write_rts)); + rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, nullptr)); + rs232.rxd_handler().set(m_acia, FUNC(acia6850_device::write_rxd)); + rs232.cts_handler().set(m_acia, FUNC(acia6850_device::write_cts)); +} + + +/* ROM definition */ +ROM_START( datum ) + ROM_REGION( 0x800, "roms", 0 ) + ROM_LOAD( "datum.bin", 0x0000, 0x0800, BAD_DUMP CRC(6fb11628) SHA1(8a77a846b62eee0d12848da76e16b4c66ef445d8) ) +ROM_END + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1982, datum, 0, 0, datum, datum, datum_state, empty_init, "Gammatron", "Datum", MACHINE_NO_SOUND_HW | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/ausnz/dg680.cpp b/src/mame/ausnz/dg680.cpp new file mode 100644 index 00000000000..ccb6b441e00 --- /dev/null +++ b/src/mame/ausnz/dg680.cpp @@ -0,0 +1,337 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert +/*************************************************************************** + +DG680 + +2013-01-14 Driver created + +All input must be in uppercase. + +DG680 (ETI-680), using the DGOS-Z80 operating system. + +This is a S100 card. + +In some ways, this system is the ancestor of the original Microbee. + +No schematic available, most of this is guesswork. + +Port 0 is the input from an ascii keyboard. + +Port 2 is the cassette interface. + +Port 8 controls some kind of memory protection scheme. +The code indicates that B is the page to protect, and +A is the code (0x08 = inhibit; 0x0B = unprotect; +0x0C = enable; 0x0E = protect). There are 256 pages so +each page is 256 bytes. + +The clock is controlled by the byte in D80D. + +Monitor Commands: +C (compare)* +E (edit)* +F (fill)* +G - Go to address +I - Inhibit CTC +M (move)* +P (clear screen)* +R (read tape)* +S (search)* +T hhmm [ss] - Set the time +W (write tape)* +X - protection status +XC - clear ram +XD - same as X +XE - enable facilities +XF - disable facilities +XP - protect block +XU - unprotect block +Z - go to 0000. + +* These commands are identical to the Microbee ones. + +ToDo: +- dips +- leds +- need schematic to find out what else is missing + +****************************************************************************/ + +#include "emu.h" +#include "machine/keyboard.h" +#include "machine/z80daisy.h" +#include "cpu/z80/z80.h" +#include "imagedev/cassette.h" +#include "machine/clock.h" +#include "machine/timer.h" +#include "machine/z80ctc.h" +#include "machine/z80pio.h" +#include "bus/s100/s100.h" +#include "bus/s100/dg640.h" +#include "speaker.h" + + +class dg680_state : public driver_device +{ +public: + dg680_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_cass(*this, "cassette") + , m_pio(*this, "pio") + , m_ctc(*this, "ctc") + , m_clock(*this, "cass_clock") + , m_s100(*this, "s100") + { } + + void dg680(machine_config &config); + +private: + u8 porta_r(); + u8 portb_r(); + void portb_w(u8 data); + u8 port08_r(); + void port08_w(u8 data); + u8 mem_r(offs_t offset); + void mem_w(offs_t offset, u8 data); + DECLARE_WRITE_LINE_MEMBER(kansas_w); + TIMER_DEVICE_CALLBACK_MEMBER(kansas_r); + void kbd_put(u8 data); + + void io_map(address_map &map); + void mem_map(address_map &map); + void machine_reset() override; + void machine_start() override; + + u8 m_pio_b = 0U; + u8 m_term_data = 0U; + u8 m_protection[0x100]{}; + u8 m_cass_data[4]{}; + bool m_cassold = 0, m_cassinbit = 0, m_cassoutbit = 0; + + required_device m_maincpu; + required_device m_cass; + required_device m_pio; + required_device m_ctc; + required_device m_clock; + required_device m_s100; +}; + +WRITE_LINE_MEMBER( dg680_state::kansas_w ) +{ + if ((m_cass->get_state() & CASSETTE_MASK_UISTATE) != CASSETTE_RECORD) + return; + + u8 twobit = m_cass_data[3] & 15; + + if (state) + { + if (twobit == 0) + m_cassold = m_cassoutbit; + + if (m_cassold) + m_cass->output(BIT(m_cass_data[3], 0) ? -1.0 : +1.0); // 2400Hz + else + m_cass->output(BIT(m_cass_data[3], 1) ? -1.0 : +1.0); // 1200Hz + + m_cass_data[3]++; + } +} + +TIMER_DEVICE_CALLBACK_MEMBER( dg680_state::kansas_r ) +{ + // no tape - set to idle + m_cass_data[1]++; + if (m_cass_data[1] > 32) + { + m_cass_data[1] = 32; + m_cassinbit = 1; + } + + if ((m_cass->get_state() & CASSETTE_MASK_UISTATE) != CASSETTE_PLAY) + return; + + /* cassette - turn 1200/2400Hz to a bit */ + u8 cass_ws = (m_cass->input() > +0.04) ? 1 : 0; + + if (cass_ws != m_cass_data[0]) + { + m_cass_data[0] = cass_ws; + m_cassinbit = (m_cass_data[1] < 12) ? 1 : 0; + m_cass_data[1] = 0; + m_pio->pb0_w(m_cassinbit); + } +} + +u8 dg680_state::mem_r(offs_t offset) +{ + return m_s100->smemr_r(offset + 0xf000); +} + +void dg680_state::mem_w(offs_t offset, u8 data) +{ + m_s100->mwrt_w(offset + 0xf000, data); +} + + +void dg680_state::mem_map(address_map &map) +{ + map.unmap_value_high(); + map(0x0000, 0xcfff).ram(); + map(0xd000, 0xd7ff).rom().region("maincpu", 0); + map(0xd800, 0xefff).ram(); + map(0xf000, 0xffff).rw(FUNC(dg680_state::mem_r),FUNC(dg680_state::mem_w)); +} + +void dg680_state::io_map(address_map &map) +{ + map.unmap_value_high(); + map.global_mask(0xff); + map(0x00, 0x03).rw(m_pio, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt)); + map(0x04, 0x07).rw(m_ctc, FUNC(z80ctc_device::read), FUNC(z80ctc_device::write)); + map(0x08, 0x08).rw(FUNC(dg680_state::port08_r), FUNC(dg680_state::port08_w)); //SWP Control and Status + //map(0x09,0x09) parallel input port + // Optional AM9519 Programmable Interrupt Controller (port c = data, port d = control) + //map(0x0c,0x0d).rw("am9519", FUNC(am9519_device::read), FUNC(am9519_device::write)); +} + +void dg680_state::machine_start() +{ + save_item(NAME(m_pio_b)); + save_item(NAME(m_term_data)); + save_item(NAME(m_protection)); + save_item(NAME(m_cass_data)); + save_item(NAME(m_cassold)); + save_item(NAME(m_cassinbit)); + save_item(NAME(m_cassoutbit)); +} + +void dg680_state::machine_reset() +{ + m_maincpu->set_pc(0xd000); + m_pio_b = 0xFF; +} + +// this is a guess there is no information available +static const z80_daisy_config dg680_daisy_chain[] = +{ + { "ctc" }, + { "pio" }, + { 0x00 } +}; + + +/* Input ports */ +static INPUT_PORTS_START( dg680 ) +INPUT_PORTS_END + +void dg680_state::kbd_put(u8 data) +{ + if (data == 8) + data = 127; // fix backspace + m_term_data = data; + /* strobe in keyboard data */ + m_pio->strobe_a(0); + m_pio->strobe_a(1); +} + +u8 dg680_state::porta_r() +{ + u8 data = m_term_data; + m_term_data = 0; + return data; +} + +u8 dg680_state::portb_r() +{ + return m_pio_b | m_cassinbit; +} + +// bit 1 = cassout; bit 2 = motor on +void dg680_state::portb_w(u8 data) +{ + if (BIT(m_pio_b ^ data, 2)) + m_cass->change_state(BIT(data, 2) ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR); + m_pio_b = data & 0xfe; + m_cassoutbit = BIT(data, 1); +} + +u8 dg680_state::port08_r() +{ + u8 breg = m_maincpu->state_int(Z80_B); + return m_protection[breg]; +} + +void dg680_state::port08_w(u8 data) +{ + u8 breg = m_maincpu->state_int(Z80_B); + m_protection[breg] = data; +} + + +static void dg680_s100_devices(device_slot_interface &device) +{ + device.option_add("dg640", S100_DG640); +} + +DEVICE_INPUT_DEFAULTS_START(dg680_dg640_f000) + DEVICE_INPUT_DEFAULTS("DSW", 0x1f, 0x1e) // F000-F7FF +DEVICE_INPUT_DEFAULTS_END + +void dg680_state::dg680(machine_config &config) +{ + SPEAKER(config, "mono").front_center(); + + /* Cassette */ + CASSETTE(config, m_cass); + m_cass->set_default_state(CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED); + m_cass->add_route(ALL_OUTPUTS, "mono", 0.05); + TIMER(config, "kansas_r").configure_periodic(FUNC(dg680_state::kansas_r), attotime::from_hz(40000)); + + CLOCK(config, m_clock, 4'800); // 300 baud x 16(divider) = 4800 + m_clock->signal_handler().set(FUNC(dg680_state::kansas_w)); + m_clock->signal_handler().append(m_ctc, FUNC(z80ctc_device::trg2)); + m_clock->signal_handler().append(m_ctc, FUNC(z80ctc_device::trg3)); + + /* basic machine hardware */ + z80_device& maincpu(Z80(config, m_maincpu, XTAL(8'000'000) / 4)); + maincpu.set_addrmap(AS_PROGRAM, &dg680_state::mem_map); + maincpu.set_addrmap(AS_IO, &dg680_state::io_map); + maincpu.set_daisy_config(dg680_daisy_chain); + + /* Keyboard */ + generic_keyboard_device &keyb(GENERIC_KEYBOARD(config, "keyb", 0)); + keyb.set_keyboard_callback(FUNC(dg680_state::kbd_put)); + + /* Devices */ + Z80CTC(config, m_ctc, XTAL(8'000'000) / 4); + m_ctc->intr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); + m_ctc->set_clk<0>(200); + m_ctc->zc_callback<0>().set(m_ctc, FUNC(z80ctc_device::trg1)); + + Z80PIO(config, m_pio, XTAL(8'000'000) / 4); + m_pio->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); + m_pio->in_pa_callback().set(FUNC(dg680_state::porta_r)); + // OUT_ARDY - this activates to ask for kbd data but not known if actually used + m_pio->in_pb_callback().set(FUNC(dg680_state::portb_r)); + m_pio->out_pb_callback().set(FUNC(dg680_state::portb_w)); + + S100_BUS(config, m_s100, 1_MHz_XTAL); + S100_SLOT(config, "s100:1", dg680_s100_devices, "dg640") + .set_option_device_input_defaults("dg640", DEVICE_INPUT_DEFAULTS_NAME(dg680_dg640_f000)); +} + +/* ROM definition */ +ROM_START( dg680 ) + ROM_REGION( 0x0800, "maincpu", 0 ) + ROM_LOAD( "dg680.rom", 0x0000, 0x0800, BAD_DUMP CRC(c1aaef6a) SHA1(1508ca8315452edfb984718e795ccbe79a0c0b58) ) + + ROM_REGION( 0x0020, "proms", 0 ) + ROM_LOAD( "82s123.bin", 0x0000, 0x0020, NO_DUMP ) +ROM_END + +/* Driver */ + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1980, dg680, 0, 0, dg680, dg680, dg680_state, empty_init, "David Griffiths", "DG680 with DGOS-Z80 1.4", MACHINE_NO_SOUND_HW | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/ausnz/dmax8000.cpp b/src/mame/ausnz/dmax8000.cpp new file mode 100644 index 00000000000..d63b2224d45 --- /dev/null +++ b/src/mame/ausnz/dmax8000.cpp @@ -0,0 +1,211 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert +/****************************************************************************************************************** + +Datamax 8000 + +2016-07-24 Skeleton driver + +This computer was designed and made by Datamax Pty Ltd, in Manly, Sydney, Australia. + +It could have up to 4x 8 inch floppy drives, in the IBM format. +There were a bunch of optional extras such as 256kB RAM, numeric coprocessor, RTC, etc. + + +ToDo: +- Parallel port +- Centronics port +- AUX serial port +- FDC/FDD/HD setup - no schematics available of this section, so guessing... + +What there is of the schematic shows no sign of a daisy chain or associated interrupts. + + +****************************************************************************************************************/ + +#include "emu.h" +#include "cpu/z80/z80.h" +#include "imagedev/floppy.h" +#include "machine/wd_fdc.h" +#include "machine/z80daisy.h" +#include "machine/z80pio.h" +#include "machine/z80sio.h" +#include "machine/z80ctc.h" +#include "machine/mm58174.h" +#include "bus/rs232/rs232.h" + +namespace { + +class dmax8000_state : public driver_device +{ +public: + dmax8000_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_rom(*this, "maincpu") + , m_ram(*this, "mainram") + , m_bank1(*this, "bank1") + , m_fdc(*this, "fdc") + , m_floppy0(*this, "fdc:0") + { } + + void dmax8000(machine_config &config); + +private: + void machine_reset() override; + void machine_start() override; + void port0c_w(u8 data); + void port0d_w(u8 data); + void port14_w(u8 data); + void port40_w(u8 data); + DECLARE_WRITE_LINE_MEMBER(fdc_drq_w); + + void io_map(address_map &map); + void mem_map(address_map &map); + + required_device m_maincpu; + required_region_ptr m_rom; + required_shared_ptr m_ram; + required_memory_bank m_bank1; + required_device m_fdc; + required_device m_floppy0; +}; + + +WRITE_LINE_MEMBER( dmax8000_state::fdc_drq_w ) +{ + if (state) printf("DRQ "); +} + +void dmax8000_state::port0c_w(u8 data) +{ + printf("Port0c=%X\n", data); + m_fdc->dden_w(BIT(data, 6)); + floppy_image_device *floppy = nullptr; + if (BIT(data, 0)) floppy = m_floppy0->get_device(); + m_fdc->set_floppy(floppy); + if (floppy) + { + floppy->mon_w(0); + floppy->ss_w(0); // no idea + } +} + +void dmax8000_state::port0d_w(u8 data) +{ + printf("Port0d=%X\n", data); +} + +void dmax8000_state::port14_w(u8 data) +{ + printf("Port14=%X\n", data); +} + +void dmax8000_state::port40_w(u8 data) +{ + m_bank1->set_entry(BIT(~data, 0)); +} + +void dmax8000_state::mem_map(address_map &map) +{ + map(0x0000, 0xffff).ram().share("mainram"); + map(0x0000, 0x0fff).bankr("bank1"); +} + +void dmax8000_state::io_map(address_map &map) +{ + map.global_mask(0xff); + map.unmap_value_high(); + map(0x00, 0x03).rw(m_fdc, FUNC(fd1793_device::read), FUNC(fd1793_device::write)); + map(0x04, 0x07).rw("dart1", FUNC(z80dart_device::ba_cd_r), FUNC(z80dart_device::ba_cd_w)); + map(0x08, 0x0b).rw("ctc", FUNC(z80ctc_device::read), FUNC(z80ctc_device::write)); + map(0x0c, 0x0f).rw("pio1", FUNC(z80pio_device::read), FUNC(z80pio_device::write)); // fdd controls + map(0x10, 0x13).rw("pio2", FUNC(z80pio_device::read), FUNC(z80pio_device::write)); // centronics & parallel ports + map(0x14, 0x17).w(FUNC(dmax8000_state::port14_w)); // control lines for the centronics & parallel ports + //map(0x18, 0x19).mirror(2).rw("am9511", FUNC(am9512_device::read), FUNC(am9512_device::write)); // optional numeric coprocessor + //map(0x1c, 0x1d).mirror(2); // optional hard disk controller (1C=status, 1D=data) + map(0x20, 0x23).rw("dart2", FUNC(z80dart_device::ba_cd_r), FUNC(z80dart_device::ba_cd_w)); + map(0x40, 0x40).w(FUNC(dmax8000_state::port40_w)); // memory bank control + //map(0x60, 0x67) // optional IEEE488 GPIB + map(0x70, 0x7f).rw("rtc", FUNC(mm58174_device::read), FUNC(mm58174_device::write)); // optional RTC +} + +/* Input ports */ +static INPUT_PORTS_START( dmax8000 ) +INPUT_PORTS_END + +void dmax8000_state::machine_reset() +{ + m_bank1->set_entry(1); + m_maincpu->set_input_line_vector(0, 0xee); // Z80 - fdc vector +} + +void dmax8000_state::machine_start() +{ + m_bank1->configure_entry(0, m_ram); + m_bank1->configure_entry(1, m_rom); +} + +static void floppies(device_slot_interface &device) +{ + device.option_add("8dsdd", FLOPPY_8_DSDD); +} + + +void dmax8000_state::dmax8000(machine_config &config) +{ + /* basic machine hardware */ + Z80(config, m_maincpu, 4'000'000); // no idea what crystal is used, but 4MHz clock is confirmed + m_maincpu->set_addrmap(AS_PROGRAM, &dmax8000_state::mem_map); + m_maincpu->set_addrmap(AS_IO, &dmax8000_state::io_map); + + z80ctc_device &ctc(Z80CTC(config, "ctc", 4_MHz_XTAL)); + ctc.set_clk<0>(4_MHz_XTAL / 2); // 2MHz + ctc.zc_callback<0>().set("dart1", FUNC(z80dart_device::rxca_w)); + ctc.zc_callback<0>().append("dart1", FUNC(z80dart_device::txca_w)); + ctc.zc_callback<0>().append("dart2", FUNC(z80dart_device::rxca_w)); + ctc.zc_callback<0>().append("dart2", FUNC(z80dart_device::txca_w)); + ctc.set_clk<1>(4_MHz_XTAL / 2); // 2MHz + ctc.zc_callback<1>().set("dart2", FUNC(z80dart_device::rxtxcb_w)); + ctc.set_clk<2>(4_MHz_XTAL / 2); // 2MHz + ctc.zc_callback<2>().set("dart1", FUNC(z80dart_device::rxtxcb_w)); + + z80dart_device& dart1(Z80DART(config, "dart1", 4'000'000)); // A = terminal; B = aux + dart1.out_txda_callback().set("rs232", FUNC(rs232_port_device::write_txd)); + dart1.out_dtra_callback().set("rs232", FUNC(rs232_port_device::write_dtr)); + dart1.out_rtsa_callback().set("rs232", FUNC(rs232_port_device::write_rts)); + + rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, "terminal")); + rs232.rxd_handler().set("dart1", FUNC(z80dart_device::rxa_w)); + rs232.dcd_handler().set("dart1", FUNC(z80dart_device::dcda_w)); + rs232.ri_handler().set("dart1", FUNC(z80dart_device::ria_w)); + rs232.cts_handler().set("dart1", FUNC(z80dart_device::ctsa_w)); + + Z80DART(config, "dart2", 4'000'000); // RS232 ports + + z80pio_device& pio1(Z80PIO(config, "pio1", 4'000'000)); + pio1.out_pa_callback().set(FUNC(dmax8000_state::port0c_w)); + pio1.out_pb_callback().set(FUNC(dmax8000_state::port0d_w)); + + Z80PIO(config, "pio2", 4'000'000); + + FD1793(config, m_fdc, 2'000'000); // no idea + m_fdc->intrq_wr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); + m_fdc->drq_wr_callback().set(FUNC(dmax8000_state::fdc_drq_w)); + FLOPPY_CONNECTOR(config, "fdc:0", floppies, "8dsdd", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); + + MM58174(config, "rtc", 0); +} + + +/* ROM definition */ +ROM_START( dmax8000 ) + ROM_REGION( 0x1000, "maincpu", 0 ) + ROM_LOAD( "rev1_0.rom", 0x0000, 0x001000, CRC(acbec83f) SHA1(fce0a4307a791250dbdc6bb6a190f7fec3619d82) ) + // ROM_LOAD( "rev1_1.rom", 0x0000, 0x001000, CRC(2eb98a61) SHA1(cdd9a58f63ee7e3d3dd1c4ae3fd4376b308fd10f) ) // this is a hacked rom to speed up the serial port +ROM_END + +} // Anonymous namespace + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1981, dmax8000, 0, 0, dmax8000, dmax8000, dmax8000_state, empty_init, "Datamax", "Datamax 8000", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/ausnz/eacc.cpp b/src/mame/ausnz/eacc.cpp new file mode 100644 index 00000000000..57102dac044 --- /dev/null +++ b/src/mame/ausnz/eacc.cpp @@ -0,0 +1,302 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert +/****************************************************************************** +* +* EA Car Computer +* by Robbbert, March 2011. +* +* Described in Electronics Australia magazine during 1982. +* Construction and usage: http://messui.polygonal-moogle.com/comp/eacc.pdf +* +* The only RAM is the 128 bytes that comes inside the CPU. +* +* This computer is mounted in a car, and various sensors (fuel flow, etc) +* are connected up. By pressing the appropriate buttons various statistics +* may be obtained. +* +* Memory Map +* 0000-007F internal ram +* 4000-7FFF ROM +* 8000-BFFF 6821 +* C000-FFFF ROM (mirror) +* +* The ROM was typed in twice from the dump in the magazine article, and the +* results compared. Only one byte was different, so I can be confident that +* it has been typed in properly. +* +* Setting up: You need to enter the number of expected pulses from the fuel +* and distance sensors. Paste this: 5 6M123N 7M400N (start, set litres cal to +* 123 pulses. set km cal to 400 pulses). Then paste this: 1950M0N 1845M0N (set +* petrol tank capacity to 50 litres, set current amount of petrol to 45). +* Now enter: 28M100N (the journey is 100km). Press 5 to start the journey. +* All settings are saved in nvram. +* +* Stats you can see while travelling: +* 0 - time elapsed +* 08 - time remaining +* 1 - fuel used +* 18 - fuel left +* 2 - km travelled +* 28 - km remaining +* 29 - km that could be travelled with the fuel you have left +* 3 - speed now +* 39 - average speed +* 4 - fuel consumption now (litres per 100km) +* 49 - fuel average consumption +* +******************************************************************************/ + +/* Core includes */ +#include "emu.h" +#include "cpu/m6800/m6800.h" +#include "eacc.lh" +#include "machine/6821pia.h" +#include "machine/7474.h" +#include "machine/clock.h" +#include "machine/nvram.h" + + +class eacc_state : public driver_device +{ +public: + eacc_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_pia(*this, "pia") + , m_p_nvram(*this, "nvram") + , m_7474(*this, "7474") + , m_io_keyboard(*this, "X%u", 0U) + , m_digits(*this, "digit%u", 0U) + , m_leds(*this, "led%u", 0U) + { } + + void eacc(machine_config &config); + +protected: + virtual void machine_reset() override; + virtual void machine_start() override; + +private: + DECLARE_WRITE_LINE_MEMBER(scan_w); + DECLARE_WRITE_LINE_MEMBER(cb2_w); + DECLARE_WRITE_LINE_MEMBER(inputs_w); + uint8_t keyboard_r(); + void digit_w(uint8_t data); + void segment_w(uint8_t data); + void mem_map(address_map &map); + void do_nmi(bool, bool); + uint8_t m_digit = 0U; + bool m_cb2 = false; + bool m_scan = false; + bool m_disp = false; + + required_device m_maincpu; + required_device m_pia; + required_shared_ptr m_p_nvram; + required_device m_7474; + required_ioport_array<4> m_io_keyboard; + output_finder<7> m_digits; + output_finder<8> m_leds; +}; + + + + +/****************************************************************************** + Address Maps +******************************************************************************/ + +void eacc_state::mem_map(address_map &map) +{ + map.unmap_value_high(); + map.global_mask(0xc7ff); // A11,A12,A13 not connected + map(0x0000, 0x001f).ram().share("nvram"); // inside cpu, battery-backed + map(0x0020, 0x007f).ram(); // inside cpu + map(0x4000, 0x47ff).rom().mirror(0x8000).region("maincpu",0); + map(0x8000, 0x8003).mirror(0x7fc).rw(m_pia, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); +} + + +/****************************************************************************** + Input Ports +******************************************************************************/ + +static INPUT_PORTS_START(eacc) + PORT_START("X0") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("6 Litres Cal") PORT_CODE(KEYCODE_6_PAD) PORT_CHAR('6') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("ENTER") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR('M') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("2 km") PORT_CODE(KEYCODE_2_PAD) PORT_CHAR('2') + PORT_BIT( 0xf8, 0, IPT_UNUSED ) + + PORT_START("X1") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("5 START") PORT_CODE(KEYCODE_5_PAD) PORT_CHAR('5') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("END") PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR('N') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("3 km/h") PORT_CODE(KEYCODE_3_PAD) PORT_CHAR('3') + PORT_BIT( 0xf8, 0, IPT_UNUSED ) + + PORT_START("X2") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("7 Km Cal") PORT_CODE(KEYCODE_7_PAD) PORT_CHAR('7') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("0 hour.min") PORT_CODE(KEYCODE_0_PAD) PORT_CHAR('0') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("4 l/100km") PORT_CODE(KEYCODE_4_PAD) PORT_CHAR('4') + PORT_BIT( 0xf8, 0, IPT_UNUSED ) + + PORT_START("X3") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("8 REM") PORT_CODE(KEYCODE_8_PAD) PORT_CHAR('8') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("1 litres") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR('1') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("9 AV") PORT_CODE(KEYCODE_9_PAD) PORT_CHAR('9') + PORT_BIT( 0xf8, 0, IPT_UNUSED ) +INPUT_PORTS_END + +void eacc_state::machine_reset() +{ + m_cb2 = false; // pia is supposed to set this low at reset + m_digit = 0; +} + +void eacc_state::machine_start() +{ + m_digits.resolve(); + m_leds.resolve(); + + save_item(NAME(m_cb2)); + save_item(NAME(m_scan)); + save_item(NAME(m_digit)); + save_item(NAME(m_disp)); +} + +WRITE_LINE_MEMBER( eacc_state::inputs_w ) +{ + if (state) + m_pia->ca1_w(machine().rand() & 1); // movement + else + m_pia->ca2_w(machine().rand() & 1); // fuel usage +} + +void eacc_state::do_nmi(bool in_scan, bool in_cb2) +{ + if (in_scan && in_cb2) + { + m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE); + m_7474->clock_w(0); + } + else + { + m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE); + m_7474->clock_w(1); + } +} + +WRITE_LINE_MEMBER( eacc_state::cb2_w ) +{ + m_cb2 = state ? 1 : 0; + do_nmi(m_scan, m_cb2); +} + +WRITE_LINE_MEMBER( eacc_state::scan_w ) +{ + m_scan = state ? 1 : 0; + do_nmi(m_scan, m_cb2); +} + +uint8_t eacc_state::keyboard_r() +{ + uint8_t data = m_digit; + + for (uint8_t i = 3; i < 7; i++) + if (BIT(m_digit, i)) + data |= m_io_keyboard[i - 3]->read(); + + return data; +} + +void eacc_state::segment_w(uint8_t data) +{ + //d7 segment dot + //d6 segment c + //d5 segment d + //d4 segment e + //d3 segment a + //d2 segment b + //d1 segment f + //d0 segment g + + if (m_disp) + { + m_disp = false; + if (BIT(m_digit, 7)) + { + data ^= 0xff; + + for (uint8_t i = 0; i < 8; i++) + m_leds[i] = BIT(data, i); + } + else + { + for (uint8_t i = 3; i < 7; i++) + if (BIT(m_digit, i)) + m_digits[i] = bitswap<8>(data, 7, 0, 1, 4, 5, 6, 2, 3); + } + } +} + +void eacc_state::digit_w(uint8_t data) +{ + m_digit = data & 0xf8; + m_disp = true; +} + + +/****************************************************************************** + Machine Drivers +******************************************************************************/ + +void eacc_state::eacc(machine_config &config) +{ + /* basic machine hardware */ + M6802(config, m_maincpu, XTAL(3'579'545)); /* Divided by 4 inside the m6802*/ + m_maincpu->set_ram_enable(false); // FIXME: needs standby support + m_maincpu->set_addrmap(AS_PROGRAM, &eacc_state::mem_map); + + config.set_default_layout(layout_eacc); + + PIA6821(config, m_pia, 0); + m_pia->readpb_handler().set(FUNC(eacc_state::keyboard_r)); + m_pia->writepa_handler().set(FUNC(eacc_state::segment_w)); + m_pia->writepb_handler().set(FUNC(eacc_state::digit_w)); + m_pia->cb2_handler().set(FUNC(eacc_state::cb2_w)); + m_pia->irqa_handler().set_inputline("maincpu", M6802_IRQ_LINE); + m_pia->irqb_handler().set_inputline("maincpu", M6802_IRQ_LINE); + + NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); + + TTL7474(config, m_7474, 0); + m_7474->output_cb().set(m_pia, FUNC(pia6821_device::cb1_w)); + + clock_device &eacc_scan(CLOCK(config, "eacc_scan", 600)); // 74C14 with 100k & 10nF = 1200Hz, but article says 600. + eacc_scan.signal_handler().set(FUNC(eacc_state::scan_w)); + + clock_device &eacc_cb1(CLOCK(config, "eacc_cb1", 15)); // cpu E -> MM5369 -> 15Hz + eacc_cb1.signal_handler().set(m_7474, FUNC(ttl7474_device::d_w)); + + clock_device &eacc_rnd(CLOCK(config, "eacc_rnd", 30)); // random pulse for distance and fuel + eacc_rnd.signal_handler().set(FUNC(eacc_state::inputs_w)); +} + + + +/****************************************************************************** + ROM Definitions +******************************************************************************/ + +ROM_START(eacc) + ROM_REGION(0x0800, "maincpu", 0) + ROM_LOAD("eacc.bin", 0x0000, 0x0800, CRC(287a63c0) SHA1(f61b397d33ea40e5742e34d5f5468572125e8b39) ) +ROM_END + + +/****************************************************************************** + Drivers +******************************************************************************/ + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1982, eacc, 0, 0, eacc, eacc, eacc_state, empty_init, "Electronics Australia", "EA Car Computer", MACHINE_NO_SOUND_HW | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/ausnz/eti660.cpp b/src/mame/ausnz/eti660.cpp new file mode 100644 index 00000000000..df72dd86e63 --- /dev/null +++ b/src/mame/ausnz/eti660.cpp @@ -0,0 +1,411 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder, Robbbert +/***************************************************************************************** + + ETI project 660, featured in the Australian magazine Electronics Today International. + + Commands: + R - Reset (use this before any other instruction) + S - Step + 0 - Enter modify memory mode + 2 - Save memory to cassette + 4 - Load memory from cassette + 6 - start binary program + 8 - start chip-8 program. + + To modify memory, press R, 0, enter 4-digit address, S, enter data, S, continue on. + R to escape. + + To save a tape, enter the start address into 0400,0401 (big endian), and the end + address into 0402,0403. Press R. Press record on the tape, press 2. + + To load a tape, enter the start and end addresses as above. Press R, 4. Screen goes + black. Press play on tape. If the screen is still black after the tape ends, press R. + + All chip-8 programs start at 0600. The manual says the max end address is 7FF (gives + 512 bytes), but you can fill up all of memory (gives 2560 bytes). + + TODO: + - sometimes there's no sound when started. You may need to hard reset until it beeps. + - doesn't run programs for other chip-8 computers (this might be normal?) + - we support BIN files, but have none to test with. + - possible CPU bugs?: + - in Invaders, can't shoot them + - in Maze, the result is rubbish (works in Emma02 emulator v1.21, but not in v1.30) + +**************************************************************************************************/ + +#include "emu.h" +#include "cpu/cosmac/cosmac.h" +#include "machine/ram.h" +#include "machine/6821pia.h" +#include "machine/rescap.h" +#include "sound/cdp1864.h" +#include "imagedev/cassette.h" +#include "imagedev/snapquik.h" +#include "screen.h" +#include "softlist_dev.h" +#include "speaker.h" + +#define CDP1802_TAG "ic3" +#define CDP1864_TAG "ic4" +#define MC6821_TAG "ic5" + +enum +{ + LED_POWER = 0, + LED_PULSE +}; + +class eti660_state : public driver_device +{ +public: + eti660_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_p_videoram(*this, "videoram") + , m_maincpu(*this, CDP1802_TAG) + , m_cti(*this, CDP1864_TAG) + , m_pia(*this, MC6821_TAG) + , m_cassette(*this, "cassette") + , m_io_keyboard(*this, "X%d", 0U) + , m_special(*this, "SPECIAL") + , m_leds(*this, "led%d", 0U) + { } + + void eti660(machine_config &config); + +private: + u8 pia_r(); + void pia_w(u8 data); + void colorram_w(offs_t offset, u8 data); + DECLARE_READ_LINE_MEMBER( clear_r ); + DECLARE_READ_LINE_MEMBER( ef2_r ); + DECLARE_READ_LINE_MEMBER( ef4_r ); + DECLARE_WRITE_LINE_MEMBER( q_w ); + DECLARE_WRITE_LINE_MEMBER( ca2_w ); + void dma_w(offs_t offset, u8 data); + u8 pia_pa_r(); + void pia_pa_w(u8 data); + DECLARE_QUICKLOAD_LOAD_MEMBER(quickload_cb); + required_shared_ptr m_p_videoram; + + void io_map(address_map &map); + void mem_map(address_map &map); + + required_device m_maincpu; + required_device m_cti; + required_device m_pia; + required_device m_cassette; + required_ioport_array<4> m_io_keyboard; + required_ioport m_special; + output_finder<2> m_leds; + + virtual void machine_start() override; + virtual void machine_reset() override; + uint16_t m_resetcnt; + + /* keyboard state */ + u8 m_keylatch = 0U; + + /* video state */ + u8 m_color_ram[0xc0]{}; + u8 m_color = 0U; +}; + + +/* Read/Write Handlers */ +// Schematic is wrong, PCB layout is correct: D0-7 swapped around on PIA. +u8 eti660_state::pia_r() +{ + u8 pia_offset = m_maincpu->get_memory_address() & 0x03; + + return bitswap<8>(m_pia->read(pia_offset), 0,1,2,3,4,5,6,7); +} + +void eti660_state::pia_w(u8 data) +{ + u8 pia_offset = m_maincpu->get_memory_address() & 0x03; + data = bitswap<8>(data,0,1,2,3,4,5,6,7); + m_pia->write(pia_offset, data); +} + +WRITE_LINE_MEMBER( eti660_state::ca2_w ) // test with Wipeout game - it should start up in colour +{ + m_cti->con_w(state); +} + +void eti660_state::colorram_w(offs_t offset, u8 data) +{ + offset = m_maincpu->get_memory_address() - 0xc80; + + u8 colorram_offset = (((offset & 0x1f0) >> 1) | (offset & 0x07)); + + if (colorram_offset < 0xc0) + m_color_ram[colorram_offset] = data; +} + +/* Memory Maps */ + +void eti660_state::mem_map(address_map &map) +{ + map.global_mask(0xfff); + map(0x0000, 0x03ff).rom(); + map(0x0400, 0x047f).ram(); + map(0x0480, 0x05ff).ram().share("videoram"); + map(0x0600, 0x0fff).ram(); +} + +void eti660_state::io_map(address_map &map) +{ + map(0x01, 0x01).rw(m_cti, FUNC(cdp1864_device::dispon_r), FUNC(cdp1864_device::step_bgcolor_w)); + map(0x02, 0x02).rw(FUNC(eti660_state::pia_r), FUNC(eti660_state::pia_w)); + map(0x03, 0x03).w(FUNC(eti660_state::colorram_w)); + map(0x04, 0x04).rw(m_cti, FUNC(cdp1864_device::dispoff_r), FUNC(cdp1864_device::tone_latch_w)); +} + +/* Input Ports */ +static INPUT_PORTS_START( eti660 ) + PORT_START("X0") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') + PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("X1") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') + PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("X2") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') + PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("X3") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_F) PORT_CHAR('F') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_E) PORT_CHAR('E') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') + PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("SPECIAL") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("RESET") PORT_CODE(KEYCODE_R) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("STEP") PORT_CODE(KEYCODE_S) +INPUT_PORTS_END + +/* CDP1802 Interface */ + +READ_LINE_MEMBER( eti660_state::clear_r ) +{ + // A hack to make the machine reset itself on + // boot, like the real one does. + if (m_resetcnt < 0xffff) + m_resetcnt++; + if (m_resetcnt == 0xf000) + return 0; + return BIT(m_special->read(), 0); // R key +} + +READ_LINE_MEMBER( eti660_state::ef2_r ) +{ + return m_cassette->input() < 0; +} + +READ_LINE_MEMBER( eti660_state::ef4_r ) +{ + return BIT(m_special->read(), 1); // S key +} + +WRITE_LINE_MEMBER( eti660_state::q_w ) +{ + /* CDP1864 audio output enable */ + m_cti->aoe_w(state); + + /* PULSE led */ + m_leds[LED_PULSE] = state ? 1 : 0; + + /* tape output */ + m_cassette->output(state ? 1.0 : -1.0); +} + +void eti660_state::dma_w(offs_t offset, u8 data) +{ + offset -= 0x480; + + m_color = 7; + + u8 colorram_offset = ((offset & 0x1f0) >> 1) | (offset & 0x07); + + if (colorram_offset < 0xc0) + m_color = m_color_ram[colorram_offset]; + + m_cti->dma_w(data); +} + +/* PIA6821 Interface */ + +u8 eti660_state::pia_pa_r() +{ + /* + + bit description + + PA0 keyboard row 0 + PA1 keyboard row 1 + PA2 keyboard row 2 + PA3 keyboard row 3 + PA4 keyboard column 0 + PA5 keyboard column 1 + PA6 keyboard column 2 + PA7 keyboard column 3 + + */ + + u8 i, data = 0xff; + + for (i = 0; i < 4; i++) + if (BIT(m_keylatch, i)) + return m_io_keyboard[i]->read(); + + return data; +} + +void eti660_state::pia_pa_w(u8 data) +{ + /* + + bit description + + PA0 keyboard row 0 + PA1 keyboard row 1 + PA2 keyboard row 2 + PA3 keyboard row 3 + PA4 keyboard column 0 + PA5 keyboard column 1 + PA6 keyboard column 2 + PA7 keyboard column 3 + + */ + + m_keylatch = bitswap<8>(data,0,1,2,3,4,5,6,7) ^ 0xff; +} + +void eti660_state::machine_reset() +{ + m_resetcnt = 0; + m_maincpu->reset(); // needed +} + +void eti660_state::machine_start() +{ + m_leds.resolve(); + + save_item(NAME(m_color_ram)); + save_item(NAME(m_color)); + save_item(NAME(m_keylatch)); + save_item(NAME(m_resetcnt)); +} + +QUICKLOAD_LOAD_MEMBER(eti660_state::quickload_cb) +{ + address_space &space = m_maincpu->space(AS_PROGRAM); + int i; + int quick_addr = 0x600; + int quick_length; + std::vector quick_data; + int read_; + image_init_result result = image_init_result::FAIL; + + quick_length = image.length(); + quick_data.resize(quick_length); + read_ = image.fread( &quick_data[0], quick_length); + if (read_ != quick_length) + { + image.seterror(image_error::INVALIDIMAGE, "Cannot read the file"); + image.message(" Cannot read the file"); + } + else + { + for (i = 0; i < quick_length; i++) + if ((quick_addr + i) < 0x1000) + space.write_byte(i + quick_addr, quick_data[i]); + + /* display a message about the loaded quickload */ + if (image.is_filetype("bin")) + image.message(" Quickload: size=%04X : start=%04X : end=%04X : Press 6 to start",quick_length,quick_addr,quick_addr+quick_length); + else + image.message(" Quickload: size=%04X : start=%04X : end=%04X : Press 8 to start",quick_length,quick_addr,quick_addr+quick_length); + + result = image_init_result::PASS; + } + + return result; +} + +/* Machine Drivers */ + +void eti660_state::eti660(machine_config &config) +{ + /* basic machine hardware */ + CDP1802(config, m_maincpu, XTAL(8'867'238)/5); + m_maincpu->set_addrmap(AS_PROGRAM, &eti660_state::mem_map); + m_maincpu->set_addrmap(AS_IO, &eti660_state::io_map); + m_maincpu->wait_cb().set_constant(1); + m_maincpu->clear_cb().set(FUNC(eti660_state::clear_r)); + m_maincpu->ef2_cb().set(FUNC(eti660_state::ef2_r)); + m_maincpu->ef4_cb().set(FUNC(eti660_state::ef4_r)); + m_maincpu->q_cb().set(FUNC(eti660_state::q_w)); + m_maincpu->dma_wr_cb().set(FUNC(eti660_state::dma_w)); + + /* video hardware */ + SCREEN(config, "screen", SCREEN_TYPE_RASTER); + + /* sound hardware */ + SPEAKER(config, "mono").front_center(); + CDP1864(config, m_cti, XTAL(8'867'238)/5).set_screen("screen"); + m_cti->inlace_cb().set_constant(0); + m_cti->int_cb().set_inputline(m_maincpu, COSMAC_INPUT_LINE_INT); + m_cti->dma_out_cb().set_inputline(m_maincpu, COSMAC_INPUT_LINE_DMAOUT); + m_cti->efx_cb().set_inputline(m_maincpu, COSMAC_INPUT_LINE_EF1); + m_cti->rdata_cb().set([this] () { return BIT(m_color, 0); }); + m_cti->bdata_cb().set([this] () { return BIT(m_color, 1); }); + m_cti->gdata_cb().set([this] () { return BIT(m_color, 2); }); + m_cti->set_chrominance(RES_K(2.2), RES_K(1), RES_K(4.7), RES_K(4.7)); // R7, R5, R6, R4 + m_cti->add_route(ALL_OUTPUTS, "mono", 0.25); + + /* devices */ + PIA6821(config, m_pia, 0); + m_pia->readpa_handler().set(FUNC(eti660_state::pia_pa_r)); + m_pia->writepa_handler().set(FUNC(eti660_state::pia_pa_w)); + m_pia->ca2_handler().set(FUNC(eti660_state::ca2_w)); // not working, bug in pia + m_pia->irqa_handler().set_inputline(m_maincpu, COSMAC_INPUT_LINE_INT).invert(); // FIXME: use an input merger for these lines + m_pia->irqb_handler().set_inputline(m_maincpu, COSMAC_INPUT_LINE_INT).invert(); + + 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); + + /* internal ram */ + RAM(config, RAM_TAG).set_default_size("3K"); + + /* quickload */ + quickload_image_device &quickload(QUICKLOAD(config, "quickload", "bin,c8,ch8", attotime::from_seconds(2))); + quickload.set_load_callback(FUNC(eti660_state::quickload_cb)); + quickload.set_interface("etiquik"); + SOFTWARE_LIST(config, "quik_list").set_original("eti660_quik"); +} + +/* ROMs */ + +ROM_START( eti660 ) + ROM_REGION( 0x10000, CDP1802_TAG, 0 ) + ROM_LOAD( "eti660.bin", 0x0000, 0x0400, CRC(811dfa62) SHA1(c0c4951e02f873f15560bdc3f35cdf3f99653922) ) +ROM_END + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1981, eti660, 0, 0, eti660, eti660, eti660_state, empty_init, "Electronics Today International", "ETI-660 Learners' Microcomputer", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/ausnz/excali64.cpp b/src/mame/ausnz/excali64.cpp new file mode 100644 index 00000000000..d0e78a93245 --- /dev/null +++ b/src/mame/ausnz/excali64.cpp @@ -0,0 +1,694 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert +/*************************************************************************** + +Excalibur 64 kit computer, designed and sold in Australia by BGR Computers. +The official schematics have a LOT of errors and omissions. + +Skeleton driver created on 2014-12-09. + +Chips: Z80A, 8251, 8253, 8255, 6845 +We have Basic 1.1. Other known versions are 1.01, 2.1 +There are 2 versions of the colour prom, which have different palettes. +We have the later version. + +Notes: +- When booted it asks for a disk. Press enter to start ROM BASIC. +- Control W then Enter will switch between 40 and 80 characters per line. +- Control V turns cursor on +- Graphics commands such as LINE, CIRCLE, HGRCLS, HGRSET etc only work with disk basic + +ToDo: +- Colours are approximate. +- Hardware supports 20cm and 13cm floppies, but we only support 13cm as this + is the only software that exists. +- The schematic shows the audio counter connected to 2MHz, but this produces + sounds that are too high. Connected to 1MHz for now. +- Serial +- Pasting can sometimes drop a character. + +****************************************************************************/ + + +#include "emu.h" + +#include "bus/centronics/ctronics.h" +#include "bus/rs232/rs232.h" +#include "cpu/z80/z80.h" +#include "imagedev/cassette.h" +#include "imagedev/floppy.h" +#include "machine/74123.h" +#include "machine/i8251.h" +#include "machine/i8255.h" +#include "machine/pit8253.h" +#include "machine/rescap.h" +#include "machine/wd_fdc.h" +#include "machine/z80dma.h" +#include "sound/spkrdev.h" +#include "video/mc6845.h" + +#include "emupal.h" +#include "screen.h" +#include "softlist_dev.h" +#include "speaker.h" + +#include "formats/excali64_dsk.h" + + +namespace { + +class excali64_state : public driver_device +{ +public: + excali64_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_palette(*this, "palette") + , m_maincpu(*this, "maincpu") + , m_p_chargen(*this, "chargen") + , m_bankr(*this, "bankr%u", 1U) + , m_bankw(*this, "bankw%u", 1U) + , m_cass(*this, "cassette") + , m_crtc(*this, "crtc") + , m_io_keyboard(*this, "KEY.%u", 0) + , m_dma(*this, "dma") + , m_u12(*this, "u12") + , m_centronics(*this, "centronics") + , m_fdc(*this, "fdc") + , m_floppy0(*this, "fdc:0") + , m_floppy1(*this, "fdc:1") + { } + + void excali64(machine_config &config); + +protected: + virtual void machine_reset() override; + virtual void machine_start() override; + +private: + void excali64_palette(palette_device &palette); + void ppib_w(u8 data); + u8 ppic_r(); + void ppic_w(u8 data); + u8 port00_r(); + u8 port50_r(); + void port70_w(u8 data); + void porte4_w(u8 data); + u8 porte8_r(); + void portec_w(u8 data); + static void floppy_formats(format_registration &fr); + DECLARE_WRITE_LINE_MEMBER(cent_busy_w); + DECLARE_WRITE_LINE_MEMBER(busreq_w); + u8 memory_read_byte(offs_t offset); + void memory_write_byte(offs_t offset, u8 data); + u8 io_read_byte(offs_t offset); + void io_write_byte(offs_t offset, u8 data); + MC6845_UPDATE_ROW(update_row); + DECLARE_WRITE_LINE_MEMBER(crtc_hs); + DECLARE_WRITE_LINE_MEMBER(crtc_vs); + DECLARE_WRITE_LINE_MEMBER(motor_w); + + void io_map(address_map &map); + void mem_map(address_map &map); + + u8 m_sys_status = 0U; + u8 m_kbdrow = 0U; + bool m_crtc_vs = 0; + bool m_crtc_hs = 0; + bool m_motor = 0; + bool m_centronics_busy = 0; + std::unique_ptr m_vram; + std::unique_ptr m_hram; + std::unique_ptr m_ram; + required_device m_palette; + required_device m_maincpu; + required_region_ptr m_p_chargen; + required_memory_bank_array<4> m_bankr; + required_memory_bank_array<4> m_bankw; + required_device m_cass; + required_device m_crtc; + required_ioport_array<8> m_io_keyboard; + required_device m_dma; + required_device m_u12; + required_device m_centronics; + required_device m_fdc; + required_device m_floppy0; + required_device m_floppy1; +}; + +void excali64_state::mem_map(address_map &map) +{ + map(0x0000, 0x1fff).bankr(m_bankr[0]).bankw(m_bankw[0]); + map(0x2000, 0x2fff).bankr(m_bankr[1]).bankw(m_bankw[1]); + map(0x3000, 0x3fff).bankr(m_bankr[2]).bankw(m_bankw[2]); + map(0x4000, 0xbfff).bankr(m_bankr[3]).bankw(m_bankw[3]); + map(0xc000, 0xffff).ram(); +} + +void excali64_state::io_map(address_map &map) +{ + map.global_mask(0xff); + map(0x00, 0x0f).r(FUNC(excali64_state::port00_r)); + map(0x10, 0x11).mirror(0x0e).rw("uart", FUNC(i8251_device::read), FUNC(i8251_device::write)); + map(0x20, 0x23).mirror(0x0c).rw("pit", FUNC(pit8253_device::read), FUNC(pit8253_device::write)); + map(0x30, 0x30).mirror(0x0e).rw(m_crtc, FUNC(mc6845_device::status_r), FUNC(mc6845_device::address_w)); + map(0x31, 0x31).mirror(0x0e).rw(m_crtc, FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w)); + map(0x50, 0x5f).r(FUNC(excali64_state::port50_r)); + map(0x60, 0x63).mirror(0x0c).rw("ppi", FUNC(i8255_device::read), FUNC(i8255_device::write)); + map(0x70, 0x7f).w(FUNC(excali64_state::port70_w)); + map(0xe0, 0xe3).rw(m_dma, FUNC(z80dma_device::read), FUNC(z80dma_device::write)); + map(0xe4, 0xe7).w(FUNC(excali64_state::porte4_w)); + map(0xe8, 0xeb).r(FUNC(excali64_state::porte8_r)); + map(0xec, 0xef).w(FUNC(excali64_state::portec_w)); + map(0xf0, 0xf3).rw(m_fdc, FUNC(wd2793_device::read), FUNC(wd2793_device::write)); +} + + +static INPUT_PORTS_START( excali64 ) + PORT_START("KEY.0") /* line 0 */ + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') PORT_CHAR(0x12) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') PORT_CHAR(0x17) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') PORT_CHAR(0x05) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("TAB") PORT_CODE(KEYCODE_TAB) PORT_CHAR(0x09) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CAPSLOCK") PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') PORT_CHAR(0x01) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') PORT_CHAR(0x11) + + PORT_START("KEY.1") /* line 1 */ + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F3") PORT_CODE(KEYCODE_F3) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F2") PORT_CODE(KEYCODE_F2) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F4") PORT_CODE(KEYCODE_F4) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_SHIFT_2) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) // space + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F1") PORT_CODE(KEYCODE_F1) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) // F1 + + PORT_START("KEY.2") /* line 2 */ + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(". >") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') PORT_CHAR(0x0d) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("/ ?") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(", <") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') PORT_CHAR(0x02) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) //B + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') PORT_CHAR(0x0e) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) //N + + PORT_START("KEY.3") /* line 3 */ + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("' \"") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(0x27) PORT_CHAR(0x22) PORT_CHAR(0x27) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') PORT_CHAR(0x0c) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(0x0d) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("; :") PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') PORT_CHAR(0x0a) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') PORT_CHAR(0x07) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') PORT_CHAR(0x0b) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') PORT_CHAR(0x08) + + PORT_START("KEY.4") /* line 4 */ + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4 $") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2 @") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5 %") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3 #") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("DEL") PORT_CODE(KEYCODE_DEL) PORT_CHAR(0x7f) PORT_CHAR(0x7f) PORT_CHAR(0x1f) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("ESC") PORT_CODE(KEYCODE_ESC) PORT_CHAR(0x1b) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1 !") PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("INS") PORT_CODE(KEYCODE_INSERT) + + PORT_START("KEY.5") /* line 5 */ + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("[ {") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') PORT_CHAR(0x1b) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') PORT_CHAR(0x0f) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("] }") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') PORT_CHAR(0x1d) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') PORT_CHAR(0x10) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') PORT_CHAR(0x15) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') PORT_CHAR(0x14) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') PORT_CHAR(0x09) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') PORT_CHAR(0x19) + + PORT_START("KEY.6") /* line 6 */ + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') PORT_CHAR(0x06) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') PORT_CHAR(0x18) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') PORT_CHAR(0x16) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') PORT_CHAR(0x03) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') PORT_CHAR(0x04) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') PORT_CHAR(0x13) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') PORT_CHAR(0x1a) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) //Z + + PORT_START("KEY.7") /* line 7 */ + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("= +") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') PORT_CHAR('=') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0 )") PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Backspace") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(0x08) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("- _") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8 *") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6 ^") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9 (") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7 &") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') +INPUT_PORTS_END + +WRITE_LINE_MEMBER( excali64_state::cent_busy_w ) +{ + m_centronics_busy = state; +} + +void excali64_state::floppy_formats(format_registration &fr) +{ + fr.add_mfm_containers(); + fr.add(FLOPPY_EXCALI64_FORMAT); +} + +static void excali64_floppies(device_slot_interface &device) +{ + device.option_add("525qd", FLOPPY_525_QD); +} + +// pulses from port E4 bit 5 restart the 74123. After 3.6 secs without a pulse, the motor gets turned off. +WRITE_LINE_MEMBER( excali64_state::motor_w ) +{ + m_motor = state; + m_floppy1->get_device()->mon_w(!m_motor); + m_floppy0->get_device()->mon_w(!m_motor); +} + +u8 excali64_state::porte8_r() +{ + return 0xfc | (u8)m_motor; +} + +void excali64_state::porte4_w(u8 data) +{ + floppy_image_device *floppy = nullptr; + if (BIT(data, 0)) + floppy = m_floppy0->get_device(); + + if (BIT(data, 1)) + floppy = m_floppy1->get_device(); + + m_fdc->set_floppy(floppy); + if (floppy) + floppy->ss_w(BIT(data, 4)); + + m_u12->b_w(BIT(data, 5)); // motor pulse +} + +/* +d0 = precomp (selectable by jumper) +d1 = size select +d2 = density select (0 = double) +*/ +void excali64_state::portec_w(u8 data) +{ + m_fdc->enmf_w(BIT(data, 1)); + m_fdc->dden_w(BIT(data, 2)); +} + +WRITE_LINE_MEMBER( excali64_state::busreq_w ) +{ +// since our Z80 has no support for BUSACK, we assume it is granted immediately + m_maincpu->set_input_line(Z80_INPUT_LINE_BUSRQ, state); + m_dma->bai_w(state); // tell dma that bus has been granted +} + +u8 excali64_state::memory_read_byte(offs_t offset) +{ + address_space& prog_space = m_maincpu->space(AS_PROGRAM); + return prog_space.read_byte(offset); +} + +void excali64_state::memory_write_byte(offs_t offset, u8 data) +{ + address_space& prog_space = m_maincpu->space(AS_PROGRAM); + prog_space.write_byte(offset, data); +} + +u8 excali64_state::io_read_byte(offs_t offset) +{ + address_space& prog_space = m_maincpu->space(AS_IO); + return prog_space.read_byte(offset); +} + +void excali64_state::io_write_byte(offs_t offset, u8 data) +{ + address_space& prog_space = m_maincpu->space(AS_IO); + prog_space.write_byte(offset, data); +} + +void excali64_state::ppib_w(u8 data) +{ + m_kbdrow = data; +} + +u8 excali64_state::ppic_r() +{ + u8 data = 0xf4; // READY line must be low to print + data |= (u8)m_centronics_busy; + data |= (m_cass->input() > 0.1) << 3; + return data; +} + +void excali64_state::ppic_w(u8 data) +{ + m_cass->output(BIT(data, 7) ? -1.0 : +1.0); + m_centronics->write_strobe(BIT(data, 4)); +} + +u8 excali64_state::port00_r() +{ + u8 data = 0xff; + + for (int i = 0; i < 8; i++) + { + if (!BIT(m_kbdrow, i)) + data &= m_io_keyboard[i]->read(); + } + + return data; +} + +/* +d0 : /rom ; screen +d1 : ram on +d2 : /low ; high res +d3 : 2nd colour set (previously, dispen, which is a mistake in hardware and schematic) +d4 : vsync +d5 : rombank +*/ +u8 excali64_state::port50_r() +{ + u8 data = m_sys_status & 0x2f; + bool csync = m_crtc_hs | m_crtc_vs; + data |= (u8)csync << 4; + return data; +} + +/* +d0,1,2,3,5 : same as port50 +(schematic wrongly says d7 used for 2nd colour set) +*/ +void excali64_state::port70_w(u8 data) +{ + m_sys_status = data; + m_crtc->set_unscaled_clock(BIT(data, 2) ? 2e6 : 1e6); + if (BIT(data, 1)) + { + // select 64k ram + m_bankr[0]->set_entry(0); + m_bankr[1]->set_entry(0); + m_bankr[2]->set_entry(0); + m_bankr[3]->set_entry(0); + + m_bankw[1]->set_entry(0); + m_bankw[2]->set_entry(0); + m_bankw[3]->set_entry(0); + } + else if (BIT(data, 0)) + { + // select videoram and hiresram + m_bankr[0]->set_entry(1); + m_bankr[1]->set_entry(2); + m_bankr[2]->set_entry(2); + m_bankr[3]->set_entry(2); + + m_bankw[1]->set_entry(2); + m_bankw[2]->set_entry(2); + m_bankw[3]->set_entry(2); + } + else + { + // select rom, videoram, and main ram + m_bankr[0]->set_entry(1); + m_bankr[1]->set_entry(1); + m_bankr[2]->set_entry(1); + m_bankr[3]->set_entry(0); + + m_bankw[1]->set_entry(2); + m_bankw[2]->set_entry(2); + m_bankw[3]->set_entry(0); + } + + // other half of ROM_1 + if ((data & 0x22) == 0x20) + m_bankr[0]->set_entry(2); +} + +void excali64_state::machine_reset() +{ + m_bankr[0]->set_entry(1); // read from ROM + m_bankr[1]->set_entry(1); // read from ROM + m_bankr[2]->set_entry(1); // read from ROM + m_bankr[3]->set_entry(0); // read from RAM + + m_bankw[0]->set_entry(0); // write to RAM + m_bankw[1]->set_entry(2); // write to videoram + m_bankw[2]->set_entry(2); // write to videoram hires pointers + m_bankw[3]->set_entry(0); // write to RAM + + m_maincpu->reset(); +} + +void excali64_state::machine_start() +{ + save_pointer(NAME(m_vram), 0x2000); + save_pointer(NAME(m_hram), 0x8000); + save_pointer(NAME(m_ram), 0xc000); + save_item(NAME(m_sys_status)); + save_item(NAME(m_kbdrow)); + save_item(NAME(m_crtc_vs)); + save_item(NAME(m_crtc_hs)); + save_item(NAME(m_motor)); + save_item(NAME(m_centronics_busy)); + + m_sys_status = 0; +} +WRITE_LINE_MEMBER( excali64_state::crtc_hs ) +{ + m_crtc_hs = state; +} + +WRITE_LINE_MEMBER( excali64_state::crtc_vs ) +{ + m_crtc_vs = state; +} + +/* F4 Character Displayer */ +static const gfx_layout excali64_charlayout = +{ + 8, 12, /* 8 x 12 characters */ + 256, /* 256 characters */ + 1, /* 1 bits per pixel */ + { 0 }, /* no bitplanes */ + /* x offsets */ + { 7, 6, 5, 4, 3, 2, 1, 0 }, + /* y offsets */ + { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8, 10*8, 11*8 }, + 8*16 /* every char takes 16 bytes */ +}; + +static GFXDECODE_START( gfx_excali64 ) + GFXDECODE_ENTRY( "chargen", 0x0000, excali64_charlayout, 0, 1 ) +GFXDECODE_END + +// The prom, the schematic, and the manual all contradict each other, +// so the colours can only be described as wild guesses. Further, the 38 +// colour-load resistors are missing labels and values. +void excali64_state::excali64_palette(palette_device &palette) +{ + // do this here because driver_init hasn't run yet + m_vram = make_unique_clear(0x2000); + m_hram = make_unique_clear(0x8000); + m_ram = make_unique_clear(0xc000); + u8 *v = m_vram.get(); + u8 *h = m_hram.get(); + u8 *r = m_ram.get(); + u8 *main = memregion("roms")->base(); + + // main ram (cp/m mode) + m_bankr[0]->configure_entry(0, r); + m_bankr[1]->configure_entry(0, r+0x2000); + m_bankr[2]->configure_entry(0, r+0x3000); + m_bankr[3]->configure_entry(0, r+0x4000);//boot + m_bankw[0]->configure_entry(0, r);//boot + m_bankw[1]->configure_entry(0, r+0x2000); + m_bankw[2]->configure_entry(0, r+0x3000); + m_bankw[3]->configure_entry(0, r+0x4000);//boot + // rom_1 + m_bankr[0]->configure_entry(1, &main[0x0000]);//boot + m_bankr[0]->configure_entry(2, &main[0x2000]); + // rom_2 + m_bankr[1]->configure_entry(1, &main[0x4000]);//boot + m_bankr[2]->configure_entry(1, &main[0x5000]);//boot + // videoram + m_bankr[1]->configure_entry(2, v); + m_bankw[1]->configure_entry(2, v);//boot + // hiresram + m_bankr[2]->configure_entry(2, v+0x1000); + m_bankw[2]->configure_entry(2, v+0x1000);//boot + m_bankr[3]->configure_entry(2, h); + m_bankw[3]->configure_entry(2, h); + + // Set up foreground colours + for (u8 i = 0; i < 32; i++) + { + u8 const code = m_p_chargen[0x1000+i]; + u8 const r = (BIT(code, 0) ? 38 : 0) + (BIT(code, 1) ? 73 : 0) + (BIT(code, 2) ? 144 : 0); + u8 const b = (BIT(code, 3) ? 38 : 0) + (BIT(code, 4) ? 73 : 0) + (BIT(code, 5) ? 144 : 0); + u8 const g = (BIT(code, 6) ? 85 : 0) + (BIT(code, 7) ? 170 : 0); + palette.set_pen_color(i, r, g, b); + } + + // Background + palette.set_pen_color(32, 0x00, 0x00, 0x00); // 0 Black + palette.set_pen_color(33, 0xff, 0x00, 0x00); // 1 Red + palette.set_pen_color(34, 0x00, 0x00, 0xff); // 2 Blue + palette.set_pen_color(35, 0xff, 0x00, 0xff); // 3 Magenta + palette.set_pen_color(36, 0x00, 0xff, 0x00); // 4 Green + palette.set_pen_color(37, 0xff, 0xff, 0x00); // 5 Yellow + palette.set_pen_color(38, 0x00, 0xff, 0xff); // 6 Cyan + palette.set_pen_color(39, 0xff, 0xff, 0xff); // 7 White +} + +MC6845_UPDATE_ROW( excali64_state::update_row ) +{ + rgb_t const *const palette = m_palette->palette()->entry_list_raw(); + u8 const col_base = BIT(m_sys_status, 3) ? 16 : 0; + u32 *p = &bitmap.pix(y); + + for (u16 x = 0; x < x_count; x++) + { + u16 const mem = (ma + x) & 0x7ff; + u8 const chr = m_vram[mem]; + u8 const col = m_vram[mem+0x800]; + u8 const fg = col_base + (col >> 4); + u8 const bg = 32 + ((col >> 1) & 7); + + u8 gfx; + if (BIT(col, 0)) + { + u8 h = m_vram[mem+0x1000] - 4; + if (h > 5) + h = 0; // keep us in bounds + // hires definition - pixels are opposite order to characters + gfx = bitswap<8>(m_hram[(h << 12) | (chr<<4) | ra], 0, 1, 2, 3, 4, 5, 6, 7); + } + else + gfx = m_p_chargen[(chr<<4) | ra]; // normal character + + gfx ^= (x == cursor_x) ? 0xff : 0; + + /* Display a scanline of a character */ + *p++ = palette[BIT(gfx, 0) ? fg : bg]; + *p++ = palette[BIT(gfx, 1) ? fg : bg]; + *p++ = palette[BIT(gfx, 2) ? fg : bg]; + *p++ = palette[BIT(gfx, 3) ? fg : bg]; + *p++ = palette[BIT(gfx, 4) ? fg : bg]; + *p++ = palette[BIT(gfx, 5) ? fg : bg]; + *p++ = palette[BIT(gfx, 6) ? fg : bg]; + *p++ = palette[BIT(gfx, 7) ? fg : bg]; + } +} + +void excali64_state::excali64(machine_config &config) +{ + /* basic machine hardware */ + Z80(config, m_maincpu, 16_MHz_XTAL / 4); + m_maincpu->set_addrmap(AS_PROGRAM, &excali64_state::mem_map); + m_maincpu->set_addrmap(AS_IO, &excali64_state::io_map); + + I8251(config, "uart", 0); + //uart.txd_handler().set("rs232", FUNC(rs232_port_device::write_txd)); + //uart.rts_handler().set("rs232", FUNC(rs232_port_device::write_rts)); + + pit8253_device &pit(PIT8253(config, "pit", 0)); + pit.set_clk<0>(16_MHz_XTAL / 16); /* Timer 0: tone gen for speaker */ + pit.out_handler<0>().set("speaker", FUNC(speaker_sound_device::level_w)); + //pit.set_clk<1>(16_MHz_XTAL / 16); /* Timer 1: baud rate gen for 8251 */ + //pit.out_handler<1>().set(FUNC(excali64_state::write_uart_clock)); + //pit.set_clk<2>(16_MHz_XTAL / 16); /* Timer 2: not used */ + + i8255_device &ppi(I8255A(config, "ppi")); + ppi.out_pa_callback().set("cent_data_out", FUNC(output_latch_device::write)); // parallel port + ppi.out_pb_callback().set(FUNC(excali64_state::ppib_w)); + ppi.in_pc_callback().set(FUNC(excali64_state::ppic_r)); + ppi.out_pc_callback().set(FUNC(excali64_state::ppic_w)); + + /* sound hardware */ + SPEAKER(config, "mono").front_center(); + SPEAKER_SOUND(config, "speaker").add_route(ALL_OUTPUTS, "mono", 0.50); + + /* Video hardware */ + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); + screen.set_refresh_hz(50); + screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */ + screen.set_size(80*8, 24*12); + screen.set_visarea_full(); + screen.set_screen_update("crtc", FUNC(mc6845_device::screen_update)); + + PALETTE(config, m_palette, FUNC(excali64_state::excali64_palette), 40); + GFXDECODE(config, "gfxdecode", m_palette, gfx_excali64); + + MC6845(config, m_crtc, 16_MHz_XTAL / 16); // 1MHz for lowres; 2MHz for highres + m_crtc->set_screen("screen"); + m_crtc->set_show_border_area(false); + m_crtc->set_char_width(8); + m_crtc->set_update_row_callback(FUNC(excali64_state::update_row)); + m_crtc->out_hsync_callback().set(FUNC(excali64_state::crtc_hs)); + m_crtc->out_vsync_callback().set(FUNC(excali64_state::crtc_vs)); + + /* Devices */ + CASSETTE(config, m_cass); + m_cass->add_route(ALL_OUTPUTS, "mono", 0.05); + + WD2793(config, m_fdc, 16_MHz_XTAL / 8); + m_fdc->drq_wr_callback().set(m_dma, FUNC(z80dma_device::rdy_w)); + FLOPPY_CONNECTOR(config, "fdc:0", excali64_floppies, "525qd", excali64_state::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, "fdc:1", excali64_floppies, "525qd", excali64_state::floppy_formats).enable_sound(true); + + Z80DMA(config, m_dma, 16_MHz_XTAL / 4); + m_dma->out_busreq_callback().set(FUNC(excali64_state::busreq_w)); + m_dma->in_mreq_callback().set(FUNC(excali64_state::memory_read_byte)); + m_dma->out_mreq_callback().set(FUNC(excali64_state::memory_write_byte)); + m_dma->in_iorq_callback().set(FUNC(excali64_state::io_read_byte)); + m_dma->out_iorq_callback().set(FUNC(excali64_state::io_write_byte)); + + TTL74123(config, m_u12, 0); + m_u12->set_connection_type(TTL74123_GROUNDED); /* Hook up type (no idea what this means) */ + m_u12->set_resistor_value(RES_K(100)); /* resistor connected between RCext & 5v */ + m_u12->set_capacitor_value(CAP_U(100)); /* capacitor connected between Cext and RCext */ + m_u12->set_a_pin_value(0); /* A pin - grounded */ + m_u12->set_b_pin_value(1); /* B pin - driven by port e4 bit 5 */ + m_u12->set_clear_pin_value(1); /* Clear pin - pulled high */ + m_u12->out_cb().set(FUNC(excali64_state::motor_w)); + + CENTRONICS(config, m_centronics, centronics_devices, "printer"); + m_centronics->busy_handler().set(FUNC(excali64_state::cent_busy_w)); + + output_latch_device ¢_data_out(OUTPUT_LATCH(config, "cent_data_out")); + m_centronics->set_output_latch(cent_data_out); + + SOFTWARE_LIST(config, "flop_list").set_original("excalibur64"); +} + +/* ROM definition */ +ROM_START( excali64 ) + ROM_REGION(0x6000, "roms", 0) + ROM_LOAD( "rom_1.ic17", 0x0000, 0x4000, CRC(e129a305) SHA1(e43ec7d040c2b2e548d22fd6bbc7df8b45a26e5a) ) + ROM_LOAD( "rom_2.ic24", 0x4000, 0x2000, CRC(916d9f5a) SHA1(91c527cce963481b7bebf077e955ca89578bb553) ) + // fix a bug that causes screen to be filled with 'p' + ROM_FILL(0x4ee, 1, 0) + ROM_FILL(0x4ef, 1, 8) + ROM_FILL(0x4f6, 1, 0) + ROM_FILL(0x4f7, 1, 8) + // patch out the protection + ROM_FILL(0x3ce7, 1, 0) + + ROM_REGION(0x1020, "chargen", 0) + ROM_LOAD( "genex_3.ic43", 0x0000, 0x1000, CRC(b91619a9) SHA1(2ced636cb7b94ba9d329868d7ecf79963cefe9d9) ) + ROM_LOAD( "hm7603.ic55", 0x1000, 0x0020, CRC(c74f47dc) SHA1(331ff3c913846191ddd97cacb80bd19438c1ff71) ) +ROM_END + +} // Anonymous namespace + + +/* Driver */ + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1984, excali64, 0, 0, excali64, excali64, excali64_state, empty_init, "BGR Computers", "Excalibur 64", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/ausnz/labtam.cpp b/src/mame/ausnz/labtam.cpp new file mode 100644 index 00000000000..cfcee9809f1 --- /dev/null +++ b/src/mame/ausnz/labtam.cpp @@ -0,0 +1,114 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +/* + * Labtam International 3000 Systems + * + * Sources: + * - + * + * TODO: + * - additional cards + */ + +/* +3000 1983 +??? + +3003 1983 +Desktop +Board: +one - Z80 SBC +one - 8086 VDU/COMM +one - WD1002-HDO (Like Kaypro-10) https://retrocmp.de/kaypro/kay-p2_hrdw.htm#hdc +one - FDD 5'25 - Connect to WD1002 board +one - MFM HDD 5'25 NEC D5124 10MB - Connect to WD1002 board + +3006 1983 +Monoblock +Board: +one - Z80 SBC +one - 8086 VDU/COMM +two - FDD 8" - Connect to Z80 SBC board (to WD2793A on board) +one - FDD 5"25 - Connect to Z80 SBC board (to WD2793A on board) + +3015-V32 1985 +Tower +Board: +one - Z80 SBC +four - 8086 VDU/COMM (one board with main ROM and others slave ROM) +one - V32 (main processor board on CPU - NS32032, MMU - NS32082, FPU - NS32081, 2 Megabyte RAM), Optional SCSI contoler on board. +one or two - Additional one or two RAM board with 6 Megabyte. +one - INTERPHASE SMD 2190 (Controller SMD HDD) +one - Xylogics 472 (Controller 1/2 inch TAPE with PERTEC interface) + */ + +#include "emu.h" + +#include "bus/multibus/multibus.h" + +#include "bus/multibus/labtam_3232.h" +#include "bus/multibus/labtam_vducom.h" +#include "bus/multibus/labtam_z80sbc.h" + +#define VERBOSE 0 +#include "logmacro.h" + +namespace { + +class labtam_state : public driver_device +{ +public: + labtam_state(machine_config const &mconfig, device_type type, char const *tag) + : driver_device(mconfig, type, tag) + , m_bus(*this, "slot") + { + } + +protected: + // driver_device overrides + virtual void machine_start() override; + virtual void machine_reset() override; + +public: + // machine config + void labtam(machine_config &config); + +private: + required_device m_bus; +}; + +void labtam_state::machine_start() +{ +} + +void labtam_state::machine_reset() +{ +} + +static void labtam_cards(device_slot_interface &device) +{ + device.option_add("labtam_3232", LABTAM_3232); + device.option_add("labtam_vducom", LABTAM_VDUCOM); + device.option_add("labtam_z80sbc", LABTAM_Z80SBC); +} + +void labtam_state::labtam(machine_config &config) +{ + MULTIBUS(config, m_bus, 10_MHz_XTAL); // FIXME: clock driven by bus master + + MULTIBUS_SLOT(config, "slot:0", m_bus, labtam_cards, nullptr, false); + MULTIBUS_SLOT(config, "slot:1", m_bus, labtam_cards, nullptr, false); + MULTIBUS_SLOT(config, "slot:2", m_bus, labtam_cards, nullptr, false); + MULTIBUS_SLOT(config, "slot:3", m_bus, labtam_cards, nullptr, false); + MULTIBUS_SLOT(config, "slot:4", m_bus, labtam_cards, "labtam_vducom", false); + MULTIBUS_SLOT(config, "slot:5", m_bus, labtam_cards, "labtam_z80sbc", false); +} + +ROM_START(labtam) +ROM_END + +} + +/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ +COMP(1983, labtam, 0, 0, labtam, 0, labtam_state, empty_init, "Labtam International", "3006", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW) diff --git a/src/mame/ausnz/magnum.cpp b/src/mame/ausnz/magnum.cpp new file mode 100644 index 00000000000..f6e17c87b27 --- /dev/null +++ b/src/mame/ausnz/magnum.cpp @@ -0,0 +1,337 @@ +// license:BSD-3-Clause +// copyright-holders:Carl + +// Dulmont Magnum +// Additional info https://www.youtube.com/watch?v=st7H_vqSaQc and +// http://www.eevblog.com/forum/blog/eevblog-949-vintage-australian-made-laptop-teardown/msg1080508/#msg1080508 +// TODO: cartridge dumps + +#include "emu.h" +#include "cpu/i86/i186.h" +#include "machine/cdp1879.h" +#include "machine/wd_fdc.h" +#include "video/hd61830.h" +#include "video/i8275.h" +#include "sound/beep.h" +#include "emupal.h" +#include "screen.h" +#include "speaker.h" + +class magnum_state : public driver_device +{ +public: + magnum_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_beep(*this, "beep") + , m_shift(*this, "SHIFT") + { + } + void magnum(machine_config &config); + DECLARE_INPUT_CHANGED_MEMBER(keypress); +protected: + virtual void machine_reset() override; + virtual void machine_start() override; + +private: + void beep_w(u8 data); + u8 sysctl_r(offs_t offset); + void sysctl_w(offs_t offset, u8 data); + u16 irqstat_r(); + void port50_w(u16 data); + DECLARE_WRITE_LINE_MEMBER(rtcirq_w); + + void check_irq(); + void magnum_io(address_map &map); + void magnum_map(address_map &map); + void magnum_lcdc(address_map &map); + + required_device m_maincpu; + required_device m_beep; + required_ioport m_shift; + + u8 m_key; + bool m_wake, m_rtcirq, m_keybirq; +}; + +void magnum_state::check_irq() +{ + if(m_rtcirq || m_keybirq) + { + m_maincpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); + m_maincpu->int0_w(ASSERT_LINE); + m_wake = true; + } + else + m_maincpu->int0_w(CLEAR_LINE); +} + +INPUT_CHANGED_MEMBER(magnum_state::keypress) +{ + if(newval != oldval) + { + m_key = (uint8_t)(param & 0xff) | (m_shift->read() & 0xc ? 0 : 0x80); + m_keybirq = true; + check_irq(); + } +} + +static INPUT_PORTS_START(magnum) + PORT_START("ROW.0") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 0) + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 1) + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 4) + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 5) + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 8) + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 9) + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 12) + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 13) + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 2) // all 0x4 bits in every nibble also repeated in row 4+ + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 3) // all 0x8 bits in every nibble also repeated in row 4+ + PORT_START("ROW.1") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 16) + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 17) + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F11) PORT_CHAR(UCHAR_MAMEKEY(F11)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 20) + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 21) + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 24) + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 25) + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 28) + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 29) + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 18) + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 19) + PORT_START("ROW.2") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 32) + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 33) + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 36) + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 37) + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 40) + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 41) + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 44) + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 45) + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 34) + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 35) + PORT_START("ROW.3") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 48) + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 49) + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Help") PORT_CODE(KEYCODE_INSERT) PORT_CHAR(UCHAR_MAMEKEY(INSERT)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 52) + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 53) + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 56) + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 57) + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 60) + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 61) + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 50) + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 51) + PORT_START("ROW.4") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 64) + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 65) + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 68) + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 69) + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 72) + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 73) + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 76) + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 77) + PORT_START("ROW.5") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 80) + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 81) + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F12) PORT_CHAR(UCHAR_MAMEKEY(F12)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 84) + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 85) + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 88) + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 89) + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 92) + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 93) + PORT_START("ROW.6") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 96) + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_UNKNOWN) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 97) + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Line Feed") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 100) + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 101) + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 104) + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 105) + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 108) + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 109) + PORT_START("ROW.7") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 112) + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 113) + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 116) + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F10) PORT_CHAR(UCHAR_MAMEKEY(F10)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 117) + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 120) + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 121) + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 124) + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 125) + PORT_START("SHIFT") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_MAMEKEY(RCONTROL)) +INPUT_PORTS_END + +void magnum_state::machine_start() +{ +} + +void magnum_state::machine_reset() +{ + m_wake = false; + m_rtcirq = false; + m_keybirq = false; +} + +void magnum_state::beep_w(u8 data) +{ + if (data & ~1) logerror("beep_w unmapped bits %02x\n", data); + m_beep->set_state(BIT(data, 0)); +} + +void magnum_state::magnum_map(address_map &map) +{ + map(0x00000, 0x3ffff).ram(); // fixed 256k for now + map(0xe0000, 0xfffff).rom().region("bios", 0); +} + +u8 magnum_state::sysctl_r(offs_t offset) +{ + switch(offset) + { + case 0: + return m_key; + case 1: + { + u8 ret = m_keybirq ? 1 : 0; + m_keybirq = false; + check_irq(); + return ret | (m_shift->read() & 3 ? 0 : 4); + } + } + return 0; +} + +void magnum_state::sysctl_w(offs_t offset, u8 data) +{ + switch(offset) + { + case 0: + break; + case 2: + m_maincpu->set_input_line(INPUT_LINE_RESET, data ? CLEAR_LINE : ASSERT_LINE); + break; + case 4: + break; + case 6: + break; + case 12: + break; + } +} + +/* IRQs + * bit 0 - + * 1 - + * 2 - + * 3 - + * 4 - + * 5 - Keyboard? + * 6 - RTC? + * 7 - + * 8 - UART1? + * 9 - UART2? + * 10- Reset? + * 11-14 ... + * 15- CRTC? + */ + +u16 magnum_state::irqstat_r() +{ + u16 ret = m_wake ? 0 : 0x400; + ret |= m_rtcirq ? 0x40 : 0; + ret |= m_keybirq ? 0x20 : 0; + m_wake = false; + return ret; +} + +void magnum_state::port50_w(u16 data) +{ +} + +WRITE_LINE_MEMBER(magnum_state::rtcirq_w) +{ + m_rtcirq = state == ASSERT_LINE; + check_irq(); +} + +void magnum_state::magnum_io(address_map &map) +{ + map.unmap_value_high(); + //map(0x000a, 0x000b) cdp1854 1 + //map(0x000e, 0x000f) cpd1854 2 + //map(0x0014, 0x0017).rw("crtc", FUNC(i8275_device::read), FUNC(i8275_device::write)).umask16(0x00ff); + map(0x0018, 0x0019).rw("lcdc2", FUNC(hd61830_device::data_r), FUNC(hd61830_device::data_w)).umask16(0x00ff); + map(0x001a, 0x001b).rw("lcdc2", FUNC(hd61830_device::status_r), FUNC(hd61830_device::control_w)).umask16(0x00ff); + map(0x001c, 0x001d).rw("lcdc1", FUNC(hd61830_device::data_r), FUNC(hd61830_device::data_w)).umask16(0x00ff); + map(0x001e, 0x001f).rw("lcdc1", FUNC(hd61830_device::status_r), FUNC(hd61830_device::control_w)).umask16(0x00ff); + map(0x0040, 0x004f).rw(FUNC(magnum_state::sysctl_r), FUNC(magnum_state::sysctl_w)); + map(0x0050, 0x0051).rw(FUNC(magnum_state::irqstat_r), FUNC(magnum_state::port50_w)); + map(0x0056, 0x0056).w(FUNC(magnum_state::beep_w)); + map(0x0080, 0x008f).rw("rtc", FUNC(cdp1879_device::read), FUNC(cdp1879_device::write)).umask16(0x00ff); + //map(0x0100, 0x0107).rw("fdc", FUNC(wd1793_device::read), FUNC(wd1793_device::write)).umask16(0x00ff); +} + +void magnum_state::magnum_lcdc(address_map &map) +{ + map(0x0000, 0x027f).ram(); +} + +void magnum_state::magnum(machine_config &config) +{ + I80186(config, m_maincpu, XTAL(12'000'000)); + m_maincpu->set_addrmap(AS_PROGRAM, &magnum_state::magnum_map); + m_maincpu->set_addrmap(AS_IO, &magnum_state::magnum_io); + + CDP1879(config, "rtc", XTAL(32'768)).irq_callback().set(FUNC(magnum_state::rtcirq_w)); + + screen_device &screen1(SCREEN(config, "screen1", SCREEN_TYPE_LCD)); + screen1.set_refresh_hz(50); + screen1.set_screen_update("lcdc1", FUNC(hd61830_device::screen_update)); + screen1.set_size(6*40, 9*16); + screen1.set_visarea(0, 6*40-1, 0, 8*16-1); + screen1.set_palette("palette"); + + screen_device &screen2(SCREEN(config, "screen2", SCREEN_TYPE_LCD)); + screen2.set_refresh_hz(50); + screen2.set_screen_update("lcdc2", FUNC(hd61830_device::screen_update)); + screen2.set_size(6*40, 9*16); + screen2.set_visarea(0, 6*40-1, 0, 8*16-1); + screen2.set_palette("palette"); + + hd61830_device &lcdc1(HD61830(config, "lcdc1", 1000000)); // unknown clock + lcdc1.set_addrmap(0, &magnum_state::magnum_lcdc); + lcdc1.set_screen("screen1"); + + hd61830_device &lcdc2(HD61830(config, "lcdc2", 1000000)); // unknown clock + lcdc2.set_addrmap(0, &magnum_state::magnum_lcdc); + lcdc2.set_screen("screen2"); + + //I8275(config, "crtc", 3000000); // unknown clock + + //WD1793(config, "fdc", 1000000); // nothing known, type or if any disks even exist, port 0x44 is possibly motor control + + PALETTE(config, "palette", palette_device::MONOCHROME_INVERTED); + + SPEAKER(config, "speaker").front_center(); + BEEP(config, m_beep, 500).add_route(ALL_OUTPUTS, "speaker", 0.50); // frequency is guessed +} + +ROM_START( magnum ) + ROM_REGION16_LE(0x20000, "bios", 0) + ROM_LOAD16_BYTE("a1.7.88.bin", 0x00000, 0x4000, CRC(57882427) SHA1(97637b65ca43eb9d3bba546fb8ca701ba25ade8d)) + ROM_LOAD16_BYTE("a1.7.81.bin", 0x00001, 0x4000, CRC(949f53a8) SHA1(b339f1495d9af7dfff0c3a2c24789631f9d1265b)) + ROM_LOAD16_BYTE("a1.7.87.bin", 0x08000, 0x4000, CRC(25036dda) SHA1(20bc3782a66855b20cb0abe1051fa2eb50c7a860)) + ROM_LOAD16_BYTE("a1.7.82.bin", 0x08001, 0x4000, CRC(ecf387d8) SHA1(8b42f6ab030afb51f21f4a56c62e5acf7d074066)) + ROM_LOAD16_BYTE("a1.7.86.bin", 0x10000, 0x4000, CRC(c80b3a6b) SHA1(0f0d2cb653bbeff8f3bab6d20dc30c220a67a315)) + ROM_LOAD16_BYTE("a1.7.83.bin", 0x10001, 0x4000, CRC(51f56d78) SHA1(df717eada5e6439b1c01d91bd0ea009cd0f8ddfa)) + ROM_LOAD16_BYTE("a1.7.85.bin", 0x18000, 0x4000, CRC(f5dd5407) SHA1(af2edf7a658bcf648acb8be9f13849f838d96214)) + ROM_LOAD16_BYTE("a1.7.84.bin", 0x18001, 0x4000, CRC(b3434bb0) SHA1(8000a7aca8fc505b136a618d9eb210c50393eff1)) + + ROM_REGION(0x1000, "char", 0) + ROM_LOAD("dulmontcharrom.bin", 0x0000, 0x1000, CRC(9dff89bf) SHA1(d359aeba7f0b0c81accf3bca25e7da636c033721)) +ROM_END + +COMP( 1983, magnum, 0, 0, magnum, magnum, magnum_state, empty_init, "Dulmont", "Magnum", MACHINE_IMPERFECT_SOUND) diff --git a/src/mame/ausnz/mbee.cpp b/src/mame/ausnz/mbee.cpp new file mode 100644 index 00000000000..7c864a175fd --- /dev/null +++ b/src/mame/ausnz/mbee.cpp @@ -0,0 +1,1194 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert +/*************************************************************************** + +Driver completely rewritten by Robbbert, in a process begun on 2009-02-24. +Assistance/advice was gratefully received from: + E.J.Wordsworth (owner of Microbee Systems), nama, ChickenMan, + and the author of the "ubee512" emulator. + +Previous driver was written by Juergen Buchmueller, Jan 2000 with assistance +from Brett Selwood and Andrew Davies. + + + Keyboard notes are in video/microbee.cpp + + 256tc: The 1.31 rom version which appears to fit the 256TC is actually + part of the Z80 emulation in the Matilda model. If you fit this rom into a real + 256TC, the floppy disk will not be detected. + + The unemulated Matilda is a IBM XT clone fitted with a NEC V40, and has the + ability to emulate the 256TC as mentioned above. + + The Premium Plus was a limited-edition kit from Microbee Systems, but we don't + have any technical info or schematic as yet. It starts up, keyboard works, disks + work much the same as a 128k or 256tc. It has 1024k of RAM. + The kit itself has an extra custom FPGA CPU board with memory-card slot, but there's + no info on it yet. We just emulate the Z80 portion. + + ICs on schematics, pcbs, and manuals which never made it into production machines: + - Z80SCC; + - SN76489A; + - 2651A; + - B & C roms on disk-based machines. + + Floppy formats: + - All disks are the standard CPCEMU 'dsk' format. + - Types are 9/13cm 40/80 track (single or double sided) + - 13cm has been specified as QD to prevent a nasty crash if an 80-track disk was mounted + - The tracks/sector layout is the same regardless of size + - Although certain models came with particular drives as standard, users could add + the other size if they wished. We support both sizes on any model. + + Early machines have 'standard' video (128 hires characters). + Later machines had the option of 'premium' video which + provides thousands of hires characters, enough to simulate + bit-mapped graphics. + + Commands to call up built-in roms (depends on the model): + NET - Jump to E000, usually the Telcom communications program. + This rom can be replaced with the Dreamdisk Chip-8 rom. + Note that Telcom 3.21 is 8k, it uses a rombank switch + (by reading port 0A) to swap between the two halves. + See Telcom notes below. + + MEM - same as NET. + + EDASM - Jump to C000, usually the Editor/Assembler package. + + MENU - Do a rombank switch to bank 5 and jump to C000 to start the Shell + + PAK n - Do a rombank switch (write to port 0A) to bank "n" and jump to C000. + + These early colour computers have a PROM to create the foreground palette. + + Notes about the printer: + - Older models default to a 1200 baud serial printer, which we do not support. + - You need to change it to parallel by entering OUTL#1 while in Basic. + - After you mount/create a printfile, you can LPRINT and LLIST in Basic, + or by using the printing option in other apps. + + Notes about Telcom: + - On the older models, Telcom is called up by entering NET from within Basic. Models + from the pc85 onwards have it as a menu option. + - To exit, press Enter without any input. Disk versions, enter CPM or press ^C. + - After being used, version 3 and up will enable the use of OUT#7 in Basic, which + changes the screen to 80x24. Enter OUT#0 to revert to normal. + - Most versions of Telcom can have their parameters adjusted directly from Basic, + without needing to enter the Telcom program. + - Most versions of Telcom have an optional clock. In older models firstly select VS + from the MAME config menu, then enter NET CLOCK to enable it. NET TIME hhmm to set + the time (24hour format). NET CLOCKD is supposed to remove the status line, but it + doesn't, although the clock stops updating. NET CLOCK and NET CLOCKD are toggles. + - Telcom 1.2 (used in mbeeic) has a bug. If you enter NET CLOCK, the status line is + filled with inverse K. You can fix this from Basic by doing NET CLOCK 3 times. + + Notes about Disk System + - Ports 44 to 47 are for standard connection to FD2793. + - Port 48 is used for drive/side/density select on write, and intrq/drq on read. + intrq and drq are OR'd together, then gated to bit 7 of the data bus whenever + port 48 is activated on read. There are no interrupts used. + - The 256TC can boot from the B drive if you hold down Shift and hit F1 at the menu. + + How to use the config switch for PIO B7: + - Teleterm: Must use RTC. Anything else makes teleterm go crazy. + - 256TC, 128, 128p: Doesn't seem to matter, leave at the default. + - Standard: Has no effect, best left at "Tied High" + - Other rom-based models: "VS" to make the Telcom clock work, or "Tied high". + - 56k: not sure yet, leave as "Tied high" until more is known. + +*************************************************************************** + + TODO/not working: + + Old CRTC-based keyboard: + - Paste drops many characters. + - Typing can drop the occasional character. + - mbee -bios 1 is unusable due to keyboard issues. + + FDC: (TODO: see if these bugs still exist) + - B drive doesn't work with most disks. + - some disks cause MAME to freeze. + + - 128k: Simply Write has no keyboard. + + - 256tc: the Intro disk doesn't work + + - 256tc, Teleterm: Keyboard CPU inbuilt ROM needs to be dumped. + - 128k, 64k: PALs need to be dumped for the bankswitching. + + - Mouse: a few programs support the use of a serial mouse which interfaced + directly to the Z80PIO. However there's little info to be found. + PIO B3 to ground activates the mouse pointer in Shell v3.01. + + - Hard drive (10MB) & controller + +*******************************************************************************/ + +#include "emu.h" +#include "mbee.h" +#include "formats/mbee_cas.h" +#include "sound/sn76496.h" +#include "softlist_dev.h" +#include "speaker.h" + +void mbee_state::mbee_mem(address_map &map) +{ + map.unmap_value_high(); + map(0x0000, 0x7fff).ram(); + map(0x8000, 0xbfff).rom().region("maincpu",0); + map(0xc000, 0xdfff).r(FUNC(mbee_state::pak_r)); + map(0xe000, 0xefff).r(FUNC(mbee_state::net_r)); + map(0xf000, 0xf7ff).rw(FUNC(mbee_state::video_low_r), FUNC(mbee_state::video_low_w)); + map(0xf800, 0xffff).rw(FUNC(mbee_state::video_high_r), FUNC(mbee_state::video_high_w)); +} + +void mbee_state::mbeeic_mem(address_map &map) +{ + map(0x0000, 0x7fff).ram(); + map(0x8000, 0xbfff).rom().region("maincpu",0); + map(0xc000, 0xdfff).r(FUNC(mbee_state::pak_r)); + map(0xe000, 0xefff).r(FUNC(mbee_state::net_r)); + map(0xf000, 0xf7ff).rw(FUNC(mbee_state::video_low_r), FUNC(mbee_state::video_low_w)); + map(0xf800, 0xffff).rw(FUNC(mbee_state::video_high_r), FUNC(mbee_state::video_high_w)); +} + +void mbee_state::mbeeppc_mem(address_map &map) +{ + map(0x0000, 0x7fff).ram(); + map(0x8000, 0x9fff).bankr("basic"); + map(0xa000, 0xbfff).rom().region("maincpu",0); + map(0xc000, 0xdfff).r(FUNC(mbee_state::pak_r)); + map(0xe000, 0xefff).r(FUNC(mbee_state::net_r)); + map(0xf000, 0xf7ff).rw(FUNC(mbee_state::video_low_r), FUNC(mbee_state::video_low_w)); + map(0xf800, 0xffff).rw(FUNC(mbee_state::video_high_r), FUNC(mbee_state::video_high_w)); +} + +void mbee_state::mbeett_mem(address_map &map) +{ + map(0x0000, 0x7fff).ram(); + map(0x8000, 0x9fff).rom().region("maincpu",0); + map(0xa000, 0xbfff).ram(); + map(0xc000, 0xdfff).r(FUNC(mbee_state::pak_r)); + map(0xe000, 0xefff).r(FUNC(mbee_state::net_r)); + map(0xf000, 0xf7ff).rw(FUNC(mbee_state::video_low_r), FUNC(mbee_state::video_low_w)); + map(0xf800, 0xffff).rw(FUNC(mbee_state::video_high_r), FUNC(mbee_state::video_high_w)); +} + +void mbee_state::mbee56_mem(address_map &map) +{ + map(0x0000, 0xdfff).ram(); + map(0xe000, 0xefff).rom().region("maincpu",0); + map(0xf000, 0xf7ff).rw(FUNC(mbee_state::video_low_r), FUNC(mbee_state::video_low_w)); + map(0xf800, 0xffff).rw(FUNC(mbee_state::video_high_r), FUNC(mbee_state::video_high_w)); +} + +void mbee_state::mbee256_mem(address_map &map) +{ + map(0x0000, 0x0fff).bankr("bankr0").bankw("bankw0"); + map(0x1000, 0x1fff).bankr("bankr1").bankw("bankw1"); + map(0x2000, 0x2fff).bankr("bankr2").bankw("bankw2"); + map(0x3000, 0x3fff).bankr("bankr3").bankw("bankw3"); + map(0x4000, 0x4fff).bankr("bankr4").bankw("bankw4"); + map(0x5000, 0x5fff).bankr("bankr5").bankw("bankw5"); + map(0x6000, 0x6fff).bankr("bankr6").bankw("bankw6"); + map(0x7000, 0x7fff).bankr("bankr7").bankw("bankw7"); + map(0x8000, 0x8fff).bankr("bankr8").bankw("bankw8"); + map(0x9000, 0x9fff).bankr("bankr9").bankw("bankw9"); + map(0xa000, 0xafff).bankr("bankr10").bankw("bankw10"); + map(0xb000, 0xbfff).bankr("bankr11").bankw("bankw11"); + map(0xc000, 0xcfff).bankr("bankr12").bankw("bankw12"); + map(0xd000, 0xdfff).bankr("bankr13").bankw("bankw13"); + map(0xe000, 0xefff).bankr("bankr14").bankw("bankw14"); + map(0xf000, 0xffff).bankr("bankr15").bankw("bankw15"); +} + +void mbee_state::mbee_io(address_map &map) +{ + map.global_mask(0xff); + map.unmap_value_high(); + map(0x00, 0x03).mirror(0x10).rw(m_pio, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt)); + map(0x0b, 0x0b).mirror(0x10).w(FUNC(mbee_state::port0b_w)); + map(0x0c, 0x0c).mirror(0x10).r(m_crtc, FUNC(mc6845_device::status_r)).w(FUNC(mbee_state::m6545_index_w)); + map(0x0d, 0x0d).mirror(0x10).r(m_crtc, FUNC(mc6845_device::register_r)).w(FUNC(mbee_state::m6545_data_w)); +} + +void mbee_state::mbeeic_io(address_map &map) +{ + map.unmap_value_high(); + map(0x0000, 0x0003).mirror(0xff10).rw(m_pio, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt)); + map(0x0008, 0x0008).mirror(0xff10).rw(FUNC(mbee_state::port08_r), FUNC(mbee_state::port08_w)); + map(0x0009, 0x0009).mirror(0xff00).nopw(); + map(0x000a, 0x000a).select(0xff10).rw(FUNC(mbee_state::telcom_r), FUNC(mbee_state::port0a_w)); + map(0x000b, 0x000b).mirror(0xff10).w(FUNC(mbee_state::port0b_w)); + map(0x000c, 0x000c).mirror(0xff10).r(m_crtc, FUNC(mc6845_device::status_r)).w(FUNC(mbee_state::m6545_index_w)); + map(0x000d, 0x000d).mirror(0xff10).r(m_crtc, FUNC(mc6845_device::register_r)).w(FUNC(mbee_state::m6545_data_w)); +} + +void mbee_state::mbeeppc_io(address_map &map) +{ + map.unmap_value_high(); + map(0x0000, 0x0003).mirror(0xff10).rw(m_pio, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt)); + map(0x0008, 0x0008).mirror(0xff10).rw(FUNC(mbee_state::port08_r), FUNC(mbee_state::port08_w)); + map(0x0009, 0x0009).mirror(0xff00).nopw(); + map(0x000a, 0x000a).select(0xff10).rw(FUNC(mbee_state::telcom_r), FUNC(mbee_state::port0a_w)); + map(0x000b, 0x000b).mirror(0xff10).w(FUNC(mbee_state::port0b_w)); + map(0x000c, 0x000c).mirror(0xff00).r(m_crtc, FUNC(mc6845_device::status_r)).w(FUNC(mbee_state::m6545_index_w)); + map(0x000d, 0x000d).mirror(0xff10).r(m_crtc, FUNC(mc6845_device::register_r)).w(FUNC(mbee_state::m6545_data_w)); + map(0x001c, 0x001c).mirror(0xff00).rw(FUNC(mbee_state::port1c_r), FUNC(mbee_state::port1c_w)); +} + +void mbee_state::mbeett_io(address_map &map) +{ + map.unmap_value_high(); + map(0x0000, 0x0003).mirror(0xff00).rw(m_pio, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt)); + map(0x0004, 0x0004).mirror(0xff00).w(FUNC(mbee_state::port04_w)); + map(0x0006, 0x0006).mirror(0xff00).w(FUNC(mbee_state::port06_w)); + map(0x0007, 0x0007).mirror(0xff00).r(FUNC(mbee_state::port07_r)); + map(0x0008, 0x0008).mirror(0xff00).rw(FUNC(mbee_state::port08_r), FUNC(mbee_state::port08_w)); + map(0x000a, 0x000a).select(0xff10).rw(FUNC(mbee_state::telcom_r), FUNC(mbee_state::port0a_w)); + map(0x000b, 0x000b).mirror(0xff00).w(FUNC(mbee_state::port0b_w)); + map(0x000c, 0x000c).mirror(0xff00).r(m_crtc, FUNC(mc6845_device::status_r)).w(FUNC(mbee_state::m6545_index_w)); + map(0x000d, 0x000d).mirror(0xff00).r(m_crtc, FUNC(mc6845_device::register_r)).w(FUNC(mbee_state::m6545_data_w)); + map(0x0018, 0x001b).mirror(0xff00).r(FUNC(mbee_state::port18_r)); + map(0x001c, 0x001f).mirror(0xff00).rw(FUNC(mbee_state::port1c_r), FUNC(mbee_state::port1c_w)); + map(0x0009, 0x0009).select(0xff00).r(FUNC(mbee_state::speed_r)); + map(0x0068, 0x006f).mirror(0xff00).noprw(); // swallow i/o to SCC which was never fitted to production machines +} + +void mbee_state::mbee56_io(address_map &map) +{ + map.global_mask(0xff); + map.unmap_value_high(); + map(0x00, 0x03).rw(m_pio, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt)); + map(0x08, 0x08).rw(FUNC(mbee_state::port08_r), FUNC(mbee_state::port08_w)); + map(0x09, 0x09).nopw(); + map(0x0b, 0x0b).w(FUNC(mbee_state::port0b_w)); + map(0x0c, 0x0c).r(m_crtc, FUNC(mc6845_device::status_r)).w(FUNC(mbee_state::m6545_index_w)); + map(0x0d, 0x0d).r(m_crtc, FUNC(mc6845_device::register_r)).w(FUNC(mbee_state::m6545_data_w)); + map(0x44, 0x47).rw(m_fdc, FUNC(wd2793_device::read), FUNC(wd2793_device::write)); + map(0x48, 0x4f).rw(FUNC(mbee_state::fdc_status_r), FUNC(mbee_state::fdc_motor_w)); +} + +void mbee_state::mbee128_io(address_map &map) +{ + map.global_mask(0xff); + map.unmap_value_high(); + map(0x00, 0x03).rw(m_pio, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt)); + map(0x04, 0x04).w(FUNC(mbee_state::port04_w)); + map(0x06, 0x06).w(FUNC(mbee_state::port06_w)); + map(0x07, 0x07).r(FUNC(mbee_state::port07_r)); + map(0x08, 0x08).rw(FUNC(mbee_state::port08_r), FUNC(mbee_state::port08_w)); + map(0x09, 0x09).nopw(); + map(0x0b, 0x0b).w(FUNC(mbee_state::port0b_w)); + map(0x0c, 0x0c).r(m_crtc, FUNC(mc6845_device::status_r)).w(FUNC(mbee_state::m6545_index_w)); + map(0x0d, 0x0d).r(m_crtc, FUNC(mc6845_device::register_r)).w(FUNC(mbee_state::m6545_data_w)); + map(0x1c, 0x1f).rw(FUNC(mbee_state::port1c_r), FUNC(mbee_state::port1c_w)); + map(0x44, 0x47).rw(m_fdc, FUNC(wd2793_device::read), FUNC(wd2793_device::write)); + map(0x48, 0x4f).rw(FUNC(mbee_state::fdc_status_r), FUNC(mbee_state::fdc_motor_w)); + map(0x50, 0x57).w(FUNC(mbee_state::port50_w)); +} + +void mbee_state::mbee128p_io(address_map &map) +{ + map.global_mask(0xff); + map.unmap_value_high(); + mbee128_io(map); + map(0x10, 0x13).w("sn1", FUNC(sn76489a_device::write)); +} + +void mbee_state::mbee256_io(address_map &map) +{ + map.unmap_value_high(); + map(0x0000, 0x0003).mirror(0xff00).rw(m_pio, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt)); + map(0x0004, 0x0004).mirror(0xff00).w(FUNC(mbee_state::port04_w)); + map(0x0006, 0x0006).mirror(0xff00).w(FUNC(mbee_state::port06_w)); + map(0x0007, 0x0007).mirror(0xff00).r(FUNC(mbee_state::port07_r)); + map(0x0008, 0x0008).mirror(0xff00).rw(FUNC(mbee_state::port08_r), FUNC(mbee_state::port08_w)); + map(0x0009, 0x0009).select(0xff00).r(FUNC(mbee_state::speed_r)); + map(0x0009, 0x0009).mirror(0xff00).nopw(); + map(0x000b, 0x000b).mirror(0xff00).w(FUNC(mbee_state::port0b_w)); + map(0x000c, 0x000c).mirror(0xff00).r(m_crtc, FUNC(mc6845_device::status_r)).w(FUNC(mbee_state::m6545_index_w)); + map(0x000d, 0x000d).mirror(0xff00).r(m_crtc, FUNC(mc6845_device::register_r)).w(FUNC(mbee_state::m6545_data_w)); + map(0x0010, 0x0013).mirror(0xff00).w("sn1", FUNC(sn76489a_device::write)); + map(0x0018, 0x001b).mirror(0xff00).r(FUNC(mbee_state::port18_r)); + map(0x001c, 0x001f).mirror(0xff00).rw(FUNC(mbee_state::port1c_r), FUNC(mbee_state::port1c_w)); + map(0x0044, 0x0047).mirror(0xff00).rw(m_fdc, FUNC(wd2793_device::read), FUNC(wd2793_device::write)); + map(0x0048, 0x004f).mirror(0xff00).rw(FUNC(mbee_state::fdc_status_r), FUNC(mbee_state::fdc_motor_w)); + map(0x0050, 0x0057).mirror(0xff00).w(FUNC(mbee_state::port50_w)); + // map(0x0058, 0x005f).mirror(0xff00); External options: floppy drive, hard drive and keyboard + // map(0x0060, 0x0067).mirror(0xff00); Reserved for file server selection (unused) + // map(0x0068, 0x006f).mirror(0xff00); Reserved for 8530 SCC (never used) +} + +static INPUT_PORTS_START( oldkb ) + PORT_START("X.0") /* IN0 KEY ROW 0 [000] */ + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("@") PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR('@') PORT_CHAR('`') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') PORT_CHAR(0x01) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') PORT_CHAR(0x02) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') PORT_CHAR(0x03) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') PORT_CHAR(0x04) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') PORT_CHAR(0x05) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') PORT_CHAR(0x06) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') PORT_CHAR(0x07) + + PORT_START("X.1") /* IN1 KEY ROW 1 [080] */ + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') PORT_CHAR(0x08) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') PORT_CHAR(0x09) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') PORT_CHAR(0x0a) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') PORT_CHAR(0x0b) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') PORT_CHAR(0x0c) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') PORT_CHAR(0x0d) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') PORT_CHAR(0x0e) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') PORT_CHAR(0x0f) + + PORT_START("X.2") /* IN2 KEY ROW 2 [100] */ + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') PORT_CHAR(0x10) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') PORT_CHAR(0x11) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') PORT_CHAR(0x12) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') PORT_CHAR(0x13) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') PORT_CHAR(0x14) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') PORT_CHAR(0x15) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') PORT_CHAR(0x16) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') PORT_CHAR(0x17) + + PORT_START("X.3") /* IN3 KEY ROW 3 [180] */ + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') PORT_CHAR(0x18) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') PORT_CHAR(0x19) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') PORT_CHAR(0x1a) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("[") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') PORT_CHAR(0x1b) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("\\") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') PORT_CHAR(0x1c) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("]") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') PORT_CHAR(0x1d) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("^") PORT_CODE(KEYCODE_TILDE) PORT_CHAR('^') PORT_CHAR('~') PORT_CHAR(0x1e) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Delete") PORT_CODE(KEYCODE_DEL) PORT_CHAR(8) PORT_CHAR(0x5f) PORT_CHAR(0x1f) // port_char not working - hijacked + + PORT_START("X.4") /* IN4 KEY ROW 4 [200] */ + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("1 !") PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("2 \"") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('\"') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("3 #") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("4 $") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("5 %") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("6 &") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("7 '") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'') + + PORT_START("X.5") /* IN5 KEY ROW 5 [280] */ + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("8 (") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("9 )") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(": *") PORT_CODE(KEYCODE_COLON) PORT_CHAR(':') PORT_CHAR('*') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("; +") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(';') PORT_CHAR('+') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(", <") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("- =") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('=') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(". >") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("/ ?") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') + + PORT_START("X.6") /* IN6 KEY ROW 6 [300] */ + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Escape") PORT_CODE(KEYCODE_ESC) PORT_CHAR(27) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Backspace") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tab") PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Linefeed") PORT_CODE(KEYCODE_HOME) PORT_CHAR(10) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Enter") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Lock") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Break") PORT_CODE(KEYCODE_END) PORT_CHAR(3) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + + PORT_START("X.7") /* IN7 KEY ROW 7 [380] */ + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("(Up)") PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Ctrl") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_SHIFT_2) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("(Down)") PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("(Left)") PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("(Right)") PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) +INPUT_PORTS_END + +static INPUT_PORTS_START( mbee ) + + PORT_INCLUDE( oldkb ) + + // Autorun on quickload + PORT_START("CONFIG") + PORT_CONFNAME( 0x01, 0x01, "Autorun on Quickload") + PORT_CONFSETTING( 0x00, DEF_STR(No)) + PORT_CONFSETTING( 0x01, DEF_STR(Yes)) + // monochrome monitor could be used + PORT_CONFNAME( 0x30, 0x00, "Monitor type") + PORT_CONFSETTING( 0x00, "Colour") + PORT_CONFSETTING( 0x10, "Green") + PORT_CONFSETTING( 0x20, "Amber") + PORT_CONFSETTING( 0x30, "White") + // Wire links on motherboard + PORT_CONFNAME( 0xc0, 0x00, "PIO B7") + PORT_CONFSETTING( 0x00, "VS") // sync pulse to enable telcom clock + PORT_CONFSETTING( 0x40, "RTC") // optional board usually not fitted + PORT_CONFSETTING( 0x80, "Tied high") // default resistor to vcc + PORT_CONFSETTING( 0xc0, "Reserved for net") +INPUT_PORTS_END + +static INPUT_PORTS_START( mbee128 ) + + PORT_INCLUDE( oldkb ) + + // Autorun on quickload + PORT_START("CONFIG") + PORT_CONFNAME( 0x01, 0x01, "Autorun on Quickload") + PORT_CONFSETTING( 0x00, DEF_STR(No)) + PORT_CONFSETTING( 0x01, DEF_STR(Yes)) + // monochrome monitor could be used + PORT_CONFNAME( 0x30, 0x00, "Monitor type") + PORT_CONFSETTING( 0x00, "Colour") + PORT_CONFSETTING( 0x10, "Green") + PORT_CONFSETTING( 0x20, "Amber") + PORT_CONFSETTING( 0x30, "White") + // Wire links on motherboard + PORT_CONFNAME( 0xc0, 0x80, "PIO B7") + PORT_CONFSETTING( 0x00, "VS") // sync pulse to enable telcom clock + PORT_CONFSETTING( 0x40, "RTC") // RTC IRQ for clock + PORT_CONFSETTING( 0x80, "Tied high") // default resistor to vcc + PORT_CONFSETTING( 0xc0, "Reserved for net") +INPUT_PORTS_END + +static INPUT_PORTS_START( mbee256 ) + PORT_START("Y.0") /* IN0 KEY ROW 0 [+00] */ + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F1") PORT_CODE(KEYCODE_F1) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Escape") PORT_CODE(KEYCODE_ESC) PORT_CHAR(27) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Tab") PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Break") PORT_CODE(KEYCODE_END) PORT_CHAR(3) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("0 (num)") PORT_CODE(KEYCODE_0_PAD) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("DEL (num)") PORT_CODE(KEYCODE_DEL_PAD) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + + PORT_START("Y.1") /* IN1 KEY ROW 1 [+08] */ + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F2") PORT_CODE(KEYCODE_F2) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("1 !") PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') PORT_CHAR(0x11) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') PORT_CHAR(0x01) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Lock") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Linefeed") PORT_CODE(KEYCODE_HOME) PORT_CHAR(10) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Insert") PORT_CODE(KEYCODE_INSERT) + + PORT_START("Y.2") /* IN2 KEY ROW 2 [+10] */ + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F3") PORT_CODE(KEYCODE_F3) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("2 @") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') PORT_CHAR(0x17) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') PORT_CHAR(0x13) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("+ (num)") PORT_CODE(KEYCODE_PLUS_PAD) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("2 (num)") PORT_CODE(KEYCODE_2_PAD) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("3 (num)") PORT_CODE(KEYCODE_3_PAD) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') PORT_CHAR(0x1a) + + PORT_START("Y.3") /* IN3 KEY ROW 3 [+18] */ + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F4") PORT_CODE(KEYCODE_F4) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("3 #") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') PORT_CHAR(0x05) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') PORT_CHAR(0x04) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("- (num)") PORT_CODE(KEYCODE_MINUS_PAD) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("5 (num)") PORT_CODE(KEYCODE_5_PAD) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("6 (num)") PORT_CODE(KEYCODE_6_PAD) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') PORT_CHAR(0x18) + + PORT_START("Y.4") /* IN4 KEY ROW 4 [+20] */ + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F5") PORT_CODE(KEYCODE_F5) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("4 $") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') PORT_CHAR(0x12) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') PORT_CHAR(0x06) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("* (num)") PORT_CODE(KEYCODE_ASTERISK) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("8 (num)") PORT_CODE(KEYCODE_8_PAD) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("9 (num)") PORT_CODE(KEYCODE_9_PAD) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') PORT_CHAR(0x03) + + PORT_START("Y.5") /* IN5 KEY ROW 5 [+28] */ + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F6") PORT_CODE(KEYCODE_F6) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("5 %") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') PORT_CHAR(0x14) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') PORT_CHAR(0x07) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("7 (num)") PORT_CODE(KEYCODE_7_PAD) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("1 (num)") PORT_CODE(KEYCODE_1_PAD) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("4 (num)") PORT_CODE(KEYCODE_4_PAD) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') PORT_CHAR(0x16) + + PORT_START("Y.6") /* IN6 KEY ROW 6 [+30] */ + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F7") PORT_CODE(KEYCODE_F7) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("6 &") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') PORT_CHAR(0x19) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') PORT_CHAR(0x08) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("/ (num)") PORT_CODE(KEYCODE_SLASH_PAD) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("(Down)") PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("(Right)") PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') PORT_CHAR(0x02) + + PORT_START("Y.7") /* IN7 KEY ROW 7 [+38] */ + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F8") PORT_CODE(KEYCODE_F8) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("7 &") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') PORT_CHAR(0x15) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') PORT_CHAR(0x0a) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("(Left)") PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') PORT_CHAR(0x0e) + + PORT_START("Y.8") /* IN0 KEY ROW 0 [+40] */ + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F9") PORT_CODE(KEYCODE_F9) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("8 *") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') PORT_CHAR(0x09) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') PORT_CHAR(0x0b) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("(Up)") PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') PORT_CHAR(0x0d) + + PORT_START("Y.9") /* IN1 KEY ROW 1 [+48] */ + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F10") PORT_CODE(KEYCODE_F10) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("9 (") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') PORT_CHAR(0x0f) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') PORT_CHAR(0x0c) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Backspace") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Enter") PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(13) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(", <") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') + + PORT_START("Y.10") /* IN2 KEY ROW 2 [+50] */ + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F11") PORT_CODE(KEYCODE_F11) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("0 )") PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') PORT_CHAR(0x10) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("; :") PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Delete") PORT_CODE(KEYCODE_DEL) PORT_CHAR(127) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("` ~") PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("\\ |") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') PORT_CHAR(0x1c) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(". >") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') + + PORT_START("Y.11") /* IN3 KEY ROW 3 [+58] */ + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F12") PORT_CODE(KEYCODE_F12) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("-") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("[ {") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') PORT_CHAR(0x1b) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("\' \"") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('\"') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("= +") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("] }") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') PORT_CHAR(0x1d) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("/ ?") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') + + PORT_START("Y.12") /* IN4 KEY ROW 4 [+60] */ + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + + PORT_START("Y.13") /* IN5 KEY ROW 5 [+68] */ + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Ctrl") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_SHIFT_2) + + PORT_START("Y.14") /* IN6 KEY ROW 6 [+70] */ + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Alt") PORT_CODE(KEYCODE_LALT) PORT_CODE(KEYCODE_RALT) + + // Autorun on quickload + PORT_START("CONFIG") + PORT_CONFNAME( 0x01, 0x01, "Autorun on Quickload") + PORT_CONFSETTING( 0x00, DEF_STR(No)) + PORT_CONFSETTING( 0x01, DEF_STR(Yes)) + // Wire links on motherboard + PORT_CONFNAME( 0xc0, 0x80, "PIO B7") + PORT_CONFSETTING( 0x00, "VS") // sync pulse to enable telcom clock + PORT_CONFSETTING( 0x40, "RTC") // RTC IRQ must be used on teleterm + PORT_CONFSETTING( 0x80, "Tied high") // default resistor to vcc + PORT_CONFSETTING( 0xc0, "Reserved for net") +INPUT_PORTS_END + +static const z80_daisy_config mbee_daisy_chain[] = +{ + { "z80pio" }, + { nullptr } +}; + +/**************************** F4 CHARACTER DISPLAYER */ +static const gfx_layout charlayout = +{ + 8,16, /* 8 x 16 characters */ + RGN_FRAC(1,1), + 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, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8 }, + 8*16 /* every char takes 16 bytes */ +}; + +static GFXDECODE_START( gfx_mono ) + GFXDECODE_ENTRY( "chargen", 0x0000, charlayout, 96, 1 ) +GFXDECODE_END + +static GFXDECODE_START( gfx_standard ) + GFXDECODE_ENTRY( "chargen", 0x0000, charlayout, 0, 48 ) +GFXDECODE_END + +static GFXDECODE_START( gfx_premium ) + GFXDECODE_ENTRY( "chargen", 0x0000, charlayout, 0, 8 ) +GFXDECODE_END + +static void mbee_floppies(device_slot_interface &device) +{ + device.option_add("35dd", FLOPPY_35_DD); + device.option_add("525qd", FLOPPY_525_QD); +} + + +void mbee_state::remove_carts(machine_config &config) +{ + config.device_remove("cart_list"); + config.device_remove("optrom1"); + config.device_remove("optrom2"); + config.device_remove("optrom3"); + config.device_remove("optrom4"); + config.device_remove("optrom5"); + config.device_remove("optrom6"); + config.device_remove("optrom7"); +} + +void mbee_state::remove_quick(machine_config &config) +{ + config.device_remove("cass_list"); + config.device_remove("quickload"); + config.device_remove("quik_list"); +} + +void mbee_state::mbee(machine_config &config) +{ + /* basic machine hardware */ + Z80(config, m_maincpu, 12_MHz_XTAL / 6); /* 2 MHz */ + m_maincpu->set_addrmap(AS_PROGRAM, &mbee_state::mbee_mem); + m_maincpu->set_addrmap(AS_IO, &mbee_state::mbee_io); + m_maincpu->set_daisy_config(mbee_daisy_chain); + + Z80PIO(config, m_pio, 12_MHz_XTAL / 6); + m_pio->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); + m_pio->out_pa_callback().set("cent_data_out", FUNC(output_latch_device::write)); + m_pio->out_ardy_callback().set(FUNC(mbee_state::pio_ardy)); + m_pio->in_pb_callback().set(FUNC(mbee_state::pio_port_b_r)); + m_pio->out_pb_callback().set(FUNC(mbee_state::pio_port_b_w)); + + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_refresh_hz(50); + m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(250)); /* not accurate */ + m_screen->set_size(64*8, 19*16); /* need at least 17 lines for NET */ + m_screen->set_visarea(0*8, 64*8-1, 0, 19*16-1); + m_screen->set_screen_update(FUNC(mbee_state::screen_update_mbee)); + + GFXDECODE(config, "gfxdecode", m_palette, gfx_mono); + + PALETTE(config, m_palette, FUNC(mbee_state::standard_palette), 100); + + /* sound hardware */ + SPEAKER(config, "mono").front_center(); + SPEAKER_SOUND(config, "speaker").add_route(ALL_OUTPUTS, "mono", 0.50); + + /* devices */ + SY6545_1(config, m_crtc, 12_MHz_XTAL / 8); + m_crtc->set_screen(m_screen); + m_crtc->set_show_border_area(false); + m_crtc->set_char_width(8); + m_crtc->set_update_row_callback(FUNC(mbee_state::crtc_update_row)); + m_crtc->set_on_update_addr_change_callback(FUNC(mbee_state::crtc_update_addr)); + m_crtc->out_vsync_callback().set(FUNC(mbee_state::crtc_vs)); + + quickload_image_device &quickload(QUICKLOAD(config, "quickload", "mwb,com,bee,bin", attotime::from_seconds(3))); + quickload.set_load_callback(FUNC(mbee_state::quickload_cb)); + quickload.set_interface("mbee_quik"); + + CENTRONICS(config, m_centronics, centronics_devices, nullptr); + m_centronics->ack_handler().set(m_pio, FUNC(z80pio_device::strobe_a)); + + OUTPUT_LATCH(config, m_cent_data_out); + m_centronics->set_output_latch(*m_cent_data_out); + + CASSETTE(config, m_cassette); + m_cassette->set_formats(mbee_cassette_formats); + 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("mbee_cass"); + + generic_slot_device &optrom1(GENERIC_SOCKET(config, "optrom1", generic_plain_slot, "mbee_net", "mbn")); // net + optrom1.set_device_load(FUNC(mbee_state::pak_load<1U>)); + optrom1.set_device_unload(FUNC(mbee_state::pak_unload<1U>)); + generic_slot_device &optrom2(GENERIC_SOCKET(config, "optrom2", generic_plain_slot, "mbee_pak", "mbp")); // edasm + optrom2.set_device_load(FUNC(mbee_state::pak_load<2U>)); + optrom2.set_device_unload(FUNC(mbee_state::pak_unload<2U>)); + + SOFTWARE_LIST(config, "cass_list").set_original("mbee_cass").set_filter("1"); + SOFTWARE_LIST(config, "quik_list").set_original("mbee_quik").set_filter("1"); + SOFTWARE_LIST(config, "cart_list").set_original("mbee_cart").set_filter("1"); +} + + +void mbee_state::mbeeic(machine_config &config) +{ + /* basic machine hardware */ + Z80(config, m_maincpu, 13.5_MHz_XTAL / 4); /* 3.37500 MHz */ + m_maincpu->set_addrmap(AS_PROGRAM, &mbee_state::mbeeic_mem); + m_maincpu->set_addrmap(AS_IO, &mbee_state::mbeeic_io); + m_maincpu->set_daisy_config(mbee_daisy_chain); + + Z80PIO(config, m_pio, 13.5_MHz_XTAL / 4); + m_pio->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); + m_pio->out_pa_callback().set("cent_data_out", FUNC(output_latch_device::write)); + m_pio->out_ardy_callback().set(FUNC(mbee_state::pio_ardy)); + m_pio->in_pb_callback().set(FUNC(mbee_state::pio_port_b_r)); + m_pio->out_pb_callback().set(FUNC(mbee_state::pio_port_b_w)); + + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_refresh_hz(50); + m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(250)); /* not accurate */ + m_screen->set_size(80*8, 310); + m_screen->set_visarea(0, 80*8-1, 0, 19*16-1); + m_screen->set_screen_update(FUNC(mbee_state::screen_update_mbee)); + + GFXDECODE(config, "gfxdecode", m_palette, gfx_standard); + + PALETTE(config, m_palette, FUNC(mbee_state::standard_palette), 100); + + /* sound hardware */ + SPEAKER(config, "mono").front_center(); + SPEAKER_SOUND(config, "speaker").add_route(ALL_OUTPUTS, "mono", 0.50); + + /* devices */ + SY6545_1(config, m_crtc, 13.5_MHz_XTAL / 8); + m_crtc->set_screen(m_screen); + m_crtc->set_show_border_area(false); + m_crtc->set_char_width(8); + m_crtc->set_update_row_callback(FUNC(mbee_state::crtc_update_row)); + m_crtc->set_on_update_addr_change_callback(FUNC(mbee_state::crtc_update_addr)); + m_crtc->out_vsync_callback().set(FUNC(mbee_state::crtc_vs)); + + quickload_image_device &quickload(QUICKLOAD(config, "quickload", "mwb,com,bee,bin", attotime::from_seconds(3))); + quickload.set_load_callback(FUNC(mbee_state::quickload_cb)); + quickload.set_interface("mbee_quik"); + + CENTRONICS(config, m_centronics, centronics_devices, "printer"); + m_centronics->ack_handler().set(m_pio, FUNC(z80pio_device::strobe_a)); + + OUTPUT_LATCH(config, m_cent_data_out); + m_centronics->set_output_latch(*m_cent_data_out); + + CASSETTE(config, m_cassette); + m_cassette->set_formats(mbee_cassette_formats); + 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("mbee_cass"); + + generic_slot_device &optrom1(GENERIC_SOCKET(config, "optrom1", generic_plain_slot, "mbee_net", "mbn")); // net + optrom1.set_device_load(FUNC(mbee_state::pak_load<1U>)); + optrom1.set_device_unload(FUNC(mbee_state::pak_unload<1U>)); + generic_slot_device &optrom2(GENERIC_SOCKET(config, "optrom2", generic_plain_slot, "mbee_pak", "mbp")); // pak0 + optrom2.set_device_load(FUNC(mbee_state::pak_load<2U>)); + optrom2.set_device_unload(FUNC(mbee_state::pak_unload<2U>)); + generic_slot_device &optrom3(GENERIC_SOCKET(config, "optrom3", generic_plain_slot, "mbee_pak", "mbp")); // pak1 + optrom3.set_device_load(FUNC(mbee_state::pak_load<3U>)); + optrom3.set_device_unload(FUNC(mbee_state::pak_unload<3U>)); + generic_slot_device &optrom4(GENERIC_SOCKET(config, "optrom4", generic_plain_slot, "mbee_pak", "mbp")); // pak2 + optrom4.set_device_load(FUNC(mbee_state::pak_load<4U>)); + optrom4.set_device_unload(FUNC(mbee_state::pak_unload<4U>)); + generic_slot_device &optrom5(GENERIC_SOCKET(config, "optrom5", generic_plain_slot, "mbee_pak", "mbp")); // pak3 + optrom5.set_device_load(FUNC(mbee_state::pak_load<5U>)); + optrom5.set_device_unload(FUNC(mbee_state::pak_unload<5U>)); + generic_slot_device &optrom6(GENERIC_SOCKET(config, "optrom6", generic_plain_slot, "mbee_pak", "mbp")); // pak4 + optrom6.set_device_load(FUNC(mbee_state::pak_load<6U>)); + optrom6.set_device_unload(FUNC(mbee_state::pak_unload<6U>)); + generic_slot_device &optrom7(GENERIC_SOCKET(config, "optrom7", generic_plain_slot, "mbee_pak", "mbp")); // pak5 + optrom7.set_device_load(FUNC(mbee_state::pak_load<7U>)); + optrom7.set_device_unload(FUNC(mbee_state::pak_unload<7U>)); + + SOFTWARE_LIST(config, "cass_list").set_original("mbee_cass").set_filter("2"); + SOFTWARE_LIST(config, "quik_list").set_original("mbee_quik").set_filter("2"); + SOFTWARE_LIST(config, "cart_list").set_original("mbee_cart").set_filter("2"); +} + +void mbee_state::mbeepc85(machine_config &config) +{ + mbeeic(config); + SOFTWARE_LIST(config.replace(), "cart_list").set_original("mbee_cart").set_filter("3"); +} + +void mbee_state::mbeeppc(machine_config &config) +{ + mbeepc85(config); + + m_maincpu->set_addrmap(AS_PROGRAM, &mbee_state::mbeeppc_mem); + m_maincpu->set_addrmap(AS_IO, &mbee_state::mbeeppc_io); + subdevice("gfxdecode")->set_info(gfx_premium); + m_palette->set_init(FUNC(mbee_state::premium_palette)); + + MC146818(config, m_rtc, 32.768_kHz_XTAL); + m_rtc->irq().set(FUNC(mbee_state::rtc_irq_w)); +} + +void mbee_state::mbee56(machine_config &config) +{ + mbeeic(config); + m_maincpu->set_addrmap(AS_PROGRAM, &mbee_state::mbee56_mem); + m_maincpu->set_addrmap(AS_IO, &mbee_state::mbee56_io); + + WD2793(config, m_fdc, 4_MHz_XTAL / 2); + m_fdc->intrq_wr_callback().set(FUNC(mbee_state::fdc_intrq_w)); + m_fdc->drq_wr_callback().set(FUNC(mbee_state::fdc_drq_w)); + m_fdc->enmf_rd_callback().set_constant(0); + FLOPPY_CONNECTOR(config, m_floppy0, mbee_floppies, "35dd", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppy1, mbee_floppies, "35dd", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); + + SOFTWARE_LIST(config, "flop_list").set_original("mbee_flop").set_filter("1"); + remove_carts(config); + remove_quick(config); +} + +void mbee_state::mbee128(machine_config &config) +{ + mbee56(config); + m_maincpu->set_addrmap(AS_PROGRAM, &mbee_state::mbee256_mem); + m_maincpu->set_addrmap(AS_IO, &mbee_state::mbee128_io); + + MC146818(config, m_rtc, 32.768_kHz_XTAL); + m_rtc->irq().set(FUNC(mbee_state::rtc_irq_w)); + + SOFTWARE_LIST(config.replace(), "flop_list").set_original("mbee_flop").set_filter("2"); +} + +void mbee_state::mbee128p(machine_config &config) +{ + mbeeppc(config); + m_maincpu->set_addrmap(AS_PROGRAM, &mbee_state::mbee256_mem); + m_maincpu->set_addrmap(AS_IO, &mbee_state::mbee128p_io); + + WD2793(config, m_fdc, 4_MHz_XTAL / 2); + m_fdc->intrq_wr_callback().set(FUNC(mbee_state::fdc_intrq_w)); + m_fdc->drq_wr_callback().set(FUNC(mbee_state::fdc_drq_w)); + m_fdc->enmf_rd_callback().set_constant(0); + FLOPPY_CONNECTOR(config, m_floppy0, mbee_floppies, "35dd", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppy1, mbee_floppies, "35dd", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); + + SN76489A(config, "sn1", 13.5_MHz_XTAL / 4).add_route(ALL_OUTPUTS, "mono", 0.50); + + SOFTWARE_LIST(config, "flop_list").set_original("mbee_flop").set_filter("3"); + remove_carts(config); + remove_quick(config); +} + +void mbee_state::mbeepp(machine_config &config) +{ + mbee128p(config); + SOFTWARE_LIST(config.replace(), "flop_list").set_original("mbee_flop").set_filter("2,3"); +} + +void mbee_state::mbee256(machine_config &config) +{ + mbee128p(config); + m_maincpu->set_addrmap(AS_PROGRAM, &mbee_state::mbee256_mem); + m_maincpu->set_addrmap(AS_IO, &mbee_state::mbee256_io); + + TIMER(config, "newkb_timer").configure_periodic(FUNC(mbee_state::newkb_timer), attotime::from_hz(50)); + + SOFTWARE_LIST(config.replace(), "flop_list").set_original("mbee_flop").set_filter("4"); +} + +void mbee_state::mbeett(machine_config &config) +{ + mbeeppc(config); + m_maincpu->set_addrmap(AS_PROGRAM, &mbee_state::mbeett_mem); + m_maincpu->set_addrmap(AS_IO, &mbee_state::mbeett_io); + TIMER(config, "newkb_timer").configure_periodic(FUNC(mbee_state::newkb_timer), attotime::from_hz(50)); + remove_quick(config); + config.device_remove("optrom3"); + config.device_remove("optrom4"); + config.device_remove("optrom5"); + config.device_remove("optrom6"); + config.device_remove("optrom7"); + SOFTWARE_LIST(config.replace(), "cart_list").set_original("mbee_cart").set_filter("TT"); +} + +// This represents the Series 1: Kit computer, 16K, 32K, 16K Plus, and 32K plus. +ROM_START( mbee ) + ROM_REGION( 0x6000, "maincpu", 0 ) + ROM_SYSTEM_BIOS( 0, "510", "Basic 5.10" ) + ROMX_LOAD("bas510a.ic25", 0x0000, 0x1000, CRC(2ca47c36) SHA1(f36fd0afb3f1df26edc67919e78000b762b6cbcb), ROM_BIOS(0) ) + ROMX_LOAD("bas510b.ic27", 0x1000, 0x1000, CRC(a07a0c51) SHA1(dcbdd9df78b4b6b2972de2e4050dabb8ae9c3f5a), ROM_BIOS(0) ) + ROMX_LOAD("bas510c.ic28", 0x2000, 0x1000, CRC(906ac00f) SHA1(9b46458e5755e2c16cdb191a6a70df6de9fe0271), ROM_BIOS(0) ) + ROMX_LOAD("bas510d.ic30", 0x3000, 0x1000, CRC(61727323) SHA1(c0fea9fd0e25beb9faa7424db8efd07cf8d26c1b), ROM_BIOS(0) ) + ROM_SYSTEM_BIOS( 1, "500", "Basic 5.00" ) + ROMX_LOAD("bas500a.ic25", 0x0000, 0x1000, CRC(5fabd317) SHA1(a91bb6a802da17bc02e720e68b8bdd80261b5039), ROM_BIOS(1) ) + ROMX_LOAD("bas500b.ic27", 0x1000, 0x1000, CRC(0aaf5d04) SHA1(f871a2991d4a487596ec637e237fc0d9656f4a64), ROM_BIOS(1) ) + ROMX_LOAD("bas500c.ic28", 0x2000, 0x1000, CRC(ab7d79b8) SHA1(75f71b63dcd81946afce7e2c4d83c6f3ba5c2bc3), ROM_BIOS(1) ) + ROMX_LOAD("bas500d.ic30", 0x3000, 0x1000, CRC(19f83c4e) SHA1(3ca985bb6b31d39e9cd42ea0a4baeb266c1b5e86), ROM_BIOS(1) ) + + // first 0x800 for normal chars, 2nd 0x800 for small chars. Some roms don't have small chars so normal ones loaded twice. + ROM_REGION( 0x1000, "chargen", 0 ) + ROM_LOAD("charrom.ic13", 0x0000, 0x0800, CRC(b149737b) SHA1(a3cd4f5d0d3c71137cd1f0f650db83333a2e3597) ) + ROM_RELOAD( 0x0800, 0x0800 ) + + ROM_REGION( 0x0020, "proms", 0 ) + ROM_LOAD_OPTIONAL( "82s123.ic16", 0x0000, 0x0020, CRC(79fa1e9d) SHA1(0454051697b23e4561744466fb31e7a133d02246) ) // video switching prom, not needed for emulation purposes +ROM_END + +// This represents the Series 1: IC (Integrated Computer), and the Series 2: Experimenter, the Educator, and the Personal Communicator +ROM_START( mbeeic ) + ROM_REGION( 0x4000, "maincpu", 0 ) + ROM_SYSTEM_BIOS( 0, "522e", "Basic 5.22e" ) + ROMX_LOAD("bas522e.ic5", 0x0000, 0x2000, CRC(7896a696) SHA1(a158f7803296766160e1f258dfc46134735a9477), ROM_BIOS(0) ) + ROMX_LOAD("bas522e.ic10", 0x2000, 0x2000, CRC(b21d9679) SHA1(332844433763331e9483409cd7da3f90ac58259d), ROM_BIOS(0) ) + ROM_SYSTEM_BIOS( 1, "522d", "Basic 5.22d" ) + ROMX_LOAD("bas522d.ic5", 0x0000, 0x2000, CRC(7896a696) SHA1(a158f7803296766160e1f258dfc46134735a9477), ROM_BIOS(1) ) + ROMX_LOAD("bas522d.ic10", 0x2000, 0x2000, CRC(523a38ff) SHA1(a5383067bc712123849710d8b69cbd879d17a61f), ROM_BIOS(1) ) + + ROM_REGION( 0x1000, "netdef", ROMREGION_ERASEFF ) + ROM_LOAD_OPTIONAL( "telcom10.mbn", 0x0000, 0x1000, CRC(d1617e4f) SHA1(c73dc4dcf4c69419842fa4b52aa92e86924a2e2b) ) // net + + /* PAK option roms */ + ROM_REGION( 0x20000, "pakdef", ROMREGION_ERASEFF ) + ROM_LOAD_OPTIONAL("wbee12.mbp", 0x0000, 0x2000, CRC(0fc21cb5) SHA1(33b3995988fc51ddef1568e160dfe699867adbd5) ) // pak0 + ROM_LOAD_OPTIONAL("help1.mbp", 0x2000, 0x2000, CRC(d34fae54) SHA1(5ed30636f48e9d208ce2da367ba4425782a5bce3) ) // pak1 + + ROM_REGION( 0x1000, "chargen", 0 ) + ROM_LOAD("charrom.bin", 0x0000, 0x1000, CRC(1f9fcee4) SHA1(e57ac94e03638075dde68a0a8c834a4f84ba47b0) ) + + ROM_REGION( 0x0040, "proms", 0 ) + ROM_LOAD( "82s123.ic7", 0x0000, 0x0020, CRC(61b9c16c) SHA1(0ee72377831c21339360c376f7248861d476dc20) ) + ROM_LOAD_OPTIONAL( "82s123.ic16", 0x0020, 0x0020, CRC(79fa1e9d) SHA1(0454051697b23e4561744466fb31e7a133d02246) ) // video switching prom, not needed for emulation purposes +ROM_END + +// This represents the Series 3: 16K Educator, and the 32K Communicator +ROM_START( mbeepc ) + ROM_REGION( 0x4000, "maincpu", 0 ) + ROM_SYSTEM_BIOS( 0, "522e", "Basic 5.22e" ) + ROMX_LOAD("bas522e.ic5", 0x0000, 0x2000, CRC(7896a696) SHA1(a158f7803296766160e1f258dfc46134735a9477), ROM_BIOS(0) ) + ROMX_LOAD("bas522e.ic10", 0x2000, 0x2000, CRC(b21d9679) SHA1(332844433763331e9483409cd7da3f90ac58259d), ROM_BIOS(0) ) + ROM_SYSTEM_BIOS( 1, "524e", "Basic 5.24e" ) + ROMX_LOAD("bas524e.ic5", 0x0000, 0x2000, CRC(ec9c7a60) SHA1(a4021bcedc8da8c0eb0bda036a1d457619a175b0), ROM_BIOS(1) ) + ROMX_LOAD("bas524e.ic10", 0x2000, 0x2000, CRC(9621cfc8) SHA1(81ab332d366466ae84cff2e8b8596dd86c6b6f63), ROM_BIOS(1) ) + + ROM_REGION( 0x1000, "netdef", ROMREGION_ERASEFF ) + ROM_LOAD_OPTIONAL( "telcom10.mbn", 0x0000, 0x1000, CRC(d1617e4f) SHA1(c73dc4dcf4c69419842fa4b52aa92e86924a2e2b) ) // net + + /* PAK option roms */ + ROM_REGION( 0x20000, "pakdef", ROMREGION_ERASEFF ) + ROM_LOAD_OPTIONAL("wbee12.mbp", 0x0000, 0x2000, CRC(0fc21cb5) SHA1(33b3995988fc51ddef1568e160dfe699867adbd5) ) // pak0 + ROM_LOAD_OPTIONAL("help1.mbp", 0x2000, 0x2000, CRC(d34fae54) SHA1(5ed30636f48e9d208ce2da367ba4425782a5bce3) ) // pak1 + + ROM_REGION( 0x1000, "chargen", 0 ) + ROM_LOAD("charrom.bin", 0x0000, 0x1000, CRC(1f9fcee4) SHA1(e57ac94e03638075dde68a0a8c834a4f84ba47b0) ) + + ROM_REGION( 0x0040, "proms", 0 ) + ROM_LOAD( "82s123.ic7", 0x0000, 0x0020, CRC(61b9c16c) SHA1(0ee72377831c21339360c376f7248861d476dc20) ) + ROM_LOAD_OPTIONAL( "82s123.ic16", 0x0020, 0x0020, CRC(79fa1e9d) SHA1(0454051697b23e4561744466fb31e7a133d02246) ) // video switching prom, not needed for emulation purposes +ROM_END + +ROM_START( mbeepc85 ) // The PC85 with the earlier menu + ROM_REGION( 0x4000, "maincpu", 0 ) + ROM_LOAD("bas525a.rom", 0x0000, 0x2000, CRC(a6e02afe) SHA1(0495308c7e1d84b5989a3af6d3b881f4580b2641) ) + ROM_LOAD("bas525b.rom", 0x2000, 0x2000, CRC(245dd36b) SHA1(dd288f3e6737627f50d3d2a49df3e57c423d3118) ) + + ROM_REGION( 0x2000, "netdef", ROMREGION_ERASEFF ) + ROM_LOAD_OPTIONAL("telcom321a.mbn", 0x0000, 0x2000, CRC(36852a11) SHA1(c45b8d03629e86231c6b256a7435abd87d8872a4) ) + + // PAK option roms - Wordbee must be in slot 0 and Shell must be in slot 5. + ROM_REGION( 0x20000, "pakdef", ROMREGION_ERASEFF ) + ROM_LOAD("wbee13r3.mbp", 0x0000, 0x2000, CRC(d7c58b7b) SHA1(5af1b8d21a0f21534ed1833ae919dbbc6ca973e2) ) // 0 + ROM_LOAD("help2.mbp", 0x2000, 0x2000, CRC(a4f1fa90) SHA1(1456abc6ed0501a3b15a99b4302750843293ae5f) ) // 1 + ROM_LOAD("shell.mbp", 0xa000, 0x2000, CRC(5a2c7cd6) SHA1(8edc086710cb558f2146d660eddc8a18ba6a141c) ) // 5 + + ROM_REGION( 0x1000, "chargen", 0 ) + ROM_LOAD("charrom.bin", 0x0000, 0x1000, CRC(1f9fcee4) SHA1(e57ac94e03638075dde68a0a8c834a4f84ba47b0) ) + + ROM_REGION( 0x0040, "proms", 0 ) + ROM_LOAD( "82s123.ic7", 0x0000, 0x0020, CRC(61b9c16c) SHA1(0ee72377831c21339360c376f7248861d476dc20) ) + ROM_LOAD_OPTIONAL( "82s123.ic16", 0x0020, 0x0020, CRC(79fa1e9d) SHA1(0454051697b23e4561744466fb31e7a133d02246) ) // video switching prom, not needed for emulation purposes +ROM_END + +ROM_START( mbeepc85b ) // The PC85 with the later menu + ROM_REGION( 0x4000, "maincpu", 0 ) + ROM_LOAD("bas525a.rom", 0x0000, 0x2000, CRC(a6e02afe) SHA1(0495308c7e1d84b5989a3af6d3b881f4580b2641) ) + ROM_LOAD("bas525b.rom", 0x2000, 0x2000, CRC(245dd36b) SHA1(dd288f3e6737627f50d3d2a49df3e57c423d3118) ) + + ROM_REGION( 0x2000, "netdef", ROMREGION_ERASEFF ) + ROM_LOAD_OPTIONAL("telcom321a.mbn", 0x0000, 0x2000, CRC(36852a11) SHA1(c45b8d03629e86231c6b256a7435abd87d8872a4) ) + + // PAK option roms - Wordbee must be in slot 0 and Shell must be in slot 5. + ROM_REGION( 0x20000, "pakdef", ROMREGION_ERASEFF ) + ROM_LOAD("wbee13r3.mbp", 0x0000, 0x2000, CRC(d7c58b7b) SHA1(5af1b8d21a0f21534ed1833ae919dbbc6ca973e2) ) // 0 + ROM_LOAD("help2.mbp", 0x2000, 0x2000, CRC(a4f1fa90) SHA1(1456abc6ed0501a3b15a99b4302750843293ae5f) ) // 1 + ROM_LOAD("busy.mbp", 0x4000, 0x2000, CRC(56255f60) SHA1(fd2e37209fd49290be6875bc460cfc05392938ba) ) // 2 + ROM_CONTINUE( 0x14000, 0x2000 ) + ROM_LOAD("graphics.mbp", 0x6000, 0x2000, CRC(9e9d327c) SHA1(aebf60ed153004380b9f271f2212376910a6cef9) ) // 3 + ROM_CONTINUE( 0x16000, 0x2000 ) + ROM_LOAD("viatel23.mbp", 0x8000, 0x2000, CRC(2da2411f) SHA1(d3cfa978165feef0a96e28197f6a762aa6604799) ) // 4 + ROM_LOAD("shell-b.mbp", 0xa000, 0x2000, CRC(17bf2d58) SHA1(ae22a5fc5783f37066ba5555497e40945272ca3d) ) // 5 + + ROM_REGION( 0x1000, "chargen", 0 ) + ROM_LOAD("charrom.bin", 0x0000, 0x1000, CRC(1f9fcee4) SHA1(e57ac94e03638075dde68a0a8c834a4f84ba47b0) ) + + ROM_REGION( 0x0040, "proms", 0 ) + ROM_LOAD( "82s123.ic7", 0x0000, 0x0020, CRC(61b9c16c) SHA1(0ee72377831c21339360c376f7248861d476dc20) ) + ROM_LOAD_OPTIONAL( "82s123.ic16", 0x0020, 0x0020, CRC(79fa1e9d) SHA1(0454051697b23e4561744466fb31e7a133d02246) ) // video switching prom, not needed for emulation purposes +ROM_END + +ROM_START( mbeepc85s ) // The Swedish version of the PC85, with custom localised software paks + ROM_REGION( 0x4000, "maincpu", 0 ) + ROM_LOAD("bas524a.rom", 0x0000, 0x2000, CRC(ec9c7a60) SHA1(a4021bcedc8da8c0eb0bda036a1d457619a175b0) ) + ROM_LOAD("bas524b.rom", 0x2000, 0x2000, CRC(17d3eac7) SHA1(d40d376cc5e751d257d951909a34445e70506c7b) ) + + ROM_REGION( 0x2000, "netdef", ROMREGION_ERASEFF ) + ROM_LOAD_OPTIONAL("telcom321s.mbp", 0x0000, 0x2000, CRC(00f8fde1) SHA1(eb881bbab90c85fd6e29540decd25e884c67f738) ) + + // PAK roms - These are not optional and will only work in the correct slots. + ROM_REGION( 0x20000, "pakdef", ROMREGION_ERASEFF ) + ROM_LOAD("wbee20s.mbp", 0x0000, 0x2000, CRC(6a0fe57f) SHA1(a101b588b1872e19382b9e9ea50fabb0fd060aa6) ) // 0 + ROM_LOAD("db-s.mbp", 0x2000, 0x2000, CRC(e2094771) SHA1(62d7fb66c91d2bd24523bc84e4f005cf2c4480bb) ) // 1 + ROM_LOAD("kalk-s.mbp", 0x4000, 0x2000, CRC(08dd71ee) SHA1(c9d506d8bb56f602c3481b253d4cac226f545d98) ) // 2 + ROM_LOAD("bg-s.mbp", 0x6000, 0x2000, CRC(5aa4813e) SHA1(a8638e9046bfb9d5a98c878322295ce408bd879d) ) // 3 + ROM_LOAD("vtex11s.mbp", 0x8000, 0x2000, CRC(67592b3f) SHA1(7f1d23ded34781ccda5f36b4a4fa118a8c0e44ec) ) // 4 + ROM_LOAD("shell-s.mbp", 0xa000, 0x2000, CRC(bdf1768f) SHA1(4385351d07288cf94947ac63131eeed98572caa1) ) // 5 + + ROM_REGION( 0x1000, "chargen", 0 ) + ROM_LOAD("charrom-s.bin", 0x0000, 0x1000, CRC(1bcbf083) SHA1(6438649b8b5fc20dd772ec7195e69a5bbe016b09) ) + + ROM_REGION( 0x0040, "proms", 0 ) + ROM_LOAD( "82s123.ic7", 0x0000, 0x0020, CRC(61b9c16c) SHA1(0ee72377831c21339360c376f7248861d476dc20) ) + ROM_LOAD_OPTIONAL( "82s123.ic16", 0x0020, 0x0020, CRC(79fa1e9d) SHA1(0454051697b23e4561744466fb31e7a133d02246) ) // video switching prom, not needed for emulation purposes +ROM_END + +ROM_START( mbeett ) // The Teleterm + ROM_REGION( 0x2000, "maincpu", 0 ) + ROM_LOAD("kernel_106.rom", 0x0000, 0x2000, CRC(5ab9cb1d) SHA1(a1fb971622f85c4d866b91cb4bec6d75757e8c5f) ) + + ROM_REGION( 0x2000, "netdef", ROMREGION_ERASEFF ) + ROM_LOAD("wm_106.mbn", 0x0000, 0x2000, CRC(77e0b355) SHA1(1db6769cd6b12e1c335c83f17f8c139986c87758) ) + + ROM_REGION( 0x20000, "pakdef", ROMREGION_ERASEFF ) + ROM_LOAD("tv_470311.mbp", 0x2000, 0x2000, CRC(2c4c2dcb) SHA1(77cd75166a389cb2d1d8abf00b1ddd077ce98354) ) // 1 + ROM_CONTINUE( 0x12000, 0x2000 ) + ROM_LOAD("tw_103.mbp", 0x4000, 0x2000, CRC(881edb4b) SHA1(f6e30a12b1537bd55b69d1319799b150e80a471b) ) // 2 + ROM_CONTINUE( 0x14000, 0x2000 ) + ROM_LOAD("oside_107.mbp", 0x6000, 0x2000, CRC(05d99aba) SHA1(4f88d63025f99bcc54d6f2abc20a699c97384f68) ) // 3 + ROM_CONTINUE( 0x16000, 0x1000 ) + ROM_LOAD("test_105.mbp", 0x8000, 0x2000, CRC(b69aa618) SHA1(49de8cbad59f549c7ad9f8efc9beee0cfcd901fe) ) // 4 + + ROM_REGION( 0x1000, "chargen", 0 ) + ROM_LOAD("charrom.bin", 0x0000, 0x1000, CRC(1f9fcee4) SHA1(e57ac94e03638075dde68a0a8c834a4f84ba47b0) ) +ROM_END + +ROM_START( mbeeppc ) // The Premium PC85 + ROM_REGION( 0x2000, "maincpu", 0 ) + ROM_LOAD("bas529b.rom", 0x0000, 0x2000, CRC(a1bd986b) SHA1(5d79f210c9042db5aefc85a0bdf45210cb9e9899) ) + + ROM_REGION( 0x4000, "basicrom", 0 ) + ROM_LOAD("bas529a.rom", 0x0000, 0x4000, CRC(fe8242e1) SHA1(ff790edf4fcc7a134d451dbad7779157b07f6abf) ) + + ROM_REGION( 0x2000, "netdef", ROMREGION_ERASEFF ) + ROM_LOAD_OPTIONAL("telco321.rom", 0x0000, 0x2000, CRC(36852a11) SHA1(c45b8d03629e86231c6b256a7435abd87d8872a4) ) + + /* PAK option roms - Wordbee must be in slot 0 and Shell must be in slot 5. */ + ROM_REGION( 0x20000, "pakdef", ROMREGION_ERASEFF ) + ROM_LOAD("wbee13r3.mbp", 0x0000, 0x2000, CRC(d7c58b7b) SHA1(5af1b8d21a0f21534ed1833ae919dbbc6ca973e2) ) // 0 + ROM_LOAD("help2.mbp", 0x2000, 0x2000, CRC(a4f1fa90) SHA1(1456abc6ed0501a3b15a99b4302750843293ae5f) ) // 1 + ROM_LOAD("busy-p.mbp", 0x4000, 0x2000, CRC(f2897427) SHA1(b4c351bdac72d89589980be6d654f9b931bcba6b) ) // 2 + ROM_CONTINUE( 0x14000, 0x2000 ) + ROM_LOAD("graphics.mbp", 0x6000, 0x2000, CRC(9e9d327c) SHA1(aebf60ed153004380b9f271f2212376910a6cef9) ) // 3 + ROM_CONTINUE( 0x16000, 0x2000 ) + ROM_LOAD("vtex235.mbp", 0x8000, 0x2000, CRC(8c30ecb2) SHA1(cf068462d7def885bdb5d3a265851b88c727c0d7) ) // 4 + ROM_LOAD("ppcshell.mbp", 0xa000, 0x2000, CRC(1e793555) SHA1(ddeaa081ec4408e80e3fb192865d87daa035c701) ) // 5 + + ROM_REGION( 0x1000, "chargen", 0 ) + ROM_LOAD("charrom.bin", 0x0000, 0x1000, CRC(1f9fcee4) SHA1(e57ac94e03638075dde68a0a8c834a4f84ba47b0) ) +ROM_END + +// This represents the Series 1: 64K, and 64K Plus +ROM_START( mbee56 ) + ROM_REGION( 0x1000, "maincpu", 0 ) + ROM_LOAD("56kb.rom", 0x0000, 0x1000, CRC(28211224) SHA1(b6056339402a6b2677b0e6c57bd9b78a62d20e4f) ) + + ROM_REGION( 0x1000, "chargen", 0 ) + ROM_LOAD("charrom.bin", 0x0000, 0x1000, CRC(1f9fcee4) SHA1(e57ac94e03638075dde68a0a8c834a4f84ba47b0) ) + + ROM_REGION( 0x0040, "proms", 0 ) + ROM_LOAD( "82s123.ic7", 0x0000, 0x0020, CRC(61b9c16c) SHA1(0ee72377831c21339360c376f7248861d476dc20) ) + ROM_LOAD_OPTIONAL( "82s123.ic16", 0x0020, 0x0020, CRC(79fa1e9d) SHA1(0454051697b23e4561744466fb31e7a133d02246) ) // video switching prom, not needed for emulation purposes +ROM_END + +// This represents the Series 3: 64K CIAB (Computer-in-a-Book), and the standard 128K Small Business Computer +ROM_START( mbee128 ) + ROM_REGION( 0x8000, "maincpu", 0 ) + ROM_LOAD("bn54.bin", 0x0000, 0x2000, CRC(995c53db) SHA1(46e1a5cfd5795b8cf528bacf9dc79398ff7d64af) ) + //ROM_SYSTEM_BIOS( 1, "bn55", "bn55" ) + //ROMX_LOAD("bn55.rom", 0x0000, 0x2000, CRC(ca2c1073) SHA1(355d90d181de899cc7af892df96305fead9c81b4), ROM_BIOS(1) ) // not working - meant for standard CIAB + + ROM_REGION( 0x1000, "chargen", 0 ) + ROM_LOAD("charrom.bin", 0x0000, 0x1000, CRC(1f9fcee4) SHA1(e57ac94e03638075dde68a0a8c834a4f84ba47b0) ) + + ROM_REGION( 0x4000, "pals", 0 ) // undumped; using prom from 256tc for now + ROM_LOAD( "silver.u39", 0x0000, 0x4000, BAD_DUMP CRC(c34aab64) SHA1(781fe648488dec90185760f8e081e488b73b68bf) ) + + ROM_REGION( 0x0040, "proms", 0 ) + ROM_LOAD( "82s123.ic7", 0x0000, 0x0020, CRC(61b9c16c) SHA1(0ee72377831c21339360c376f7248861d476dc20) ) + ROM_LOAD_OPTIONAL( "82s123.ic16", 0x0020, 0x0020, CRC(79fa1e9d) SHA1(0454051697b23e4561744466fb31e7a133d02246) ) // video switching prom, not needed for emulation purposes +ROM_END + +// This represents the 64K Premium CIAB, the 128K Premium Small Business Computer, and the 128K Overdrive +ROM_START( mbee128p ) + ROM_REGION( 0x8000, "maincpu", 0 ) + ROM_SYSTEM_BIOS( 0, "bn60", "Version 2.03" ) + ROMX_LOAD("bn60.rom", 0x0000, 0x2000, CRC(ed15d4ee) SHA1(3ea42b63d42b9a4c5402676dee8912ad1f906bda), ROM_BIOS(0) ) + ROM_SYSTEM_BIOS( 1, "bn59", "Version 2.02" ) + ROMX_LOAD("bn59.rom", 0x0000, 0x2000, CRC(97384116) SHA1(87f2c4ab1a1f2964ba4f2bb60e62dc9c163831ba), ROM_BIOS(1) ) + ROM_SYSTEM_BIOS( 2, "bn58", "Version 2.01" ) + ROMX_LOAD("bn58.rom", 0x0000, 0x2000, CRC(2f3757a6) SHA1(37158da0e8609fea50382f6b941fe473eaaf20cf), ROM_BIOS(2) ) + ROM_SYSTEM_BIOS( 3, "bn56", "bn56" ) + ROMX_LOAD("bn56.rom", 0x0000, 0x2000, CRC(3f76769d) SHA1(cfae2069d739c26fe39f734d9f705a3c965d1e6f), ROM_BIOS(3) ) + ROM_SYSTEM_BIOS( 4, "bn54", "bn54" ) + ROMX_LOAD("bn54.rom", 0x0000, 0x2000, CRC(995c53db) SHA1(46e1a5cfd5795b8cf528bacf9dc79398ff7d64af), ROM_BIOS(4) ) + ROM_SYSTEM_BIOS( 5, "bn54s", "bn54_Swedish" ) + ROMX_LOAD("bn54_swedish.rom", 0x0000, 0x2000, CRC(694179a6) SHA1(1d465330845cd7878c236a0c84a85b5512ccfd65), ROM_BIOS(5) ) + ROM_SYSTEM_BIOS( 6, "bn56s", "bn56_Swedish" ) + ROMX_LOAD("bn56_swedish.rom", 0x0000, 0x2000, CRC(dad4a515) SHA1(9c1e0faaccd8d2062bb3b99c8600b515ed460479), ROM_BIOS(6) ) + ROM_SYSTEM_BIOS( 7, "hd18", "Hard Disk System" ) + ROMX_LOAD("hd18.rom", 0x0000, 0x2000, CRC(ed53ace7) SHA1(534e2e00cc527197c76b3c106b3c9ff7f1328487), ROM_BIOS(7) ) + + ROM_REGION( 0x4000, "pals", 0 ) // undumped; using prom from 256tc for now + ROM_LOAD( "silver.u39", 0x0000, 0x4000, BAD_DUMP CRC(c34aab64) SHA1(781fe648488dec90185760f8e081e488b73b68bf) ) + + ROM_REGION( 0x1000, "chargen", 0 ) + ROM_LOAD("charrom.bin", 0x0000, 0x1000, CRC(1f9fcee4) SHA1(e57ac94e03638075dde68a0a8c834a4f84ba47b0) ) +ROM_END + +ROM_START( mbee256 ) // The 256K Telecomputer + ROM_REGION( 0x4000, "maincpu", 0 ) + ROM_SYSTEM_BIOS( 0, "1.20", "Version 1.20" ) + ROMX_LOAD("256tc_boot_1.20.u38", 0x0000, 0x4000, CRC(fe8d6a84) SHA1(a037a1b90b18a2180e9f5f216b829fcd480449a4), ROM_BIOS(0) ) + ROM_SYSTEM_BIOS( 1, "1.15", "Version 1.15" ) + ROMX_LOAD("256tc_boot_1.15.u38", 0x0000, 0x4000, CRC(1902062d) SHA1(e4a1c0b3f4996e313da0bac0edb6d34e3270723e), ROM_BIOS(1) ) + + ROM_REGION( 0x4000, "pals", 0 ) + ROM_LOAD( "silver.u39", 0x0000, 0x4000, CRC(c34aab64) SHA1(781fe648488dec90185760f8e081e488b73b68bf) ) + + ROM_REGION( 0x2000, "chargen", 0 ) + ROM_LOAD("char256.u53", 0x0000, 0x2000, CRC(9372af3c) SHA1(a63591822c0504de2fed52e88d64e1dbd6124b74) ) +ROM_END + +// Premium Plus - Note: The bios rom is the only one confirmed to be in the machine. IC position numbers are unknown. +// No technical information has been released. +ROM_START( mbeepp ) // Premium Plus + ROM_REGION( 0x4000, "maincpu", 0 ) + ROM_LOAD( "pp.bin", 0x0000, 0x4000, CRC(33292300) SHA1(8ba32123ef1b3beffa797855a1de0ea2078d652a) ) // ver 1.0 + + ROM_REGION( 0x4000, "pals", 0 ) + ROM_LOAD( "silver.u39", 0x0000, 0x4000, BAD_DUMP CRC(c34aab64) SHA1(781fe648488dec90185760f8e081e488b73b68bf) ) + + ROM_REGION( 0x2000, "chargen", 0 ) + ROM_LOAD("char256.u53", 0x0000, 0x2000, BAD_DUMP CRC(9372af3c) SHA1(a63591822c0504de2fed52e88d64e1dbd6124b74) ) +ROM_END + +/*************************************************************************** + + Game driver(s) + +***************************************************************************/ + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME +COMP( 1982, mbee, 0, 0, mbee, mbee, mbee_state, init_mbee, "Applied Technology", "Microbee 16k Standard", MACHINE_SUPPORTS_SAVE ) +COMP( 1983, mbeeic, mbee, 0, mbeeic, mbee, mbee_state, init_mbeeic, "Applied Technology", "Microbee 32k IC", MACHINE_SUPPORTS_SAVE ) +COMP( 1983, mbee56, mbee, 0, mbee56, mbee, mbee_state, init_mbee56, "Applied Technology", "Microbee 64k", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) +COMP( 1984, mbeepc, mbee, 0, mbeeic, mbee, mbee_state, init_mbeeic, "Applied Technology", "Microbee 32k Communicator", MACHINE_SUPPORTS_SAVE ) +COMP( 1984, mbee128, mbee, 0, mbee128, mbee128, mbee_state, init_mbee128, "Applied Technology", "Microbee 128k Standard", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) +COMP( 1985, mbeepc85, mbee, 0, mbeepc85, mbee, mbee_state, init_mbeeic, "Applied Technology", "Microbee PC85", MACHINE_SUPPORTS_SAVE ) +COMP( 1985, mbeepc85s, mbee, 0, mbeepc85, mbee, mbee_state, init_mbeeic, "Applied Technology", "Microbee PC85 (Swedish)", MACHINE_SUPPORTS_SAVE ) +COMP( 1985, mbeepc85b, mbee, 0, mbeepc85, mbee, mbee_state, init_mbeeic, "Microbee Systems", "Microbee PC85 (New version)", MACHINE_SUPPORTS_SAVE ) +COMP( 1986, mbeeppc, mbee, 0, mbeeppc, mbee, mbee_state, init_mbeeppc, "Microbee Systems", "Microbee Premium PC85", MACHINE_SUPPORTS_SAVE ) +COMP( 1986, mbeett, mbee, 0, mbeett, mbee256, mbee_state, init_mbeett, "Microbee Systems", "Microbee Teleterm", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) +COMP( 1986, mbee128p, mbee, 0, mbee128p, mbee128, mbee_state, init_mbee128p, "Microbee Systems", "Microbee 128k Premium", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) +COMP( 1987, mbee256, mbee, 0, mbee256, mbee256, mbee_state, init_mbee256, "Microbee Systems", "Microbee 256TC", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) +COMP( 2012, mbeepp, mbee, 0, mbeepp, mbee128, mbee_state, init_mbeepp, "Microbee Systems", "Microbee Premium Plus+", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/ausnz/mbee.h b/src/mame/ausnz/mbee.h new file mode 100644 index 00000000000..8cb40b3d5e0 --- /dev/null +++ b/src/mame/ausnz/mbee.h @@ -0,0 +1,212 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert +/***************************************************************************** + * + * includes/mbee.h + * + ****************************************************************************/ +#ifndef MAME_INCLUDES_MBEE_H +#define MAME_INCLUDES_MBEE_H + +#pragma once + +#include "bus/centronics/ctronics.h" +#include "bus/generic/carts.h" +#include "bus/generic/slot.h" + +#include "cpu/z80/z80.h" +#include "machine/z80daisy.h" + +#include "imagedev/cassette.h" +#include "imagedev/floppy.h" +#include "imagedev/snapquik.h" + +#include "machine/buffer.h" +#include "machine/mc146818.h" +#include "machine/wd_fdc.h" +#include "machine/z80pio.h" + +#include "sound/spkrdev.h" + +#include "video/mc6845.h" + +#include "machine/timer.h" +#include "emupal.h" +#include "screen.h" + + +class mbee_state : public driver_device +{ +public: + mbee_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_palette(*this, "palette") + , m_maincpu(*this, "maincpu") + , m_pio(*this, "z80pio") + , m_cassette(*this, "cassette") + , m_speaker(*this, "speaker") + , m_centronics(*this, "centronics") + , m_cent_data_out(*this, "cent_data_out") + , m_crtc(*this, "crtc") + , m_fdc(*this, "fdc") + , m_floppy0(*this, "fdc:0") + , m_floppy1(*this, "fdc:1") + , m_rtc(*this, "rtc") + , m_pakdef(*this, "pakdef") + , m_netdef(*this, "netdef") + , m_p_pakdef(*this, "pakdef") + , m_p_netdef(*this, "netdef") + , m_basic(*this, "basic") + , m_io_x7(*this, "X.7") + , m_io_oldkb(*this, "X.%u", 0U) + , m_io_newkb(*this, "Y.%u", 0U) + , m_io_config(*this, "CONFIG") + , m_screen(*this, "screen") + , m_bankr(*this, "bankr%d", 0U) + , m_bankw(*this, "bankw%d", 0U) + , m_pak(*this, "optrom%u", 0U) // "rom" causes issues + { + for (u8 n : m_pak_extended) + m_pak_extended[n] = 0; + } + + void mbee56(machine_config &config); + void mbeeppc(machine_config &config); + void mbee128(machine_config &config); + void mbee256(machine_config &config); + void mbee(machine_config &config); + void mbeett(machine_config &config); + void mbeeic(machine_config &config); + void mbeepc85(machine_config &config); + void mbee128p(machine_config &config); + void mbeepp(machine_config &config); + void remove_carts(machine_config &config); + void remove_quick(machine_config &config); + + void init_mbee() { m_features = 0x00; } + void init_mbeett() { m_features = 0x0d; } + void init_mbeeppc() { m_features = 0x09; } + void init_mbeepp() { m_features = 0x39; } + void init_mbeeic() { m_features = 0x01; } + void init_mbee56() { m_features = 0x03; } + void init_mbee128() { m_features = 0x11; } + void init_mbee128p() { m_features = 0x19; } + void init_mbee256() { m_features = 0x2d; } + +private: + void port04_w(u8 data); + void port06_w(u8 data); + u8 port07_r(); + u8 port08_r(); + void port08_w(u8 data); + void port0a_w(u8 data); + void port0b_w(u8 data); + u8 port18_r(); + u8 port1c_r(); + void port1c_w(u8 data); + void port50_w(u8 data); + u8 telcom_r(offs_t); + u8 speed_r(offs_t); + void m6545_index_w(u8 data); + void m6545_data_w(u8 data); + u8 video_low_r(offs_t offset); + u8 video_high_r(offs_t offset); + void video_low_w(offs_t offset, u8 data); + void video_high_w(offs_t offset, u8 data); + void pio_port_b_w(u8 data); + u8 pio_port_b_r(); + DECLARE_WRITE_LINE_MEMBER(pio_ardy); + DECLARE_WRITE_LINE_MEMBER(crtc_vs); + u8 fdc_status_r(); + u8 pak_r(offs_t); + u8 net_r(offs_t); + void fdc_motor_w(u8 data); + void standard_palette(palette_device &palette) const; + void premium_palette(palette_device &palette) const; + uint32_t screen_update_mbee(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + TIMER_DEVICE_CALLBACK_MEMBER(newkb_timer); + image_init_result load_cart(device_image_interface &image, generic_slot_device *slot, u8); + void unload_cart(u8); + DECLARE_QUICKLOAD_LOAD_MEMBER(quickload_cb); + template DECLARE_DEVICE_IMAGE_LOAD_MEMBER(pak_load) { return load_cart(image, m_pak[T], T); } + template DECLARE_DEVICE_IMAGE_UNLOAD_MEMBER(pak_unload) { unload_cart(T); } + WRITE_LINE_MEMBER(rtc_irq_w); + WRITE_LINE_MEMBER(fdc_intrq_w); + WRITE_LINE_MEMBER(fdc_drq_w); + MC6845_UPDATE_ROW(crtc_update_row); + MC6845_ON_UPDATE_ADDR_CHANGED(crtc_update_addr); + void machine_start() override; + void machine_reset() override; + + required_device m_palette; + void mbee128_io(address_map &map); + void mbee128p_io(address_map &map); + void mbee256_io(address_map &map); + void mbee256_mem(address_map &map); + void mbee56_io(address_map &map); + void mbee56_mem(address_map &map); + void mbee_io(address_map &map); + void mbee_mem(address_map &map); + void mbeeic_io(address_map &map); + void mbeeic_mem(address_map &map); + void mbeeppc_io(address_map &map); + void mbeeppc_mem(address_map &map); + void mbeett_io(address_map &map); + void mbeett_mem(address_map &map); + + u8 m_features = 0; + u16 m_size = 0; + u32 m_ramsize = 0; + bool m_b7_rtc = false; + bool m_b7_vs = false; + bool m_b2 = false; + u8 m_framecnt = 0; + u8 m_08 = 0; + u8 m_09 = 0; + u8 m_0a = 0; + u8 m_0b = 0; + u8 m_1c = 0; + u8 m_newkb_was_pressed[15] = { }; + u8 m_newkb_q[20] = { }; + u8 m_newkb_q_pos = 0; + u8 m_sy6545_reg[32] = { }; + u8 m_sy6545_ind = 0; + u8 m_fdc_rq = 0; + u8 m_bank_array[33] = { }; + bool m_pak_extended[10] = { }; + std::unique_ptr m_dummy; // black hole for writes to rom + std::unique_ptr m_ram; // main banked-switch ram, 128/256/pp + std::unique_ptr m_vram; // video ram, all models + std::unique_ptr m_pram; // pcg ram, all models + std::unique_ptr m_cram; // colour ram, all except mbee + std::unique_ptr m_aram; // attribute ram, ppc/128/256/pp/tt + void setup_banks(u8 data, bool first_time, u8 b_mask); + void oldkb_scan(uint16_t param); + void oldkb_matrix_r(uint16_t offs); + required_device m_maincpu; + required_device m_pio; + required_device m_cassette; + required_device m_speaker; + required_device m_centronics; + required_device m_cent_data_out; + required_device m_crtc; + optional_device m_fdc; + optional_device m_floppy0; + optional_device m_floppy1; + optional_device m_rtc; + optional_memory_region m_pakdef; + optional_memory_region m_netdef; + optional_region_ptr m_p_pakdef; + optional_region_ptr m_p_netdef; + optional_memory_bank m_basic; + optional_ioport m_io_x7; + optional_ioport_array<8> m_io_oldkb; + optional_ioport_array<15> m_io_newkb; + required_ioport m_io_config; + required_device m_screen; + optional_memory_bank_array<16> m_bankr; + optional_memory_bank_array<16> m_bankw; + optional_device_array m_pak; +}; + +#endif // MAME_INCLUDES_MBEE_H diff --git a/src/mame/ausnz/mbee_m.cpp b/src/mame/ausnz/mbee_m.cpp new file mode 100644 index 00000000000..b26b127d645 --- /dev/null +++ b/src/mame/ausnz/mbee_m.cpp @@ -0,0 +1,792 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert +/*************************************************************************** + +Microbee machine driver +Originally written by Juergen Buchmueller, Jan 2000 + +Rewritten by Robbbert (see notes in driver file). + +****************************************************************************/ + +#include "emu.h" +#include "mbee.h" + +#include "z80bin.h" + + +/*********************************************************** + + PIO + +************************************************************/ + +WRITE_LINE_MEMBER( mbee_state::pio_ardy ) +{ + m_centronics->write_strobe((state) ? 0 : 1); +} + +void mbee_state::pio_port_b_w(u8 data) +{ +/* PIO port B - d5..d2 not emulated + d7 interrupt from network or rtc or vsync or not used (see config switch) + d6 speaker + d5 rs232 output (1=mark) + d4 rs232 input (0=mark) + d3 rs232 CTS (0=clear to send) + d2 rs232 clock or DTR + d1 cass out and (on new keyboard) keyboard irq + d0 cass in */ + + m_cassette->output(BIT(data, 1) ? -1.0 : +1.0); + m_speaker->level_w(BIT(data, 6)); +} + +u8 mbee_state::pio_port_b_r() +{ + u8 data = 0; + + if (m_cassette->input() > 0.03) + data |= 1; + + data |= 8; // CTS held high via resistor. If low, the disk-based models think a mouse is plugged in. + + switch (m_io_config->read() & 0xc0) + { + case 0x00: + data |= (u8)m_b7_vs << 7; + break; + case 0x40: + data |= (u8)m_b7_rtc << 7; + break; + case 0x80: + data |= 0x80; + break; + } + data |= (u8)m_b2 << 1; // key pressed on new keyboard + + return data; +} + +/************************************************************************************* + + Floppy Disk + + The callback is quite simple, no interrupts are used. + If either IRQ or DRQ activate, they set bit 7 of inport 0x48. + +*************************************************************************************/ + +WRITE_LINE_MEMBER( mbee_state::fdc_intrq_w ) +{ + m_fdc_rq = (m_fdc_rq & 2) | state; +} + +WRITE_LINE_MEMBER( mbee_state::fdc_drq_w ) +{ + m_fdc_rq = (m_fdc_rq & 1) | (state << 1); +} + +u8 mbee_state::fdc_status_r() +{ +/* d7 indicate if IRQ or DRQ is occurring (1=happening) + d6..d0 not used */ + + return m_fdc_rq ? 0xff : 0x7f; +} + +void mbee_state::fdc_motor_w(u8 data) +{ +/* d7..d4 not used + d3 density (1=MFM) + d2 side (1=side 1) + d1..d0 drive select (0 to 3) */ + + floppy_image_device *floppy = nullptr; + floppy = m_floppy0->get_device(); + floppy->mon_w(0); // motor on always + floppy = m_floppy1->get_device(); + floppy->mon_w(0); // motor on always + + if ((data&3)==0) + floppy = m_floppy0->get_device(); + else + if ((data&3)==1) + floppy = m_floppy1->get_device(); + + m_fdc->set_floppy(floppy); + m_fdc->dden_w(!BIT(data, 3)); // /Q output of ic29 + + if (floppy) + { + floppy->ss_w(BIT(data, 2)); // inverted on the board + } +} + +/*********************************************************** + + 256TC Keyboard + +************************************************************/ + + +TIMER_DEVICE_CALLBACK_MEMBER( mbee_state::newkb_timer ) +{ + /* Keyboard scanner is a Mostek M3870 chip. Its speed of operation is determined by a 15k resistor on + pin 2 (XTL2) and is therefore 2MHz. If a key change is detected (up or down), the /strobe + line activates, sending a high to bit 1 of port 2 (one of the pio input lines). The next read of + port 18 will clear this line, and read the key scancode. It will also signal the 3870 that the key + data has been read, on pin 38 (/extint). The 3870 can cache up to 9 keys. With no rom dump + available, the following is a guess. + + The 3870 (MK3870) 8-bit microcontroller is a single chip implementation of Fairchild F8 (Mostek 3850). + It includes up to 4 KB of mask-programmable ROM, 64 bytes of scratchpad RAM and up to 64 bytes + of executable RAM. The MCU also integrates 32-bit I/O and a programmable timer. */ + + if (!BIT(m_features, 2)) + return; + + u8 i, j, pressed; + + // find what has changed + for (i = 0; i < 15; i++) + { + pressed = m_io_newkb[i]->read(); + if (pressed != m_newkb_was_pressed[i]) + { + // get scankey value + for (j = 0; j < 8; j++) + { + if (BIT(pressed^m_newkb_was_pressed[i], j)) + { + // put it in the queue + u8 code = (i << 3) | j | (BIT(pressed, j) ? 0x80 : 0); + m_newkb_q[m_newkb_q_pos] = code; + if (m_newkb_q_pos < (std::size(m_newkb_q)-1)) + m_newkb_q_pos++; + } + } + m_newkb_was_pressed[i] = pressed; + } + } + + // if anything queued, cause an interrupt + if (m_newkb_q_pos) + m_b2 = 1; // set irq + + if (m_b2) + m_pio->port_b_write(pio_port_b_r()); +} + +u8 mbee_state::port18_r() +{ + u8 i, data = m_newkb_q[0]; // get oldest key + + if (m_newkb_q_pos) + { + for (i = 0; i < m_newkb_q_pos; i++) m_newkb_q[i] = m_newkb_q[i+1]; // ripple queue + m_newkb_q[m_newkb_q_pos] = 0; + m_newkb_q_pos--; + } + + m_b2 = 0; // clear irq + m_pio->port_b_write(pio_port_b_r()); + return data; +} + + +/*********************************************************** + + 256TC Change CPU speed + +************************************************************/ + +u8 mbee_state::speed_r(offs_t offset) +{ + m_maincpu->set_unscaled_clock(BIT(offset, 8, 2) ? 6750000 : 3375000); + return 0xff; +} + + +/*********************************************************** + + 256TC Real Time Clock + +************************************************************/ + +void mbee_state::port04_w(u8 data) // address +{ + m_rtc->write(0, data); +} + +void mbee_state::port06_w(u8 data) // write +{ + m_rtc->write(1, data); +} + +u8 mbee_state::port07_r() // read +{ + return m_rtc->read(1); +} + +// See it work: Run mbeett, choose RTC in the config switches, run the F3 test, press Esc. +WRITE_LINE_MEMBER( mbee_state::rtc_irq_w ) +{ + m_b7_rtc = state; // inverted by IC15 (pins 8,9,10) then again by mame + + if ((m_io_config->read() & 0xc0) == 0x40) // RTC selected in config menu + m_pio->port_b_write(pio_port_b_r()); +} + + +/*********************************************************** + + 256TC Memory Banking + + Selection of ROM, RAM, and video access by the CPU is controlled by U39, + a PAL14L8. When read as an ordinary rom it is 16k in size. The dumper has + arranged the pins as (bit0,1,..) (input = 1,23,2,3,4,5,6,7,8,9,10,11,14,13) + and (output = 22,21,20,19,18,17,16,15). The prom is also used to control + the refresh required by the dynamic rams, however we ignore this function. + + b_mask = total dynamic ram (1=64k; 3=128k; 7=256k or more) + + Certain software (such as the PJB system) constantly switch banks around, + causing slowness. Therefore this function only changes the banks that need + changing, leaving the others as is. + +************************************************************/ + +void mbee_state::setup_banks(u8 data, bool first_time, u8 b_mask) +{ + b_mask &= 7; + u32 dbank = m_ramsize / 0x1000; + u8 extra_bits = (data & 0xc0) & (dbank - 1); + data &= 0x3f; // (bits 0-5 are referred to as S0-S5) + address_space &mem = m_maincpu->space(AS_PROGRAM); + u8 *prom = memregion("pals")->base(); + u8 b_data = bitswap<8>(data, 7,5,3,2,4,6,1,0) & 0x3b; // arrange data bits to S0,S1,-,S4,S2,S3 + u8 b_bank, b_byte, b_byte_t, b_addr, p_bank = 1; + uint16_t b_vid; + + if (first_time || (b_data != m_bank_array[0])) // if same data as last time, leave now + { + m_bank_array[0] = b_data; + + for (b_bank = 0; b_bank < 16; b_bank++) + { + b_vid = b_bank << 12; + b_addr = bitswap<8>(b_bank, 7,4,5,3,1,2,6,0) & 0x1f; // arrange address bits to A12,-,A14,A13,A15 + + // Calculate read-bank + b_byte_t = prom[b_addr | (b_data << 8) | 0x82]; // read-bank (RDS and MREQ are low, RFSH is high) + b_byte = bitswap<8>(b_byte_t, 7,5,0,3,6,2,1,4); // rearrange so that bits 0-2 are rambank, bit 3 = rom select, bit 4 = video select, others not used + + if (first_time || (b_byte != m_bank_array[p_bank])) + { + m_bank_array[p_bank] = b_byte; + + if (!BIT(data, 5)) + b_byte &= 0xfb; // U42/1 - S17 only valid if S5 is on + + if (!BIT(b_byte, 4)) + { + // select video + mem.install_read_handler (b_vid, b_vid + 0x7ff, read8sm_delegate(*this, FUNC(mbee_state::video_low_r))); + mem.install_read_handler (b_vid + 0x800, b_vid + 0xfff, read8sm_delegate(*this, FUNC(mbee_state::video_high_r))); + } + else + { + mem.install_read_bank( b_vid, b_vid+0xfff, m_bankr[b_bank] ); + + if (!BIT(b_byte, 3)) + m_bankr[b_bank]->set_entry(dbank + (b_bank & 3)); // read from rom + else + m_bankr[b_bank]->set_entry(extra_bits + (b_bank & 7) + ((b_byte & b_mask) << 3)); // ram + } + } + p_bank++; + + // Calculate write-bank + b_byte_t = prom[b_addr | (b_data << 8) | 0xc0]; // write-bank (XWR and MREQ are low, RFSH is high) + b_byte = bitswap<8>(b_byte_t, 7,5,0,3,6,2,1,4); // rearrange so that bits 0-2 are rambank, bit 3 = rom select, bit 4 = video select, others not used + + if (first_time || (b_byte != m_bank_array[p_bank])) + { + m_bank_array[p_bank] = b_byte; + + if (!BIT(data, 5)) + b_byte &= 0xfb; // U42/1 - S17 only valid if S5 is on + + if (!BIT(b_byte, 4)) + { + // select video + mem.install_write_handler (b_vid, b_vid + 0x7ff, write8sm_delegate(*this, FUNC(mbee_state::video_low_w))); + mem.install_write_handler (b_vid + 0x800, b_vid + 0xfff, write8sm_delegate(*this, FUNC(mbee_state::video_high_w))); + } + else + { + mem.install_write_bank( b_vid, b_vid+0xfff, m_bankw[b_bank] ); + + //if (!BIT(b_byte, 3)) + //m_bankw[b_bank]->set_entry(dbank); // write to rom dummy area + //else + m_bankw[b_bank]->set_entry(extra_bits + (b_bank & 7) + ((b_byte & b_mask) << 3)); // ram + } + } + p_bank++; + } + } +} + +void mbee_state::port50_w(u8 data) +{ + u8 mask = ((m_ramsize / 0x8000) - 1) & 7; + setup_banks(data, 0, mask); +} + +/*********************************************************** + + 128k Memory Banking + + The only difference to the 256TC is that bit 5 switches + between rom2 and rom3. Since neither of these is dumped, + this bit is not emulated. If it was, this scheme is used: + + Low - rom2 occupies C000-FFFF + High - ram = C000-DFFF, rom3 = E000-FFFF. + +************************************************************/ + + +/*********************************************************** + + ROM Banking on older models + + Set A to 0 or 1 then read the port to switch between the + halves of the Telcom ROM. + + Output the PAK number to choose an optional PAK ROM. + + The bios will support 256 PAKs, although normally only + 6 are available in hardware. Each PAK is normally a 8K + ROM. If 16K ROMs are used, the 2nd half becomes PAK+8, + thus 16 PAKs in total. This is used in the PC85 models. + +************************************************************/ + +void mbee_state::port0a_w(u8 data) +{ + m_0a = data & 15; +} + +// Banking of Telcom rom +// Some boards use bits 8 and 9, but there are no roms big enough in existence. +u8 mbee_state::telcom_r(offs_t offset) +{ + m_09 = BIT(offset, 8); + return m_09; +} + +u8 mbee_state::pak_r(offs_t offset) +{ + u8 data = (m_0a & 7)+2; + + if (m_pak[data] && m_pak[data]->exists()) + { + if (BIT(m_0a, 3)) + { + if (m_pak_extended[data]) + return m_pak[data]->read_rom(0x2000 | offset); + else + return 0xff; + } + else + return m_pak[data]->read_rom(offset); + } + else + { + m_pak_extended[data] = false; + if (m_pakdef) + return m_p_pakdef[(m_0a<<13)|offset]; + else + return 0xff; + } +} + +u8 mbee_state::net_r(offs_t offset) +{ + if (m_pak[1] && m_pak[1]->exists()) + { + if (m_09 && m_pak_extended[1]) + return m_pak[1]->read_rom(0x1000 | offset); + else + return m_pak[1]->read_rom(offset); + } + else + { + m_pak_extended[1] = false; + if (m_netdef) + return m_p_netdef[(m_09<<12)|offset]; + else + return 0xff; + } +} + +/*********************************************************** + + Machine + +************************************************************/ + +/* + On reset or power on, a circuit forces rom 8000-8FFF to appear at 0000-0FFF, while ram is disabled. + It gets set back to normal on the first attempt to write to memory. (/WR line goes active). +*/ + +void mbee_state::machine_start() +{ + save_item(NAME(m_ramsize)); + save_item(NAME(m_features)); + save_item(NAME(m_size)); + save_item(NAME(m_b7_rtc)); + save_item(NAME(m_b7_vs)); + save_item(NAME(m_b2)); + save_item(NAME(m_framecnt)); // not important + save_item(NAME(m_08)); + save_item(NAME(m_09)); + save_item(NAME(m_0a)); + save_item(NAME(m_0b)); + save_item(NAME(m_1c)); + save_item(NAME(m_newkb_was_pressed)); + save_item(NAME(m_newkb_q)); + save_item(NAME(m_newkb_q_pos)); + save_item(NAME(m_sy6545_reg)); + save_item(NAME(m_sy6545_ind)); + save_item(NAME(m_fdc_rq)); + save_item(NAME(m_bank_array)); + + m_b2 = 0; + + // banking of the BASIC roms + if (m_basic) + { + u8 *b = memregion("basicrom")->base(); + m_basic->configure_entries(0, 2, b, 0x2000); + } + + // videoram + m_vram = make_unique_clear(0x0800); + save_pointer(NAME(m_vram), 0x0800); + + // colour + if (BIT(m_features, 0)) + { + m_cram = make_unique_clear(0x0800); + save_pointer(NAME(m_cram), 0x0800); + } + + // minimal main ram + if (BIT(m_features, 1)) + m_size = 0xE000; + else + m_size = 0x8000; + + // premium + if (BIT(m_features, 3)) + { + m_aram = make_unique_clear(0x0800); + save_pointer(NAME(m_aram), 0x0800); + m_pram = make_unique_clear(0x8800); + save_pointer(NAME(m_pram), 0x8800); + } + else + { + m_pram = make_unique_clear(0x1000); + save_pointer(NAME(m_pram), 0x1000); + } + + // Banked systems + u8 b = BIT(m_features, 4, 2); + if (b) + { + m_ramsize = 0x20000; // 128k + if (b == 2) + m_ramsize = 0x40000; // 256k + else + if (b == 3) + m_ramsize = 0x100000; // 1MB for PP + + m_ram = make_unique_clear(m_ramsize); + save_pointer(NAME(m_ram), m_ramsize); + m_dummy = std::make_unique(0x1000); // don't save this + + u8 *r = m_ram.get(); + u8 *d = m_dummy.get(); + u8 *m = memregion("maincpu")->base(); + + u32 banks = m_ramsize / 0x1000; + + for (u8 b_bank = 0; b_bank < 16; b_bank++) + { + m_bankr[b_bank]->configure_entries(0, banks, r, 0x1000); // RAM banks + m_bankr[b_bank]->configure_entries(banks, 4, m, 0x1000); // rom + m_bankw[b_bank]->configure_entries(0, banks, r, 0x1000); // RAM banks + m_bankw[b_bank]->configure_entry(banks, d); // dummy rom + } + } + + // set pak index to true for 16k roms + if (m_pakdef) + for (u8 i = 8; i < 14; i++) + if (!(m_pak[i-8] && m_pak[i-8]->exists())) + if (m_p_pakdef[(i<<13)] != 0xff) + m_pak_extended[(i & 7)+2] = true; + + // set net index to true for 8k roms + if (m_netdef && (m_netdef->bytes() > 0x1000)) + if (!(m_pak[1] && m_pak[1]->exists())) + m_pak_extended[1] = true; +} + +void mbee_state::machine_reset() +{ + m_fdc_rq = 0; + m_08 = 0; + m_09 = 0; + m_0a = 0; + m_0b = 0; + m_1c = 0; + + // set default chars + memcpy(m_pram.get(), memregion("chargen")->base(), 0x800); + + if (m_basic) + m_basic->set_entry(0); + + m_maincpu->set_pc(m_size); + + // init new kbd + if (BIT(m_features, 2)) + m_newkb_q_pos = 0; + + // set banks to default + if (BIT(m_features, 4, 2) == 1) + setup_banks(0, 1, 3); + else + if (BIT(m_features, 4, 2) == 2) + setup_banks(0, 1, 7); + else + if (BIT(m_features, 4, 2) == 3) + setup_banks(0, 1, 31); +} + + +/* m_features: +bit 0 : (colour fitted) 1 = yes +bit 1 : (initial pc value / size of main ram) 1=0xE000, 0=0x8000 +bit 2 : (keyboard type) 1 = new keyboard +bit 3 : (core type) 1 = premium +bit 4,5 : (banking main ram) 0x10 = 128k; 0x20 = 256k +*/ + +/*********************************************************** + + Quickload + + This loads the standard BIN format, as well + as BEE, COM and MWB files. + +************************************************************/ + +QUICKLOAD_LOAD_MEMBER(mbee_state::quickload_cb) +{ + address_space &space = m_maincpu->space(AS_PROGRAM); + bool autorun = BIT(m_io_config->read(), 0); + if (image.is_filetype("bin")) + { + uint16_t execute_address, start_addr, end_addr; + + /* load the binary into memory */ + if (z80bin_load_file(image, space, execute_address, start_addr, end_addr) != image_init_result::PASS) + return image_init_result::FAIL; + + /* is this file executable? */ + if (execute_address != 0xffff) + { + space.write_word(0xa6, execute_address); /* fix the EXEC command */ + + if (autorun) + { + space.write_word(0xa2, execute_address); /* fix warm-start vector to get around some copy-protections */ + m_maincpu->set_pc(execute_address); + } + else + { + space.write_word(0xa2, 0x8517); + } + } + + return image_init_result::PASS; + } + + uint16_t i, j; + u8 data; + + size_t quickload_size = image.length(); + if (image.is_filetype("mwb")) + { + /* mwb files - standard basic files */ + for (i = 0; i < quickload_size; i++) + { + j = 0x8c0 + i; + + if (image.fread(&data, 1) != 1) + { + image.message("Unexpected EOF"); + return image_init_result::FAIL; + } + + if ((j < m_size) || (j > 0xefff)) + space.write_byte(j, data); + else + { + image.message("Not enough memory in this microbee"); + return image_init_result::FAIL; + } + } + + if (autorun) + { + space.write_word(0xa2,0x801e); /* fix warm-start vector to get around some copy-protections */ + m_maincpu->set_pc(0x801e); + } + else + space.write_word(0xa2,0x8517); + } + else + if (image.is_filetype("com")) + { + /* com files - most com files are just machine-language games with a wrapper and don't need cp/m to be present */ + for (i = 0; i < quickload_size; i++) + { + j = 0x100 + i; + + if (image.fread(&data, 1) != 1) + { + image.message("Unexpected EOF"); + return image_init_result::FAIL; + } + + if ((j < m_size) || (j > 0xefff)) + space.write_byte(j, data); + else + { + image.message("Not enough memory in this microbee"); + return image_init_result::FAIL; + } + } + + if (autorun) + m_maincpu->set_pc(0x100); + } + else + if (image.is_filetype("bee")) + { + /* bee files - machine-language games that start at 0900 */ + for (i = 0; i < quickload_size; i++) + { + j = 0x900 + i; + + if (image.fread(&data, 1) != 1) + { + image.message("Unexpected EOF"); + return image_init_result::FAIL; + } + + if ((j < m_size) || (j > 0xefff)) + space.write_byte(j, data); + else + { + image.message("Not enough memory in this microbee"); + return image_init_result::FAIL; + } + } + + if (autorun) + m_maincpu->set_pc(0x900); + } + + return image_init_result::PASS; +} + +// Index usage: 0 = not used; 1 = net rom; 2-7 = pak roms +image_init_result mbee_state::load_cart(device_image_interface &image, generic_slot_device *slot, u8 pak_index) +{ + u32 size = slot->common_get_size("rom"); + + if (pak_index > 1) + { + // "mbp" roms + if ((size == 0) || (size > 0x4000)) + { + image.seterror(image_error::INVALIDIMAGE, "Unsupported ROM size"); + return image_init_result::FAIL; + } + + m_pak_extended[pak_index] = (size > 0x2000) ? true : false; + + slot->rom_alloc(m_pak_extended[pak_index] ? 0x4000 : 0x2000, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE); // we alloc the amount for a real rom + slot->common_load_rom(slot->get_rom_base(), size, "rom"); + + // Validate the rom + logerror ("Rom header = %02X %02X %02X\n", slot->read_rom(0), slot->read_rom(1), slot->read_rom(2)); + if ((slot->read_rom(0) != 0xc3) || ((slot->read_rom(2) & 0xe0) != 0xc0)) + { + image.seterror(image_error::INVALIDIMAGE, "Not a PAK rom"); + slot->call_unload(); + return image_init_result::FAIL; + } + } + else + { + // "mbn" roms + if ((size == 0) || (size > 0x2000)) + { + image.seterror(image_error::INVALIDIMAGE, "Unsupported ROM size"); + return image_init_result::FAIL; + } + m_pak_extended[pak_index] = (size > 0x1000) ? true : false; + + slot->rom_alloc(m_pak_extended[pak_index] ? 0x2000 : 0x1000, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE); + slot->common_load_rom(slot->get_rom_base(), size, "rom"); + + // Validate the rom + logerror ("Rom header = %02X %02X %02X\n", slot->read_rom(0), slot->read_rom(1), slot->read_rom(2)); + if (!image.loaded_through_softlist()) // need to let pascal through without testing + { + if ((slot->read_rom(0) != 0xc3) || ((slot->read_rom(2) & 0xf0) != 0xe0)) + { + image.seterror(image_error::INVALIDIMAGE, "Not a NET rom"); + slot->call_unload(); + return image_init_result::FAIL; + } + } + } + + return image_init_result::PASS; +} + +void mbee_state::unload_cart(u8 pak_index) +{ + if (pak_index > 1) + { + if (m_pakdef) + m_pak_extended[pak_index] = (m_p_pakdef[((pak_index+8)<<13)] == 0xff) ? false : true; + else + m_pak_extended[pak_index] = false; + } + else + m_pak_extended[pak_index] = (m_netdef && (m_netdef->bytes() > 0x1000)) ? true : false; +} + diff --git a/src/mame/ausnz/mbee_v.cpp b/src/mame/ausnz/mbee_v.cpp new file mode 100644 index 00000000000..fafe7a2ca6a --- /dev/null +++ b/src/mame/ausnz/mbee_v.cpp @@ -0,0 +1,408 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert +/*************************************************************************** +Microbee video hardware +Originally written by Juergen Buchmueller, Dec 1999 + +Rewritten by Robbbert (see notes in driver file). + +Operation of old keyboard: + The design is taken from the SY6545 Application Note AN3. As the CRTC + renders the picture, the MA lines also scan the keyboard. When a keydown + is detected, the lightpen pin is activated, which sets bit 6 of the status + register. The CPU continuously monitors this register. Once bit 6 is set, + the CPU needs to determine which key is pressed. It firstly clears bit 6, + then sets port 0B to 1. This prevents the CRTC from scanning the keyboard + and causing interference. Next, the CPU writes an address to regs 18,19 and + then instigates the transparent access. This checks one keyboard row, which + if the pressed key is found, will once again set bit 6. If not found, the + next row will be checked. Once found, the CPU clears bit 6 and port 0B, then + works out the ascii key code of the pressed key. + +Tests of old keyboard. Start mbeeic. +1. Load ASTEROIDS PLUS, stay in attract mode, hold down spacebar, + it should only fire bullets. If it sometimes starts turning, + thrusting or using the shield, then there is a problem. + +2. Load SCAVENGER and make sure it doesn't go to the next level + until you find the Exit. + +3. At the Basic prompt, type in EDASM press enter. At the memory size + prompt press enter. Now, make sure the keyboard works properly. + +See drivers\mbee.cpp for any issues. + +****************************************************************************/ + + +#include "emu.h" +#include "mbee.h" + +WRITE_LINE_MEMBER( mbee_state::crtc_vs ) +{ + m_b7_vs = state; + if ((m_io_config->read() & 0xc0) == 0) // VS selected in config menu + m_pio->port_b_write(pio_port_b_r()); +} + + +/*********************************************************** + + Handlers of video, colour, and attribute RAM + +************************************************************/ + + +u8 mbee_state::video_low_r(offs_t offset) +{ + if ((m_1c & 0x9f) == 0x90) + return m_aram[offset]; + else + if (m_0b) + return m_pram[offset]; + else + return m_vram[offset]; +} + +void mbee_state::video_low_w(offs_t offset, u8 data) +{ + if (BIT(m_1c, 4)) + { + // non-premium attribute writes are discarded + if (BIT(m_1c, 7)) + m_aram[offset] = data; + } + else + m_vram[offset] = data; +} + +u8 mbee_state::video_high_r(offs_t offset) +{ + if (BIT(m_08, 6) && BIT(m_features, 0)) + return m_cram[offset]; + else + return m_pram[(((m_1c & 15) + 1) << 11) | offset]; +} + +void mbee_state::video_high_w(offs_t offset, u8 data) +{ + if (BIT(m_08, 6) && (m_0b==0) && BIT(m_features, 0)) + m_cram[offset] = data; + else + m_pram[(((m_1c & 15) + 1) << 11) | offset] = data; +} + +void mbee_state::port0b_w(u8 data) +{ + m_0b = BIT(data, 0); +} + +u8 mbee_state::port08_r() +{ + return m_08; +} + +void mbee_state::port08_w(u8 data) +{ + m_08 = data & 0x4e; +} + +u8 mbee_state::port1c_r() +{ + return m_1c; +} + +void mbee_state::port1c_w(u8 data) +{ +/* d7 extended graphics (1=allow attributes and pcg banks) + d5 bankswitch basic rom + d4 select attribute ram + d3..d0 select videoram bank */ + + if (BIT(m_features, 3) && BIT(data, 7)) + m_1c = data; + else + m_1c = data & 0x30; + + if (m_basic) + m_basic->set_entry(BIT(data, 5)); +} + + +/*********************************************************** + + CRTC-driven keyboard + +************************************************************/ + + +void mbee_state::oldkb_matrix_r(u16 offs) +{ + if (!BIT(m_features, 2)) + { + u8 port = BIT(offs, 7, 3); + u8 bit = BIT(offs, 4, 3); + u8 extra = 0; + u8 data = m_io_oldkb[port]->read(); + bool keydown = BIT(data, bit); + + // This adds premium-style cursor keys to the old keyboard. + // They are used by the pc85 menu. Premium keyboards already + // have these keys fitted. + if (!keydown && !BIT(m_features, 3)) + { + if ((port == 0) || (port == 2) || (port == 3)) + extra = m_io_x7->read(); + else if (port == 7) + extra = data; + + if (extra) + { + if (BIT(extra, 0)) // cursor up + { + if( port == 7 && bit == 1 ) keydown = 1; + if( port == 0 && bit == 5 ) keydown = 1; // control E + } + else if (BIT(extra, 2)) // cursor down + { + if( port == 7 && bit == 1 ) keydown = 1; + if( port == 3 && bit == 0 ) keydown = 1; // control X + } + else if (BIT(extra, 3)) // cursor left + { + if( port == 7 && bit == 1 ) keydown = 1; + if( port == 2 && bit == 3 ) keydown = 1; // control S + } + else if (BIT(extra, 6)) // cursor right + { + if( port == 7 && bit == 1 ) keydown = 1; + if( port == 0 && bit == 4 ) keydown = 1; // control D + } + } + } + + if( keydown ) + m_crtc->assert_light_pen_input(offs); //lpen_strobe + } +} + + +void mbee_state::oldkb_scan( u16 param ) +{ + if (m_0b) return; // IC5 (pins 11,12,13) + if (param & 15) return; // only scan once per row instead of 16 times + oldkb_matrix_r(param); +} + + +/*********************************************************** + + CRTC registers + +************************************************************/ + +void mbee_state::m6545_index_w(u8 data) +{ + data &= 0x1f; + m_sy6545_ind = data; + m_crtc->address_w(data); +} + +void mbee_state::m6545_data_w(u8 data) +{ + static const u8 sy6545_mask[32]={0xff,0xff,0xff,0x0f,0x7f,0x1f,0x7f,0x7f,3,0x1f,0x7f,0x1f,0x3f,0xff,0x3f,0xff,0,0,0x3f,0xff}; + + switch( m_sy6545_ind ) + { + case 12: + data &= 0x3f; // select alternate character set + if( m_sy6545_reg[12] != data ) + memcpy(m_pram.get(), memregion("chargen")->base() + (((data & 0x30) == 0x20) << 11), 0x800); + break; + } + m_sy6545_reg[m_sy6545_ind] = data & sy6545_mask[m_sy6545_ind]; /* save data in register */ + m_crtc->register_w(data); +} + + + + +/*********************************************************** + + Video + +************************************************************/ + +u32 mbee_state::screen_update_mbee(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + m_framecnt++; + m_crtc->screen_update(screen, bitmap, cliprect); + return 0; +} + + +MC6845_ON_UPDATE_ADDR_CHANGED( mbee_state::crtc_update_addr ) +{ +// parameters passed are address, strobe +// not used on 256TC + + if (strobe) + oldkb_matrix_r(address); +} + + +MC6845_UPDATE_ROW( mbee_state::crtc_update_row ) +{ + if (!de) + return; + + const rgb_t *palette = m_palette->palette()->entry_list_raw(); + + // colours + u8 colourm = BIT(m_08, 1, 3); + u8 monopal = BIT(m_io_config->read(), 4, 2); + // if colour chosen on mono bee, default to amber + if ((monopal==0) && !BIT(m_features, 0)) + monopal = 2; + + u32 *p = &bitmap.pix(y); + u8 inv, attr=0, gfx, fg=96+monopal, bg=96, col=0; + u16 mem, x, chr; + + for (x = 0; x < x_count; x++) // for each character + { + inv = (x == cursor_x) ? 0xff : 0; + mem = (ma + x) & 0x7ff; + chr = m_vram[mem]; + + if (BIT(m_1c, 7)) // premium graphics enabled? + { + attr = m_aram[mem]; + + if (BIT(chr, 7)) + chr += ((attr & 15) << 7); // bump chr to its particular pcg definition + + if (BIT(attr, 6)) + inv ^= 0xff; // inverse attribute + + if (BIT(attr, 7) & BIT(m_framecnt, 4)) // flashing attribute + chr = 0x20; + } + + oldkb_scan(x+ma); + + /* get pattern of pixels for that character scanline */ + gfx = m_pram[(chr<<4) | ra] ^ inv; + + // get colours + if (monopal==0) + { + col = m_cram[mem]; // read a byte of colour + + if (BIT(m_features, 3)) // premium + { + fg = col & 15; + bg = col >> 4; + } + else + { + fg = (col & 0x1f) | 64; + bg = ((col & 0xe0) >> 2) | colourm; + } + } + + /* Display a scanline of a character (8 pixels) */ + *p++ = palette[BIT(gfx, 7) ? fg : bg]; + *p++ = palette[BIT(gfx, 6) ? fg : bg]; + *p++ = palette[BIT(gfx, 5) ? fg : bg]; + *p++ = palette[BIT(gfx, 4) ? fg : bg]; + *p++ = palette[BIT(gfx, 3) ? fg : bg]; + *p++ = palette[BIT(gfx, 2) ? fg : bg]; + *p++ = palette[BIT(gfx, 1) ? fg : bg]; + *p++ = palette[BIT(gfx, 0) ? fg : bg]; + } +} + + +/***************************************************************************************************** + + Palette + + Standard Palette: The 8 bits from the colour RAM are divided into 5 bits for foreground, and 3 + bits for background. The 5 foreground bits pass through a PAL, which has 6 outputs. A write to + port 8 produces 3 more background lines, giving 6 in total. These 12 lines travel to a pair of + 74LS157 switching chips, where the foreground or background lines are selected by the absence or + or presence of a pixel. The 6 chosen lines pass through a 7407 then are merged to the final 3 RGB + lines. Each pair is merged like this: + VCC --- 330 ohm --- primary colour line + out to monitor ---- 120 ohm --- secondary colour line + +*****************************************************************************************************/ + +void mbee_state::standard_palette(palette_device &palette) const +{ + constexpr u8 bglevel[] = { 0, 0x54, 0xa0, 0xff }; + constexpr u8 fglevel[] = { 0, 0xa0, 0xff, 0xff }; + + // set up background colours (00-63) + u8 i = 0; + for (u8 b : bglevel) + { + for (u8 g : bglevel) + { + for (u8 r : bglevel) + { + u8 const k = bitswap<8>(i, 7, 6, 5, 3, 1, 4, 2, 0); + palette.set_pen_color(k, rgb_t(r, g, b)); + i++; + } + } + } + + // set up foreground palette (64-95) by reading the prom + u8 const *const color_prom = memregion("proms")->base(); + for (i = 0; i < 32; i++) + { + u8 const k = color_prom[i]; + u8 const r = fglevel[(BIT(k, 2))|(BIT(k, 5)<<1)]; + u8 const g = fglevel[(BIT(k, 1))|(BIT(k, 4)<<1)]; + u8 const b = fglevel[(BIT(k, 0))|(BIT(k, 3)<<1)]; + palette.set_pen_color(i|64, rgb_t(r, g, b)); + } + + // monochrome palette + palette.set_pen_color(96, rgb_t(0x00, 0x00, 0x00)); // black + palette.set_pen_color(97, rgb_t(0x00, 0xff, 0x00)); // green + palette.set_pen_color(98, rgb_t(0xf7, 0xaa, 0x00)); // amber + palette.set_pen_color(99, rgb_t(0xff, 0xff, 0xff)); // white +} + + +void mbee_state::premium_palette(palette_device &palette) const +{ + // set up 8 low intensity colours + for (u8 i = 0; i < 7; i++) + { + u8 const r = BIT(i, 0) ? 0xc0 : 0; + u8 const g = BIT(i, 1) ? 0xc0 : 0; + u8 const b = BIT(i, 2) ? 0xc0 : 0; + palette.set_pen_color(i, rgb_t(r, g, b)); + } + + // colour 8 is dark grey, rather than black + palette.set_pen_color(8, rgb_t(96, 96, 96)); + + // set up 8 high intensity colours + for (u8 i = 9; i < 16; i++) + { + u8 const r = BIT(i, 0) ? 0xff : 0; + u8 const g = BIT(i, 1) ? 0xff : 0; + u8 const b = BIT(i, 2) ? 0xff : 0; + palette.set_pen_color(i, rgb_t(r, g, b)); + } + + // monochrome palette + palette.set_pen_color(96, rgb_t(0x00, 0x00, 0x00)); // black + palette.set_pen_color(97, rgb_t(0x00, 0xff, 0x00)); // green + palette.set_pen_color(98, rgb_t(0xf7, 0xaa, 0x00)); // amber + palette.set_pen_color(99, rgb_t(0xff, 0xff, 0xff)); // white +} diff --git a/src/mame/ausnz/pipbug.cpp b/src/mame/ausnz/pipbug.cpp new file mode 100644 index 00000000000..9c56eac0505 --- /dev/null +++ b/src/mame/ausnz/pipbug.cpp @@ -0,0 +1,248 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert +/*************************************************************************** + +PIPBUG + +2010-04-08 Skeleton driver. +2012-05-16 Connected to serial terminal.. working +2019-07-17 Added cassette onto L command + +All input must be in UPPER case. + +Commands: +A - See and alter memory +B - Set breakpoint (2 permitted) +C - Clear breakpoint +D - Dump memory to paper tape +G - Go to address, run +L - Load memory from paper tape +S - See and alter registers + +PIPBUG isn't a computer; it is a the name of the bios used +in a number of small 2650-based computers from 1976 to 1978. +Examples include Baby 2650, Eurocard 2650, etc., plus Signetics +own PC1001, PC1500, and KT9500 systems. PIPBUG was written by Signetics. + +The sole means of communication is via a serial terminal. +PIPBUG uses the SENSE and FLAG pins as serial lines, thus +there is no need for a UART. The baud rate is 110. + +The Baby 2650 (featured in Electronics Australia magazine in +March 1977) has 256 bytes of RAM. + +The terminal is expected to have a papertape device attached, and +use it to save and load programs. PIPBUG still thinks it is talking +to the terminal, when in fact the data is flowing to the papertape +reader and punch. + +Cassette: +There is software available at 110 baud, using 1200/2400 Hz. This has +been hooked up to the otherwise-useless L command. Baud rate = 110. +After load completes, G440 to run. + +****************************************************************************/ + +#include "emu.h" +#include "bus/rs232/rs232.h" +#include "cpu/s2650/s2650.h" +#include "imagedev/cassette.h" +#include "machine/terminal.h" +#include "imagedev/snapquik.h" +#include "machine/timer.h" +#include "speaker.h" + + +class pipbug_state : public driver_device +{ +public: + pipbug_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_rs232(*this, "rs232") + , m_maincpu(*this, "maincpu") + , m_cass(*this, "cassette") + { } + + void pipbug(machine_config &config); + +private: + virtual void machine_start() override; + void pipbug_ctrl_w(u8 data); + DECLARE_READ_LINE_MEMBER(serial_r); + TIMER_DEVICE_CALLBACK_MEMBER(kansas_r); + required_device m_rs232; + required_device m_maincpu; + required_device m_cass; + DECLARE_QUICKLOAD_LOAD_MEMBER(quickload_cb); + void data_map(address_map &map); + void mem_map(address_map &map); + u8 m_cass_data[4]{}; + bool m_cassold = false, m_cassinbit = false; +}; + +void pipbug_state::pipbug_ctrl_w(u8 data) +{ +// 0x80 is written here - not connected in the baby 2650 +} + +TIMER_DEVICE_CALLBACK_MEMBER( pipbug_state::kansas_r ) +{ + // no tape - set to idle + m_cass_data[1]++; + if (m_cass_data[1] > 32) + { + m_cass_data[1] = 32; + m_cassinbit = 1; + } + + if ((m_cass->get_state() & CASSETTE_MASK_UISTATE) != CASSETTE_PLAY) + return; + + /* cassette - turn 1200/2400Hz to a bit */ + bool cass_ws = (m_cass->input() > +0.04) ? 1 : 0; + + if (cass_ws != m_cassold) + { + m_cassold = cass_ws; + m_cassinbit = (m_cass_data[1] < 12) ? 1 : 0; + m_cass_data[1] = 0; + } +} + +READ_LINE_MEMBER( pipbug_state::serial_r ) +{ + return m_rs232->rxd_r() & m_cassinbit; +} + +void pipbug_state::machine_start() +{ + save_pointer(NAME(m_cass_data), 4); + save_item(NAME(m_cassold)); + save_item(NAME(m_cassinbit)); +} + +void pipbug_state::mem_map(address_map &map) +{ + map.unmap_value_high(); + map(0x0000, 0x03ff).rom(); + map(0x0400, 0x7fff).ram(); +} + +void pipbug_state::data_map(address_map &map) +{ +// map.unmap_value_high(); + map(S2650_CTRL_PORT, S2650_CTRL_PORT).w(FUNC(pipbug_state::pipbug_ctrl_w)); +} + +/* Input ports */ +static INPUT_PORTS_START( pipbug ) +INPUT_PORTS_END + +static DEVICE_INPUT_DEFAULTS_START( terminal ) + DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_110 ) + DEVICE_INPUT_DEFAULTS( "RS232_RXBAUD", 0xff, RS232_BAUD_110 ) + DEVICE_INPUT_DEFAULTS( "RS232_DATABITS", 0xff, RS232_DATABITS_7 ) + DEVICE_INPUT_DEFAULTS( "RS232_PARITY", 0xff, RS232_PARITY_EVEN ) + DEVICE_INPUT_DEFAULTS( "RS232_STOPBITS", 0xff, RS232_STOPBITS_1 ) +DEVICE_INPUT_DEFAULTS_END + +QUICKLOAD_LOAD_MEMBER(pipbug_state::quickload_cb) +{ + address_space &space = m_maincpu->space(AS_PROGRAM); + int i; + int quick_addr = 0x440; + int exec_addr; + int quick_length; + std::vector quick_data; + int read_; + image_init_result result = image_init_result::FAIL; + + quick_length = image.length(); + if (quick_length < 0x0444) + { + image.seterror(image_error::INVALIDIMAGE, "File too short"); + image.message(" File too short"); + } + else if (quick_length > 0x8000) + { + image.seterror(image_error::INVALIDIMAGE, "File too long"); + image.message(" File too long"); + } + else + { + quick_data.resize(quick_length); + read_ = image.fread( &quick_data[0], quick_length); + if (read_ != quick_length) + { + image.seterror(image_error::INVALIDIMAGE, "Cannot read the file"); + image.message(" Cannot read the file"); + } + else if (quick_data[0] != 0xc4) + { + image.seterror(image_error::INVALIDIMAGE, "Invalid header"); + image.message(" Invalid header"); + } + else + { + exec_addr = quick_data[1] * 256 + quick_data[2]; + + if (exec_addr >= quick_length) + { + image.seterror(image_error::INVALIDIMAGE, "Exec address beyond end of file"); + image.message(" Exec address beyond end of file"); + } + else + { + for (i = quick_addr; i < read_; i++) + space.write_byte(i, quick_data[i]); + + /* display a message about the loaded quickload */ + image.message(" Quickload: size=%04X : exec=%04X",quick_length,exec_addr); + + // Start the quickload + m_maincpu->set_state_int(S2650_PC, exec_addr); + + result = image_init_result::PASS; + } + } + } + + return result; +} + +void pipbug_state::pipbug(machine_config &config) +{ + /* basic machine hardware */ + S2650(config, m_maincpu, XTAL(1'000'000)); + m_maincpu->set_addrmap(AS_PROGRAM, &pipbug_state::mem_map); + m_maincpu->set_addrmap(AS_DATA, &pipbug_state::data_map); + m_maincpu->flag_handler().set("rs232", FUNC(rs232_port_device::write_txd)); + m_maincpu->sense_handler().set(FUNC(pipbug_state::serial_r)); + + /* video hardware */ + RS232_PORT(config, m_rs232, default_rs232_devices, "terminal"); + m_rs232->set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(terminal)); + + /* quickload */ + QUICKLOAD(config, "quickload", "pgm", attotime::from_seconds(1)).set_load_callback(FUNC(pipbug_state::quickload_cb)); + + SPEAKER(config, "mono").front_center(); + + /* Cassette */ + CASSETTE(config, m_cass); + m_cass->set_default_state(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED); + m_cass->add_route(ALL_OUTPUTS, "mono", 0.05); + TIMER(config, "kansas_r").configure_periodic(FUNC(pipbug_state::kansas_r), attotime::from_hz(40000)); +} + + +/* ROM definition */ +ROM_START( pipbug ) + ROM_REGION( 0x0400, "maincpu", 0 ) + ROM_LOAD( "pipbug.rom", 0x0000, 0x0400, CRC(f242b93e) SHA1(f82857cc882e6b5fc9f00b20b375988024f413ff)) +ROM_END + +/* Driver */ + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1979, pipbug, 0, 0, pipbug, pipbug, pipbug_state, empty_init, "Signetics", "PIPBUG", MACHINE_NO_SOUND_HW | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/ausnz/poly.cpp b/src/mame/ausnz/poly.cpp new file mode 100644 index 00000000000..e91b9869d1a --- /dev/null +++ b/src/mame/ausnz/poly.cpp @@ -0,0 +1,449 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert,Nigel Barnes +// thanks-to:Andrew Trotman +/*************************************************************************** + + Poly 1/2 (New Zealand) + + 10/07/2011 Skeleton driver. + + http://www.cs.otago.ac.nz/homepages/andrew/poly/Poly.htm + + Andrew has supplied the roms for -bios 1 + + It uses a 6809 for all main functions. There is a Z80 for CP/M, but all + of the roms are 6809 code. + + The keyboard controller is one of those custom XR devices. + Will use the terminal keyboard instead. + + With bios 1, after entering your userid and password, you get a black + screen. This is normal, because it joins to a network which isn't there. + + TODO: + - Connect up the device ports & lines + - Find out about graphics mode and how it is selected + - Fix Keyboard with KR2376-12 encoder + - Poly 2 and Poly 1 (early) probably require a different keyboard matrix + - Find out how to make 2nd teletext screen to display + - Improve MC6854 emulation for network + +****************************************************************************/ + +#include "emu.h" +#include "poly.h" +#include "formats/flex_dsk.h" +#include "softlist_dev.h" + + +void poly_state::poly_bank(address_map &map) +{ + map.unmap_value_high(); + /* System mode */ + map(0x00000, 0x0ffff).rw(FUNC(poly_state::logical_mem_r), FUNC(poly_state::logical_mem_w)); // Logical Memory + map(0x0e000, 0x0e003).rw(m_pia[0], FUNC(pia6821_device::read), FUNC(pia6821_device::write)); // Video control PIA 6821 + map(0x0e004, 0x0e005).rw(m_acia, FUNC(acia6850_device::read), FUNC(acia6850_device::write)); // Optional RS232 Interface + map(0x0e006, 0x0e006).w(FUNC(poly_state::baud_rate_w)); // Baud rate controller + map(0x0e00c, 0x0e00f).rw(m_pia[1], FUNC(pia6821_device::read), FUNC(pia6821_device::write)); // Keyboard PIA 6821 + map(0x0e020, 0x0e027).rw(m_ptm, FUNC(ptm6840_device::read), FUNC(ptm6840_device::write)); // Timer 6840 + map(0x0e030, 0x0e036).rw(FUNC(poly_state::network_r), FUNC(poly_state::network_w)); // Data Link Controller 6854 + map(0x0e040, 0x0e040).w(FUNC(poly_state::set_protect_w)); // Set protect flip-flop after 1 E-cycle + map(0x0e050, 0x0e05f).ram().share("dat"); // Dynamic Address Translator + map(0x0e060, 0x0e060).rw(FUNC(poly_state::select_map_r), FUNC(poly_state::select_map1_w)); // Select Map 1 + map(0x0e070, 0x0e070).rw(FUNC(poly_state::select_map_r), FUNC(poly_state::select_map2_w)); // Select Map 2 + map(0x0e800, 0x0efff).ram().share("videoram"); // Teletext screens and System data + map(0x0f000, 0x0ffff).rom().region("system", 0); // System Program ROM + /* User mode */ + map(0x10000, 0x1ffff).rw(FUNC(poly_state::logical_mem_r), FUNC(poly_state::logical_mem_w)); // Logical Memory + map(0x1fff0, 0x1ffff).r(FUNC(poly_state::vector_r)); // Vector fetch (interrupt and reset) +} + +void polydev_state::poly_bank(address_map &map) +{ + poly_state::poly_bank(map); + map(0x0e014, 0x0e014).rw(FUNC(polydev_state::drive_register_r), FUNC(polydev_state::drive_register_w)); // Drive register + map(0x0e018, 0x0e01b).rw(FUNC(polydev_state::fdc_inv_r), FUNC(polydev_state::fdc_inv_w)); // Floppy controller +} + +void poly_state::poly_mem(address_map &map) +{ + map(0x0000, 0xffff).m(m_bankdev, FUNC(address_map_bank_device::amap8)); +} + + +static INPUT_PORTS_START( poly1 ) + PORT_START("MODIFIERS") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Ctrl") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Caps Lock") PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) + + PORT_START("X0") + PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("Keypad 1 Red") + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("Keypad 0") + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_HOME) PORT_NAME("Help Calc") + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL_PAD) PORT_NAME("Keypad .") + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_UNUSED) + + PORT_START("X1") + PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("Keypad 3 Yellow") + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("Keypad 4 Blue") + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("Keypad 2 Green") + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_INSERT) PORT_NAME("Ins Char Line") + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_PGDN) PORT_NAME("Repeat Next") + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_UNUSED) + + PORT_START("X2") + PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("Keypad 6 Cyan") + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("Keypad 7 White") + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("Keypad 5 Magenta") + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL) PORT_NAME("Del Char Line") + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_PGUP) PORT_NAME("Back Exit") + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_UNUSED) + + PORT_START("X3") + PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("Keypad 9") + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("Keypad 8 Flash") + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('@') PORT_CHAR(0xa3) + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_END) PORT_NAME("Pause") + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_NAME(UTF8_UP) + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_NAME(UTF8_RIGHT) + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_NAME(UTF8_DOWN) + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_NAME(UTF8_LEFT) + + PORT_START("X4") + PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_UNUSED) + + PORT_START("X5") + PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('+') + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(':') PORT_CHAR('*') + + PORT_START("X6") + PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_NAME("EXP \xE2\x80\x96") + + PORT_START("X7") + PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"') + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('=') +INPUT_PORTS_END + +static INPUT_PORTS_START( poly1e ) + PORT_INCLUDE(poly1) + // TODO: unknown matrix, contains extra user definable keys +INPUT_PORTS_END + +static INPUT_PORTS_START( poly2 ) + PORT_INCLUDE(poly1) + // TODO: unknown matrix, seems to differ from poly1 +INPUT_PORTS_END + + +void poly_state::machine_start() +{ + m_dat_bank = 0; + m_protect_timer = timer_alloc(FUNC(poly_state::set_protect), this); +} + + +void poly_state::machine_reset() +{ + m_protect_timer->adjust(attotime::never); + + //m_kr2376->set_input_pin(kr2376_device::KR2376_DSII, 0); + //m_kr2376->set_input_pin(kr2376_device::KR2376_PII, 0); + + /* system mode is entered on Reset */ + m_bankdev->set_bank(0); +} + + +void poly_state::init_poly() +{ + uint8_t bitswapped[0x4000]; + uint8_t *rom; + + /* basic rom region */ + rom = m_user->base() + 0xc000; + + /* decrypt rom data lines */ + for (int i = 0x0000; i<0x4000; i++) + bitswapped[i] = bitswap<8>(rom[i], 3, 4, 2, 5, 1, 6, 0, 7); + + /* decrypt rom address lines */ + for (int i = 0x0000; i<0x4000; i++) + rom[i] = bitswapped[bitswap<16>(i, 15, 14, 13, 12, 10, 8, 4, 2, 0, 1, 3, 5, 6, 7, 9, 11)]; + + /* system rom region */ + rom = m_system->base(); + + /* decrypt rom data lines */ + for (int i = 0x0000; i<0x1000; i++) + bitswapped[i] = bitswap<8>(rom[i], 3, 4, 2, 5, 1, 6, 0, 7); + + /* decrypt rom address lines */ + for (int i = 0x0000; i<0x1000; i++) + rom[i] = bitswapped[bitswap<16>(i, 15, 14, 13, 12, 10, 8, 4, 2, 0, 1, 3, 5, 6, 7, 9, 11)]; +} + + +void polydev_state::floppy_formats(format_registration &fr) +{ + fr.add_fm_containers(); + fr.add(FLOPPY_FLEX_FORMAT); +} + +static void poly_floppies(device_slot_interface &device) +{ + device.option_add("8dssd", FLOPPY_8_DSSD); + device.option_add("525sd", FLOPPY_525_SD); +} + + +void poly_state::poly(machine_config &config) +{ + /* basic machine hardware */ + MC6809(config, m_maincpu, 12.0576_MHz_XTAL / 3); + m_maincpu->set_addrmap(AS_PROGRAM, &poly_state::poly_mem); + + ADDRESS_MAP_BANK(config, "bankdev").set_map(&poly_state::poly_bank).set_options(ENDIANNESS_LITTLE, 8, 17, 0x10000); + + INPUT_MERGER_ANY_HIGH(config, "irqs").output_handler().set_inputline(m_maincpu, M6809_IRQ_LINE); + + /* video hardware */ + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); + screen.set_refresh_hz(50); + screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); + screen.set_size(40 * 12, 24 * 20); + screen.set_visarea(0, 40 * 12 - 1, 0, 24 * 20 - 1); + screen.set_screen_update(FUNC(poly_state::screen_update)); + + SAA5050(config, m_trom[0], 12.0576_MHz_XTAL / 2); + m_trom[0]->d_cb().set(FUNC(poly_state::videoram_1_r)); + m_trom[0]->set_screen_size(40, 24, 40); + + SAA5050(config, m_trom[1], 12.0576_MHz_XTAL / 2); + m_trom[1]->d_cb().set(FUNC(poly_state::videoram_2_r)); + m_trom[1]->set_screen_size(40, 24, 40); + + /* sound hardware */ + SPEAKER(config, "mono").front_center(); + SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.50); + + /* internal ram */ + RAM(config, m_ram).set_default_size("128K").set_extra_options("64K"); + + /* network */ + MC6854(config, m_adlc); + //m_adlc->out_txd_cb().set(NETWORK_TAG, FUNC(poly_network_device::data_w)); + //m_adlc->out_irq_cb().set("irqs", FUNC(input_merger_device::in_w<0>)); + + //MCFG_POLY_NETWORK_ADD() + //MCFG_POLY_NETWORK_CLK_CB(WRITELINE(*this, poly_state, network_clk_w)) + //MCFG_POLY_NETWORK_DATA_CB(WRITELINE("mc6854", mc6854_device, set_rx)) + //MCFG_POLY_NETWORK_SLOT_ADD("netup", poly_network_devices, "proteus") + //MCFG_POLY_NETWORK_SLOT_ADD("netdown", poly_network_devices, nullptr) + + /* timer */ + PTM6840(config, m_ptm, 12.0576_MHz_XTAL / 3); + m_ptm->set_external_clocks(0, 0, 0); + m_ptm->o2_callback().set(FUNC(poly_state::ptm_o2_callback)); + m_ptm->o3_callback().set(FUNC(poly_state::ptm_o3_callback)); + //m_ptm->irq_callback().set("irqs", FUNC(input_merger_device::in_w<1>)); + + /* keyboard encoder */ + //KR2376_12(config, m_kr2376, 50000); + //m_kr2376->x<0>().set_ioport("X0"); + //m_kr2376->x<1>().set_ioport("X1"); + //m_kr2376->x<2>().set_ioport("X2"); + //m_kr2376->x<3>().set_ioport("X3"); + //m_kr2376->x<4>().set_ioport("X4"); + //m_kr2376->x<5>().set_ioport("X5"); + //m_kr2376->x<6>().set_ioport("X6"); + //m_kr2376->x<7>().set_ioport("X7"); + //m_kr2376->shift().set(FUNC(poly_state::kbd_shift_r)); + //m_kr2376->control().set(FUNC(poly_state::kbd_control_r)); + //m_kr2376->strobe().set("pia1", FUNC(pia6821_device::cb1_w)); + + /* generic keyboard until ROM in KR2376-12 is known */ + generic_keyboard_device &keyboard(GENERIC_KEYBOARD(config, "keyboard", 0)); + keyboard.set_keyboard_callback(FUNC(poly_state::kbd_put)); + + /* video control */ + PIA6821(config, m_pia[0], 0); + m_pia[0]->writepa_handler().set(FUNC(poly_state::pia0_pa_w)); + m_pia[0]->writepb_handler().set(FUNC(poly_state::pia0_pb_w)); + m_pia[0]->irqa_handler().set("irqs", FUNC(input_merger_device::in_w<2>)); + m_pia[0]->irqb_handler().set("irqs", FUNC(input_merger_device::in_w<3>)); + + /* keyboard PIA */ + PIA6821(config, m_pia[1], 0); + m_pia[1]->readpb_handler().set(FUNC(poly_state::pia1_b_in)); + m_pia[1]->irqa_handler().set("irqs", FUNC(input_merger_device::in_w<4>)); + m_pia[1]->irqb_handler().set("irqs", FUNC(input_merger_device::in_w<5>)); + + /* optional rs232 interface */ + ACIA6850(config, m_acia, 0); + //m_acia->txd_handler().set("rs232", FUNC(rs232_port_device::write_txd)); + //m_acia->rts_handler().set("rs232", FUNC(rs232_port_device::write_rts)); + m_acia->irq_handler().set("irqs", FUNC(input_merger_device::in_w<6>)); + + CLOCK(config, m_acia_clock, 153600); + m_acia_clock->signal_handler().set(m_acia, FUNC(acia6850_device::write_txc)); + m_acia_clock->signal_handler().append(m_acia, FUNC(acia6850_device::write_rxc)); + + /* software lists */ + SOFTWARE_LIST(config, "flop_list").set_original("poly_flop").set_filter("POLY1"); +} + + +void poly_state::poly2(machine_config &config) +{ + poly(config); + + /* internal ram */ + m_ram->set_default_size("128K"); + + /* software lists */ + subdevice("flop_list")->set_filter("POLY2"); +} + + +void polydev_state::polydev(machine_config &config) +{ + poly(config); + + /* fdc */ + FD1771(config, m_fdc, 12.0_MHz_XTAL / 12); + m_fdc->hld_wr_callback().set(FUNC(polydev_state::motor_w)); + m_fdc->set_force_ready(true); + + FLOPPY_CONNECTOR(config, "fdc:0", poly_floppies, "525sd", polydev_state::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, "fdc:1", poly_floppies, nullptr, polydev_state::floppy_formats).enable_sound(true); + + /* remove devices*/ + //config.device_remove("netup"); + //config.device_remove("netdown"); +} + + +/* ROM definition */ +ROM_START( poly1 ) + ROM_REGION( 0x20000, "user", 0 ) + ROM_SYSTEM_BIOS(0, "bas34", "PolyBASIC 3.4") + ROMX_LOAD( "bas1.u92", 0xc000, 0x1000, CRC(04d96d81) SHA1(8d2d0980afb8c447cf235325e4dc15ed2a200f16), ROM_BIOS(0) ) + ROMX_LOAD( "bas2.u91", 0xd000, 0x1000, CRC(3e12f823) SHA1(0b37f2dfa241fac1bf06ca93b19e44a660c7758e), ROM_BIOS(0) ) + ROMX_LOAD( "bas3.u90", 0xe000, 0x1000, CRC(22759a84) SHA1(d22edea312567596b4ef92290ffe52a25de01487), ROM_BIOS(0) ) + ROMX_LOAD( "bas4.u89", 0xf000, 0x1000, CRC(30650d92) SHA1(4e41ea2ec127b9ed277f5a62d52cb3432d64aa84), ROM_BIOS(0) ) + + ROM_REGION( 0x1000, "system", 0 ) + ROMX_LOAD( "bios.u86", 0x0000, 0x1000, CRC(fc97cc6a) SHA1(103dce01a86a47e7e235c9d2f820fa1501ab9800), ROM_BIOS(0) ) +ROM_END + +ROM_START( poly1e ) + ROM_REGION( 0x20000, "user", 0 ) + ROM_SYSTEM_BIOS(0, "bas23", "PolyBASIC 2.3") + ROMX_LOAD( "v3bas1.u92", 0xc000, 0x1000, CRC(ee25fe89) SHA1(af1a73434c9f5524c5a1a5e19d06500ad1b643d1), ROM_BIOS(0) ) + ROMX_LOAD( "v3bas2.u91", 0xd000, 0x1000, CRC(6ca4a8b5) SHA1(54e71e34b55a5ee41a9e0da05d9c9cbcb2fb80c2), ROM_BIOS(0) ) + ROMX_LOAD( "v3bas3.u90", 0xe000, 0x1000, CRC(6021fc00) SHA1(214aab19e096ddfd417993d48c11f81ec139fef3), ROM_BIOS(0) ) + ROMX_LOAD( "v3bas4.u89", 0xf000, 0x1000, CRC(df071e52) SHA1(41482517a5dfc64f3728732b3907cee636674de4), ROM_BIOS(0) ) + + ROM_REGION( 0x1000, "system", 0 ) + ROMX_LOAD( "plrt16v3e9.u86", 0x0000, 0x1000, CRC(f7e3aa86) SHA1(b642c281e54ad9698cfaec19508ae8b4df50c296), ROM_BIOS(0) ) +ROM_END + +ROM_START( poly2 ) + ROM_DEFAULT_BIOS("bas31") + ROM_SYSTEM_BIOS(0, "bas31", "PolyBASIC 3.1") + ROM_SYSTEM_BIOS(1, "bas30", "PolyBASIC 3.0") + + ROM_REGION( 0x20000, "user", 0 ) + ROMX_LOAD( "bas1.u92", 0xc000, 0x1000, CRC(340b7d75) SHA1(330d31b5c90c82c08c62e2df40669ca62c8fffed), ROM_BIOS(0) ) + ROMX_LOAD( "bas2.u91", 0xd000, 0x1000, CRC(45152d26) SHA1(7da2663f253031a587705b9db9a18e93ba4db2cf), ROM_BIOS(0) ) + ROMX_LOAD( "bas3.u90", 0xe000, 0x1000, CRC(a6f70e62) SHA1(7912a9da29d682bb5922f3adf6136b4efc0494dc), ROM_BIOS(0) ) + ROMX_LOAD( "bas4.u89", 0xf000, 0x1000, CRC(72d21cea) SHA1(d413490d043845ce4a9cf5cc70bd92ddc931c837), ROM_BIOS(0) ) + + ROMX_LOAD( "bas1-12-12-84.u92", 0xc000, 0x1000, CRC(a3791342) SHA1(e801db28419eedf6eebdbb5a7eb551ba36c43cd6), ROM_BIOS(1) ) + ROMX_LOAD( "bas2-12-12-84.u91", 0xd000, 0x1000, CRC(3bb5849e) SHA1(71c47a0d3dba096a6a79300edf56ffedce276ac6), ROM_BIOS(1) ) + ROMX_LOAD( "bas3-12-12-84.u90", 0xe000, 0x1000, CRC(a6f70e62) SHA1(7912a9da29d682bb5922f3adf6136b4efc0494dc), ROM_BIOS(1) ) + ROMX_LOAD( "bas4-12-12-84.u89", 0xf000, 0x1000, CRC(8f736cee) SHA1(3ec5cc49a426fc921bbadb2bcc1b86b4768627fa), ROM_BIOS(1) ) + + + ROM_REGION( 0x1000, "system", 0 ) + ROMX_LOAD( "sys31.u86", 0x0000, 0x1000, CRC(fb54c36e) SHA1(934f84a7a99a76b0a017379a6ecd8a8e444cd085), ROM_BIOS(0) ) + ROMX_LOAD( "plrt17-5-11-84.u86", 0x0000, 0x1000, CRC(896165dd) SHA1(005584310f1c689a9b1bb549989c5fedabead6c4), ROM_BIOS(1) ) +ROM_END + +ROM_START( polydev ) + ROM_REGION( 0x20000, "user", 0 ) + ROM_SYSTEM_BIOS(0, "bas34", "PolyBASIC 3.4") + ROMX_LOAD( "v2bas1.bin", 0xc000, 0x1000, CRC(04d96d81) SHA1(8d2d0980afb8c447cf235325e4dc15ed2a200f16), ROM_BIOS(0) ) + ROMX_LOAD( "v2bas2.bin", 0xd000, 0x1000, CRC(3e12f823) SHA1(0b37f2dfa241fac1bf06ca93b19e44a660c7758e), ROM_BIOS(0) ) + ROMX_LOAD( "v2bas3.bin", 0xe000, 0x1000, CRC(22759a84) SHA1(d22edea312567596b4ef92290ffe52a25de01487), ROM_BIOS(0) ) + ROMX_LOAD( "v2bas4.bin", 0xf000, 0x1000, CRC(30650d92) SHA1(4e41ea2ec127b9ed277f5a62d52cb3432d64aa84), ROM_BIOS(0) ) + + ROM_REGION( 0x1000, "system", 0 ) + ROMX_LOAD( "slrt15_00f9.bin", 0x0000, 0x1000, CRC(046a9aef) SHA1(c5c74b0f66e8969c12db03899244e18228be38eb), ROM_BIOS(0) ) +ROM_END + +/* Driver */ + +/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ +COMP( 1981, poly1, 0, 0, poly, poly1, poly_state, init_poly, "Polycorp", "Poly 1 Educational Computer", MACHINE_NOT_WORKING ) +COMP( 1981, poly1e, poly1, 0, poly, poly1e, poly_state, init_poly, "Polycorp", "Poly 1 Educational Computer (early)", MACHINE_NOT_WORKING ) +COMP( 1984, poly2, poly1, 0, poly2, poly2, poly_state, init_poly, "Polycorp", "Poly 2 Learning System", MACHINE_NOT_WORKING ) +COMP( 1983, polydev, poly1, 0, polydev, poly1, polydev_state, init_poly, "Polycorp", "Poly Development System", MACHINE_NOT_WORKING ) diff --git a/src/mame/ausnz/poly.h b/src/mame/ausnz/poly.h new file mode 100644 index 00000000000..a39c91ef979 --- /dev/null +++ b/src/mame/ausnz/poly.h @@ -0,0 +1,187 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert,Nigel Barnes +// thanks-to:Andrew Trotman +/*************************************************************************** + + Poly/Proteus (New Zealand) + + 10/07/2011 Skeleton driver. + + http://www.cs.otago.ac.nz/homepages/andrew/poly/Poly.htm + + Andrew has supplied the roms for -bios 1 + + It uses a 6809 for all main functions. There is a Z80 for CP/M, but all + of the roms are 6809 code. + + The keyboard controller is one of those custom XR devices. + Will use the terminal keyboard instead. + + With bios 1, after entering your userid and password, you get a black + screen. This is normal, because it joins to a network which isn't there. + + ToDo: + - Almost Everything! + - Connect up the device ports & lines + - Find out about graphics mode and how it is selected + - Fix Keyboard so that the Enter key tells BASIC to do something + - Find out how to make 2nd teletext screen to display + - Banking + +****************************************************************************/ + +#ifndef MAME_INCLUDES_POLY_H +#define MAME_INCLUDES_POLY_H + +#pragma once + +#include "cpu/m6809/m6809.h" +#include "imagedev/floppy.h" +#include "machine/6821pia.h" +#include "machine/6840ptm.h" +#include "machine/6850acia.h" +#include "machine/kr2376.h" +#include "machine/clock.h" +#include "machine/mc6854.h" +#include "machine/bankdev.h" +#include "machine/ram.h" +#include "machine/input_merger.h" +#include "machine/wd_fdc.h" +#include "machine/keyboard.h" +#include "sound/spkrdev.h" +#include "video/saa5050.h" +#include "screen.h" +#include "speaker.h" + +//#include "bus/poly/network.h" + + +class poly_state : public driver_device +{ +public: + poly_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_bankdev(*this, "bankdev") + , m_ram(*this, RAM_TAG) + , m_trom(*this, "saa5050_%u", 1U) + , m_pia(*this, "pia%u", 0U) + , m_adlc(*this, "mc6854") + , m_ptm(*this, "ptm") + , m_irqs(*this, "irqs") +// , m_kr2376(*this, "kr2376") + , m_kbd(*this, "X%u", 0U) + , m_modifiers(*this, "MODIFIERS") + , m_speaker(*this, "speaker") + , m_user(*this, "user") + , m_system(*this, "system") + , m_videoram(*this, "videoram") + , m_dat(*this, "dat") + , m_acia(*this, "acia") + , m_acia_clock(*this, "acia_clock") + , m_protect_timer(nullptr) + { + } + + static constexpr feature_type imperfect_features() { return feature::KEYBOARD; } + + void poly(machine_config &config); + void poly2(machine_config &config); + + void init_poly(); + + virtual void poly_bank(address_map &map); + +private: + virtual void machine_start() override; + virtual void machine_reset() override; + + void poly_mem(address_map &map); + + uint8_t logical_mem_r(offs_t offset); + void logical_mem_w(offs_t offset, uint8_t data); + uint8_t vector_r(offs_t offset); + void kbd_put(u8 data); // remove when KR2376 is implemented + DECLARE_READ_LINE_MEMBER( kbd_shift_r ); + DECLARE_READ_LINE_MEMBER( kbd_control_r ); + void pia0_pa_w(uint8_t data); + void pia0_pb_w(uint8_t data); + uint8_t pia1_b_in(); + uint8_t videoram_1_r(offs_t offset); + uint8_t videoram_2_r(offs_t offset); + DECLARE_WRITE_LINE_MEMBER( ptm_o2_callback ); + DECLARE_WRITE_LINE_MEMBER( ptm_o3_callback ); + void baud_rate_w(uint8_t data); + TIMER_CALLBACK_MEMBER( set_protect ); + void set_protect_w(uint8_t data); + uint8_t select_map_r(); + void select_map1_w(uint8_t data); + void select_map2_w(uint8_t data); + uint8_t network_r(offs_t offset); + void network_w(offs_t offset, uint8_t data); + DECLARE_WRITE_LINE_MEMBER( network_clk_w ); + + uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + + required_device m_maincpu; + required_device m_bankdev; + required_device m_ram; + required_device_array m_trom; + required_device_array m_pia; + required_device m_adlc; + required_device m_ptm; + required_device m_irqs; + //required_device m_kr2376; + required_ioport_array<8> m_kbd; + required_ioport m_modifiers; + required_device m_speaker; + required_memory_region m_user; + required_memory_region m_system; + required_shared_ptr m_videoram; + required_shared_ptr m_dat; + optional_device m_acia; + optional_device m_acia_clock; + uint8_t m_video_pa = 0U; + uint8_t m_video_pb = 0U; + uint8_t m_term_data = 0U; + emu_timer *m_protect_timer; + + inline offs_t physical(offs_t offset); + + int m_dat_bank = 0; +}; + + +class polydev_state : public poly_state +{ +public: + polydev_state(const machine_config &mconfig, device_type type, const char *tag) + : poly_state(mconfig, type, tag) + , m_fdc(*this, "fdc") + , m_floppy(*this, "fdc:%u", 0U) + , m_current_floppy(nullptr) + { + } + + static constexpr feature_type imperfect_features() { return feature::KEYBOARD; } + + void polydev(machine_config &config); + +private: + void drive_register_w(uint8_t data); + uint8_t drive_register_r(); + DECLARE_WRITE_LINE_MEMBER(motor_w); + uint8_t fdc_inv_r(offs_t offset); + void fdc_inv_w(offs_t offset, uint8_t data); + + + virtual void poly_bank(address_map &map) override; + + static void floppy_formats(format_registration &fr); + + required_device m_fdc; + required_device_array m_floppy; + floppy_image_device *m_current_floppy; +}; + +#endif // MAME_INCLUDES_POLY_H diff --git a/src/mame/ausnz/poly_m.cpp b/src/mame/ausnz/poly_m.cpp new file mode 100644 index 00000000000..815b6b758b5 --- /dev/null +++ b/src/mame/ausnz/poly_m.cpp @@ -0,0 +1,259 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert,Nigel Barnes +// thanks-to:Andrew Trotman +/*************************************************************************** + + Poly 1/2 (New Zealand) + +****************************************************************************/ + +#include "emu.h" +#include "poly.h" + + +inline offs_t poly_state::physical(offs_t offset) +{ + return (((~m_dat[(m_dat_bank << 3) | (offset >> 13)]) & 0x0f) << 13) | (offset & 0x1fff); +} + +uint8_t poly_state::logical_mem_r(offs_t offset) +{ + return m_user->base()[physical(offset)]; +} + +void poly_state::logical_mem_w(offs_t offset, uint8_t data) +{ + m_user->base()[physical(offset)] = data; +} + + +uint8_t poly_state::vector_r(offs_t offset) +{ + /* system mode is selected by a vector fetch (interrupt and reset) */ + m_bankdev->set_bank(0); + + return m_system->base()[0x0ff0 + offset]; +} + + +TIMER_CALLBACK_MEMBER(poly_state::set_protect) +{ + m_bankdev->set_bank(1); +} + +void poly_state::set_protect_w(uint8_t data) +{ + /* set protect after 1 E cycle */ + m_protect_timer->adjust(m_maincpu->cycles_to_attotime(2)); +} + + +uint8_t poly_state::select_map_r() +{ + return 0x00; +} + +void poly_state::select_map1_w(uint8_t data) +{ + m_dat_bank = 0; +} + +void poly_state::select_map2_w(uint8_t data) +{ + m_dat_bank = 1; +} + + +void poly_state::pia0_pa_w(uint8_t data) +{ + logerror("PIA0: Port A out: %02X\n", data); + m_video_pa = data; + m_ptm->set_g3(BIT(data, 7)); +} + +void poly_state::pia0_pb_w(uint8_t data) +{ + logerror("PIA0: Port B out: %02X\n", data); + m_video_pb = data; +} + + +uint8_t poly_state::pia1_b_in() +{ + // B1 - D0 + // B2 - D1 + // B3 - D2 + // B4 - D3 + // B5 - D4 + // B6 + // B7 + // B8 - D6 + // STROBE - D7 + + /* return key code */ + //data = m_kr2376->data_r(space, 0) & 0x7f; + /* bit 5 is derived from data bits 5,6 and caps lock */ + //data |= !(!(BIT(m_kr2376->data_r(space, 0), 6) && !caps_lock) && !(caps_lock && BIT(m_kr2376->data_r(space, 0), 5))) << 5; + /* bit 6 is data bit 7 */ + //data |= BIT(m_kr2376->data_r(space, 0), 7) << 6; + /* caps lock needs verifying */ + //data |= ((caps_lock && BIT(m_kr2376->data_r(space, 0), 6)) ? 0 : BIT(m_kr2376->data_r(space, 0), 5)) << 5; + /* bit 7 is the strobe value */ + //data |= m_kr2376->get_output_pin(kr2376_device::KR2376_SO) << 7; + + // return ascii key value, bit 7 is the strobe value + uint8_t data = m_term_data; + m_term_data &= 0x7f; + return data; +} + + +uint8_t poly_state::videoram_1_r(offs_t offset) +{ + return m_videoram[offset]; +} + +uint8_t poly_state::videoram_2_r(offs_t offset) +{ + return m_videoram[offset + 0x400]; +} + + +void poly_state::kbd_put(u8 data) +{ + m_term_data = data | 0x80; + + m_pia[1]->cb1_w(1); + m_pia[1]->cb1_w(0); +} + +READ_LINE_MEMBER(poly_state::kbd_shift_r) +{ + return BIT(m_modifiers->read(), 1); +} + +READ_LINE_MEMBER(poly_state::kbd_control_r) +{ + return BIT(m_modifiers->read(), 0); +} + + +WRITE_LINE_MEMBER(poly_state::ptm_o2_callback) +{ + m_ptm->set_c1(state); +} + +WRITE_LINE_MEMBER(poly_state::ptm_o3_callback) +{ + m_speaker->level_w(state); +} + +void poly_state::baud_rate_w (uint8_t data) +{ + /* baud rate controller (0=9600,2=4800,4=2400,6=1200,8=600,A=300) */ + int selector = (data & 0x0e) >> 1; + m_acia_clock->set_clock_scale((selector <= 5) ? 1.0 / (1 << selector) : 0.0); +} + +uint8_t poly_state::network_r(offs_t offset) +{ + return m_adlc->read(offset >> 1); +} + +void poly_state::network_w(offs_t offset, uint8_t data) +{ + m_adlc->write(offset >> 1, data); +} + +WRITE_LINE_MEMBER(poly_state::network_clk_w) +{ + m_adlc->rxc_w(state); + m_adlc->txc_w(state); +} + + +void polydev_state::drive_register_w(uint8_t data) +{ + /* drive select */ + switch (data & 0x03) + { + case 0: + m_current_floppy = m_floppy[0]->get_device(); + break; + + case 1: + m_current_floppy = m_floppy[1]->get_device(); + break; + + default: + m_current_floppy = nullptr; + break; + } + m_fdc->set_floppy(m_current_floppy); + + if (m_current_floppy) + { + /* side select */ + m_current_floppy->ss_w(BIT(data, 6)); + } +} + +uint8_t polydev_state::drive_register_r() +{ + /* disk change */ + return (m_current_floppy ? m_current_floppy->dskchg_r() : 1) << 1; +} + +WRITE_LINE_MEMBER(polydev_state::motor_w) +{ + if (m_current_floppy) m_current_floppy->mon_w(!state); +} + +uint8_t polydev_state::fdc_inv_r(offs_t offset) +{ + return m_fdc->read(offset) ^ 0xff; +} + +void polydev_state::fdc_inv_w(offs_t offset, uint8_t data) +{ + m_fdc->write(offset, data ^ 0xff); +} + + +uint32_t poly_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + /* + PA0 Not used. Connected to CA2. + PA1 ( Mix colour 0) Blue 1) Green 0) Red 1) No + PA2 ( Graphics 1 0) 0) 1) 1) Mix + PA3 1 = Enable Teletext 1 screen + PA4 1 = 480 Graphics mode. 0 = 240 Graphics mode. + PA5 1 = Enable Graphics 1 screen or 480 Graphics screen. + PA6 1 = Mix Mode 0 = Priority mode + PA7 Must be 0. Connected to PA7 and timer G3. + + PB0 1 = Enable Teletext 2 screen. + PB1 1 = Enable Graphics 2 (must be 0 for 480 Graphics) + PB2 ( Mix colour 0) Blue 1) Green 0) Red 1) No + PB3 ( Graphics 2 0) 0) 1) 1) Mix + PB4 1 = Enable Red Background + PB5 1 = Enable Green Background + PB6 1 = Enable Blue Background + PB7 Not used. + + CA1 Connected to PA7 and timer G3. Must be 0. + CA2 Not used. Connected to PA0. + CB1 Not used. + CB2 Not used. + */ + + /* Enable Teletext 1 screen */ + if (BIT(m_video_pa, 3)) + m_trom[0]->screen_update(screen, bitmap, cliprect); + + /* Enable Teletext 2 screen */ + if (BIT(m_video_pb, 0)) + m_trom[1]->screen_update(screen, bitmap, cliprect); + + return 0; +} diff --git a/src/mame/ausnz/proteus.cpp b/src/mame/ausnz/proteus.cpp new file mode 100644 index 00000000000..cccc4cc2cac --- /dev/null +++ b/src/mame/ausnz/proteus.cpp @@ -0,0 +1,433 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +// thanks-to:Andrew Trotman +/********************************************************************** + + Poly Proteus Computer + + http://www.cs.otago.ac.nz/homepages/andrew/poly/Poly.htm + + Specifications: + + Processors 6809,Z80 + + RAM 64 Kbytes + + ROM 4 Kbytes + + Clock Z80 4 MHz (1 wait state per machine cycle) + 6809 4 MHz clock, 1 MHz cycle + + Disk Drives One or two 8" half height drives (Shugart SA860) + Double sided single density + Capacity 630 Kbytes per disk (CP/M) + 590 Kbytes (Flex,Polysys) + Single sided can be used for compatibility + + Ports Standard One RS232 + One Poly network + Optional Total 3 RS232 + One Poly network + One parallel + One disk drive extension + + Operating systems + CP/M. The standard operating system for 8080/Z80 micros. + FLEX. The standard operating system for 6809 micros. + POLYSYS. The operating system for the POLY network. + +**********************************************************************/ + + +#include "emu.h" +#include "cpu/m6809/m6809.h" +#include "cpu/z80/z80.h" +#include "imagedev/floppy.h" +#include "machine/6821pia.h" +#include "machine/6840ptm.h" +#include "machine/6850acia.h" +#include "machine/mc6854.h" +#include "machine/ram.h" +#include "machine/input_merger.h" +#include "machine/clock.h" +#include "machine/wd_fdc.h" +#include "bus/rs232/rs232.h" +#include "bus/centronics/ctronics.h" +#include "formats/flex_dsk.h" +#include "formats/poly_dsk.h" +#include "softlist_dev.h" + + +class proteus_state : public driver_device +{ +public: + proteus_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_z80(*this, "z80") + , m_adlc(*this, "mc6854") + , m_ptm(*this, "ptm") + , m_irqs(*this, "irqs") + , m_pia(*this, "pia") + , m_acia(*this, "acia%u", 0) + , m_fdc(*this, "fdc") + , m_floppy0(*this, "fdc:0") + , m_floppy1(*this, "fdc:1") + , m_floppy(nullptr) + { } + + void proteus(machine_config &config); + +private: + virtual void machine_reset() override; + virtual void machine_start() override; + + DECLARE_WRITE_LINE_MEMBER(ptm_o2_callback); + DECLARE_WRITE_LINE_MEMBER(ptm_o3_callback); + uint8_t network_r(offs_t offset); + void network_w(offs_t offset, uint8_t data); + + uint8_t drive_register_r(); + void drive_register_w(uint8_t data); + DECLARE_WRITE_LINE_MEMBER(motor_w); + uint8_t fdc_inv_r(offs_t offset); + void fdc_inv_w(offs_t offset, uint8_t data); + static void floppy_formats(format_registration &fr); + + void enable_z80_w(uint8_t data); + void enable_6809_w(uint8_t data); + + void proteus_6809_mem(address_map &map); + void proteus_z80_mem(address_map &map); + void proteus_z80_io(address_map &map); + + required_device m_maincpu; + required_device m_z80; + required_device m_adlc; + required_device m_ptm; + required_device m_irqs; + required_device m_pia; + required_device_array m_acia; + required_device m_fdc; + required_device m_floppy0; + required_device m_floppy1; + floppy_image_device *m_floppy = nullptr; +}; + + +void proteus_state::machine_start() +{ + uint8_t bitswapped[0x1000]; + uint8_t *rom; + + /* bios rom region */ + rom = memregion("bios")->base(); + + /* decrypt rom data lines */ + for (int i = 0x0000; i<0x1000; i++) + bitswapped[i] = bitswap<8>(rom[i], 3, 4, 2, 5, 1, 6, 0, 7); + + /* decrypt rom address lines */ + for (int i = 0x0000; i<0x1000; i++) + rom[i] = bitswapped[bitswap<16>(i, 15, 14, 13, 12, 10, 8, 4, 2, 0, 1, 3, 5, 6, 7, 9, 11)]; + + /* + The Proteus BIOS contains a serial ID for copy protection. Disks also contain the + OS serial ID which must match the BIOS serial ID. This can be negated by patching the + serial in the BIOS to 0x0000. + */ + rom[0x02] = 0x00; + rom[0x03] = 0x00; +} + + +void proteus_state::machine_reset() +{ + /* system starts with 6809 running and the Z80 remains reset */ + m_z80->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); +} + + +WRITE_LINE_MEMBER(proteus_state::ptm_o2_callback) +{ + m_ptm->set_c1(state); +} + +WRITE_LINE_MEMBER(proteus_state::ptm_o3_callback) +{ + m_adlc->txc_w(state); + m_adlc->rxc_w(!state); +} + + +uint8_t proteus_state::network_r(offs_t offset) +{ + return m_adlc->read(offset >> 1); +} + +void proteus_state::network_w(offs_t offset, uint8_t data) +{ + m_adlc->write(offset >> 1, data); +} + + +void proteus_state::drive_register_w(uint8_t data) +{ + /* drive select */ + switch (data & 0x03) + { + case 0: + m_floppy = m_floppy0->get_device(); + break; + + case 1: + m_floppy = m_floppy1->get_device(); + break; + + default: + m_floppy = nullptr; + break; + } + m_fdc->set_floppy(m_floppy); + + if (m_floppy) + { + /* side select */ + m_floppy->ss_w(BIT(data, 6)); + } +} + +uint8_t proteus_state::drive_register_r() +{ + /* disk change */ + return (m_floppy ? m_floppy->dskchg_r() : 1) << 1; +} + +WRITE_LINE_MEMBER(proteus_state::motor_w) +{ + if (m_floppy) m_floppy->mon_w(!state); +} + +uint8_t proteus_state::fdc_inv_r(offs_t offset) +{ + return m_fdc->read(offset) ^ 0xff; +} + +void proteus_state::fdc_inv_w(offs_t offset, uint8_t data) +{ + m_fdc->write(offset, data ^ 0xff); +} + + +void proteus_state::enable_z80_w(uint8_t data) +{ + logerror("%04X enable z80\n", m_maincpu->pc()); + // Enable Z80 (store an address at E060 and when the 6809 comes back it'll load PC with that address) + m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); + m_z80->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); +} + +void proteus_state::enable_6809_w(uint8_t data) +{ + logerror("%04X enable 6809\n", m_z80->pc()); + // TODO: this is untested, not aware of any software that uses it + m_z80->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); + m_maincpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE); +} + + +void proteus_state::proteus_6809_mem(address_map &map) +{ + map(0x0000, 0xffff).ram().share(RAM_TAG); + map(0xe000, 0xe003).rw(m_pia, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); // Parallel port + map(0xe004, 0xe005).rw(m_acia[0], FUNC(acia6850_device::read), FUNC(acia6850_device::write)); // Terminal + map(0xe008, 0xe009).rw(m_acia[1], FUNC(acia6850_device::read), FUNC(acia6850_device::write)); // Printer + map(0xe00c, 0xe00d).rw(m_acia[2], FUNC(acia6850_device::read), FUNC(acia6850_device::write)); // Modem + map(0xe014, 0xe014).rw(FUNC(proteus_state::drive_register_r), FUNC(proteus_state::drive_register_w)); + map(0xe018, 0xe01b).rw(FUNC(proteus_state::fdc_inv_r), FUNC(proteus_state::fdc_inv_w)); // Floppy control + map(0xe020, 0xe027).rw(m_ptm, FUNC(ptm6840_device::read), FUNC(ptm6840_device::write)); // Timer + map(0xe030, 0xe036).rw(FUNC(proteus_state::network_r), FUNC(proteus_state::network_w)); // Poly network + map(0xe060, 0xe060).w(FUNC(proteus_state::enable_z80_w)); + map(0xf000, 0xffff).rom().region("bios", 0); +} + + +void proteus_state::proteus_z80_mem(address_map &map) +{ + map(0x0000, 0xffff).ram().share(RAM_TAG); +} + + +void proteus_state::proteus_z80_io(address_map &map) +{ + map(0x00, 0x03).mirror(0xff00).rw(m_pia, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); // Parallel port + map(0x04, 0x05).mirror(0xff00).rw(m_acia[0], FUNC(acia6850_device::read), FUNC(acia6850_device::write)); // Terminal + map(0x08, 0x09).mirror(0xff00).rw(m_acia[1], FUNC(acia6850_device::read), FUNC(acia6850_device::write)); // Printer + map(0x0c, 0x0d).mirror(0xff00).rw(m_acia[2], FUNC(acia6850_device::read), FUNC(acia6850_device::write)); // Modem + map(0x14, 0x14).mirror(0xff00).rw(FUNC(proteus_state::drive_register_r), FUNC(proteus_state::drive_register_w)); + map(0x18, 0x1b).mirror(0xff00).rw(FUNC(proteus_state::fdc_inv_r), FUNC(proteus_state::fdc_inv_w)); // Floppy control + map(0x20, 0x27).mirror(0xff00).rw(m_ptm, FUNC(ptm6840_device::read), FUNC(ptm6840_device::write)); // Timer + map(0x30, 0x36).mirror(0xff00).rw(FUNC(proteus_state::network_r), FUNC(proteus_state::network_w)); // Poly network + map(0x50, 0x50).mirror(0xff00).w(FUNC(proteus_state::enable_6809_w)); +} + + +//Parameter 1: Baud Rate from BIOS +// 00 = 9600 +// 02 = 4800 +// 04 = 2400 +// 06 = 1200 +// 08 = 600 +// 0A = 300 +static INPUT_PORTS_START(proteus) + PORT_START("TERM_BAUD") + PORT_CONFNAME(0x07, 0x00, "Terminal Baud Rate") + PORT_CONFSETTING(0x00, "9600") + PORT_CONFSETTING(0x01, "4800") + PORT_CONFSETTING(0x02, "2400") + PORT_CONFSETTING(0x03, "1200") + PORT_CONFSETTING(0x04, "600") + PORT_CONFSETTING(0x05, "300") + PORT_CONFSETTING(0x06, "150") + + PORT_START("J1") + PORT_CONFNAME(0x07, 0x00, "J1 Modem Baud Rate") + PORT_CONFSETTING(0x00, "9600") + PORT_CONFSETTING(0x01, "4800") + PORT_CONFSETTING(0x02, "2400") + PORT_CONFSETTING(0x03, "1200") + PORT_CONFSETTING(0x04, "600") + PORT_CONFSETTING(0x05, "300") + + PORT_START("J2") + PORT_CONFNAME(0x07, 0x00, "J2 Printer Baud Rate") + PORT_CONFSETTING(0x00, "9600") + PORT_CONFSETTING(0x01, "4800") + PORT_CONFSETTING(0x02, "2400") + PORT_CONFSETTING(0x03, "1200") + PORT_CONFSETTING(0x04, "600") + PORT_CONFSETTING(0x05, "300") +INPUT_PORTS_END + + +void proteus_state::floppy_formats(format_registration &fr) +{ + fr.add_fm_containers(); + fr.add(FLOPPY_FLEX_FORMAT); + fr.add(FLOPPY_POLY_CPM_FORMAT); +} + +static void proteus_floppies(device_slot_interface &device) +{ + device.option_add("8dssd", FLOPPY_8_DSSD); // Shugart SA-860 +} + + +void proteus_state::proteus(machine_config &config) +{ + /* basic machine hardware */ + MC6809(config, m_maincpu, 4_MHz_XTAL); + m_maincpu->set_addrmap(AS_PROGRAM, &proteus_state::proteus_6809_mem); + + Z80(config, m_z80, 4_MHz_XTAL); + m_z80->set_addrmap(AS_PROGRAM, &proteus_state::proteus_z80_mem); + m_z80->set_addrmap(AS_IO, &proteus_state::proteus_z80_io); + + INPUT_MERGER_ANY_HIGH(config, m_irqs); + m_irqs->output_handler().set_inputline(m_maincpu, M6809_IRQ_LINE); + m_irqs->output_handler().append_inputline(m_z80, INPUT_LINE_IRQ0); + + /* fdc */ + FD1771(config, m_fdc, 4_MHz_XTAL / 2); + m_fdc->hld_wr_callback().set(FUNC(proteus_state::motor_w)); + m_fdc->set_force_ready(true); + + FLOPPY_CONNECTOR(config, "fdc:0", proteus_floppies, "8dssd", proteus_state::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, "fdc:1", proteus_floppies, "8dssd", proteus_state::floppy_formats).enable_sound(true); + + /* ram */ + RAM(config, RAM_TAG).set_default_size("64K"); + + /* network */ + MC6854(config, m_adlc); + m_adlc->out_irq_cb().set("irqs", FUNC(input_merger_device::in_w<0>)); + + PTM6840(config, m_ptm, 4_MHz_XTAL / 2); + m_ptm->set_external_clocks(0, 0, 0); + m_ptm->o2_callback().set(FUNC(proteus_state::ptm_o2_callback)); + m_ptm->o3_callback().set(FUNC(proteus_state::ptm_o3_callback)); + m_ptm->irq_callback().set("irqs", FUNC(input_merger_device::in_w<1>)); + + /* parallel port */ + PIA6821(config, m_pia, 0); + //m_pia->readpb_handler().set(FUNC(proteus_state::pia_pb_r)); + //m_pia->writepa_handler().set(FUNC(proteus_state::pia_pa_w)); + //m_pia->writepb_handler().set(FUNC(proteus_state::pia_pb_w)); + //m_pia->ca2_handler().set(CENTRONICS_TAG, FUNC(centronics_device::write_strobe)); + m_pia->irqa_handler().set("irqs", FUNC(input_merger_device::in_w<2>)); + m_pia->irqb_handler().set("irqs", FUNC(input_merger_device::in_w<3>)); + + centronics_device ¶llel(CENTRONICS(config, "parallel", centronics_devices, "printer")); + parallel.ack_handler().set(m_pia, FUNC(pia6821_device::ca1_w)); + output_latch_device ¢_data_out(OUTPUT_LATCH(config, "cent_data_out")); + parallel.set_output_latch(cent_data_out); + + /* terminal port */ + ACIA6850(config, m_acia[0], 0); + m_acia[0]->txd_handler().set("terminal", FUNC(rs232_port_device::write_txd)); + m_acia[0]->rts_handler().set("terminal", FUNC(rs232_port_device::write_rts)); + m_acia[0]->irq_handler().set("irqs", FUNC(input_merger_device::in_w<4>)); + + rs232_port_device &terminal(RS232_PORT(config, "terminal", default_rs232_devices, "terminal")); // TODO: ADM-31 terminal required + terminal.rxd_handler().set(m_acia[0], FUNC(acia6850_device::write_rxd)); + terminal.cts_handler().set(m_acia[0], FUNC(acia6850_device::write_cts)); + + clock_device &acia0_clock(CLOCK(config, "acia0_clock", 4_MHz_XTAL / 2 / 13)); // TODO: this is set using jumpers + acia0_clock.signal_handler().set(m_acia[0], FUNC(acia6850_device::write_txc)); + acia0_clock.signal_handler().append(m_acia[0], FUNC(acia6850_device::write_rxc)); + + /* printer port */ + ACIA6850(config, m_acia[1], 0); + m_acia[1]->txd_handler().set("printer", FUNC(rs232_port_device::write_txd)); + m_acia[1]->rts_handler().set("printer", FUNC(rs232_port_device::write_rts)); + m_acia[1]->irq_handler().set("irqs", FUNC(input_merger_device::in_w<5>)); + + rs232_port_device &printer(RS232_PORT(config, "printer", default_rs232_devices, nullptr)); + printer.rxd_handler().set(m_acia[1], FUNC(acia6850_device::write_rxd)); + printer.cts_handler().set(m_acia[1], FUNC(acia6850_device::write_cts)); + + clock_device &acia1_clock(CLOCK(config, "acia1_clock", 4_MHz_XTAL / 2 / 13)); // TODO: this is set using jumpers J2 + acia1_clock.signal_handler().set(m_acia[1], FUNC(acia6850_device::write_txc)); + acia1_clock.signal_handler().append(m_acia[1], FUNC(acia6850_device::write_rxc)); + + /* modem port */ + ACIA6850(config, m_acia[2], 0); + m_acia[2]->txd_handler().set("modem", FUNC(rs232_port_device::write_txd)); + m_acia[2]->rts_handler().set("modem", FUNC(rs232_port_device::write_rts)); + m_acia[2]->irq_handler().set("irqs", FUNC(input_merger_device::in_w<6>)); + + rs232_port_device &modem(RS232_PORT(config, "modem", default_rs232_devices, nullptr)); + modem.rxd_handler().set(m_acia[2], FUNC(acia6850_device::write_rxd)); + modem.cts_handler().set(m_acia[2], FUNC(acia6850_device::write_cts)); + + clock_device &acia2_clock(CLOCK(config, "acia2_clock", 4_MHz_XTAL / 2 / 13)); // TODO: this is set using jumpers J1 + acia2_clock.signal_handler().set(m_acia[2], FUNC(acia6850_device::write_txc)); + acia2_clock.signal_handler().append(m_acia[2], FUNC(acia6850_device::write_rxc)); + + /* software lists */ + SOFTWARE_LIST(config, "flop_list").set_original("poly_flop").set_filter("PROTEUS"); +} + + +ROM_START(proteus) + ROM_REGION(0x1000, "bios", 0) + ROM_DEFAULT_BIOS("82") + ROM_SYSTEM_BIOS(0, "82", "030982") + ROMX_LOAD("proteusv30.u28", 0x0000, 0x1000, CRC(ad02dc36) SHA1(f73aff8b3d85448f603a2fe807e3a7e02550db27), ROM_BIOS(0)) + ROM_SYSTEM_BIOS(1, "86", "300986") + ROMX_LOAD("300986.u28", 0x0000, 0x1000, CRC(f607d396) SHA1(0b9d9d3178b5587e60da56885b9e8a83f7d5dd26), ROM_BIOS(1)) +ROM_END + + +/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ +COMP( 1982, proteus, 0, 0, proteus, proteus, proteus_state, empty_init, "Polycorp", "Poly Proteus (Standalone)", MACHINE_NOT_WORKING ) diff --git a/src/mame/ausnz/pulsar.cpp b/src/mame/ausnz/pulsar.cpp new file mode 100644 index 00000000000..f5cbab47b88 --- /dev/null +++ b/src/mame/ausnz/pulsar.cpp @@ -0,0 +1,278 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert +/*************************************************************************** + +Pulsar Little Big Board (6000 series) + +2013-12-29 Skeleton driver. + +Chips: Z80A @4MHz, Z80DART, FD1797-02, 8255A-5, AY-5-8116, MSM5832. +Crystals: 4 MHz, 5.0688 MHz, 32768. + +This is a complete CP/M single-board computer. You needed to supply your own +power supply and serial terminal. + +The terminal must be set for 9600 baud, 7 bits, even parity, 1 stop bit. + + +ToDo: +- Fix floppy. It needs to WAIT the cpu whenever port 0xD3 is read, wait + for either DRQ or INTRQ to assert, then release the cpu and then do the + actual port read. Our Z80 cannot do that. +- Fix FDC so MAME doesn't crash when a certain disk is inserted. + + +Monitor Commands: +B - Boot from disk +D - Dump memory +F - Fill memory +G - Go +I - In port +L - Load bootstrap from drive A to 0x80 +M - Modify memory +O - Out port +P - choose which rs232 channel for the console +T - Test memory +V - Move memory +X - Test off-board memory banks + +****************************************************************************/ + +#include "emu.h" + +#include "bus/rs232/rs232.h" +#include "cpu/z80/z80.h" +#include "imagedev/floppy.h" +#include "machine/com8116.h" +#include "machine/i8255.h" +#include "machine/msm5832.h" +#include "machine/wd_fdc.h" +#include "machine/z80daisy.h" +#include "machine/z80sio.h" + + +namespace { + +class pulsar_state : public driver_device +{ +public: + pulsar_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_rom(*this, "maincpu") + , m_ram(*this, "mainram") + , m_bank1(*this, "bank1") + , m_fdc (*this, "fdc") + , m_floppy0(*this, "fdc:0") + , m_floppy1(*this, "fdc:1") + , m_rtc(*this, "rtc") + { } + + void pulsar(machine_config &config); + +private: + virtual void machine_reset() override; + virtual void machine_start() override; + + void ppi_pa_w(u8 data); + void ppi_pb_w(u8 data); + void ppi_pc_w(u8 data); + u8 ppi_pc_r(); + + void io_map(address_map &map); + void mem_map(address_map &map); + + floppy_image_device *m_floppy; + memory_passthrough_handler m_rom_shadow_tap; + required_device m_maincpu; + required_region_ptr m_rom; + required_shared_ptr m_ram; + required_memory_bank m_bank1; + required_device m_fdc; + required_device m_floppy0; + required_device m_floppy1; + required_device m_rtc; +}; + +void pulsar_state::mem_map(address_map &map) +{ + map(0x0000, 0xffff).ram().share("mainram"); + map(0xf800, 0xffff).bankr("bank1"); +} + +void pulsar_state::io_map(address_map &map) +{ + map.unmap_value_high(); + map.global_mask(0xff); + map(0xc0, 0xc3).mirror(0x0c).rw("dart", FUNC(z80dart_device::ba_cd_r), FUNC(z80dart_device::ba_cd_w)); + map(0xd0, 0xd3).mirror(0x0c).rw(m_fdc, FUNC(fd1797_device::read), FUNC(fd1797_device::write)); + map(0xe0, 0xe3).mirror(0x0c).rw("ppi", FUNC(i8255_device::read), FUNC(i8255_device::write)); + map(0xf0, 0xf0).mirror(0x0f).w("brg", FUNC(com8116_device::stt_str_w)); +} + + +/* +d0..d3 Drive select 0-3 (we only emulate 1 drive) +d4 Side select 0=side0 +d5 /DDEN +d6 /DSK_WAITEN (don't know what this is, not emulated) +d7 XMEMEX line (for external memory, not emulated) +*/ +void pulsar_state::ppi_pa_w(u8 data) +{ + m_floppy = nullptr; + if (BIT(data, 0)) + m_floppy = m_floppy0->get_device(); + else + if (BIT(data, 1)) + m_floppy = m_floppy1->get_device(); + m_fdc->set_floppy(m_floppy); + m_fdc->dden_w(BIT(data, 5)); + if (m_floppy) + m_floppy->mon_w(0); +} + +/* +d0..d3 RTC address +d4 RTC read line +d5 RTC write line +d6 RTC hold line +d7 Allow 64k of ram +*/ +void pulsar_state::ppi_pb_w(u8 data) +{ + m_rtc->address_w(data & 0x0f); + m_rtc->read_w(BIT(data, 4)); + m_rtc->write_w(BIT(data, 5)); + m_rtc->hold_w(BIT(data, 6)); + m_bank1->set_entry(BIT(data, 7)); +} + +// d0..d3 Data lines to rtc +void pulsar_state::ppi_pc_w(u8 data) +{ + m_rtc->data_w(data & 15); +} + +// d7 /2 SIDES +u8 pulsar_state::ppi_pc_r() +{ + uint8_t data = 0; + if (m_floppy) + data = m_floppy->twosid_r() << 7; + return m_rtc->data_r() | data; +} + +static const z80_daisy_config daisy_chain_intf[] = +{ + { "dart" }, + { nullptr } +}; + +static DEVICE_INPUT_DEFAULTS_START( terminal ) + DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_9600 ) + DEVICE_INPUT_DEFAULTS( "RS232_RXBAUD", 0xff, RS232_BAUD_9600 ) + DEVICE_INPUT_DEFAULTS( "RS232_DATABITS", 0xff, RS232_DATABITS_7 ) + DEVICE_INPUT_DEFAULTS( "RS232_PARITY", 0xff, RS232_PARITY_EVEN ) + DEVICE_INPUT_DEFAULTS( "RS232_STOPBITS", 0xff, RS232_STOPBITS_1 ) +DEVICE_INPUT_DEFAULTS_END + +static void pulsar_floppies(device_slot_interface &device) +{ + device.option_add("flop", FLOPPY_8_DSDD); +} + +/* Input ports */ +static INPUT_PORTS_START( pulsar ) +INPUT_PORTS_END + +void pulsar_state::machine_reset() +{ + + m_bank1->set_entry(1); + m_rtc->cs_w(1); // always enabled + + address_space &program = m_maincpu->space(AS_PROGRAM); + program.install_rom(0x0000, 0x07ff, m_rom); // do it here for F3 + m_rom_shadow_tap.remove(); + m_rom_shadow_tap = program.install_read_tap( + 0xf800, 0xffff, + "rom_shadow_r", + [this] (offs_t offset, u8 &data, u8 mem_mask) + { + if (!machine().side_effects_disabled()) + { + // delete this tap + m_rom_shadow_tap.remove(); + + // reinstall ram over the rom shadow + m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram); + } + }, + &m_rom_shadow_tap); +} + +void pulsar_state::machine_start() +{ + // register for savestates + m_bank1->configure_entry(0, m_ram+0xf800); + m_bank1->configure_entry(1, m_rom); +} + +void pulsar_state::pulsar(machine_config &config) +{ + /* basic machine hardware */ + Z80(config, m_maincpu, 4_MHz_XTAL); + m_maincpu->set_addrmap(AS_PROGRAM, &pulsar_state::mem_map); + m_maincpu->set_addrmap(AS_IO, &pulsar_state::io_map); + m_maincpu->set_daisy_config(daisy_chain_intf); + + + /* Devices */ + i8255_device &ppi(I8255(config, "ppi")); + ppi.out_pa_callback().set(FUNC(pulsar_state::ppi_pa_w)); + ppi.out_pb_callback().set(FUNC(pulsar_state::ppi_pb_w)); + ppi.in_pc_callback().set(FUNC(pulsar_state::ppi_pc_r)); + ppi.out_pc_callback().set(FUNC(pulsar_state::ppi_pc_w)); + + MSM5832(config, "rtc", 32.768_kHz_XTAL); + + z80dart_device& dart(Z80DART(config, "dart", 4_MHz_XTAL)); + dart.out_txda_callback().set("rs232", FUNC(rs232_port_device::write_txd)); + dart.out_dtra_callback().set("rs232", FUNC(rs232_port_device::write_dtr)); + dart.out_rtsa_callback().set("rs232", FUNC(rs232_port_device::write_rts)); + dart.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); + + rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, "terminal")); + rs232.rxd_handler().set("dart", FUNC(z80dart_device::rxa_w)); + rs232.cts_handler().set("dart", FUNC(z80dart_device::ctsa_w)); + rs232.set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(terminal)); + + com8116_device &brg(COM8116(config, "brg", 5.0688_MHz_XTAL)); + // Schematic has the labels for FT and FR the wrong way around, but the pin numbers are correct. + brg.fr_handler().set("dart", FUNC(z80dart_device::txca_w)); + brg.fr_handler().append("dart", FUNC(z80dart_device::rxca_w)); + brg.ft_handler().set("dart", FUNC(z80dart_device::txcb_w)); + brg.ft_handler().append("dart", FUNC(z80dart_device::rxcb_w)); + + FD1797(config, m_fdc, 4_MHz_XTAL / 2); + FLOPPY_CONNECTOR(config, "fdc:0", pulsar_floppies, "flop", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, "fdc:1", pulsar_floppies, "flop", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); +} + +/* ROM definition */ +ROM_START( pulsarlb ) + ROM_REGION( 0x0800, "maincpu", 0 ) + ROM_SYSTEM_BIOS(0, "mon7", "MP7A") + ROMX_LOAD( "mp7a.u2", 0x0000, 0x0800, CRC(726b8a19) SHA1(43b2af84d5622c1f67584c501b730acf002a6113), ROM_BIOS(0)) + ROM_SYSTEM_BIOS(1, "mon6", "LBOOT6") // Blank screen until floppy boots + ROMX_LOAD( "lboot6.u2", 0x0000, 0x0800, CRC(3bca9096) SHA1(ff99288e51a9e832785ce8e3ab5a9452b1064231), ROM_BIOS(1)) +ROM_END + +} // anonymous namespace + +/* Driver */ + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1981, pulsarlb, 0, 0, pulsar, pulsar, pulsar_state, empty_init, "Pulsar", "Little Big Board (6000 series)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW | MACHINE_SUPPORTS_SAVE ) + diff --git a/src/mame/ausnz/super80.cpp b/src/mame/ausnz/super80.cpp new file mode 100644 index 00000000000..a4c1999d72f --- /dev/null +++ b/src/mame/ausnz/super80.cpp @@ -0,0 +1,995 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert +/***************************************************************************** + +Super80.cpp written by Robbbert, 2005-2010. + +2010-12-19: Added V3.7 bios freshly dumped today. +2014-04-28: Added disk system and did cleanups + +See the MAME sysinfo and wiki for usage +documentation. Below for the most technical bits: + += Architecture (super80): + + * Z80 @ 2MHz + * 16k, 32k or 48k RAM (0000-BFFF) + * 12k ROM (C000-EFFF) + * 3.5k RAM (F000-FDFF), comes with the "64k ram" modification + * 0.5k RAM (FE00-FFFF) for Chipspeed colour board + += Architecture (super80v): + + * Z80 @ 2MHz + * 16k, 32k or 48k RAM (0000-BFFF) + * 12k ROM (C000-EFFF) + * 2k Video RAM (F000-F7FF) banked with Colour RAM (modified Chipspeed board) + * 2k PCG RAM (F800-FFFF) banked with Character Generator ROM + += Super80 ports: + + port $F0: General Purpose output port + Bit 0 - cassette output + Bit 1 - cassette relay control; 0=relay on + Bit 2 - turns screen on and off;0=screen off + Bit 3 - Available for user projects [We will use it for sound] + Bit 4 - Available for user projects + Bit 5 - cassette LED; 0=LED on + Bit 6/7 - not decoded + + port $F1: Video page output port + Bit 0 - not decoded [we will use it for video switching] + Bits 1 to 7 - choose video page to display + Bit 1 controls A9, bit 2 does A10, etc + + port $F2: General purpose input port + Bit 0 - cassette input + Bit 1 - Available for user projects + Bit 2 - Available for user projects + Bit 3 - not decoded + Bit 4 - Switch A [These switches are actual DIP switches on the motherboard] + Bit 5 - Switch B + Bit 6 - Switch C + Bit 7 - Switch D + += Super80v ports: + + port $10: MC6845 control port + + port $11: MC6845 data port + + port $F0: General Purpose output port + Bit 0 - cassette output + Bit 1 - Cassette relay control; 0=relay on + Bit 2 - Colour banking (0 = Colour Ram, 1 = Video Ram) + Bit 3 - Sound + Bit 4 - PCG banking (0 = PROM, 1 = PCG) + Bit 5 - cassette LED; 0=LED on + Bit 6/7 - not decoded + + port $F2: General purpose input port - same as for Super80. + += Cassette information: + +The standard cassette system uses Kansas City format. Data rates available are 300, 400, 600, and 1200 baud. +The user has to adjust some bytes in memory in order to select a different baud rate. + + BDF8 BDF9 Baud + --------------------- + F8 04 300 + BA 03 400 + 7C 02 600 + 3E 01 1200 + +The enhanced Monitor roms (those not supplied by Dick Smith) have extra commands to change the rates +without the tedium of manually modifying memory. + +When saving, the OS toggles the cassette bit (bit 0 of port F0) at the required frequencies directly. + +When loading, the signal passes through a filter, then into a 4046 PLL (Phase-Locked-Loop) chip. +This acts as a frequency-to-voltage converter. The output of this device is passed to the "+" input +of a LM311 op-amp. The "-" input is connected to a 10-turn trimpot, which is adjusted by the owner +at construction time. It sets the switching midpoint voltage. Voltages above a certain level become +a "1" level at the output, while voltages below become a "0" level. This output in turn connects +to the cassette input bit of port F2. + +The monitor loading routine (at C066 in most monitor roms), waits for a high-to-low transition +(the low is the beginning of the start bit), then waits for half a bit, checks it is still low, +waits for a full bit, then reads the state (this is the first bit), then cycles between waiting +a bit and reading the next, until a full byte has been constructed. Lastly, the stop bit is +checked that it is at a high level. + +This means that we cannot attempt to convert frequency to voltage ourselves, since the OS only +"looks" once a bit. The solution is to use a mame timer running at a high enough rate (40 kHz) +to read the wave state. While the wave state stays constant, a counter is incremented. When the +state changes, the output is set according to how far the counter has progressed. The counter is +then reset ready for the next wave state. The code for this is in the TIMER_CALLBACK. + +A kit was produced by ETI magazine, which plugged into the line from your cassette player earphone +socket. The computer line was plugged into this box instead of the cassette player. The box was +fitted with a speaker and a volume control. You could listen to the tones, to assist with head +alignment, and with debugging. In MAME, a config switch has been provided so that you can turn +this sound on or off as needed. + += About the 1 MHz / 2 MHz switching: + +The original hardware runs with a 2 MHz clock, but operates in an unusual way. There is no video +processor chip, just a huge bunch of TTL. The system spends half the time running the CPU, +and half the time displaying the picture. The timing will activate the BUSREQ line, and the CPU will +finish its current instruction, activate the BUSACK line, and go to sleep. The video circuits will +read the video RAM and show the picture. At the end, the BUSREQ line is released, and processing can +continue. + +The processing time occurs during the black parts of the screen, therefore half the screen will be +black unless you expand the image with the monitor's controls. This method ensures that there will +be no memory contention, and thus, no snow. The processor will run at 2 MHz pulsed at 48.8 Hz, which +is an effective speed of 1 MHz. + +When saving or loading a cassette file, this pulsing would cause the save tone to be modulated with +a loud hum. When loading, the synchronisation to the start bit could be missed, causing errors. +Therefore the screen can be turned off via an output bit. This disables the BUSREQ control, which +in turn prevents screen refresh, and gives the processor a full uninterrupted 2 MHz speed. + +To obtain accurate timing, the video update routine will toggle the HALT line on alternate frames. +Although physically incorrect, it is the only way to accurately emulate the speed change function. +The video update routine emulates the blank screen by filling it with spaces. + +For the benefit of those who like to experiment, config switches have been provided in MAME to +allow you to leave the screen on at all times, and to always run at 2 MHz if desired. These options +cannot exist in real hardware. + += Quickload: + +This was not a standard feature. It is a hardware facility I added to my machine when age threatened +to kill off my cassette player and tapes. The tapes were loaded up one last time, and transferred to +a hard drive on a surplus 386 PC, in binary format (NOT a wave file). Special roms were made to allow +loading and saving to the S-100 board and its ports. These ports were plugged into the 386 via cables. +A QBASIC program on the 386 monitored the ports and would save and load files when requested by the +Super-80. This worked (and still works) very well, and is a huge improvement over the cassette, both +speedwise and accuracy-wise. + +The modified rom had the autorun option built in. Autorun was never available for cassettes. + +In MAME, the same file format is used - I can transfer files between MAME and the 386 seamlessly. +MAME has one difference - the program simply appears in memory without the processor being aware +of it. To accomplish autorun therefore requires that the processor pc register be set to the start +address of the program. BASIC programs may need some preprocessing before they can be started. This +is not necessary on a Super-80 or a Microbee, but is needed on any system running Microsoft BASIC, +such as the Exidy Sorcerer or the VZ-200. + +In MAME, quickload is available for all Super80 variants (otherwise you would not have any games +to play). MAME features a config switch so the user can turn autorun on or off as desired. + + += Start of Day circuit: + +When the computer is turned on or reset, the Z80 will want to start executing at 0000. Since this is +RAM, this is not a good idea. The SOD circuit forcibly disables the RAM and enables the ROMs, so they +will appear to be at 0000. Thus, the computer will boot. + +The Master Reset signal (power-on or Reset button pushed), triggers a flipflop that disables RAM and +causes C000 to FFFF to appear at 0000 to 3FFF. This will be reset (back to normal) when A14 and A15 +are high, and /M1 is active. This particular combination occurs on all ROM variants, when reading the +fifth byte in the ROM. In reality, the switchover can take place any time between the 4th byte until +the computer has booted up. This is because the low RAM does not contain any system areas. + + +Super80 disk WD2793, Z80DMA: + +Port(hex) Role Comment +--------- ----- -------- +30 DMA I/O Z80A DMA Controller Command Register +38 WDSTCM WD2793 Command Status +39 WDTRK WD2793 Track Register +3A WDSEC WD2793 Sector Register +3B WDDATA WD2793 Data Register + +3E UFDSTAT FDD and WD2793 Status input + Bit0 INTRQ 1 = WD2793 Interrupt Request + Bit1 DATARQ 1 = Data Ready to Receive or Send + Bit2 MOTOR ON 1 = FDD Motor On + +3F UFDCOM WD2793 Command Register output + Bit0 5/8 1 = 8" Drive Selected + Bit1 ENMF* 0 = 1MHz, 1 = 2MHz (for 8" double density) + Bit2 DR0SEL 1 = Drive 0 (Drive A) selected + Bit3 DR1SEL 1 = Drive 1 (Drive B) selected + Bit4 DR2SEL 1 = Drive 2 (Drive C) selected + Bit5 DR3SEL 1 = Drive 3 (Drive D) selected + Bit6 SIDESEL 0 = Select Disk side 0, 1 = Select Disk side 1 + Bit7 DDEN* 0 = MFM (Double Density), 1 = FM (Single Density) + +ToDo: +- Fix Paste: Shift operates randomly (only super80m is suitable, the others drop characters because + of the horrible inline editor they use) + + +***********************************************************************************************************/ + +#include "emu.h" +#include "super80.h" + +#include "screen.h" +#include "softlist_dev.h" +#include "speaker.h" + +#include "super80.lh" + + +#define MASTER_CLOCK (12_MHz_XTAL) +#define PIXEL_CLOCK (MASTER_CLOCK/2) +#define HTOTAL (384) +#define HBEND (0) +#define HBSTART (256) +#define VTOTAL (240) +#define VBEND (0) +#define VBSTART (160) + +#define SUPER80V_SCREEN_WIDTH (560) +#define SUPER80V_SCREEN_HEIGHT (300) +#define SUPER80V_DOTS (7) + + +/**************************** MEMORY AND I/O MAPPINGS *****************************************************************/ + +void super80_state::super80_map(address_map &map) +{ + map(0x0000, 0xbfff).ram().share("mainram"); + map(0xc000, 0xefff).rom().region("maincpu", 0).nopw(); + map(0xf000, 0xffff).lr8(NAME([] () { return 0xff; })).nopw(); +} + +void super80_state::super80m_map(address_map &map) +{ + map(0x0000, 0xffff).ram().share("mainram"); + map(0xc000, 0xefff).rom().region("maincpu", 0).nopw(); +} + +void super80v_state::super80v_map(address_map &map) +{ + map(0x0000, 0xbfff).ram().share("mainram"); + map(0xc000, 0xefff).rom().region("maincpu", 0).nopw(); + map(0xf000, 0xf7ff).rw(FUNC(super80v_state::low_r), FUNC(super80v_state::low_w)); + map(0xf800, 0xffff).rw(FUNC(super80v_state::high_r), FUNC(super80v_state::high_w)); +} + +void super80r_state::super80r_map(address_map &map) +{ + super80v_map(map); + map(0xf000, 0xf7ff).rw(FUNC(super80r_state::low_r), FUNC(super80r_state::low_w)); + map(0xf800, 0xffff).rw(FUNC(super80r_state::high_r), FUNC(super80r_state::high_w)); +} + +void super80_state::super80_io(address_map &map) +{ + map.global_mask(0xff); + map.unmap_value_high(); + map(0xdc, 0xdc).r("cent_status_in", FUNC(input_buffer_device::read)); + map(0xdc, 0xdc).w(FUNC(super80_state::portdc_w)); + map(0xe0, 0xe0).mirror(0x14).w(FUNC(super80_state::portf0_w)); + map(0xe1, 0xe1).mirror(0x14).w(FUNC(super80_state::portf1_w)); + map(0xe2, 0xe2).mirror(0x14).r(FUNC(super80_state::portf2_r)); + map(0xf8, 0xfb).mirror(0x04).rw(m_pio, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt)); +} + +void super80_state::super80e_io(address_map &map) +{ + map.global_mask(0xff); + map.unmap_value_high(); + map(0xbc, 0xbc).r("cent_status_in", FUNC(input_buffer_device::read)); + map(0xbc, 0xbc).w(FUNC(super80_state::portdc_w)); + map(0xe0, 0xe0).mirror(0x14).w(FUNC(super80_state::portf0_w)); + map(0xe1, 0xe1).mirror(0x14).w(FUNC(super80_state::portf1_w)); + map(0xe2, 0xe2).mirror(0x14).r(FUNC(super80_state::portf2_r)); + map(0xf8, 0xfb).mirror(0x04).rw(m_pio, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt)); +} + + +void super80v_state::super80v_io(address_map &map) +{ + map.global_mask(0xff); + map.unmap_value_high(); + map(0x10, 0x10).rw(m_crtc, FUNC(mc6845_device::status_r), FUNC(mc6845_device::address_w)); + map(0x11, 0x11).rw(m_crtc, FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w)); + map(0x30, 0x30).rw(m_dma, FUNC(z80dma_device::read), FUNC(z80dma_device::write)); + map(0x38, 0x3b).rw(m_fdc, FUNC(wd2793_device::read), FUNC(wd2793_device::write)); + map(0x3e, 0x3e).r(FUNC(super80v_state::port3e_r)); + map(0x3f, 0x3f).w(FUNC(super80v_state::port3f_w)); + map(0xdc, 0xdc).r("cent_status_in", FUNC(input_buffer_device::read)); + map(0xdc, 0xdc).w(FUNC(super80v_state::portdc_w)); + map(0xe0, 0xe0).mirror(0x14).w(FUNC(super80v_state::portf0_w)); + map(0xe2, 0xe2).mirror(0x14).r(FUNC(super80v_state::portf2_r)); + map(0xf8, 0xfb).mirror(0x04).rw(m_pio, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt)); +} + +/**************************** DIPSWITCHES, KEYBOARD, HARDWARE CONFIGURATION ****************************************/ + + /* Enhanced options not available on real hardware */ +static INPUT_PORTS_START( super80_cfg ) + PORT_START("CONFIG") + PORT_CONFNAME( 0x01, 0x01, "Autorun on Quickload") + PORT_CONFSETTING( 0x00, DEF_STR(No)) + PORT_CONFSETTING( 0x01, DEF_STR(Yes)) + PORT_CONFNAME( 0x02, 0x02, "2 MHz always") + PORT_CONFSETTING( 0x02, DEF_STR(No)) + PORT_CONFSETTING( 0x00, DEF_STR(Yes)) + PORT_CONFNAME( 0x04, 0x04, "Screen on always") + PORT_CONFSETTING( 0x04, DEF_STR(No)) + PORT_CONFSETTING( 0x00, DEF_STR(Yes)) + PORT_CONFNAME( 0x08, 0x08, "Cassette Speaker") + PORT_CONFSETTING( 0x08, DEF_STR(On)) + PORT_CONFSETTING( 0x00, DEF_STR(Off)) + PORT_CONFNAME( 0x60, 0x40, "Colour") + PORT_CONFSETTING( 0x60, "White") + PORT_CONFSETTING( 0x40, "Green") +INPUT_PORTS_END + +static INPUT_PORTS_START( super80 ) + PORT_START("DSW") + PORT_BIT( 0xf, 0xf, IPT_UNUSED ) + PORT_DIPNAME( 0x10, 0x00, "Switch A") PORT_DIPLOCATION("SW1:1") + PORT_DIPSETTING( 0x10, DEF_STR(Off)) + PORT_DIPSETTING( 0x00, DEF_STR(On)) + PORT_DIPNAME( 0x20, 0x20, "Switch B") PORT_DIPLOCATION("SW1:2") + PORT_DIPSETTING( 0x20, DEF_STR(Off)) + PORT_DIPSETTING( 0x00, DEF_STR(On)) + PORT_DIPNAME( 0x40, 0x40, "Switch C") PORT_DIPLOCATION("SW1:3") + PORT_DIPSETTING( 0x40, DEF_STR(Off)) + PORT_DIPSETTING( 0x00, DEF_STR(On)) + PORT_DIPNAME( 0x80, 0x00, "Switch D") PORT_DIPLOCATION("SW1:4") + PORT_DIPSETTING( 0x80, DEF_STR(Off)) + PORT_DIPSETTING( 0x00, DEF_STR(On)) + + PORT_START("KEY.0") // The physical keys show some shifted characters that are not actually available + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("@ `") PORT_CODE(KEYCODE_TILDE) PORT_CHAR('@') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_CHAR('H') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CHAR('P') PORT_CHAR(0x10) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CHAR('X') PORT_CHAR(0x18) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1 !") PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9 )") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("REPT") PORT_CODE(KEYCODE_LALT) + PORT_START("KEY.1") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_CHAR('A') PORT_CHAR(0x01) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('I') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_CHAR('Q') PORT_CHAR(0x11) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_CHAR('Y') PORT_CHAR(0x19) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2 \"") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('\"') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(": *") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(':') PORT_CHAR('*') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Backspace") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(0x08) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + PORT_START("KEY.2") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_CHAR('B') PORT_CHAR(0x02) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_CHAR('J') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_CHAR('R') PORT_CHAR(0x12) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_CHAR('Z') PORT_CHAR(0x1a) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3 #") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("; +") PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('+') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("TAB") PORT_CODE(KEYCODE_TAB) PORT_CHAR(0x09) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("(Fire)") PORT_CODE(KEYCODE_INSERT) PORT_CHAR(UCHAR_MAMEKEY(INSERT)) + PORT_START("KEY.3") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('C') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_CHAR('K') PORT_CHAR(0x0b) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_CHAR('S') PORT_CHAR(0x13) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("[ {") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4 $") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(", <") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LINEFEED") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(0x0a) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_SHIFT_2) + PORT_START("KEY.4") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CHAR('D') PORT_CHAR(0x04) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_CHAR('L') PORT_CHAR(0x0c) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_CHAR('T') PORT_CHAR(0x14) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("\\ |")PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('\\') PORT_CHAR(0x1c) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5 %") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("BRK") PORT_CODE(KEYCODE_NUMLOCK) PORT_CHAR(0x03) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(0x0d) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_RIGHT) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) + PORT_START("KEY.5") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_CHAR('E') PORT_CHAR(0x05) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('M') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_CHAR('U') PORT_CHAR(0x15) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("] }") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR(']') PORT_CHAR(0x1d) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6 &") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(". >") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("ESC") PORT_CODE(KEYCODE_ESC) PORT_CHAR(0x1b) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_LEFT) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) + PORT_START("KEY.6") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_CHAR('F') PORT_CHAR(0x06) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_CHAR('N') PORT_CHAR(0x0e) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_CHAR('V') PORT_CHAR(0x16) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("^ ~") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('^') PORT_CHAR('^') PORT_CHAR(0x1e) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7 \'") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("/ ?") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("DEL") PORT_CODE(KEYCODE_DEL) PORT_CHAR(0x7f) PORT_CHAR(0x7f) PORT_CHAR(0x1f) // natural kbd, press ctrl-backspace to DEL + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_DOWN) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) + PORT_START("KEY.7") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_CHAR('G') PORT_CHAR(0x07) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_CHAR('O') PORT_CHAR(0x0f) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_CHAR('W') PORT_CHAR(0x17) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("- =") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('=') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8 (") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(' ') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LOCK") PORT_CODE(KEYCODE_CAPSLOCK) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_UP) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) + PORT_INCLUDE( super80_cfg ) +INPUT_PORTS_END + +static INPUT_PORTS_START( super80d ) + PORT_START("DSW") + PORT_BIT( 0xf, 0xf, IPT_UNUSED ) + PORT_DIPNAME( 0x10, 0x00, "Switch A") PORT_DIPLOCATION("SW1:1") + PORT_DIPSETTING( 0x10, DEF_STR(Off)) + PORT_DIPSETTING( 0x00, DEF_STR(On)) + PORT_DIPNAME( 0x20, 0x20, "Switch B") PORT_DIPLOCATION("SW1:2") + PORT_DIPSETTING( 0x20, DEF_STR(Off)) + PORT_DIPSETTING( 0x00, DEF_STR(On)) + PORT_DIPNAME( 0x40, 0x40, "Switch C") PORT_DIPLOCATION("SW1:3") + PORT_DIPSETTING( 0x40, DEF_STR(Off)) + PORT_DIPSETTING( 0x00, DEF_STR(On)) + PORT_DIPNAME( 0x80, 0x00, "Switch D") PORT_DIPLOCATION("SW1:4") + PORT_DIPSETTING( 0x80, DEF_STR(Off)) + PORT_DIPSETTING( 0x00, DEF_STR(On)) + + PORT_START("KEY.0") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("@ `") PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('@') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_CHAR('h') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CHAR('p') PORT_CHAR(0x10) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CHAR('x') PORT_CHAR(0x18) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1 !") PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9 )") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("REPT") PORT_CODE(KEYCODE_LALT) + PORT_START("KEY.1") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_CHAR('a') PORT_CHAR(0x01) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_CHAR('i') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_CHAR('q') PORT_CHAR(0x11) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_CHAR('y') PORT_CHAR(0x19) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2 \"") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('\"') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(": *") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(':') PORT_CHAR('*') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Backspace") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(0x08) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + PORT_START("KEY.2") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_CHAR('b') PORT_CHAR(0x02) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_CHAR('j') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_CHAR('r') PORT_CHAR(0x12) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_CHAR('z') PORT_CHAR(0x1a) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3 #") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("; +") PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('+') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("TAB") PORT_CODE(KEYCODE_TAB) PORT_CHAR(0x09) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("(Fire)") PORT_CODE(KEYCODE_INSERT) PORT_CHAR(UCHAR_MAMEKEY(INSERT)) + PORT_START("KEY.3") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_CHAR('c') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_CHAR('k') PORT_CHAR(0x0b) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_CHAR('s') PORT_CHAR(0x13) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("[ {") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4 $") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(", <") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LINEFEED") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(0x0a) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_SHIFT_2) + PORT_START("KEY.4") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CHAR('d') PORT_CHAR(0x04) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_CHAR('l') PORT_CHAR(0x0c) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_CHAR('t') PORT_CHAR(0x14) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("\\ |")PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') PORT_CHAR(0x1c) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5 %") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("BRK") PORT_CODE(KEYCODE_NUMLOCK) PORT_CHAR(0x03) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(0x0d) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_RIGHT) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) + PORT_START("KEY.5") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_CHAR('e') PORT_CHAR(0x05) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_CHAR('m') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_CHAR('u') PORT_CHAR(0x15) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("] }") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') PORT_CHAR(0x1d) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6 &") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(". >") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("ESC") PORT_CODE(KEYCODE_ESC) PORT_CHAR(0x1b) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_LEFT) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) + PORT_START("KEY.6") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_CHAR('f') PORT_CHAR(0x06) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_CHAR('n') PORT_CHAR(0x0e) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_CHAR('v') PORT_CHAR(0x16) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("^ ~") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('^') PORT_CHAR('~') PORT_CHAR(0x1e) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7 \'") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("/ ?") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("DEL") PORT_CODE(KEYCODE_DEL) PORT_CHAR(0x7f) PORT_CHAR(0x5f) PORT_CHAR(0x1f) // natural kbd, press ctrl-backspace to DEL + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_DOWN) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) + PORT_START("KEY.7") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_CHAR('g') PORT_CHAR(0x07) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_CHAR('o') PORT_CHAR(0x0f) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_CHAR('w') PORT_CHAR(0x17) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("- =") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('=') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8 (") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(' ') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LOCK") PORT_CODE(KEYCODE_CAPSLOCK) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_UP) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) + PORT_INCLUDE( super80_cfg ) +INPUT_PORTS_END + +static INPUT_PORTS_START( super80e ) + PORT_INCLUDE( super80d ) + PORT_MODIFY("KEY.0") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("@ `") PORT_CODE(KEYCODE_TILDE) PORT_CHAR('@') PORT_CHAR('`') // fix mistake in super80d matrix +INPUT_PORTS_END + +static INPUT_PORTS_START( super80m ) + PORT_INCLUDE( super80e ) + + PORT_MODIFY("CONFIG") + + /* Enhanced options not available on real hardware */ + PORT_CONFNAME( 0x10, 0x10, "Swap CharGens") + PORT_CONFSETTING( 0x10, DEF_STR(No)) + PORT_CONFSETTING( 0x00, DEF_STR(Yes)) + PORT_CONFNAME( 0x60, 0x40, "Colour") + PORT_CONFSETTING( 0x60, "White") + PORT_CONFSETTING( 0x40, "Green") + PORT_CONFSETTING( 0x00, "Composite") + PORT_CONFSETTING( 0x20, "RGB") +INPUT_PORTS_END + +static INPUT_PORTS_START( super80v ) + PORT_INCLUDE( super80m ) + + PORT_MODIFY("CONFIG") + PORT_BIT( 0x16, 0x16, IPT_UNUSED ) +INPUT_PORTS_END + +static INPUT_PORTS_START( super80r ) + PORT_INCLUDE( super80d ) + + PORT_MODIFY("CONFIG") + PORT_BIT( 0x16, 0x16, IPT_UNUSED ) +INPUT_PORTS_END + + +/**************************** F4 CHARACTER DISPLAYER ***********************************************************/ + +static const gfx_layout super80_charlayout = +{ + 8,10, /* 8 x 10 characters */ + 64, /* 64 characters */ + 1, /* 1 bits per pixel */ + { 0 }, /* no bitplanes */ + /* x offsets */ + { 0, 1, 2, 3, 4, 5, 6, 7 }, + /* y offsets */ + { 0*8, 2*8, 4*8, 6*8, 8*8, 10*8, 12*8, 14*8, 1*8, 3*8, 5*8, 7*8, 9*8, 11*8, 13*8, 15*8 }, + 8*16 /* every char takes 16 bytes */ +}; + +static const gfx_layout super80d_charlayout = +{ + 8,10, /* 8 x 10 characters */ + 128, /* 256 characters */ + 1, /* 1 bits per pixel */ + { 0 }, /* no bitplanes */ + /* x offsets */ + { 0, 1, 2, 3, 4, 5, 6, 7 }, + /* y offsets */ + { 0*8, 2*8, 4*8, 6*8, 8*8, 10*8, 12*8, 14*8, 1*8, 3*8, 5*8, 7*8, 9*8, 11*8, 13*8, 15*8 }, + 8*16 /* every char takes 16 bytes */ +}; + +static const gfx_layout super80e_charlayout = +{ + 8,10, /* 8 x 10 characters */ + 256, /* 256 characters */ + 1, /* 1 bits per pixel */ + { 0 }, /* no bitplanes */ + /* x offsets */ + { 0, 1, 2, 3, 4, 5, 6, 7 }, + /* y offsets */ + { 0*8, 2*8, 4*8, 6*8, 8*8, 10*8, 12*8, 14*8, 1*8, 3*8, 5*8, 7*8, 9*8, 11*8, 13*8, 15*8 }, + 8*16 /* every char takes 16 bytes */ +}; + +static const gfx_layout super80v_charlayout = +{ + 8,16, /* 8 x 16 characters */ + 128, /* 128 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, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8 }, + 8*16 /* every char takes 16 bytes */ +}; + +static GFXDECODE_START( gfx_super80 ) + GFXDECODE_ENTRY( "chargen", 0x0000, super80_charlayout, 16, 1 ) +GFXDECODE_END + +static GFXDECODE_START( gfx_super80d ) + GFXDECODE_ENTRY( "chargen", 0x0000, super80d_charlayout, 16, 1 ) +GFXDECODE_END + +static GFXDECODE_START( gfx_super80e ) + GFXDECODE_ENTRY( "chargen", 0x0000, super80e_charlayout, 16, 1 ) +GFXDECODE_END + +static GFXDECODE_START( gfx_super80m ) + GFXDECODE_ENTRY( "chargen", 0x0000, super80e_charlayout, 2, 6 ) + GFXDECODE_ENTRY( "chargen", 0x1000, super80d_charlayout, 2, 6 ) +GFXDECODE_END + +static GFXDECODE_START( gfx_super80v ) + GFXDECODE_ENTRY( "chargen", 0x0000, super80v_charlayout, 2, 6 ) +GFXDECODE_END + + + +/**************************** BASIC MACHINE CONSTRUCTION ***********************************************************/ + + +static const z80_daisy_config super80_daisy_chain[] = +{ + { "z80pio" }, + { nullptr } +}; + +//------------------------------------------------- +// Z80DMA +//------------------------------------------------- + +WRITE_LINE_MEMBER( super80v_state::busreq_w ) +{ +// since our Z80 has no support for BUSACK, we assume it is granted immediately + m_maincpu->set_input_line(Z80_INPUT_LINE_BUSRQ, state); + m_maincpu->set_input_line(INPUT_LINE_HALT, state); + m_dma->bai_w(state); // tell dma that bus has been granted +} + +uint8_t super80v_state::memory_read_byte(offs_t offset) +{ + address_space& prog_space = m_maincpu->space(AS_PROGRAM); + return prog_space.read_byte(offset); +} + +void super80v_state::memory_write_byte(offs_t offset, uint8_t data) +{ + address_space& prog_space = m_maincpu->space(AS_PROGRAM); + prog_space.write_byte(offset, data); +} + +uint8_t super80v_state::io_read_byte(offs_t offset) +{ + address_space& prog_space = m_maincpu->space(AS_IO); + return prog_space.read_byte(offset); +} + +void super80v_state::io_write_byte(offs_t offset, uint8_t data) +{ + address_space& prog_space = m_maincpu->space(AS_IO); + prog_space.write_byte(offset, data); +} + +static void super80_floppies(device_slot_interface &device) +{ + device.option_add("s80flop", FLOPPY_525_QD); +} + + +static const char *const relay_sample_names[] = +{ + "*relay", + "relayoff", + "relayon", + nullptr +}; + + +void super80_state::super80(machine_config &config) +{ + /* basic machine hardware */ + Z80(config, m_maincpu, MASTER_CLOCK/6); /* 2 MHz */ + m_maincpu->set_addrmap(AS_PROGRAM, &super80_state::super80_map); + m_maincpu->set_addrmap(AS_IO, &super80_state::super80_io); + m_maincpu->set_daisy_config(super80_daisy_chain); + + Z80PIO(config, m_pio, MASTER_CLOCK/6); + m_pio->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); + m_pio->out_pa_callback().set([this](u8 data){ super80_state::pio_port_a_w(data); }); + m_pio->in_pb_callback().set([this](){ return super80_state::pio_port_b_r(); }); + + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_refresh_hz(48.8); + m_screen->set_raw(PIXEL_CLOCK, HTOTAL, HBEND, HBSTART, VTOTAL, VBEND, VBSTART); + m_screen->set_screen_update(FUNC(super80_state::screen_update_super80)); + m_screen->set_palette(m_palette); + + PALETTE(config, m_palette, FUNC(super80_state::super80m_palette), 32); + GFXDECODE(config, m_gfxdecode, m_palette, gfx_super80); + + config.set_default_layout(layout_super80); + + /* sound hardware */ + SPEAKER(config, "mono").front_center(); + SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.50); + SAMPLES(config, m_samples); + m_samples->set_channels(1); + m_samples->set_samples_names(relay_sample_names); + m_samples->add_route(ALL_OUTPUTS, "mono", 1.0); + + /* printer */ + CENTRONICS(config, m_centronics, centronics_devices, "printer"); + m_centronics->busy_handler().set("cent_status_in", FUNC(input_buffer_device::write_bit7)); + + output_latch_device ¢_data_out(OUTPUT_LATCH(config, "cent_data_out")); + m_centronics->set_output_latch(cent_data_out); + + INPUT_BUFFER(config, "cent_status_in", 0); + + /* quickload */ + quickload_image_device &quickload(QUICKLOAD(config, "quickload", "bin", attotime::from_seconds(3))); + quickload.set_load_callback(FUNC(super80_state::quickload_cb)); + quickload.set_interface("super80_quik"); + + /* cassette */ + CASSETTE(config, m_cassette); + m_cassette->set_default_state(CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED); + m_cassette->add_route(ALL_OUTPUTS, "mono", 0.05); + m_cassette->set_interface("super80_cass"); + + TIMER(config, "kansas_r").configure_periodic(FUNC(super80_state::kansas_r), attotime::from_hz(40000)); // cass read + TIMER(config, "timer_k").configure_periodic(FUNC(super80_state::timer_k), attotime::from_hz(300)); // keyb scan + TIMER(config, "timer_h").configure_periodic(FUNC(super80_state::timer_h), attotime::from_hz(100)); // half-speed + + // software list + SOFTWARE_LIST(config, "cass_list").set_original("super80_cass").set_filter("DEF"); + SOFTWARE_LIST(config, "quik_list").set_original("super80_quik").set_filter("DEF"); +} + +void super80_state::super80d(machine_config &config) +{ + super80(config); + m_gfxdecode->set_info(gfx_super80d); + m_screen->set_screen_update(FUNC(super80_state::screen_update_super80d)); + + // software list + SOFTWARE_LIST(config.replace(), "cass_list").set_original("super80_cass").set_filter("D"); + SOFTWARE_LIST(config.replace(), "quik_list").set_original("super80_quik").set_filter("D"); +} + +void super80_state::super80e(machine_config &config) +{ + super80(config); + m_maincpu->set_addrmap(AS_IO, &super80_state::super80e_io); + m_gfxdecode->set_info(gfx_super80e); + m_screen->set_screen_update(FUNC(super80_state::screen_update_super80e)); + + // software list + SOFTWARE_LIST(config.replace(), "cass_list").set_original("super80_cass").set_filter("E"); + SOFTWARE_LIST(config.replace(), "quik_list").set_original("super80_quik").set_filter("E"); +} + +void super80_state::super80m(machine_config &config) +{ + super80(config); + m_maincpu->set_addrmap(AS_PROGRAM, &super80_state::super80m_map); + + m_gfxdecode->set_info(gfx_super80m); + + m_screen->set_screen_update(FUNC(super80_state::screen_update_super80m)); + m_screen->screen_vblank().set([this](bool state) { super80_state::screen_vblank_super80m(state); }); + + // software list + SOFTWARE_LIST(config.replace(), "cass_list").set_original("super80_cass").set_filter("M"); + SOFTWARE_LIST(config.replace(), "quik_list").set_original("super80_quik").set_filter("M"); +} + +void super80v_state::super80v(machine_config &config) +{ + /* basic machine hardware */ + Z80(config, m_maincpu, MASTER_CLOCK/6); /* 2 MHz */ + m_maincpu->set_addrmap(AS_PROGRAM, &super80v_state::super80v_map); + m_maincpu->set_addrmap(AS_IO, &super80v_state::super80v_io); + m_maincpu->set_daisy_config(super80_daisy_chain); + + Z80PIO(config, m_pio, MASTER_CLOCK/6); + m_pio->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); + m_pio->out_pa_callback().set([this](u8 data){ super80v_state::pio_port_a_w(data); }); + m_pio->in_pb_callback().set([this](){ return super80v_state::pio_port_b_r(); }); + + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_refresh_hz(50); + m_screen->set_size(SUPER80V_SCREEN_WIDTH, SUPER80V_SCREEN_HEIGHT); + m_screen->set_visarea(0, SUPER80V_SCREEN_WIDTH-1, 0, SUPER80V_SCREEN_HEIGHT-1); + m_screen->set_screen_update(FUNC(super80v_state::screen_update_super80v)); + m_screen->screen_vblank().set([this](bool state) { super80v_state::screen_vblank_super80m(state); }); + + PALETTE(config, m_palette, FUNC(super80v_state::super80m_palette), 32); + GFXDECODE(config, m_gfxdecode, m_palette, gfx_super80v); + + MC6845(config, m_crtc, MASTER_CLOCK / SUPER80V_DOTS); + m_crtc->set_screen("screen"); + m_crtc->set_show_border_area(false); + m_crtc->set_char_width(SUPER80V_DOTS); + m_crtc->set_update_row_callback(FUNC(super80v_state::crtc_update_row)); + + config.set_default_layout(layout_super80); + + /* sound hardware */ + SPEAKER(config, "mono").front_center(); + SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.50); + SAMPLES(config, m_samples); + m_samples->set_channels(1); + m_samples->set_samples_names(relay_sample_names); + m_samples->add_route(ALL_OUTPUTS, "mono", 1.0); + + /* printer */ + CENTRONICS(config, m_centronics, centronics_devices, "printer"); + m_centronics->busy_handler().set("cent_status_in", FUNC(input_buffer_device::write_bit7)); + + output_latch_device ¢_data_out(OUTPUT_LATCH(config, "cent_data_out")); + m_centronics->set_output_latch(cent_data_out); + + INPUT_BUFFER(config, "cent_status_in", 0); + + /* quickload */ + quickload_image_device &quickload(QUICKLOAD(config, "quickload", "bin", attotime::from_seconds(3))); + quickload.set_load_callback(FUNC(super80v_state::quickload_cb)); + quickload.set_interface("super80_quik"); + + /* cassette */ + CASSETTE(config, m_cassette); + m_cassette->set_default_state(CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED); + m_cassette->add_route(ALL_OUTPUTS, "mono", 0.05); + m_cassette->set_interface("super80_cass"); + + TIMER(config, "kansas_r").configure_periodic(FUNC(super80v_state::kansas_r), attotime::from_hz(40000)); // cass read + TIMER(config, "timer_k").configure_periodic(FUNC(super80v_state::timer_k), attotime::from_hz(300)); // keyb scan + + Z80DMA(config, m_dma, MASTER_CLOCK/6); + m_dma->out_busreq_callback().set(FUNC(super80v_state::busreq_w)); + m_dma->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); + //ba0 - not connected + m_dma->in_mreq_callback().set(FUNC(super80v_state::memory_read_byte)); + m_dma->out_mreq_callback().set(FUNC(super80v_state::memory_write_byte)); + m_dma->in_iorq_callback().set(FUNC(super80v_state::io_read_byte)); + m_dma->out_iorq_callback().set(FUNC(super80v_state::io_write_byte)); + + WD2793(config, m_fdc, 2_MHz_XTAL); + m_fdc->drq_wr_callback().set(m_dma, FUNC(z80dma_device::rdy_w)); + FLOPPY_CONNECTOR(config, "fdc:0", super80_floppies, "s80flop", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, "fdc:1", super80_floppies, "s80flop", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, "fdc:2", super80_floppies, "s80flop", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, "fdc:3", super80_floppies, "s80flop", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); + + // software list + SOFTWARE_LIST(config, "cass_list").set_original("super80_cass").set_filter("V"); + SOFTWARE_LIST(config, "quik_list").set_original("super80_quik").set_filter("V"); + SOFTWARE_LIST(config, "flop_list").set_original("super80_flop"); +} + +void super80r_state::super80r(machine_config &config) +{ + super80v(config); + m_maincpu->set_addrmap(AS_PROGRAM, &super80r_state::super80r_map); + + // software list + SOFTWARE_LIST(config.replace(), "cass_list").set_original("super80_cass").set_filter("R"); + SOFTWARE_LIST(config.replace(), "quik_list").set_original("super80_quik").set_filter("R"); +} + +/**************************** ROMS *****************************************************************/ + +ROM_START( super80 ) + ROM_REGION(0x3000, "maincpu", 0) + ROM_LOAD("super80.u26", 0x0000, 0x1000, CRC(6a6a9664) SHA1(2c4fcd943aa9bf7419d58fbc0e28ffb89ef22e0b) ) + ROM_LOAD("super80.u33", 0x1000, 0x1000, CRC(cf8020a8) SHA1(2179a61f80372cd49e122ad3364773451531ae85) ) + ROM_LOAD("super80.u42", 0x2000, 0x1000, CRC(a1c6cb75) SHA1(d644ca3b399c1a8902f365c6095e0bbdcea6733b) ) + + ROM_REGION(0x0400, "chargen", 0) // 2513 prom + ROM_LOAD("super80.u27", 0x0000, 0x0400, CRC(d1e4b3c6) SHA1(3667b97c6136da4761937958f281609690af4081) ) +ROM_END + +ROM_START( super80d ) + ROM_REGION(0x3000, "maincpu", 0) + ROM_SYSTEM_BIOS(0, "super80d", "V2.2") + ROMX_LOAD("super80d.u26", 0x0000, 0x1000, CRC(cebd2613) SHA1(87b94cc101a5948ce590211c68272e27f4cbe95a), ROM_BIOS(0)) + ROM_SYSTEM_BIOS(1, "super80f", "MDS (original)") + ROMX_LOAD("super80f.u26", 0x0000, 0x1000, CRC(d39775f0) SHA1(b47298ee028924612e9728bb2debd0f47399add7), ROM_BIOS(1)) + ROM_SYSTEM_BIOS(2, "super80g", "MDS (upgraded)") + ROMX_LOAD("super80g.u26", 0x0000, 0x1000, CRC(7386f507) SHA1(69d7627033d62bd4e886ccc136e89f1524d38f47), ROM_BIOS(2)) + ROM_LOAD("super80.u33", 0x1000, 0x1000, CRC(cf8020a8) SHA1(2179a61f80372cd49e122ad3364773451531ae85) ) + ROM_LOAD("super80.u42", 0x2000, 0x1000, CRC(a1c6cb75) SHA1(d644ca3b399c1a8902f365c6095e0bbdcea6733b) ) + + ROM_REGION(0x0800, "chargen", 0) // 2716 eprom + ROM_LOAD("super80d.u27", 0x0000, 0x0800, CRC(cb4c81e2) SHA1(8096f21c914fa76df5d23f74b1f7f83bd8645783) ) +ROM_END + +ROM_START( super80e ) + ROM_REGION(0x3000, "maincpu", 0) + ROM_LOAD("super80e.u26", 0x0000, 0x1000, CRC(bdc668f8) SHA1(3ae30b3cab599fca77d5e461f3ec1acf404caf07) ) + ROM_LOAD("super80.u33", 0x1000, 0x1000, CRC(cf8020a8) SHA1(2179a61f80372cd49e122ad3364773451531ae85) ) + ROM_LOAD("super80.u42", 0x2000, 0x1000, CRC(a1c6cb75) SHA1(d644ca3b399c1a8902f365c6095e0bbdcea6733b) ) + + ROM_REGION(0x1000, "chargen", 0) // 2732 eprom + ROM_LOAD("super80e.u27", 0x0000, 0x1000, CRC(ebe763a7) SHA1(ffaa6d6a2c5dacc5a6651514e6707175a32e83e8) ) +ROM_END + +ROM_START( super80m ) + ROM_REGION(0x3000, "maincpu", 0) + ROM_SYSTEM_BIOS(0, "8r0", "8R0") + ROMX_LOAD("s80-8r0.u26", 0x0000, 0x1000, CRC(48d410d8) SHA1(750d984abc013a3344628300288f6d1ba140a95f), ROM_BIOS(0) ) + ROMX_LOAD("s80-8r0.u33", 0x1000, 0x1000, CRC(9765793e) SHA1(4951b127888c1f3153004cc9fb386099b408f52c), ROM_BIOS(0) ) + ROMX_LOAD("s80-8r0.u42", 0x2000, 0x1000, CRC(5f65d94b) SHA1(fe26b54dec14e1c4911d996c9ebd084a38dcb691), ROM_BIOS(0) ) +#if 0 + /* Temporary patch to fix crash when lprinting a tab */ + ROM_FILL(0x0c44,1,0x46) + ROM_FILL(0x0c45,1,0xc5) + ROM_FILL(0x0c46,1,0x06) + ROM_FILL(0x0c47,1,0x20) + ROM_FILL(0x0c48,1,0xcd) + ROM_FILL(0x0c49,1,0xc7) + ROM_FILL(0x0c4a,1,0xcb) + ROM_FILL(0x0c4b,1,0xc1) + ROM_FILL(0x0c4c,1,0x10) + ROM_FILL(0x0c4d,1,0xf7) + ROM_FILL(0x0c4e,1,0x00) + ROM_FILL(0x0c4f,1,0x00) +#endif + ROM_SYSTEM_BIOS(1, "v37", "V3.7") + ROMX_LOAD("s80-v37.u26", 0x0000, 0x1000, CRC(46043035) SHA1(1765105df4e4af83d56cafb88e158ed462d4709e), ROM_BIOS(1) ) + ROMX_LOAD("s80-v37.u33", 0x1000, 0x1000, CRC(afb52b15) SHA1(0a2c25834074ce44bf12ac8532b4add492bcf950), ROM_BIOS(1) ) + ROMX_LOAD("s80-v37.u42", 0x2000, 0x1000, CRC(7344b27a) SHA1(f43fc47ddb5c12bffffa63488301cd5eb386cc9a), ROM_BIOS(1) ) + + ROM_SYSTEM_BIOS(2, "8r2", "8R2") + ROMX_LOAD("s80-8r2.u26", 0x0000, 0x1000, CRC(1e166c8c) SHA1(15647614be9300cdd2956da913e83234c36b36a9), ROM_BIOS(2) ) + ROMX_LOAD("s80-8r0.u33", 0x1000, 0x1000, CRC(9765793e) SHA1(4951b127888c1f3153004cc9fb386099b408f52c), ROM_BIOS(2) ) + ROMX_LOAD("s80-8r0.u42", 0x2000, 0x1000, CRC(5f65d94b) SHA1(fe26b54dec14e1c4911d996c9ebd084a38dcb691), ROM_BIOS(2) ) + + ROM_SYSTEM_BIOS(3, "8r3", "8R3") + ROMX_LOAD("s80-8r3.u26", 0x0000, 0x1000, CRC(ee7dd90b) SHA1(c53f8eef82e8f943642f6ddfc2cb1bfdc32d25ca), ROM_BIOS(3) ) + ROMX_LOAD("s80-8r0.u33", 0x1000, 0x1000, CRC(9765793e) SHA1(4951b127888c1f3153004cc9fb386099b408f52c), ROM_BIOS(3) ) + ROMX_LOAD("s80-8r0.u42", 0x2000, 0x1000, CRC(5f65d94b) SHA1(fe26b54dec14e1c4911d996c9ebd084a38dcb691), ROM_BIOS(3) ) + + ROM_SYSTEM_BIOS(4, "8r4", "8R4") + ROMX_LOAD("s80-8r4.u26", 0x0000, 0x1000, CRC(637d001d) SHA1(f26b5ecc33fd44b05b1f199d79e0f072ec8d0e23), ROM_BIOS(4) ) + ROMX_LOAD("s80-8r0.u33", 0x1000, 0x1000, CRC(9765793e) SHA1(4951b127888c1f3153004cc9fb386099b408f52c), ROM_BIOS(4) ) + ROMX_LOAD("s80-8r0.u42", 0x2000, 0x1000, CRC(5f65d94b) SHA1(fe26b54dec14e1c4911d996c9ebd084a38dcb691), ROM_BIOS(4) ) + + ROM_SYSTEM_BIOS(5, "8r5", "8R5") + ROMX_LOAD("s80-8r5.u26", 0x0000, 0x1000, CRC(294f217c) SHA1(f352d54e84e94bf299726dc3af4eb7b2d06d317c), ROM_BIOS(5) ) + ROMX_LOAD("s80-8r0.u33", 0x1000, 0x1000, CRC(9765793e) SHA1(4951b127888c1f3153004cc9fb386099b408f52c), ROM_BIOS(5) ) + ROMX_LOAD("s80-8r0.u42", 0x2000, 0x1000, CRC(5f65d94b) SHA1(fe26b54dec14e1c4911d996c9ebd084a38dcb691), ROM_BIOS(5) ) + + ROM_REGION(0x1800, "chargen", 0) + ROM_LOAD("super80e.u27", 0x0000, 0x1000, CRC(ebe763a7) SHA1(ffaa6d6a2c5dacc5a6651514e6707175a32e83e8) ) + ROM_LOAD("super80d.u27", 0x1000, 0x0800, CRC(cb4c81e2) SHA1(8096f21c914fa76df5d23f74b1f7f83bd8645783) ) +ROM_END + +ROM_START( super80r ) + ROM_REGION( 0x3000, "maincpu", 0 ) + ROM_SYSTEM_BIOS(0, "super80r", "MCE (original)") + ROMX_LOAD("super80r.u26", 0x0000, 0x1000, CRC(01bb6406) SHA1(8e275ecf5141b93f86e45ff8a735b965ea3e8d44), ROM_BIOS(0)) + ROM_SYSTEM_BIOS(1, "super80s", "MCE (upgraded)") + ROMX_LOAD("super80s.u26", 0x0000, 0x1000, CRC(3e29d307) SHA1(b3f4667633e0a4eb8577e39b5bd22e1f0bfbc0a9), ROM_BIOS(1)) + + ROM_LOAD("super80.u33", 0x1000, 0x1000, CRC(cf8020a8) SHA1(2179a61f80372cd49e122ad3364773451531ae85) ) + ROM_LOAD("super80.u42", 0x2000, 0x1000, CRC(a1c6cb75) SHA1(d644ca3b399c1a8902f365c6095e0bbdcea6733b) ) + + ROM_REGION(0x0800, "chargen", 0) // 2716 eprom + ROM_LOAD("s80hmce.ic24", 0x0000, 0x0800, CRC(a6488a1e) SHA1(7ba613d70a37a6b738dcd80c2bb9988ff1f011ef) ) +ROM_END + +ROM_START( super80v ) + ROM_REGION( 0x3000, "maincpu", 0 ) + ROM_LOAD("s80-v37v.u26", 0x0000, 0x1000, CRC(01e0c0dd) SHA1(ef66af9c44c651c65a21d5bda939ffa100078c08) ) + ROM_LOAD("s80-v37v.u33", 0x1000, 0x1000, CRC(812ad777) SHA1(04f355bea3470a7d9ea23bb2811f6af7d81dc400) ) + ROM_LOAD("s80-v37v.u42", 0x2000, 0x1000, CRC(e02e736e) SHA1(57b0264c805da99234ab5e8e028fca456851a4f9) ) + + ROM_REGION(0x0800, "chargen", 0) // 2716 eprom + ROM_LOAD("s80hmce.ic24", 0x0000, 0x0800, CRC(a6488a1e) SHA1(7ba613d70a37a6b738dcd80c2bb9988ff1f011ef) ) +ROM_END + +/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME */ +COMP( 1981, super80, 0, 0, super80, super80, super80_state, empty_init, "Dick Smith Electronics", "Super-80 (V1.2)" , MACHINE_SUPPORTS_SAVE ) +COMP( 1981, super80d, super80, 0, super80d, super80d, super80_state, empty_init, "Dick Smith Electronics", "Super-80 (V2.2)" , MACHINE_SUPPORTS_SAVE ) +COMP( 1981, super80e, super80, 0, super80e, super80e, super80_state, empty_init, "Dick Smith Electronics", "Super-80 (El Graphix 4)" , MACHINE_UNOFFICIAL | MACHINE_SUPPORTS_SAVE ) +COMP( 1981, super80m, super80, 0, super80m, super80m, super80_state, empty_init, "Dick Smith Electronics", "Super-80 (with colour)" , MACHINE_UNOFFICIAL | MACHINE_SUPPORTS_SAVE ) +COMP( 1981, super80r, super80, 0, super80r, super80r, super80r_state, empty_init, "Dick Smith Electronics", "Super-80 (with VDUEB)" , MACHINE_UNOFFICIAL | MACHINE_SUPPORTS_SAVE ) +COMP( 1981, super80v, super80, 0, super80v, super80v, super80v_state, empty_init, "Dick Smith Electronics", "Super-80 (with enhanced VDUEB)" , MACHINE_UNOFFICIAL | MACHINE_SUPPORTS_SAVE ) + diff --git a/src/mame/ausnz/super80.h b/src/mame/ausnz/super80.h new file mode 100644 index 00000000000..a8a74191a55 --- /dev/null +++ b/src/mame/ausnz/super80.h @@ -0,0 +1,188 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert +#ifndef MAME_INCLUDES_SUPER80_H +#define MAME_INCLUDES_SUPER80_H + +#pragma once + +#include "bus/centronics/ctronics.h" +#include "cpu/z80/z80.h" +#include "imagedev/cassette.h" +#include "imagedev/floppy.h" +#include "imagedev/snapquik.h" +#include "machine/buffer.h" +#include "machine/timer.h" +#include "machine/wd_fdc.h" +#include "machine/z80daisy.h" +#include "machine/z80dma.h" +#include "machine/z80pio.h" +#include "sound/samples.h" +#include "sound/spkrdev.h" +#include "video/mc6845.h" + +#include "emupal.h" +#include "screen.h" + + +/* Bits in m_portf0 variable: + d5 cassette LED + d4 super80v rom or pcg bankswitch (1=pcg ram, 0=char gen rom) + d2 super80v video or colour bankswitch (1=video ram, 0=colour ram) + d2 super80 screen off (=2mhz) or on (bursts of 2mhz at 50hz = 1mhz) */ + +class super80_state : public driver_device +{ +public: + super80_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_palette(*this, "palette") + , m_gfxdecode(*this, "gfxdecode") + , m_screen(*this, "screen") + , m_maincpu(*this, "maincpu") + , m_rom(*this, "maincpu") + , m_ram(*this, "mainram") + , m_p_chargen(*this, "chargen") + , m_pio(*this, "z80pio") + , m_cassette(*this, "cassette") + , m_samples(*this, "samples") + , m_speaker(*this, "speaker") + , m_centronics(*this, "centronics") + , m_cent_data_out(*this, "cent_data_out") + , m_io_dsw(*this, "DSW") + , m_io_config(*this, "CONFIG") + , m_io_keyboard(*this, "KEY.%u", 0) + , m_cass_led(*this, "cass_led") + { } + + void super80m(machine_config &config); + void super80(machine_config &config); + void super80e(machine_config &config); + void super80d(machine_config &config); + +protected: + void machine_reset_common(); + void machine_start_common(); + void cassette_motor(bool data); + void screen_vblank_super80m(bool state); + void portf0_w(u8 data); + void portdc_w(u8 data); + void pio_port_a_w(u8 data); + u8 pio_port_b_r(); + u8 portf2_r(); + u8 m_portf0 = 0U; + u8 m_s_options = 0U; + u8 m_palette_index = 0U; + u8 m_keylatch = 0U; + u8 m_cass_data[4]{}; + u8 m_key_pressed = 0U; + u8 m_last_data = 0U; + bool m_boot_in_progress = false; + void super80m_palette(palette_device &palette) const; + TIMER_DEVICE_CALLBACK_MEMBER(timer_k); + TIMER_DEVICE_CALLBACK_MEMBER(kansas_r); + DECLARE_QUICKLOAD_LOAD_MEMBER(quickload_cb); + required_device m_palette; + required_device m_gfxdecode; + required_device m_screen; + required_device m_maincpu; + required_region_ptr m_rom; + memory_passthrough_handler m_rom_shadow_tap; + required_shared_ptr m_ram; + required_region_ptr m_p_chargen; + required_device m_pio; + required_device m_cassette; + required_device m_samples; + required_device m_speaker; + required_device m_centronics; + required_device m_cent_data_out; + required_ioport m_io_dsw; + required_ioport m_io_config; + required_ioport_array<8> m_io_keyboard; + output_finder<> m_cass_led; + +private: + void machine_reset() override; + void machine_start() override; + + void portf1_w(u8 data); + TIMER_DEVICE_CALLBACK_MEMBER(timer_h); + + uint32_t screen_update_super80(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + uint32_t screen_update_super80d(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + uint32_t screen_update_super80e(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + uint32_t screen_update_super80m(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + + void super80_io(address_map &map); + void super80_map(address_map &map); + void super80e_io(address_map &map); + void super80m_map(address_map &map); + + u8 m_int_sw = 0; + u16 m_vidpg = 0; + bool m_current_charset = false; +}; + + +class super80v_state : public super80_state +{ +public: + super80v_state(const machine_config &mconfig, device_type type, const char *tag) + : super80_state(mconfig, type, tag) + , m_crtc(*this, "crtc") + , m_dma(*this, "dma") + , m_fdc (*this, "fdc") + , m_floppy0(*this, "fdc:0") + , m_floppy1(*this, "fdc:1") + , m_floppy2(*this, "fdc:2") + , m_floppy3(*this, "fdc:3") + { } + + void super80v(machine_config &config); + +protected: + void super80v_map(address_map &map); + void super80v_io(address_map &map); + void machine_reset() override; + void machine_start() override; + void port3f_w(u8 data); + u8 port3e_r(); + std::unique_ptr m_vram; + DECLARE_WRITE_LINE_MEMBER(busreq_w); + uint8_t memory_read_byte(offs_t offset); + void memory_write_byte(offs_t offset, uint8_t data); + uint8_t io_read_byte(offs_t offset); + void io_write_byte(offs_t offset, uint8_t data); + MC6845_UPDATE_ROW(crtc_update_row); + uint32_t screen_update_super80v(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + required_device m_crtc; + required_device m_dma; + required_device m_fdc; + required_device m_floppy0; + required_device m_floppy1; + required_device m_floppy2; + required_device m_floppy3; + +private: + void low_w(offs_t offset, u8 data); + void high_w(offs_t offset, u8 data); + u8 low_r(offs_t offset); + u8 high_r(offs_t offset); +}; + +class super80r_state : public super80v_state +{ +public: + using super80v_state::super80v_state; + + void super80r(machine_config &config); + +private: + void super80r_map(address_map &map); + void low_w(offs_t offset, u8 data); + void high_w(offs_t offset, u8 data); + u8 low_r(offs_t offset); + u8 high_r(offs_t offset); +}; + + +#endif // MAME_INCLUDES_SUPER80_H diff --git a/src/mame/ausnz/super80_m.cpp b/src/mame/ausnz/super80_m.cpp new file mode 100644 index 00000000000..5b14c8cb6d3 --- /dev/null +++ b/src/mame/ausnz/super80_m.cpp @@ -0,0 +1,284 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert +/* Super80.cpp written by Robbbert, 2005-2009. See driver source for documentation. */ + +#include "emu.h" +#include "super80.h" + +#include "z80bin.h" + + +/**************************** PIO ******************************************************************************/ + + +void super80_state::pio_port_a_w(u8 data) +{ + m_keylatch = data; + m_pio->port_b_write(pio_port_b_r()); // refresh kbd int +} + +uint8_t super80_state::pio_port_b_r() +{ + uint8_t data = 0xff; + + for (int i = 0; i < 8; i++) + if (!BIT(m_keylatch, i)) + data &= m_io_keyboard[i]->read(); + + m_key_pressed = 3; + + return data; +} + +/**************************** CASSETTE ROUTINES *****************************************************************/ + +void super80_state::cassette_motor( bool motor_state ) +{ + // relay sound + if (BIT(m_last_data, 1) != motor_state) + m_samples->start(0, motor_state ? 0 : 1); + + if (motor_state) + m_cassette->change_state(CASSETTE_MOTOR_DISABLED,CASSETTE_MASK_MOTOR); + else + m_cassette->change_state(CASSETTE_MOTOR_ENABLED,CASSETTE_MASK_MOTOR); + + /* does user want to hear the sound? */ + if (BIT(m_io_config->read(), 3)) + m_cassette->change_state(CASSETTE_SPEAKER_ENABLED,CASSETTE_MASK_SPEAKER); + else + m_cassette->change_state(CASSETTE_SPEAKER_MUTED,CASSETTE_MASK_SPEAKER); +} + +/********************************************* TIMER ************************************************/ + + +// If normal keyboard scan has stopped, then do a scan to allow the interrupt key sequence +TIMER_DEVICE_CALLBACK_MEMBER( super80_state::timer_k ) +{ + if (m_key_pressed) + m_key_pressed--; + else + if (!m_key_pressed) + m_pio->port_b_write(pio_port_b_r()); +} + +/* cassette load circuit + This "emulates" U79 CD4046BCN PLL chip and U1 LM311P op-amp. U79 converts a frequency to a voltage, + and U1 amplifies that voltage to digital levels. U1 has a trimpot connected, to set the midpoint. + + The MDS homebrew input circuit consists of 2 op-amps followed by a D-flipflop. + The "read-any-system" cassette circuit is a CA3140 op-amp, the smarts being done in software. + + bit 0 = original system (U79 and U1) + bit 1 = MDS fast system + bit 2 = CA3140 */ +TIMER_DEVICE_CALLBACK_MEMBER( super80_state::kansas_r ) +{ + uint8_t cass_ws=0; + + m_cass_data[1]++; + cass_ws = ((m_cassette)->input() > +0.03) ? 4 : 0; + + if (cass_ws != m_cass_data[0]) + { + if (cass_ws) m_cass_data[3] ^= 2; // the MDS flipflop + m_cass_data[0] = cass_ws; + m_cass_data[2] = ((m_cass_data[1] < 0x0d) ? 1 : 0) | cass_ws | m_cass_data[3]; + m_cass_data[1] = 0; + } +} + + +TIMER_DEVICE_CALLBACK_MEMBER( super80_state::timer_h ) +{ + uint8_t go_fast = 0; + if ( (!BIT(m_portf0, 2)) || (!BIT(m_io_config->read(), 1)) ) // bit 2 of port F0 is low, OR user turned on config switch + go_fast++; // must be 1 at boot so banking works correctly + + /* code to slow down computer to 1 MHz by halting cpu on every second frame */ + if (!go_fast) + { + if (!m_int_sw) + m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); // if going, stop it + + m_int_sw++; + if (m_int_sw > 1) + { + m_maincpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE); // if stopped, start it + m_int_sw = 0; + } + } + else + { + if (m_int_sw < 8) // @2MHz, reset just once + { + m_maincpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE); + m_int_sw = 8; // ...not every time + } + } +} + +/*************************************** PRINTER ********************************************************/ + +/* The Super80 had an optional I/O card that plugged into the S-100 slot. The card had facility for running + an 8-bit Centronics printer, and a serial device at 300, 600, or 1200 baud. The I/O address range + was selectable via 4 dipswitches. The serial parameters (baud rate, parity, stop bits, etc) was + chosen with more dipswitches. Regretably, no parameters could be set by software. Currently, the + Centronics printer is emulated; the serial side of things may be done later, as will the dipswitches. + + The most commonly used I/O range is DC-DE (DC = centronics, DD = serial data, DE = serial control + All the home-brew roms use this, except for super80e which uses BC-BE. */ + +/**************************** I/O PORTS *****************************************************************/ + +u8 super80v_state::port3e_r() +{ + return 0xF8 | (m_fdc->intrq_r() << 0) | (m_fdc->drq_r() << 1) | 4; +} + +// UFDC board can support 4 drives; we support 2 +void super80v_state::port3f_w(u8 data) +{ + // m_fdc->58(BIT(data, 0)); 5/8 pin not emulated in wd_fdc + m_fdc->enmf_w(BIT(data,1)); + + floppy_image_device *floppy = nullptr; + if (BIT(data, 2)) floppy = m_floppy0->get_device(); + if (BIT(data, 3)) floppy = m_floppy1->get_device(); + if (BIT(data, 4)) floppy = m_floppy2->get_device(); + if (BIT(data, 5)) floppy = m_floppy3->get_device(); + + m_fdc->set_floppy(floppy); + + if (floppy) + { + floppy->mon_w(0); + floppy->ss_w(BIT(data, 6)); + } + + m_fdc->dden_w(BIT(data, 7)); +} + +u8 super80_state::portf2_r() +{ + u8 data = m_io_dsw->read() & 0xf0; // dip switches on pcb + data |= m_cass_data[2]; // bit 0 = output of U1, bit 1 = MDS cass state, bit 2 = current wave_state + data |= 0x08; // bit 3 - not used + return data; +} + +void super80_state::portdc_w(u8 data) +{ + // hardware strobe driven from port select, bit 7..0 = data + m_cent_data_out->write(data); + m_centronics->write_strobe(0); + m_centronics->write_strobe(1); +} + + +void super80_state::portf0_w(u8 data) +{ + u8 bits = data ^ m_last_data; + m_portf0 = data; + m_speaker->level_w(BIT(data, 3)); // bit 3 - speaker + if (BIT(bits, 1)) cassette_motor(BIT(data, 1)); // bit 1 - cassette motor + m_cassette->output( BIT(data, 0) ? -1.0 : +1.0); // bit 0 - cass out + + m_last_data = data; +} + + +/**************************** BASIC MACHINE CONSTRUCTION ***********************************************************/ + +void super80_state::machine_start_common() +{ + m_cass_led.resolve(); + + // register for savestates + save_item(NAME(m_portf0)); + save_item(NAME(m_s_options)); + save_item(NAME(m_palette_index)); + save_item(NAME(m_keylatch)); + save_item(NAME(m_cass_data)); + save_item(NAME(m_key_pressed)); + save_item(NAME(m_boot_in_progress)); + save_item(NAME(m_last_data)); +} + +void super80_state::machine_start() +{ + machine_start_common(); + save_item(NAME(m_int_sw)); + save_item(NAME(m_vidpg)); + save_item(NAME(m_current_charset)); +} + +void super80v_state::machine_start() +{ + // zerofill + m_vram = make_unique_clear(0x3000); + save_pointer(NAME(m_vram), 0x3000); + machine_start_common(); +} + +void super80_state::machine_reset_common() +{ + m_boot_in_progress = true; + m_portf0 = 0; // must be 0 like real machine, or banking breaks on 32-col systems + m_keylatch = 0xff; + m_key_pressed = 0; + m_palette_index = 0; + + address_space &program = m_maincpu->space(AS_PROGRAM); + program.install_rom(0x0000, 0x0fff, m_rom); // do it here for F3 + m_rom_shadow_tap.remove(); + m_rom_shadow_tap = program.install_read_tap( + 0xc000, 0xcfff, + "rom_shadow_r", + [this] (offs_t offset, u8 &data, u8 mem_mask) + { + if (!machine().side_effects_disabled()) + { + // delete this tap + m_rom_shadow_tap.remove(); + + // reinstall RAM over the ROM shadow + m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x0fff, m_ram); + } + }, + &m_rom_shadow_tap); +} + +void super80_state::machine_reset() +{ + machine_reset_common(); + m_vidpg = 0xfe00; +} + +void super80v_state::machine_reset() +{ + machine_reset_common(); +} + + +/*------------------------------------------------- + QUICKLOAD_LOAD_MEMBER( super80_state, super80 ) +-------------------------------------------------*/ + +QUICKLOAD_LOAD_MEMBER(super80_state::quickload_cb) +{ + uint16_t exec_addr, start_addr, end_addr; + + // load the binary into memory + if (z80bin_load_file(image, m_maincpu->space(AS_PROGRAM), exec_addr, start_addr, end_addr) != image_init_result::PASS) + return image_init_result::FAIL; + + // is this file executable? + if (exec_addr != 0xffff) + // check to see if autorun is on + if (BIT(m_io_config->read(), 0)) + m_maincpu->set_pc(exec_addr); + + return image_init_result::PASS; +} diff --git a/src/mame/ausnz/super80_v.cpp b/src/mame/ausnz/super80_v.cpp new file mode 100644 index 00000000000..5bdbf556c0b --- /dev/null +++ b/src/mame/ausnz/super80_v.cpp @@ -0,0 +1,420 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert +/* Super80.c written by Robbbert, 2005-2010. See the driver source for documentation. */ + + + +#include "emu.h" +#include "super80.h" + + + +/**************************** PALETTES for super80m and super80v ******************************************/ + +void super80_state::super80m_palette(palette_device &palette) const +{ + // RGB + palette.set_pen_color( 0, rgb_t(0x00, 0x00, 0x00)); // 0 Black + palette.set_pen_color( 1, rgb_t(0x00, 0x00, 0x00)); // 1 Black + palette.set_pen_color( 2, rgb_t(0x00, 0x00, 0x7f)); // 2 Blue + palette.set_pen_color( 3, rgb_t(0x00, 0x00, 0xff)); // 3 Light Blue + palette.set_pen_color( 4, rgb_t(0x00, 0x7f, 0x00)); // 4 Green + palette.set_pen_color( 5, rgb_t(0x00, 0xff, 0x00)); // 5 Bright Green + palette.set_pen_color( 6, rgb_t(0x00, 0x7f, 0x7f)); // 6 Cyan + palette.set_pen_color( 7, rgb_t(0x00, 0xff, 0xff)); // 7 Turquoise + palette.set_pen_color( 8, rgb_t(0x7f, 0x00, 0x00)); // 8 Dark Red + palette.set_pen_color( 9, rgb_t(0xff, 0x00, 0x00)); // 9 Red + palette.set_pen_color(10, rgb_t(0x7f, 0x00, 0x7f)); // 10 Purple + palette.set_pen_color(11, rgb_t(0xff, 0x00, 0xff)); // 11 Magenta + palette.set_pen_color(12, rgb_t(0x7f, 0x7f, 0x00)); // 12 Lime + palette.set_pen_color(13, rgb_t(0xff, 0xff, 0x00)); // 13 Yellow + palette.set_pen_color(14, rgb_t(0xbf, 0xbf, 0xbf)); // 14 Off White + palette.set_pen_color(15, rgb_t(0xff, 0xff, 0xff)); // 15 White + // Composite + palette.set_pen_color(16, rgb_t(0x00, 0x00, 0x00)); // 0 Black + palette.set_pen_color(17, rgb_t(0x80, 0x80, 0x80)); // 1 Grey + palette.set_pen_color(18, rgb_t(0x00, 0x00, 0xff)); // 2 Blue + palette.set_pen_color(19, rgb_t(0xff, 0xff, 0x80)); // 3 Light Yellow + palette.set_pen_color(20, rgb_t(0x00, 0xff, 0x00)); // 4 Green + palette.set_pen_color(21, rgb_t(0xff, 0x80, 0xff)); // 5 Light Magenta + palette.set_pen_color(22, rgb_t(0x00, 0xff, 0xff)); // 6 Cyan + palette.set_pen_color(23, rgb_t(0xff, 0x40, 0x40)); // 7 Light Red + palette.set_pen_color(24, rgb_t(0xff, 0x00, 0x00)); // 8 Red + palette.set_pen_color(25, rgb_t(0x00, 0x80, 0x80)); // 9 Dark Cyan + palette.set_pen_color(26, rgb_t(0xff, 0x00, 0xff)); // 10 Magenta + palette.set_pen_color(27, rgb_t(0x80, 0xff, 0x80)); // 11 Light Green + palette.set_pen_color(28, rgb_t(0xff, 0xff, 0x00)); // 12 Yellow + palette.set_pen_color(29, rgb_t(0x00, 0x00, 0x80)); // 13 Dark Blue + palette.set_pen_color(30, rgb_t(0xff, 0xff, 0xff)); // 14 White + palette.set_pen_color(31, rgb_t(0x00, 0x00, 0x00)); // 15 Black +} + + + +void super80_state::screen_vblank_super80m(bool state) +{ + // rising edge + if (state) + { + // if we chose another palette or colour mode, enable it + m_palette_index = (m_io_config->read() & 0x60) ? 0 : 16; + } +} + +uint32_t super80_state::screen_update_super80(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + address_space& program = m_maincpu->space(AS_PROGRAM); + + m_cass_led = BIT(m_portf0, 5); + + const uint8_t options = m_io_config->read(); + bool screen_on = BIT(m_portf0, 2) || !BIT(options, 2); // bit 2 of port F0 is high, OR user turned on config switch + + uint8_t fg = 0; + if (screen_on) + { + if (BIT(options, 5)) + fg = 15; // b&w + else + fg = 5; // green + } + + uint16_t sy = 0; + uint16_t ma = m_vidpg; + for (uint8_t y = 0; y < 16; y++) + { + for (uint8_t ra = 0; ra < 10; ra++) + { + uint16_t *p = &bitmap.pix(sy++); + + for (uint16_t x = 0; x < 32; x++) // done this way to avoid x overflowing on page FF + { + uint8_t chr = 32; + if (screen_on) + { + chr = program.read_byte(ma | x) & 0x7f; + if ((chr >= 0x61) && (chr <= 0x7a)) + chr &= 0x1f; + else + chr &= 0x3f; + } + + // get pattern of pixels for that character scanline + const uint8_t gfx = m_p_chargen[(chr<<4) | ((ra & 8) >> 3) | ((ra & 7) << 1)]; + + // Display a scanline of a character + *p++ = BIT(gfx, 7) ? fg : 0; + *p++ = BIT(gfx, 6) ? fg : 0; + *p++ = BIT(gfx, 5) ? fg : 0; + *p++ = BIT(gfx, 4) ? fg : 0; + *p++ = BIT(gfx, 3) ? fg : 0; + *p++ = BIT(gfx, 2) ? fg : 0; + *p++ = BIT(gfx, 1) ? fg : 0; + *p++ = BIT(gfx, 0) ? fg : 0; + } + } + ma += 32; + } + return 0; +} + +uint32_t super80_state::screen_update_super80d(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + address_space& program = m_maincpu->space(AS_PROGRAM); + m_cass_led = BIT(m_portf0, 5); + + const uint8_t options = m_io_config->read(); + bool screen_on = BIT(m_portf0, 2) || !BIT(options, 2); // bit 2 of port F0 is high, OR user turned on config switch + + uint8_t fg = 0; + if (screen_on) + { + if (BIT(options, 5)) + fg = 15; // b&w + else + fg = 5; // green + } + + uint16_t sy = 0; + uint16_t ma = m_vidpg; + for (uint8_t y = 0; y < 16; y++) + { + for (uint8_t ra = 0; ra < 10; ra++) + { + uint16_t *p = &bitmap.pix(sy++); + + for (uint16_t x = 0; x < 32; x++) + { + uint8_t chr = 32; + if (screen_on) + chr = program.read_byte(ma | x); + + // get pattern of pixels for that character scanline + const uint8_t gfx = m_p_chargen[((chr & 0x7f)<<4) | ((ra & 8) >> 3) | ((ra & 7) << 1)] ^ ((chr & 0x80) ? 0xff : 0); + + // Display a scanline of a character + *p++ = BIT(gfx, 7) ? fg : 0; + *p++ = BIT(gfx, 6) ? fg : 0; + *p++ = BIT(gfx, 5) ? fg : 0; + *p++ = BIT(gfx, 4) ? fg : 0; + *p++ = BIT(gfx, 3) ? fg : 0; + *p++ = BIT(gfx, 2) ? fg : 0; + *p++ = BIT(gfx, 1) ? fg : 0; + *p++ = BIT(gfx, 0) ? fg : 0; + } + } + ma+=32; + } + return 0; +} + +uint32_t super80_state::screen_update_super80e(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + address_space& program = m_maincpu->space(AS_PROGRAM); + m_cass_led = BIT(m_portf0, 5); + + const uint8_t options = m_io_config->read(); + bool screen_on = BIT(m_portf0, 2) || !BIT(options, 2); // bit 2 of port F0 is high, OR user turned on config switch + + uint8_t fg = 0; + if (screen_on) + { + if (BIT(options, 5)) + fg = 15; // b&w + else + fg = 5; // green + } + + uint16_t sy = 0; + uint16_t ma = m_vidpg; + for (uint8_t y = 0; y < 16; y++) + { + for (uint8_t ra = 0; ra < 10; ra++) + { + uint16_t *p = &bitmap.pix(sy++); + + for (uint16_t x = 0; x < 32; x++) + { + uint8_t chr = 32; + if (screen_on) + chr = program.read_byte(ma | x); + + // get pattern of pixels for that character scanline + const uint8_t gfx = m_p_chargen[(chr<<4) | ((ra & 8) >> 3) | ((ra & 7) << 1)]; + + // Display a scanline of a character + *p++ = BIT(gfx, 7) ? fg : 0; + *p++ = BIT(gfx, 6) ? fg : 0; + *p++ = BIT(gfx, 5) ? fg : 0; + *p++ = BIT(gfx, 4) ? fg : 0; + *p++ = BIT(gfx, 3) ? fg : 0; + *p++ = BIT(gfx, 2) ? fg : 0; + *p++ = BIT(gfx, 1) ? fg : 0; + *p++ = BIT(gfx, 0) ? fg : 0; + } + } + ma+=32; + } + return 0; +} + +uint32_t super80_state::screen_update_super80m(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + address_space& program = m_maincpu->space(AS_PROGRAM); + m_cass_led = BIT(m_portf0, 5); + + const uint8_t options = m_io_config->read(); + + // get selected character generator + const bool cgen = m_current_charset ^ BIT(options, 4); // bit 0 of port F1 and cgen config switch + + const bool screen_on = BIT(m_portf0, 2) || !BIT(options, 2); // bit 2 of port F0 is high, OR user turned on config switch + + uint8_t fg = 0; + if (screen_on) + { + if (BIT(options, 5)) + fg = 15; // b&w + else + fg = 5; // green + } + + uint16_t sy = 0; + uint16_t ma = m_vidpg; + for (uint8_t y = 0; y < 16; y++) + { + for (uint8_t ra = 0; ra < 10; ra++) + { + uint16_t *p = &bitmap.pix(sy++); + + for (uint16_t x = 0; x < 32; x++) + { + uint8_t chr = 32; + if (screen_on) + chr = program.read_byte(ma | x); + + uint8_t bg = 0; + if (!(options & 0x40)) + { + const uint8_t col = program.read_byte(0xfe00 | ma | x); // byte of colour to display + fg = m_palette_index + (col & 0x0f); + bg = m_palette_index + (col >> 4); + } + + // get pattern of pixels for that character scanline + uint8_t gfx; + if (cgen) + gfx = m_p_chargen[(chr<<4) | ((ra & 8) >> 3) | ((ra & 7) << 1)]; + else + gfx = m_p_chargen[0x1000 | ((chr & 0x7f)<<4) | ((ra & 8) >> 3) | ((ra & 7) << 1)] ^ ((chr & 0x80) ? 0xff : 0); + + // Display a scanline of a character + *p++ = BIT(gfx, 7) ? fg : bg; + *p++ = BIT(gfx, 6) ? fg : bg; + *p++ = BIT(gfx, 5) ? fg : bg; + *p++ = BIT(gfx, 4) ? fg : bg; + *p++ = BIT(gfx, 3) ? fg : bg; + *p++ = BIT(gfx, 2) ? fg : bg; + *p++ = BIT(gfx, 1) ? fg : bg; + *p++ = BIT(gfx, 0) ? fg : bg; + } + } + ma+=32; + } + return 0; +} + + +/**************************** I/O PORTS *****************************************************************/ + +void super80_state::portf1_w(u8 data) +{ + m_vidpg = (data & 0xfe) << 8; + m_current_charset = BIT(data, 0); +} + +/*--------------------------------------------------------------- + + Super-80R and Super-80V + +---------------------------------------------------------------*/ + +// we place videoram at 0x0000, colour ram at 0x1000, pcg at 0x2000 +u8 super80r_state::low_r(offs_t offset) +{ + return m_vram[offset]; +} + +void super80r_state::low_w(offs_t offset, u8 data) +{ + m_vram[offset] = data; // video +} + +u8 super80r_state::high_r(offs_t offset) +{ + return m_vram[offset+0x0800]; // video +} + +void super80r_state::high_w(offs_t offset, u8 data) +{ + m_vram[offset+0x0800] = data; // video + m_vram[offset+0x2800] = data; // pcg +} + +u8 super80v_state::low_r(offs_t offset) +{ + if (BIT(m_portf0, 2)) + return m_vram[offset]; // video + else + return m_vram[offset+0x1000]; // colour +} + +void super80v_state::low_w(offs_t offset, u8 data) +{ + if (BIT(m_portf0, 2)) + m_vram[offset] = data; // video + else + m_vram[offset+0x1000] = data; // colour +} + +u8 super80v_state::high_r(offs_t offset) +{ + if (!BIT(m_portf0, 2)) + return m_vram[offset+0x1800]; // colour + else + if (BIT(m_portf0, 4)) + return m_vram[offset+0x0800]; // video + else + return m_p_chargen[offset]; // char rom +} + +void super80v_state::high_w(offs_t offset, u8 data) +{ + if (!BIT(m_portf0, 2)) + m_vram[offset+0x1800] = data; // colour + else + { + m_vram[offset+0x0800] = data; // video + + if (BIT(m_portf0, 4)) + m_vram[offset+0x2800] = data; // pcg + } +} + +uint32_t super80v_state::screen_update_super80v(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + m_s_options = m_io_config->read(); + m_cass_led = BIT(m_portf0, 5); + m_crtc->screen_update(screen, bitmap, cliprect); + return 0; +} + +MC6845_UPDATE_ROW( super80v_state::crtc_update_row ) +{ + const rgb_t *palette = m_palette->palette()->entry_list_raw(); + uint32_t *p = &bitmap.pix(y); + + for (uint16_t x = 0; x < x_count; x++) // for each character + { + uint8_t inv = 0; + if (x == cursor_x) inv=0xff; + const uint16_t mem = (ma + x) & 0xfff; + uint8_t chr = m_vram[mem]; + + /* get colour or b&w */ + uint8_t fg = 5; // green + if ((m_s_options & 0x60) == 0x60) + fg = 15; // b&w + + uint8_t bg = 0; + if (~m_s_options & 0x40) + { + const uint8_t col = m_vram[mem+0x1000]; // byte of colour to display + fg = m_palette_index + (col & 0x0f); + bg = m_palette_index + (col >> 4); + } + + // if inverse mode, replace any pcgram chrs with inverse chrs + if (!BIT(m_portf0, 4) && BIT(chr, 7)) // is it a high chr in inverse mode + { + inv ^= 0xff; // invert the chr + chr &= 0x7f; // and drop bit 7 + } + + // get pattern of pixels for that character scanline + const uint8_t gfx = BIT(chr, 7) + ? m_vram[0x2000 | ((chr << 4) | ra)] ^ inv + : m_p_chargen[((chr << 4) | ra)] ^ inv; + + // Display a scanline of a character + *p++ = palette[BIT(gfx, 7) ? fg : bg]; + *p++ = palette[BIT(gfx, 6) ? fg : bg]; + *p++ = palette[BIT(gfx, 5) ? fg : bg]; + *p++ = palette[BIT(gfx, 4) ? fg : bg]; + *p++ = palette[BIT(gfx, 3) ? fg : bg]; + *p++ = palette[BIT(gfx, 2) ? fg : bg]; + *p++ = palette[BIT(gfx, 1) ? fg : bg]; + } +} + + diff --git a/src/mame/ausnz/tec1.cpp b/src/mame/ausnz/tec1.cpp new file mode 100644 index 00000000000..eb3a3ff630c --- /dev/null +++ b/src/mame/ausnz/tec1.cpp @@ -0,0 +1,410 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert +/*************************************************************************** + +TEC-1 driver, written by Robbbert in April, 2009. + +The TEC-1 was a single-board "computer" described in Talking Electronics +magazine, issues number 10 and 11. Talking Electronics do not have dates on +their issues, so the date is uncertain, although 1984 seems a reasonable +guess. Talking Electronics operated from Cheltenham, a suburb of Melbourne. + +The hardware is quite simple, consisting of a Z80 cpu, 2x 8212 8-bit latch, +74C923 keyboard scanner, 20 push-button keys, 6-digit LED display, a speaker, +a 2k EPROM and sundry parts. + +The cpu speed could be adjusted by using a potentiometer, the range being +250 kHz to 2MHz. This is a simple method of adjusting a game's difficulty. + +We emulate the original version. Later enhancements included more RAM, speech +synthesis and various attachments, however I have no information on these. + +2018-11-08 Obtained fresh dumps from the original designers. + +Pasting: + 0-F : as is + + (inc) : ^ + - (dec) : V + AD : - + GO : X + +Keys: +0 to 9, A to F are on the key of the same name. +AD (input an address) is the '-' key. ++ and - (increment / decrement address) are the up and down-arrow keys. +GO (execute program at current address) is the X key. +SHIFT - later monitor versions utilised an extra shift button. Hold + it down and press another key (use Left Shift). + +Whenever a program listing mentions RESET, press Left-Alt key. + +Each key causes a beep to be heard. You may need to press more than once +to get it to register. + +Inbuilt games - press the following sequence of keys: +- Invaders: RESET AD 0 0 0 8 GO GO (Paste: -0008XX) +- Nim: RESET AD 0 0 1 0 GO GO (Paste: -0010XX) +- Lunar Lander: RESET AD 0 0 1 8 GO GO (Paste: -0018XX) +Tunes: +- Bealach An Doirin: RESET AD 0 0 2 8 GO GO (Paste: -0028XX) +- Biking up the strand: RESET AD 0 0 3 0 GO GO (Paste: -0030XX) + +Thanks to Chris Schwartz who dumped his ROM for me way back in the old days. +It's only taken 25 years to get around to emulating it... + + +Differences between tec1 and tecjmon: + +On the tec1 a keypress is indicated by an NMI from the 74C923; but on +the jmon it sets bit 6 of port 3 low instead. The NMI code is simply +a 'retn' in the jmon rom, so we can use the same code. +The jmon includes a cassette interface, a serial input connection, +and an optional LCD, but the games of the tec1 have been removed. + + + +JMON ToDo: +- Add LCD display (2 rows by 16 characters) + + +***************************************************************************/ + +#include "emu.h" +#include "cpu/z80/z80.h" +#include "imagedev/cassette.h" +#include "machine/mm74c922.h" +#include "machine/rescap.h" +#include "sound/spkrdev.h" +#include "speaker.h" +#include "video/pwm.h" + +#include "tec1.lh" + + +class tec1_state : public driver_device +{ +public: + tec1_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_speaker(*this, "speaker") + , m_cass(*this, "cassette") + , m_kb(*this, "keyboard") + , m_io_shift(*this, "SHIFT") + , m_display(*this, "display") + { } + + void tec1(machine_config &config); + void tecjmon(machine_config &config); + + DECLARE_INPUT_CHANGED_MEMBER(reset_button); + +private: + virtual void machine_start() override; + u8 kbd_r(); + u8 latch_r(); + void tec1_digit_w(u8 data); + void tecjmon_digit_w(u8 data); + void segment_w(u8 data); + DECLARE_WRITE_LINE_MEMBER(da_w); + bool m_key_pressed = 0; + u8 m_seg = 0U; + u8 m_digit = 0U; + void tec1_io(address_map &map); + void tec1_map(address_map &map); + void tecjmon_io(address_map &map); + void tecjmon_map(address_map &map); + required_device m_maincpu; + required_device m_speaker; + optional_device m_cass; + required_device m_kb; + required_ioport m_io_shift; + required_device m_display; +}; + + + + +/*************************************************************************** + + Display + +***************************************************************************/ + +void tec1_state::segment_w(u8 data) +{ +/* d7 segment d + d6 segment e + d5 segment c + d4 segment dot + d3 segment b + d2 segment g + d1 segment f + d0 segment a */ + + m_seg = bitswap<8>(data, 4, 2, 1, 6, 7, 5, 3, 0); + m_display->matrix(m_digit, m_seg); +} + +void tec1_state::tec1_digit_w(u8 data) +{ +/* d7 speaker + d6 not used + d5 data digit 1 + d4 data digit 2 + d3 address digit 1 + d2 address digit 2 + d1 address digit 3 + d0 address digit 4 */ + + m_speaker->level_w(BIT(data, 7)); + + m_digit = data; + m_display->matrix(m_digit, m_seg); +} + +void tec1_state::tecjmon_digit_w(u8 data) +{ +/* d7 speaker & cassout + d6 not used + d5 data digit 1 + d4 data digit 2 + d3 address digit 1 + d2 address digit 2 + d1 address digit 3 + d0 address digit 4 */ + + m_speaker->level_w(BIT(data, 7)); + m_cass->output(BIT(data, 7) ? -1.0 : +1.0); + m_digit = data; + m_display->matrix(m_digit, m_seg); +} + + +/*************************************************************************** + + Keyboard + +***************************************************************************/ + +u8 tec1_state::latch_r() +{ +// bit 7 - cass in ; bit 6 low = key pressed + u8 data = (m_key_pressed) ? 0 : 0x40; + + if (m_cass->input() > 0.03) + data |= 0x80; + + return data; +} + + +u8 tec1_state::kbd_r() +{ + return m_kb->read() | m_io_shift->read(); +} + +WRITE_LINE_MEMBER( tec1_state::da_w ) +{ + m_key_pressed = state; + m_maincpu->set_input_line(INPUT_LINE_NMI, state ? ASSERT_LINE : CLEAR_LINE); +} + + +/*************************************************************************** + + Machine + +***************************************************************************/ + +void tec1_state::machine_start() +{ + save_item(NAME(m_key_pressed)); + save_item(NAME(m_seg)); + save_item(NAME(m_digit)); +} + +/*************************************************************************** + + Address Map + +***************************************************************************/ + +void tec1_state::tec1_map(address_map &map) +{ + map.global_mask(0x3fff); + map(0x0000, 0x07ff).rom(); + map(0x0800, 0x0fff).ram(); // on main board + map(0x1000, 0x3fff).ram(); // expansion +} + +void tec1_state::tec1_io(address_map &map) +{ + map.global_mask(0x07); + map(0x00, 0x00).r(FUNC(tec1_state::kbd_r)); + map(0x01, 0x01).w(FUNC(tec1_state::tec1_digit_w)); + map(0x02, 0x02).w(FUNC(tec1_state::segment_w)); +} + + +void tec1_state::tecjmon_map(address_map &map) +{ + map.global_mask(0x3fff); + map(0x0000, 0x07ff).rom(); + map(0x0800, 0x37ff).ram(); + map(0x3800, 0x3fff).rom().region("maincpu", 0x0800); +} + +void tec1_state::tecjmon_io(address_map &map) +{ + map.global_mask(0xff); + map(0x00, 0x00).r(FUNC(tec1_state::kbd_r)); + map(0x01, 0x01).w(FUNC(tec1_state::tecjmon_digit_w)); + map(0x02, 0x02).w(FUNC(tec1_state::segment_w)); + map(0x03, 0x03).r(FUNC(tec1_state::latch_r)); + //map(0x04, 0x04).w(FUNC(tec1_state::lcd_en_w)); + //map(0x84, 0x84).w(FUNC(tec1_state::lcd_2nd_w)); +} + + +/************************************************************************** + + Keyboard Layout + +***************************************************************************/ + +static INPUT_PORTS_START( tec1 ) + PORT_START("LINE0") /* KEY ROW 0 */ + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4) PORT_CHAR('4') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8) PORT_CHAR('8') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('C') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("+") PORT_CODE(KEYCODE_UP) PORT_CHAR('^') + + PORT_START("LINE1") /* KEY ROW 1 */ + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1) PORT_CHAR('1') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5) PORT_CHAR('5') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) PORT_CHAR('9') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('D') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("-") PORT_CODE(KEYCODE_DOWN) PORT_CHAR('V') + + PORT_START("LINE2") /* KEY ROW 2 */ + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2) PORT_CHAR('2') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6) PORT_CHAR('6') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('A') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('E') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("GO") PORT_CODE(KEYCODE_X) PORT_CHAR('X') + + PORT_START("LINE3") /* KEY ROW 3 */ + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) PORT_CHAR('3') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7) PORT_CHAR('7') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('B') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('F') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("AD") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') + + PORT_START("SHIFT") + PORT_BIT(0x1f, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT) + PORT_BIT(0xc0, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("RESET") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RESET") PORT_CODE(KEYCODE_LALT) PORT_CHANGED_MEMBER(DEVICE_SELF, tec1_state, reset_button, 0) +INPUT_PORTS_END + +INPUT_CHANGED_MEMBER(tec1_state::reset_button) +{ + m_maincpu->set_input_line(INPUT_LINE_RESET, newval ? ASSERT_LINE : CLEAR_LINE); +} + + +/*************************************************************************** + + Machine driver + +***************************************************************************/ + +void tec1_state::tec1(machine_config &config) +{ + /* basic machine hardware */ + Z80(config, m_maincpu, 1000000); /* speed can be varied between 250kHz and 2MHz */ + m_maincpu->set_addrmap(AS_PROGRAM, &tec1_state::tec1_map); + m_maincpu->set_addrmap(AS_IO, &tec1_state::tec1_io); + + /* video hardware */ + config.set_default_layout(layout_tec1); + PWM_DISPLAY(config, m_display).set_size(6, 8); + m_display->set_segmask(0x3f, 0xff); + + MM74C923(config, m_kb, 0); + m_kb->set_cap_osc(CAP_N(100)); + m_kb->set_cap_debounce(CAP_U(1)); + m_kb->da_wr_callback().set(FUNC(tec1_state::da_w)); + m_kb->x1_rd_callback().set_ioport("LINE0"); + m_kb->x2_rd_callback().set_ioport("LINE1"); + m_kb->x3_rd_callback().set_ioport("LINE2"); + m_kb->x4_rd_callback().set_ioport("LINE3"); + + /* sound hardware */ + SPEAKER(config, "mono").front_center(); + SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.50); +} + +void tec1_state::tecjmon(machine_config &config) +{ + /* basic machine hardware */ + Z80(config, m_maincpu, XTAL(3'579'545) / 2); + m_maincpu->set_addrmap(AS_PROGRAM, &tec1_state::tecjmon_map); + m_maincpu->set_addrmap(AS_IO, &tec1_state::tecjmon_io); + + /* video hardware */ + config.set_default_layout(layout_tec1); + PWM_DISPLAY(config, m_display).set_size(6, 8); + m_display->set_segmask(0x3f, 0xff); + + MM74C923(config, m_kb, 0); + m_kb->set_cap_osc(CAP_N(100)); + m_kb->set_cap_debounce(CAP_U(1)); + m_kb->da_wr_callback().set(FUNC(tec1_state::da_w)); + m_kb->x1_rd_callback().set_ioport("LINE0"); + m_kb->x2_rd_callback().set_ioport("LINE1"); + m_kb->x3_rd_callback().set_ioport("LINE2"); + m_kb->x4_rd_callback().set_ioport("LINE3"); + + /* sound hardware */ + SPEAKER(config, "mono").front_center(); + SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.50); + + /* Devices */ + CASSETTE(config, m_cass); + m_cass->set_default_state(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED); +} + + +/*************************************************************************** + + Game driver + +***************************************************************************/ + +ROM_START(tec1) + ROM_REGION(0x0800, "maincpu", 0 ) + ROM_SYSTEM_BIOS(0, "mon1", "MON1") + ROMX_LOAD( "mon1.rom", 0x0000, 0x0800, CRC(5d379e6c) SHA1(5c810885a3f0d03c54aea74aaaa8fae8a2fd9ad4), ROM_BIOS(0) ) + ROM_SYSTEM_BIOS(1, "mon1a", "MON1A") + ROMX_LOAD("mon1a.rom", 0x0000, 0x0800, CRC(b3390c36) SHA1(18aabc68d473206b7fc4e365c6b57a4e218482c3), ROM_BIOS(1)) + ROM_SYSTEM_BIOS(2, "mon1b", "MON1B") + //ROMX_LOAD("mon1b.rom", 0x0000, 0x0800, CRC(60daea3c) SHA1(383b7e7f02e91fb18c87eb03c5949e31156771d4), ROM_BIOS(2)) + ROMX_LOAD("mon1b.rom", 0x0000, 0x0800, CRC(6088811d) SHA1(2cec14a24fae769f22f6598b5a63fc79d90db394), ROM_BIOS(2)) // redump + ROM_SYSTEM_BIOS(3, "mon2", "MON2") + ROMX_LOAD("mon2.rom", 0x0000, 0x0800, CRC(082fd7e7) SHA1(7659add30ca22b15a03d1cbac0892a5c25e47ecd), ROM_BIOS(3)) +ROM_END + +ROM_START(tecjmon) + ROM_REGION(0x1000, "maincpu", 0 ) + ROM_LOAD("jmon.rom", 0x0000, 0x0800, CRC(202c47a2) SHA1(701588ec5640d633d90d94b2ccd6f65422e19a70) ) + ROM_LOAD("util.rom", 0x0800, 0x0800, CRC(7c19700d) SHA1(dc5b3ade66bb11c54430056966ed99cdd299d82b) ) +ROM_END + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1984, tec1, 0, 0, tec1, tec1, tec1_state, empty_init, "Talking Electronics magazine", "TEC-1", MACHINE_SUPPORTS_SAVE ) +COMP( 1984, tecjmon, tec1, 0, tecjmon, tec1, tec1_state, empty_init, "Talking Electronics magazine", "TEC-1A with JMON", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/dicksmith/super80.cpp b/src/mame/dicksmith/super80.cpp deleted file mode 100644 index a4c1999d72f..00000000000 --- a/src/mame/dicksmith/super80.cpp +++ /dev/null @@ -1,995 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Robbbert -/***************************************************************************** - -Super80.cpp written by Robbbert, 2005-2010. - -2010-12-19: Added V3.7 bios freshly dumped today. -2014-04-28: Added disk system and did cleanups - -See the MAME sysinfo and wiki for usage -documentation. Below for the most technical bits: - -= Architecture (super80): - - * Z80 @ 2MHz - * 16k, 32k or 48k RAM (0000-BFFF) - * 12k ROM (C000-EFFF) - * 3.5k RAM (F000-FDFF), comes with the "64k ram" modification - * 0.5k RAM (FE00-FFFF) for Chipspeed colour board - -= Architecture (super80v): - - * Z80 @ 2MHz - * 16k, 32k or 48k RAM (0000-BFFF) - * 12k ROM (C000-EFFF) - * 2k Video RAM (F000-F7FF) banked with Colour RAM (modified Chipspeed board) - * 2k PCG RAM (F800-FFFF) banked with Character Generator ROM - -= Super80 ports: - - port $F0: General Purpose output port - Bit 0 - cassette output - Bit 1 - cassette relay control; 0=relay on - Bit 2 - turns screen on and off;0=screen off - Bit 3 - Available for user projects [We will use it for sound] - Bit 4 - Available for user projects - Bit 5 - cassette LED; 0=LED on - Bit 6/7 - not decoded - - port $F1: Video page output port - Bit 0 - not decoded [we will use it for video switching] - Bits 1 to 7 - choose video page to display - Bit 1 controls A9, bit 2 does A10, etc - - port $F2: General purpose input port - Bit 0 - cassette input - Bit 1 - Available for user projects - Bit 2 - Available for user projects - Bit 3 - not decoded - Bit 4 - Switch A [These switches are actual DIP switches on the motherboard] - Bit 5 - Switch B - Bit 6 - Switch C - Bit 7 - Switch D - -= Super80v ports: - - port $10: MC6845 control port - - port $11: MC6845 data port - - port $F0: General Purpose output port - Bit 0 - cassette output - Bit 1 - Cassette relay control; 0=relay on - Bit 2 - Colour banking (0 = Colour Ram, 1 = Video Ram) - Bit 3 - Sound - Bit 4 - PCG banking (0 = PROM, 1 = PCG) - Bit 5 - cassette LED; 0=LED on - Bit 6/7 - not decoded - - port $F2: General purpose input port - same as for Super80. - -= Cassette information: - -The standard cassette system uses Kansas City format. Data rates available are 300, 400, 600, and 1200 baud. -The user has to adjust some bytes in memory in order to select a different baud rate. - - BDF8 BDF9 Baud - --------------------- - F8 04 300 - BA 03 400 - 7C 02 600 - 3E 01 1200 - -The enhanced Monitor roms (those not supplied by Dick Smith) have extra commands to change the rates -without the tedium of manually modifying memory. - -When saving, the OS toggles the cassette bit (bit 0 of port F0) at the required frequencies directly. - -When loading, the signal passes through a filter, then into a 4046 PLL (Phase-Locked-Loop) chip. -This acts as a frequency-to-voltage converter. The output of this device is passed to the "+" input -of a LM311 op-amp. The "-" input is connected to a 10-turn trimpot, which is adjusted by the owner -at construction time. It sets the switching midpoint voltage. Voltages above a certain level become -a "1" level at the output, while voltages below become a "0" level. This output in turn connects -to the cassette input bit of port F2. - -The monitor loading routine (at C066 in most monitor roms), waits for a high-to-low transition -(the low is the beginning of the start bit), then waits for half a bit, checks it is still low, -waits for a full bit, then reads the state (this is the first bit), then cycles between waiting -a bit and reading the next, until a full byte has been constructed. Lastly, the stop bit is -checked that it is at a high level. - -This means that we cannot attempt to convert frequency to voltage ourselves, since the OS only -"looks" once a bit. The solution is to use a mame timer running at a high enough rate (40 kHz) -to read the wave state. While the wave state stays constant, a counter is incremented. When the -state changes, the output is set according to how far the counter has progressed. The counter is -then reset ready for the next wave state. The code for this is in the TIMER_CALLBACK. - -A kit was produced by ETI magazine, which plugged into the line from your cassette player earphone -socket. The computer line was plugged into this box instead of the cassette player. The box was -fitted with a speaker and a volume control. You could listen to the tones, to assist with head -alignment, and with debugging. In MAME, a config switch has been provided so that you can turn -this sound on or off as needed. - -= About the 1 MHz / 2 MHz switching: - -The original hardware runs with a 2 MHz clock, but operates in an unusual way. There is no video -processor chip, just a huge bunch of TTL. The system spends half the time running the CPU, -and half the time displaying the picture. The timing will activate the BUSREQ line, and the CPU will -finish its current instruction, activate the BUSACK line, and go to sleep. The video circuits will -read the video RAM and show the picture. At the end, the BUSREQ line is released, and processing can -continue. - -The processing time occurs during the black parts of the screen, therefore half the screen will be -black unless you expand the image with the monitor's controls. This method ensures that there will -be no memory contention, and thus, no snow. The processor will run at 2 MHz pulsed at 48.8 Hz, which -is an effective speed of 1 MHz. - -When saving or loading a cassette file, this pulsing would cause the save tone to be modulated with -a loud hum. When loading, the synchronisation to the start bit could be missed, causing errors. -Therefore the screen can be turned off via an output bit. This disables the BUSREQ control, which -in turn prevents screen refresh, and gives the processor a full uninterrupted 2 MHz speed. - -To obtain accurate timing, the video update routine will toggle the HALT line on alternate frames. -Although physically incorrect, it is the only way to accurately emulate the speed change function. -The video update routine emulates the blank screen by filling it with spaces. - -For the benefit of those who like to experiment, config switches have been provided in MAME to -allow you to leave the screen on at all times, and to always run at 2 MHz if desired. These options -cannot exist in real hardware. - -= Quickload: - -This was not a standard feature. It is a hardware facility I added to my machine when age threatened -to kill off my cassette player and tapes. The tapes were loaded up one last time, and transferred to -a hard drive on a surplus 386 PC, in binary format (NOT a wave file). Special roms were made to allow -loading and saving to the S-100 board and its ports. These ports were plugged into the 386 via cables. -A QBASIC program on the 386 monitored the ports and would save and load files when requested by the -Super-80. This worked (and still works) very well, and is a huge improvement over the cassette, both -speedwise and accuracy-wise. - -The modified rom had the autorun option built in. Autorun was never available for cassettes. - -In MAME, the same file format is used - I can transfer files between MAME and the 386 seamlessly. -MAME has one difference - the program simply appears in memory without the processor being aware -of it. To accomplish autorun therefore requires that the processor pc register be set to the start -address of the program. BASIC programs may need some preprocessing before they can be started. This -is not necessary on a Super-80 or a Microbee, but is needed on any system running Microsoft BASIC, -such as the Exidy Sorcerer or the VZ-200. - -In MAME, quickload is available for all Super80 variants (otherwise you would not have any games -to play). MAME features a config switch so the user can turn autorun on or off as desired. - - -= Start of Day circuit: - -When the computer is turned on or reset, the Z80 will want to start executing at 0000. Since this is -RAM, this is not a good idea. The SOD circuit forcibly disables the RAM and enables the ROMs, so they -will appear to be at 0000. Thus, the computer will boot. - -The Master Reset signal (power-on or Reset button pushed), triggers a flipflop that disables RAM and -causes C000 to FFFF to appear at 0000 to 3FFF. This will be reset (back to normal) when A14 and A15 -are high, and /M1 is active. This particular combination occurs on all ROM variants, when reading the -fifth byte in the ROM. In reality, the switchover can take place any time between the 4th byte until -the computer has booted up. This is because the low RAM does not contain any system areas. - - -Super80 disk WD2793, Z80DMA: - -Port(hex) Role Comment ---------- ----- -------- -30 DMA I/O Z80A DMA Controller Command Register -38 WDSTCM WD2793 Command Status -39 WDTRK WD2793 Track Register -3A WDSEC WD2793 Sector Register -3B WDDATA WD2793 Data Register - -3E UFDSTAT FDD and WD2793 Status input - Bit0 INTRQ 1 = WD2793 Interrupt Request - Bit1 DATARQ 1 = Data Ready to Receive or Send - Bit2 MOTOR ON 1 = FDD Motor On - -3F UFDCOM WD2793 Command Register output - Bit0 5/8 1 = 8" Drive Selected - Bit1 ENMF* 0 = 1MHz, 1 = 2MHz (for 8" double density) - Bit2 DR0SEL 1 = Drive 0 (Drive A) selected - Bit3 DR1SEL 1 = Drive 1 (Drive B) selected - Bit4 DR2SEL 1 = Drive 2 (Drive C) selected - Bit5 DR3SEL 1 = Drive 3 (Drive D) selected - Bit6 SIDESEL 0 = Select Disk side 0, 1 = Select Disk side 1 - Bit7 DDEN* 0 = MFM (Double Density), 1 = FM (Single Density) - -ToDo: -- Fix Paste: Shift operates randomly (only super80m is suitable, the others drop characters because - of the horrible inline editor they use) - - -***********************************************************************************************************/ - -#include "emu.h" -#include "super80.h" - -#include "screen.h" -#include "softlist_dev.h" -#include "speaker.h" - -#include "super80.lh" - - -#define MASTER_CLOCK (12_MHz_XTAL) -#define PIXEL_CLOCK (MASTER_CLOCK/2) -#define HTOTAL (384) -#define HBEND (0) -#define HBSTART (256) -#define VTOTAL (240) -#define VBEND (0) -#define VBSTART (160) - -#define SUPER80V_SCREEN_WIDTH (560) -#define SUPER80V_SCREEN_HEIGHT (300) -#define SUPER80V_DOTS (7) - - -/**************************** MEMORY AND I/O MAPPINGS *****************************************************************/ - -void super80_state::super80_map(address_map &map) -{ - map(0x0000, 0xbfff).ram().share("mainram"); - map(0xc000, 0xefff).rom().region("maincpu", 0).nopw(); - map(0xf000, 0xffff).lr8(NAME([] () { return 0xff; })).nopw(); -} - -void super80_state::super80m_map(address_map &map) -{ - map(0x0000, 0xffff).ram().share("mainram"); - map(0xc000, 0xefff).rom().region("maincpu", 0).nopw(); -} - -void super80v_state::super80v_map(address_map &map) -{ - map(0x0000, 0xbfff).ram().share("mainram"); - map(0xc000, 0xefff).rom().region("maincpu", 0).nopw(); - map(0xf000, 0xf7ff).rw(FUNC(super80v_state::low_r), FUNC(super80v_state::low_w)); - map(0xf800, 0xffff).rw(FUNC(super80v_state::high_r), FUNC(super80v_state::high_w)); -} - -void super80r_state::super80r_map(address_map &map) -{ - super80v_map(map); - map(0xf000, 0xf7ff).rw(FUNC(super80r_state::low_r), FUNC(super80r_state::low_w)); - map(0xf800, 0xffff).rw(FUNC(super80r_state::high_r), FUNC(super80r_state::high_w)); -} - -void super80_state::super80_io(address_map &map) -{ - map.global_mask(0xff); - map.unmap_value_high(); - map(0xdc, 0xdc).r("cent_status_in", FUNC(input_buffer_device::read)); - map(0xdc, 0xdc).w(FUNC(super80_state::portdc_w)); - map(0xe0, 0xe0).mirror(0x14).w(FUNC(super80_state::portf0_w)); - map(0xe1, 0xe1).mirror(0x14).w(FUNC(super80_state::portf1_w)); - map(0xe2, 0xe2).mirror(0x14).r(FUNC(super80_state::portf2_r)); - map(0xf8, 0xfb).mirror(0x04).rw(m_pio, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt)); -} - -void super80_state::super80e_io(address_map &map) -{ - map.global_mask(0xff); - map.unmap_value_high(); - map(0xbc, 0xbc).r("cent_status_in", FUNC(input_buffer_device::read)); - map(0xbc, 0xbc).w(FUNC(super80_state::portdc_w)); - map(0xe0, 0xe0).mirror(0x14).w(FUNC(super80_state::portf0_w)); - map(0xe1, 0xe1).mirror(0x14).w(FUNC(super80_state::portf1_w)); - map(0xe2, 0xe2).mirror(0x14).r(FUNC(super80_state::portf2_r)); - map(0xf8, 0xfb).mirror(0x04).rw(m_pio, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt)); -} - - -void super80v_state::super80v_io(address_map &map) -{ - map.global_mask(0xff); - map.unmap_value_high(); - map(0x10, 0x10).rw(m_crtc, FUNC(mc6845_device::status_r), FUNC(mc6845_device::address_w)); - map(0x11, 0x11).rw(m_crtc, FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w)); - map(0x30, 0x30).rw(m_dma, FUNC(z80dma_device::read), FUNC(z80dma_device::write)); - map(0x38, 0x3b).rw(m_fdc, FUNC(wd2793_device::read), FUNC(wd2793_device::write)); - map(0x3e, 0x3e).r(FUNC(super80v_state::port3e_r)); - map(0x3f, 0x3f).w(FUNC(super80v_state::port3f_w)); - map(0xdc, 0xdc).r("cent_status_in", FUNC(input_buffer_device::read)); - map(0xdc, 0xdc).w(FUNC(super80v_state::portdc_w)); - map(0xe0, 0xe0).mirror(0x14).w(FUNC(super80v_state::portf0_w)); - map(0xe2, 0xe2).mirror(0x14).r(FUNC(super80v_state::portf2_r)); - map(0xf8, 0xfb).mirror(0x04).rw(m_pio, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt)); -} - -/**************************** DIPSWITCHES, KEYBOARD, HARDWARE CONFIGURATION ****************************************/ - - /* Enhanced options not available on real hardware */ -static INPUT_PORTS_START( super80_cfg ) - PORT_START("CONFIG") - PORT_CONFNAME( 0x01, 0x01, "Autorun on Quickload") - PORT_CONFSETTING( 0x00, DEF_STR(No)) - PORT_CONFSETTING( 0x01, DEF_STR(Yes)) - PORT_CONFNAME( 0x02, 0x02, "2 MHz always") - PORT_CONFSETTING( 0x02, DEF_STR(No)) - PORT_CONFSETTING( 0x00, DEF_STR(Yes)) - PORT_CONFNAME( 0x04, 0x04, "Screen on always") - PORT_CONFSETTING( 0x04, DEF_STR(No)) - PORT_CONFSETTING( 0x00, DEF_STR(Yes)) - PORT_CONFNAME( 0x08, 0x08, "Cassette Speaker") - PORT_CONFSETTING( 0x08, DEF_STR(On)) - PORT_CONFSETTING( 0x00, DEF_STR(Off)) - PORT_CONFNAME( 0x60, 0x40, "Colour") - PORT_CONFSETTING( 0x60, "White") - PORT_CONFSETTING( 0x40, "Green") -INPUT_PORTS_END - -static INPUT_PORTS_START( super80 ) - PORT_START("DSW") - PORT_BIT( 0xf, 0xf, IPT_UNUSED ) - PORT_DIPNAME( 0x10, 0x00, "Switch A") PORT_DIPLOCATION("SW1:1") - PORT_DIPSETTING( 0x10, DEF_STR(Off)) - PORT_DIPSETTING( 0x00, DEF_STR(On)) - PORT_DIPNAME( 0x20, 0x20, "Switch B") PORT_DIPLOCATION("SW1:2") - PORT_DIPSETTING( 0x20, DEF_STR(Off)) - PORT_DIPSETTING( 0x00, DEF_STR(On)) - PORT_DIPNAME( 0x40, 0x40, "Switch C") PORT_DIPLOCATION("SW1:3") - PORT_DIPSETTING( 0x40, DEF_STR(Off)) - PORT_DIPSETTING( 0x00, DEF_STR(On)) - PORT_DIPNAME( 0x80, 0x00, "Switch D") PORT_DIPLOCATION("SW1:4") - PORT_DIPSETTING( 0x80, DEF_STR(Off)) - PORT_DIPSETTING( 0x00, DEF_STR(On)) - - PORT_START("KEY.0") // The physical keys show some shifted characters that are not actually available - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("@ `") PORT_CODE(KEYCODE_TILDE) PORT_CHAR('@') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_CHAR('H') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CHAR('P') PORT_CHAR(0x10) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CHAR('X') PORT_CHAR(0x18) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1 !") PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9 )") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("REPT") PORT_CODE(KEYCODE_LALT) - PORT_START("KEY.1") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_CHAR('A') PORT_CHAR(0x01) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('I') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_CHAR('Q') PORT_CHAR(0x11) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_CHAR('Y') PORT_CHAR(0x19) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2 \"") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('\"') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(": *") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(':') PORT_CHAR('*') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Backspace") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(0x08) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) - PORT_START("KEY.2") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_CHAR('B') PORT_CHAR(0x02) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_CHAR('J') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_CHAR('R') PORT_CHAR(0x12) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_CHAR('Z') PORT_CHAR(0x1a) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3 #") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("; +") PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('+') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("TAB") PORT_CODE(KEYCODE_TAB) PORT_CHAR(0x09) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("(Fire)") PORT_CODE(KEYCODE_INSERT) PORT_CHAR(UCHAR_MAMEKEY(INSERT)) - PORT_START("KEY.3") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('C') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_CHAR('K') PORT_CHAR(0x0b) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_CHAR('S') PORT_CHAR(0x13) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("[ {") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4 $") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(", <") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LINEFEED") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(0x0a) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_SHIFT_2) - PORT_START("KEY.4") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CHAR('D') PORT_CHAR(0x04) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_CHAR('L') PORT_CHAR(0x0c) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_CHAR('T') PORT_CHAR(0x14) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("\\ |")PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('\\') PORT_CHAR(0x1c) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5 %") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("BRK") PORT_CODE(KEYCODE_NUMLOCK) PORT_CHAR(0x03) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(0x0d) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_RIGHT) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) - PORT_START("KEY.5") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_CHAR('E') PORT_CHAR(0x05) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('M') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_CHAR('U') PORT_CHAR(0x15) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("] }") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR(']') PORT_CHAR(0x1d) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6 &") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(". >") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("ESC") PORT_CODE(KEYCODE_ESC) PORT_CHAR(0x1b) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_LEFT) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) - PORT_START("KEY.6") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_CHAR('F') PORT_CHAR(0x06) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_CHAR('N') PORT_CHAR(0x0e) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_CHAR('V') PORT_CHAR(0x16) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("^ ~") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('^') PORT_CHAR('^') PORT_CHAR(0x1e) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7 \'") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("/ ?") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("DEL") PORT_CODE(KEYCODE_DEL) PORT_CHAR(0x7f) PORT_CHAR(0x7f) PORT_CHAR(0x1f) // natural kbd, press ctrl-backspace to DEL - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_DOWN) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) - PORT_START("KEY.7") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_CHAR('G') PORT_CHAR(0x07) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_CHAR('O') PORT_CHAR(0x0f) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_CHAR('W') PORT_CHAR(0x17) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("- =") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('=') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8 (") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(' ') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LOCK") PORT_CODE(KEYCODE_CAPSLOCK) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_UP) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) - PORT_INCLUDE( super80_cfg ) -INPUT_PORTS_END - -static INPUT_PORTS_START( super80d ) - PORT_START("DSW") - PORT_BIT( 0xf, 0xf, IPT_UNUSED ) - PORT_DIPNAME( 0x10, 0x00, "Switch A") PORT_DIPLOCATION("SW1:1") - PORT_DIPSETTING( 0x10, DEF_STR(Off)) - PORT_DIPSETTING( 0x00, DEF_STR(On)) - PORT_DIPNAME( 0x20, 0x20, "Switch B") PORT_DIPLOCATION("SW1:2") - PORT_DIPSETTING( 0x20, DEF_STR(Off)) - PORT_DIPSETTING( 0x00, DEF_STR(On)) - PORT_DIPNAME( 0x40, 0x40, "Switch C") PORT_DIPLOCATION("SW1:3") - PORT_DIPSETTING( 0x40, DEF_STR(Off)) - PORT_DIPSETTING( 0x00, DEF_STR(On)) - PORT_DIPNAME( 0x80, 0x00, "Switch D") PORT_DIPLOCATION("SW1:4") - PORT_DIPSETTING( 0x80, DEF_STR(Off)) - PORT_DIPSETTING( 0x00, DEF_STR(On)) - - PORT_START("KEY.0") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("@ `") PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('@') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_CHAR('h') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CHAR('p') PORT_CHAR(0x10) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CHAR('x') PORT_CHAR(0x18) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1 !") PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9 )") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("REPT") PORT_CODE(KEYCODE_LALT) - PORT_START("KEY.1") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_CHAR('a') PORT_CHAR(0x01) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_CHAR('i') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_CHAR('q') PORT_CHAR(0x11) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_CHAR('y') PORT_CHAR(0x19) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2 \"") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('\"') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(": *") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(':') PORT_CHAR('*') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Backspace") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(0x08) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) - PORT_START("KEY.2") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_CHAR('b') PORT_CHAR(0x02) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_CHAR('j') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_CHAR('r') PORT_CHAR(0x12) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_CHAR('z') PORT_CHAR(0x1a) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3 #") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("; +") PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('+') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("TAB") PORT_CODE(KEYCODE_TAB) PORT_CHAR(0x09) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("(Fire)") PORT_CODE(KEYCODE_INSERT) PORT_CHAR(UCHAR_MAMEKEY(INSERT)) - PORT_START("KEY.3") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_CHAR('c') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_CHAR('k') PORT_CHAR(0x0b) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_CHAR('s') PORT_CHAR(0x13) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("[ {") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4 $") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(", <") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LINEFEED") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(0x0a) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_SHIFT_2) - PORT_START("KEY.4") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CHAR('d') PORT_CHAR(0x04) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_CHAR('l') PORT_CHAR(0x0c) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_CHAR('t') PORT_CHAR(0x14) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("\\ |")PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') PORT_CHAR(0x1c) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5 %") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("BRK") PORT_CODE(KEYCODE_NUMLOCK) PORT_CHAR(0x03) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(0x0d) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_RIGHT) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) - PORT_START("KEY.5") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_CHAR('e') PORT_CHAR(0x05) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_CHAR('m') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_CHAR('u') PORT_CHAR(0x15) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("] }") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') PORT_CHAR(0x1d) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6 &") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(". >") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("ESC") PORT_CODE(KEYCODE_ESC) PORT_CHAR(0x1b) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_LEFT) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) - PORT_START("KEY.6") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_CHAR('f') PORT_CHAR(0x06) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_CHAR('n') PORT_CHAR(0x0e) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_CHAR('v') PORT_CHAR(0x16) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("^ ~") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('^') PORT_CHAR('~') PORT_CHAR(0x1e) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7 \'") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("/ ?") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("DEL") PORT_CODE(KEYCODE_DEL) PORT_CHAR(0x7f) PORT_CHAR(0x5f) PORT_CHAR(0x1f) // natural kbd, press ctrl-backspace to DEL - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_DOWN) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) - PORT_START("KEY.7") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_CHAR('g') PORT_CHAR(0x07) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_CHAR('o') PORT_CHAR(0x0f) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_CHAR('w') PORT_CHAR(0x17) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("- =") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('=') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8 (") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(' ') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LOCK") PORT_CODE(KEYCODE_CAPSLOCK) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_UP) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) - PORT_INCLUDE( super80_cfg ) -INPUT_PORTS_END - -static INPUT_PORTS_START( super80e ) - PORT_INCLUDE( super80d ) - PORT_MODIFY("KEY.0") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("@ `") PORT_CODE(KEYCODE_TILDE) PORT_CHAR('@') PORT_CHAR('`') // fix mistake in super80d matrix -INPUT_PORTS_END - -static INPUT_PORTS_START( super80m ) - PORT_INCLUDE( super80e ) - - PORT_MODIFY("CONFIG") - - /* Enhanced options not available on real hardware */ - PORT_CONFNAME( 0x10, 0x10, "Swap CharGens") - PORT_CONFSETTING( 0x10, DEF_STR(No)) - PORT_CONFSETTING( 0x00, DEF_STR(Yes)) - PORT_CONFNAME( 0x60, 0x40, "Colour") - PORT_CONFSETTING( 0x60, "White") - PORT_CONFSETTING( 0x40, "Green") - PORT_CONFSETTING( 0x00, "Composite") - PORT_CONFSETTING( 0x20, "RGB") -INPUT_PORTS_END - -static INPUT_PORTS_START( super80v ) - PORT_INCLUDE( super80m ) - - PORT_MODIFY("CONFIG") - PORT_BIT( 0x16, 0x16, IPT_UNUSED ) -INPUT_PORTS_END - -static INPUT_PORTS_START( super80r ) - PORT_INCLUDE( super80d ) - - PORT_MODIFY("CONFIG") - PORT_BIT( 0x16, 0x16, IPT_UNUSED ) -INPUT_PORTS_END - - -/**************************** F4 CHARACTER DISPLAYER ***********************************************************/ - -static const gfx_layout super80_charlayout = -{ - 8,10, /* 8 x 10 characters */ - 64, /* 64 characters */ - 1, /* 1 bits per pixel */ - { 0 }, /* no bitplanes */ - /* x offsets */ - { 0, 1, 2, 3, 4, 5, 6, 7 }, - /* y offsets */ - { 0*8, 2*8, 4*8, 6*8, 8*8, 10*8, 12*8, 14*8, 1*8, 3*8, 5*8, 7*8, 9*8, 11*8, 13*8, 15*8 }, - 8*16 /* every char takes 16 bytes */ -}; - -static const gfx_layout super80d_charlayout = -{ - 8,10, /* 8 x 10 characters */ - 128, /* 256 characters */ - 1, /* 1 bits per pixel */ - { 0 }, /* no bitplanes */ - /* x offsets */ - { 0, 1, 2, 3, 4, 5, 6, 7 }, - /* y offsets */ - { 0*8, 2*8, 4*8, 6*8, 8*8, 10*8, 12*8, 14*8, 1*8, 3*8, 5*8, 7*8, 9*8, 11*8, 13*8, 15*8 }, - 8*16 /* every char takes 16 bytes */ -}; - -static const gfx_layout super80e_charlayout = -{ - 8,10, /* 8 x 10 characters */ - 256, /* 256 characters */ - 1, /* 1 bits per pixel */ - { 0 }, /* no bitplanes */ - /* x offsets */ - { 0, 1, 2, 3, 4, 5, 6, 7 }, - /* y offsets */ - { 0*8, 2*8, 4*8, 6*8, 8*8, 10*8, 12*8, 14*8, 1*8, 3*8, 5*8, 7*8, 9*8, 11*8, 13*8, 15*8 }, - 8*16 /* every char takes 16 bytes */ -}; - -static const gfx_layout super80v_charlayout = -{ - 8,16, /* 8 x 16 characters */ - 128, /* 128 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, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8 }, - 8*16 /* every char takes 16 bytes */ -}; - -static GFXDECODE_START( gfx_super80 ) - GFXDECODE_ENTRY( "chargen", 0x0000, super80_charlayout, 16, 1 ) -GFXDECODE_END - -static GFXDECODE_START( gfx_super80d ) - GFXDECODE_ENTRY( "chargen", 0x0000, super80d_charlayout, 16, 1 ) -GFXDECODE_END - -static GFXDECODE_START( gfx_super80e ) - GFXDECODE_ENTRY( "chargen", 0x0000, super80e_charlayout, 16, 1 ) -GFXDECODE_END - -static GFXDECODE_START( gfx_super80m ) - GFXDECODE_ENTRY( "chargen", 0x0000, super80e_charlayout, 2, 6 ) - GFXDECODE_ENTRY( "chargen", 0x1000, super80d_charlayout, 2, 6 ) -GFXDECODE_END - -static GFXDECODE_START( gfx_super80v ) - GFXDECODE_ENTRY( "chargen", 0x0000, super80v_charlayout, 2, 6 ) -GFXDECODE_END - - - -/**************************** BASIC MACHINE CONSTRUCTION ***********************************************************/ - - -static const z80_daisy_config super80_daisy_chain[] = -{ - { "z80pio" }, - { nullptr } -}; - -//------------------------------------------------- -// Z80DMA -//------------------------------------------------- - -WRITE_LINE_MEMBER( super80v_state::busreq_w ) -{ -// since our Z80 has no support for BUSACK, we assume it is granted immediately - m_maincpu->set_input_line(Z80_INPUT_LINE_BUSRQ, state); - m_maincpu->set_input_line(INPUT_LINE_HALT, state); - m_dma->bai_w(state); // tell dma that bus has been granted -} - -uint8_t super80v_state::memory_read_byte(offs_t offset) -{ - address_space& prog_space = m_maincpu->space(AS_PROGRAM); - return prog_space.read_byte(offset); -} - -void super80v_state::memory_write_byte(offs_t offset, uint8_t data) -{ - address_space& prog_space = m_maincpu->space(AS_PROGRAM); - prog_space.write_byte(offset, data); -} - -uint8_t super80v_state::io_read_byte(offs_t offset) -{ - address_space& prog_space = m_maincpu->space(AS_IO); - return prog_space.read_byte(offset); -} - -void super80v_state::io_write_byte(offs_t offset, uint8_t data) -{ - address_space& prog_space = m_maincpu->space(AS_IO); - prog_space.write_byte(offset, data); -} - -static void super80_floppies(device_slot_interface &device) -{ - device.option_add("s80flop", FLOPPY_525_QD); -} - - -static const char *const relay_sample_names[] = -{ - "*relay", - "relayoff", - "relayon", - nullptr -}; - - -void super80_state::super80(machine_config &config) -{ - /* basic machine hardware */ - Z80(config, m_maincpu, MASTER_CLOCK/6); /* 2 MHz */ - m_maincpu->set_addrmap(AS_PROGRAM, &super80_state::super80_map); - m_maincpu->set_addrmap(AS_IO, &super80_state::super80_io); - m_maincpu->set_daisy_config(super80_daisy_chain); - - Z80PIO(config, m_pio, MASTER_CLOCK/6); - m_pio->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); - m_pio->out_pa_callback().set([this](u8 data){ super80_state::pio_port_a_w(data); }); - m_pio->in_pb_callback().set([this](){ return super80_state::pio_port_b_r(); }); - - SCREEN(config, m_screen, SCREEN_TYPE_RASTER); - m_screen->set_refresh_hz(48.8); - m_screen->set_raw(PIXEL_CLOCK, HTOTAL, HBEND, HBSTART, VTOTAL, VBEND, VBSTART); - m_screen->set_screen_update(FUNC(super80_state::screen_update_super80)); - m_screen->set_palette(m_palette); - - PALETTE(config, m_palette, FUNC(super80_state::super80m_palette), 32); - GFXDECODE(config, m_gfxdecode, m_palette, gfx_super80); - - config.set_default_layout(layout_super80); - - /* sound hardware */ - SPEAKER(config, "mono").front_center(); - SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.50); - SAMPLES(config, m_samples); - m_samples->set_channels(1); - m_samples->set_samples_names(relay_sample_names); - m_samples->add_route(ALL_OUTPUTS, "mono", 1.0); - - /* printer */ - CENTRONICS(config, m_centronics, centronics_devices, "printer"); - m_centronics->busy_handler().set("cent_status_in", FUNC(input_buffer_device::write_bit7)); - - output_latch_device ¢_data_out(OUTPUT_LATCH(config, "cent_data_out")); - m_centronics->set_output_latch(cent_data_out); - - INPUT_BUFFER(config, "cent_status_in", 0); - - /* quickload */ - quickload_image_device &quickload(QUICKLOAD(config, "quickload", "bin", attotime::from_seconds(3))); - quickload.set_load_callback(FUNC(super80_state::quickload_cb)); - quickload.set_interface("super80_quik"); - - /* cassette */ - CASSETTE(config, m_cassette); - m_cassette->set_default_state(CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED); - m_cassette->add_route(ALL_OUTPUTS, "mono", 0.05); - m_cassette->set_interface("super80_cass"); - - TIMER(config, "kansas_r").configure_periodic(FUNC(super80_state::kansas_r), attotime::from_hz(40000)); // cass read - TIMER(config, "timer_k").configure_periodic(FUNC(super80_state::timer_k), attotime::from_hz(300)); // keyb scan - TIMER(config, "timer_h").configure_periodic(FUNC(super80_state::timer_h), attotime::from_hz(100)); // half-speed - - // software list - SOFTWARE_LIST(config, "cass_list").set_original("super80_cass").set_filter("DEF"); - SOFTWARE_LIST(config, "quik_list").set_original("super80_quik").set_filter("DEF"); -} - -void super80_state::super80d(machine_config &config) -{ - super80(config); - m_gfxdecode->set_info(gfx_super80d); - m_screen->set_screen_update(FUNC(super80_state::screen_update_super80d)); - - // software list - SOFTWARE_LIST(config.replace(), "cass_list").set_original("super80_cass").set_filter("D"); - SOFTWARE_LIST(config.replace(), "quik_list").set_original("super80_quik").set_filter("D"); -} - -void super80_state::super80e(machine_config &config) -{ - super80(config); - m_maincpu->set_addrmap(AS_IO, &super80_state::super80e_io); - m_gfxdecode->set_info(gfx_super80e); - m_screen->set_screen_update(FUNC(super80_state::screen_update_super80e)); - - // software list - SOFTWARE_LIST(config.replace(), "cass_list").set_original("super80_cass").set_filter("E"); - SOFTWARE_LIST(config.replace(), "quik_list").set_original("super80_quik").set_filter("E"); -} - -void super80_state::super80m(machine_config &config) -{ - super80(config); - m_maincpu->set_addrmap(AS_PROGRAM, &super80_state::super80m_map); - - m_gfxdecode->set_info(gfx_super80m); - - m_screen->set_screen_update(FUNC(super80_state::screen_update_super80m)); - m_screen->screen_vblank().set([this](bool state) { super80_state::screen_vblank_super80m(state); }); - - // software list - SOFTWARE_LIST(config.replace(), "cass_list").set_original("super80_cass").set_filter("M"); - SOFTWARE_LIST(config.replace(), "quik_list").set_original("super80_quik").set_filter("M"); -} - -void super80v_state::super80v(machine_config &config) -{ - /* basic machine hardware */ - Z80(config, m_maincpu, MASTER_CLOCK/6); /* 2 MHz */ - m_maincpu->set_addrmap(AS_PROGRAM, &super80v_state::super80v_map); - m_maincpu->set_addrmap(AS_IO, &super80v_state::super80v_io); - m_maincpu->set_daisy_config(super80_daisy_chain); - - Z80PIO(config, m_pio, MASTER_CLOCK/6); - m_pio->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); - m_pio->out_pa_callback().set([this](u8 data){ super80v_state::pio_port_a_w(data); }); - m_pio->in_pb_callback().set([this](){ return super80v_state::pio_port_b_r(); }); - - SCREEN(config, m_screen, SCREEN_TYPE_RASTER); - m_screen->set_refresh_hz(50); - m_screen->set_size(SUPER80V_SCREEN_WIDTH, SUPER80V_SCREEN_HEIGHT); - m_screen->set_visarea(0, SUPER80V_SCREEN_WIDTH-1, 0, SUPER80V_SCREEN_HEIGHT-1); - m_screen->set_screen_update(FUNC(super80v_state::screen_update_super80v)); - m_screen->screen_vblank().set([this](bool state) { super80v_state::screen_vblank_super80m(state); }); - - PALETTE(config, m_palette, FUNC(super80v_state::super80m_palette), 32); - GFXDECODE(config, m_gfxdecode, m_palette, gfx_super80v); - - MC6845(config, m_crtc, MASTER_CLOCK / SUPER80V_DOTS); - m_crtc->set_screen("screen"); - m_crtc->set_show_border_area(false); - m_crtc->set_char_width(SUPER80V_DOTS); - m_crtc->set_update_row_callback(FUNC(super80v_state::crtc_update_row)); - - config.set_default_layout(layout_super80); - - /* sound hardware */ - SPEAKER(config, "mono").front_center(); - SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.50); - SAMPLES(config, m_samples); - m_samples->set_channels(1); - m_samples->set_samples_names(relay_sample_names); - m_samples->add_route(ALL_OUTPUTS, "mono", 1.0); - - /* printer */ - CENTRONICS(config, m_centronics, centronics_devices, "printer"); - m_centronics->busy_handler().set("cent_status_in", FUNC(input_buffer_device::write_bit7)); - - output_latch_device ¢_data_out(OUTPUT_LATCH(config, "cent_data_out")); - m_centronics->set_output_latch(cent_data_out); - - INPUT_BUFFER(config, "cent_status_in", 0); - - /* quickload */ - quickload_image_device &quickload(QUICKLOAD(config, "quickload", "bin", attotime::from_seconds(3))); - quickload.set_load_callback(FUNC(super80v_state::quickload_cb)); - quickload.set_interface("super80_quik"); - - /* cassette */ - CASSETTE(config, m_cassette); - m_cassette->set_default_state(CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED); - m_cassette->add_route(ALL_OUTPUTS, "mono", 0.05); - m_cassette->set_interface("super80_cass"); - - TIMER(config, "kansas_r").configure_periodic(FUNC(super80v_state::kansas_r), attotime::from_hz(40000)); // cass read - TIMER(config, "timer_k").configure_periodic(FUNC(super80v_state::timer_k), attotime::from_hz(300)); // keyb scan - - Z80DMA(config, m_dma, MASTER_CLOCK/6); - m_dma->out_busreq_callback().set(FUNC(super80v_state::busreq_w)); - m_dma->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); - //ba0 - not connected - m_dma->in_mreq_callback().set(FUNC(super80v_state::memory_read_byte)); - m_dma->out_mreq_callback().set(FUNC(super80v_state::memory_write_byte)); - m_dma->in_iorq_callback().set(FUNC(super80v_state::io_read_byte)); - m_dma->out_iorq_callback().set(FUNC(super80v_state::io_write_byte)); - - WD2793(config, m_fdc, 2_MHz_XTAL); - m_fdc->drq_wr_callback().set(m_dma, FUNC(z80dma_device::rdy_w)); - FLOPPY_CONNECTOR(config, "fdc:0", super80_floppies, "s80flop", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "fdc:1", super80_floppies, "s80flop", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "fdc:2", super80_floppies, "s80flop", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "fdc:3", super80_floppies, "s80flop", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); - - // software list - SOFTWARE_LIST(config, "cass_list").set_original("super80_cass").set_filter("V"); - SOFTWARE_LIST(config, "quik_list").set_original("super80_quik").set_filter("V"); - SOFTWARE_LIST(config, "flop_list").set_original("super80_flop"); -} - -void super80r_state::super80r(machine_config &config) -{ - super80v(config); - m_maincpu->set_addrmap(AS_PROGRAM, &super80r_state::super80r_map); - - // software list - SOFTWARE_LIST(config.replace(), "cass_list").set_original("super80_cass").set_filter("R"); - SOFTWARE_LIST(config.replace(), "quik_list").set_original("super80_quik").set_filter("R"); -} - -/**************************** ROMS *****************************************************************/ - -ROM_START( super80 ) - ROM_REGION(0x3000, "maincpu", 0) - ROM_LOAD("super80.u26", 0x0000, 0x1000, CRC(6a6a9664) SHA1(2c4fcd943aa9bf7419d58fbc0e28ffb89ef22e0b) ) - ROM_LOAD("super80.u33", 0x1000, 0x1000, CRC(cf8020a8) SHA1(2179a61f80372cd49e122ad3364773451531ae85) ) - ROM_LOAD("super80.u42", 0x2000, 0x1000, CRC(a1c6cb75) SHA1(d644ca3b399c1a8902f365c6095e0bbdcea6733b) ) - - ROM_REGION(0x0400, "chargen", 0) // 2513 prom - ROM_LOAD("super80.u27", 0x0000, 0x0400, CRC(d1e4b3c6) SHA1(3667b97c6136da4761937958f281609690af4081) ) -ROM_END - -ROM_START( super80d ) - ROM_REGION(0x3000, "maincpu", 0) - ROM_SYSTEM_BIOS(0, "super80d", "V2.2") - ROMX_LOAD("super80d.u26", 0x0000, 0x1000, CRC(cebd2613) SHA1(87b94cc101a5948ce590211c68272e27f4cbe95a), ROM_BIOS(0)) - ROM_SYSTEM_BIOS(1, "super80f", "MDS (original)") - ROMX_LOAD("super80f.u26", 0x0000, 0x1000, CRC(d39775f0) SHA1(b47298ee028924612e9728bb2debd0f47399add7), ROM_BIOS(1)) - ROM_SYSTEM_BIOS(2, "super80g", "MDS (upgraded)") - ROMX_LOAD("super80g.u26", 0x0000, 0x1000, CRC(7386f507) SHA1(69d7627033d62bd4e886ccc136e89f1524d38f47), ROM_BIOS(2)) - ROM_LOAD("super80.u33", 0x1000, 0x1000, CRC(cf8020a8) SHA1(2179a61f80372cd49e122ad3364773451531ae85) ) - ROM_LOAD("super80.u42", 0x2000, 0x1000, CRC(a1c6cb75) SHA1(d644ca3b399c1a8902f365c6095e0bbdcea6733b) ) - - ROM_REGION(0x0800, "chargen", 0) // 2716 eprom - ROM_LOAD("super80d.u27", 0x0000, 0x0800, CRC(cb4c81e2) SHA1(8096f21c914fa76df5d23f74b1f7f83bd8645783) ) -ROM_END - -ROM_START( super80e ) - ROM_REGION(0x3000, "maincpu", 0) - ROM_LOAD("super80e.u26", 0x0000, 0x1000, CRC(bdc668f8) SHA1(3ae30b3cab599fca77d5e461f3ec1acf404caf07) ) - ROM_LOAD("super80.u33", 0x1000, 0x1000, CRC(cf8020a8) SHA1(2179a61f80372cd49e122ad3364773451531ae85) ) - ROM_LOAD("super80.u42", 0x2000, 0x1000, CRC(a1c6cb75) SHA1(d644ca3b399c1a8902f365c6095e0bbdcea6733b) ) - - ROM_REGION(0x1000, "chargen", 0) // 2732 eprom - ROM_LOAD("super80e.u27", 0x0000, 0x1000, CRC(ebe763a7) SHA1(ffaa6d6a2c5dacc5a6651514e6707175a32e83e8) ) -ROM_END - -ROM_START( super80m ) - ROM_REGION(0x3000, "maincpu", 0) - ROM_SYSTEM_BIOS(0, "8r0", "8R0") - ROMX_LOAD("s80-8r0.u26", 0x0000, 0x1000, CRC(48d410d8) SHA1(750d984abc013a3344628300288f6d1ba140a95f), ROM_BIOS(0) ) - ROMX_LOAD("s80-8r0.u33", 0x1000, 0x1000, CRC(9765793e) SHA1(4951b127888c1f3153004cc9fb386099b408f52c), ROM_BIOS(0) ) - ROMX_LOAD("s80-8r0.u42", 0x2000, 0x1000, CRC(5f65d94b) SHA1(fe26b54dec14e1c4911d996c9ebd084a38dcb691), ROM_BIOS(0) ) -#if 0 - /* Temporary patch to fix crash when lprinting a tab */ - ROM_FILL(0x0c44,1,0x46) - ROM_FILL(0x0c45,1,0xc5) - ROM_FILL(0x0c46,1,0x06) - ROM_FILL(0x0c47,1,0x20) - ROM_FILL(0x0c48,1,0xcd) - ROM_FILL(0x0c49,1,0xc7) - ROM_FILL(0x0c4a,1,0xcb) - ROM_FILL(0x0c4b,1,0xc1) - ROM_FILL(0x0c4c,1,0x10) - ROM_FILL(0x0c4d,1,0xf7) - ROM_FILL(0x0c4e,1,0x00) - ROM_FILL(0x0c4f,1,0x00) -#endif - ROM_SYSTEM_BIOS(1, "v37", "V3.7") - ROMX_LOAD("s80-v37.u26", 0x0000, 0x1000, CRC(46043035) SHA1(1765105df4e4af83d56cafb88e158ed462d4709e), ROM_BIOS(1) ) - ROMX_LOAD("s80-v37.u33", 0x1000, 0x1000, CRC(afb52b15) SHA1(0a2c25834074ce44bf12ac8532b4add492bcf950), ROM_BIOS(1) ) - ROMX_LOAD("s80-v37.u42", 0x2000, 0x1000, CRC(7344b27a) SHA1(f43fc47ddb5c12bffffa63488301cd5eb386cc9a), ROM_BIOS(1) ) - - ROM_SYSTEM_BIOS(2, "8r2", "8R2") - ROMX_LOAD("s80-8r2.u26", 0x0000, 0x1000, CRC(1e166c8c) SHA1(15647614be9300cdd2956da913e83234c36b36a9), ROM_BIOS(2) ) - ROMX_LOAD("s80-8r0.u33", 0x1000, 0x1000, CRC(9765793e) SHA1(4951b127888c1f3153004cc9fb386099b408f52c), ROM_BIOS(2) ) - ROMX_LOAD("s80-8r0.u42", 0x2000, 0x1000, CRC(5f65d94b) SHA1(fe26b54dec14e1c4911d996c9ebd084a38dcb691), ROM_BIOS(2) ) - - ROM_SYSTEM_BIOS(3, "8r3", "8R3") - ROMX_LOAD("s80-8r3.u26", 0x0000, 0x1000, CRC(ee7dd90b) SHA1(c53f8eef82e8f943642f6ddfc2cb1bfdc32d25ca), ROM_BIOS(3) ) - ROMX_LOAD("s80-8r0.u33", 0x1000, 0x1000, CRC(9765793e) SHA1(4951b127888c1f3153004cc9fb386099b408f52c), ROM_BIOS(3) ) - ROMX_LOAD("s80-8r0.u42", 0x2000, 0x1000, CRC(5f65d94b) SHA1(fe26b54dec14e1c4911d996c9ebd084a38dcb691), ROM_BIOS(3) ) - - ROM_SYSTEM_BIOS(4, "8r4", "8R4") - ROMX_LOAD("s80-8r4.u26", 0x0000, 0x1000, CRC(637d001d) SHA1(f26b5ecc33fd44b05b1f199d79e0f072ec8d0e23), ROM_BIOS(4) ) - ROMX_LOAD("s80-8r0.u33", 0x1000, 0x1000, CRC(9765793e) SHA1(4951b127888c1f3153004cc9fb386099b408f52c), ROM_BIOS(4) ) - ROMX_LOAD("s80-8r0.u42", 0x2000, 0x1000, CRC(5f65d94b) SHA1(fe26b54dec14e1c4911d996c9ebd084a38dcb691), ROM_BIOS(4) ) - - ROM_SYSTEM_BIOS(5, "8r5", "8R5") - ROMX_LOAD("s80-8r5.u26", 0x0000, 0x1000, CRC(294f217c) SHA1(f352d54e84e94bf299726dc3af4eb7b2d06d317c), ROM_BIOS(5) ) - ROMX_LOAD("s80-8r0.u33", 0x1000, 0x1000, CRC(9765793e) SHA1(4951b127888c1f3153004cc9fb386099b408f52c), ROM_BIOS(5) ) - ROMX_LOAD("s80-8r0.u42", 0x2000, 0x1000, CRC(5f65d94b) SHA1(fe26b54dec14e1c4911d996c9ebd084a38dcb691), ROM_BIOS(5) ) - - ROM_REGION(0x1800, "chargen", 0) - ROM_LOAD("super80e.u27", 0x0000, 0x1000, CRC(ebe763a7) SHA1(ffaa6d6a2c5dacc5a6651514e6707175a32e83e8) ) - ROM_LOAD("super80d.u27", 0x1000, 0x0800, CRC(cb4c81e2) SHA1(8096f21c914fa76df5d23f74b1f7f83bd8645783) ) -ROM_END - -ROM_START( super80r ) - ROM_REGION( 0x3000, "maincpu", 0 ) - ROM_SYSTEM_BIOS(0, "super80r", "MCE (original)") - ROMX_LOAD("super80r.u26", 0x0000, 0x1000, CRC(01bb6406) SHA1(8e275ecf5141b93f86e45ff8a735b965ea3e8d44), ROM_BIOS(0)) - ROM_SYSTEM_BIOS(1, "super80s", "MCE (upgraded)") - ROMX_LOAD("super80s.u26", 0x0000, 0x1000, CRC(3e29d307) SHA1(b3f4667633e0a4eb8577e39b5bd22e1f0bfbc0a9), ROM_BIOS(1)) - - ROM_LOAD("super80.u33", 0x1000, 0x1000, CRC(cf8020a8) SHA1(2179a61f80372cd49e122ad3364773451531ae85) ) - ROM_LOAD("super80.u42", 0x2000, 0x1000, CRC(a1c6cb75) SHA1(d644ca3b399c1a8902f365c6095e0bbdcea6733b) ) - - ROM_REGION(0x0800, "chargen", 0) // 2716 eprom - ROM_LOAD("s80hmce.ic24", 0x0000, 0x0800, CRC(a6488a1e) SHA1(7ba613d70a37a6b738dcd80c2bb9988ff1f011ef) ) -ROM_END - -ROM_START( super80v ) - ROM_REGION( 0x3000, "maincpu", 0 ) - ROM_LOAD("s80-v37v.u26", 0x0000, 0x1000, CRC(01e0c0dd) SHA1(ef66af9c44c651c65a21d5bda939ffa100078c08) ) - ROM_LOAD("s80-v37v.u33", 0x1000, 0x1000, CRC(812ad777) SHA1(04f355bea3470a7d9ea23bb2811f6af7d81dc400) ) - ROM_LOAD("s80-v37v.u42", 0x2000, 0x1000, CRC(e02e736e) SHA1(57b0264c805da99234ab5e8e028fca456851a4f9) ) - - ROM_REGION(0x0800, "chargen", 0) // 2716 eprom - ROM_LOAD("s80hmce.ic24", 0x0000, 0x0800, CRC(a6488a1e) SHA1(7ba613d70a37a6b738dcd80c2bb9988ff1f011ef) ) -ROM_END - -/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME */ -COMP( 1981, super80, 0, 0, super80, super80, super80_state, empty_init, "Dick Smith Electronics", "Super-80 (V1.2)" , MACHINE_SUPPORTS_SAVE ) -COMP( 1981, super80d, super80, 0, super80d, super80d, super80_state, empty_init, "Dick Smith Electronics", "Super-80 (V2.2)" , MACHINE_SUPPORTS_SAVE ) -COMP( 1981, super80e, super80, 0, super80e, super80e, super80_state, empty_init, "Dick Smith Electronics", "Super-80 (El Graphix 4)" , MACHINE_UNOFFICIAL | MACHINE_SUPPORTS_SAVE ) -COMP( 1981, super80m, super80, 0, super80m, super80m, super80_state, empty_init, "Dick Smith Electronics", "Super-80 (with colour)" , MACHINE_UNOFFICIAL | MACHINE_SUPPORTS_SAVE ) -COMP( 1981, super80r, super80, 0, super80r, super80r, super80r_state, empty_init, "Dick Smith Electronics", "Super-80 (with VDUEB)" , MACHINE_UNOFFICIAL | MACHINE_SUPPORTS_SAVE ) -COMP( 1981, super80v, super80, 0, super80v, super80v, super80v_state, empty_init, "Dick Smith Electronics", "Super-80 (with enhanced VDUEB)" , MACHINE_UNOFFICIAL | MACHINE_SUPPORTS_SAVE ) - diff --git a/src/mame/dicksmith/super80.h b/src/mame/dicksmith/super80.h deleted file mode 100644 index a8a74191a55..00000000000 --- a/src/mame/dicksmith/super80.h +++ /dev/null @@ -1,188 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Robbbert -#ifndef MAME_INCLUDES_SUPER80_H -#define MAME_INCLUDES_SUPER80_H - -#pragma once - -#include "bus/centronics/ctronics.h" -#include "cpu/z80/z80.h" -#include "imagedev/cassette.h" -#include "imagedev/floppy.h" -#include "imagedev/snapquik.h" -#include "machine/buffer.h" -#include "machine/timer.h" -#include "machine/wd_fdc.h" -#include "machine/z80daisy.h" -#include "machine/z80dma.h" -#include "machine/z80pio.h" -#include "sound/samples.h" -#include "sound/spkrdev.h" -#include "video/mc6845.h" - -#include "emupal.h" -#include "screen.h" - - -/* Bits in m_portf0 variable: - d5 cassette LED - d4 super80v rom or pcg bankswitch (1=pcg ram, 0=char gen rom) - d2 super80v video or colour bankswitch (1=video ram, 0=colour ram) - d2 super80 screen off (=2mhz) or on (bursts of 2mhz at 50hz = 1mhz) */ - -class super80_state : public driver_device -{ -public: - super80_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_palette(*this, "palette") - , m_gfxdecode(*this, "gfxdecode") - , m_screen(*this, "screen") - , m_maincpu(*this, "maincpu") - , m_rom(*this, "maincpu") - , m_ram(*this, "mainram") - , m_p_chargen(*this, "chargen") - , m_pio(*this, "z80pio") - , m_cassette(*this, "cassette") - , m_samples(*this, "samples") - , m_speaker(*this, "speaker") - , m_centronics(*this, "centronics") - , m_cent_data_out(*this, "cent_data_out") - , m_io_dsw(*this, "DSW") - , m_io_config(*this, "CONFIG") - , m_io_keyboard(*this, "KEY.%u", 0) - , m_cass_led(*this, "cass_led") - { } - - void super80m(machine_config &config); - void super80(machine_config &config); - void super80e(machine_config &config); - void super80d(machine_config &config); - -protected: - void machine_reset_common(); - void machine_start_common(); - void cassette_motor(bool data); - void screen_vblank_super80m(bool state); - void portf0_w(u8 data); - void portdc_w(u8 data); - void pio_port_a_w(u8 data); - u8 pio_port_b_r(); - u8 portf2_r(); - u8 m_portf0 = 0U; - u8 m_s_options = 0U; - u8 m_palette_index = 0U; - u8 m_keylatch = 0U; - u8 m_cass_data[4]{}; - u8 m_key_pressed = 0U; - u8 m_last_data = 0U; - bool m_boot_in_progress = false; - void super80m_palette(palette_device &palette) const; - TIMER_DEVICE_CALLBACK_MEMBER(timer_k); - TIMER_DEVICE_CALLBACK_MEMBER(kansas_r); - DECLARE_QUICKLOAD_LOAD_MEMBER(quickload_cb); - required_device m_palette; - required_device m_gfxdecode; - required_device m_screen; - required_device m_maincpu; - required_region_ptr m_rom; - memory_passthrough_handler m_rom_shadow_tap; - required_shared_ptr m_ram; - required_region_ptr m_p_chargen; - required_device m_pio; - required_device m_cassette; - required_device m_samples; - required_device m_speaker; - required_device m_centronics; - required_device m_cent_data_out; - required_ioport m_io_dsw; - required_ioport m_io_config; - required_ioport_array<8> m_io_keyboard; - output_finder<> m_cass_led; - -private: - void machine_reset() override; - void machine_start() override; - - void portf1_w(u8 data); - TIMER_DEVICE_CALLBACK_MEMBER(timer_h); - - uint32_t screen_update_super80(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - uint32_t screen_update_super80d(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - uint32_t screen_update_super80e(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - uint32_t screen_update_super80m(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - - void super80_io(address_map &map); - void super80_map(address_map &map); - void super80e_io(address_map &map); - void super80m_map(address_map &map); - - u8 m_int_sw = 0; - u16 m_vidpg = 0; - bool m_current_charset = false; -}; - - -class super80v_state : public super80_state -{ -public: - super80v_state(const machine_config &mconfig, device_type type, const char *tag) - : super80_state(mconfig, type, tag) - , m_crtc(*this, "crtc") - , m_dma(*this, "dma") - , m_fdc (*this, "fdc") - , m_floppy0(*this, "fdc:0") - , m_floppy1(*this, "fdc:1") - , m_floppy2(*this, "fdc:2") - , m_floppy3(*this, "fdc:3") - { } - - void super80v(machine_config &config); - -protected: - void super80v_map(address_map &map); - void super80v_io(address_map &map); - void machine_reset() override; - void machine_start() override; - void port3f_w(u8 data); - u8 port3e_r(); - std::unique_ptr m_vram; - DECLARE_WRITE_LINE_MEMBER(busreq_w); - uint8_t memory_read_byte(offs_t offset); - void memory_write_byte(offs_t offset, uint8_t data); - uint8_t io_read_byte(offs_t offset); - void io_write_byte(offs_t offset, uint8_t data); - MC6845_UPDATE_ROW(crtc_update_row); - uint32_t screen_update_super80v(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - required_device m_crtc; - required_device m_dma; - required_device m_fdc; - required_device m_floppy0; - required_device m_floppy1; - required_device m_floppy2; - required_device m_floppy3; - -private: - void low_w(offs_t offset, u8 data); - void high_w(offs_t offset, u8 data); - u8 low_r(offs_t offset); - u8 high_r(offs_t offset); -}; - -class super80r_state : public super80v_state -{ -public: - using super80v_state::super80v_state; - - void super80r(machine_config &config); - -private: - void super80r_map(address_map &map); - void low_w(offs_t offset, u8 data); - void high_w(offs_t offset, u8 data); - u8 low_r(offs_t offset); - u8 high_r(offs_t offset); -}; - - -#endif // MAME_INCLUDES_SUPER80_H diff --git a/src/mame/dicksmith/super80_m.cpp b/src/mame/dicksmith/super80_m.cpp deleted file mode 100644 index 5b14c8cb6d3..00000000000 --- a/src/mame/dicksmith/super80_m.cpp +++ /dev/null @@ -1,284 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Robbbert -/* Super80.cpp written by Robbbert, 2005-2009. See driver source for documentation. */ - -#include "emu.h" -#include "super80.h" - -#include "z80bin.h" - - -/**************************** PIO ******************************************************************************/ - - -void super80_state::pio_port_a_w(u8 data) -{ - m_keylatch = data; - m_pio->port_b_write(pio_port_b_r()); // refresh kbd int -} - -uint8_t super80_state::pio_port_b_r() -{ - uint8_t data = 0xff; - - for (int i = 0; i < 8; i++) - if (!BIT(m_keylatch, i)) - data &= m_io_keyboard[i]->read(); - - m_key_pressed = 3; - - return data; -} - -/**************************** CASSETTE ROUTINES *****************************************************************/ - -void super80_state::cassette_motor( bool motor_state ) -{ - // relay sound - if (BIT(m_last_data, 1) != motor_state) - m_samples->start(0, motor_state ? 0 : 1); - - if (motor_state) - m_cassette->change_state(CASSETTE_MOTOR_DISABLED,CASSETTE_MASK_MOTOR); - else - m_cassette->change_state(CASSETTE_MOTOR_ENABLED,CASSETTE_MASK_MOTOR); - - /* does user want to hear the sound? */ - if (BIT(m_io_config->read(), 3)) - m_cassette->change_state(CASSETTE_SPEAKER_ENABLED,CASSETTE_MASK_SPEAKER); - else - m_cassette->change_state(CASSETTE_SPEAKER_MUTED,CASSETTE_MASK_SPEAKER); -} - -/********************************************* TIMER ************************************************/ - - -// If normal keyboard scan has stopped, then do a scan to allow the interrupt key sequence -TIMER_DEVICE_CALLBACK_MEMBER( super80_state::timer_k ) -{ - if (m_key_pressed) - m_key_pressed--; - else - if (!m_key_pressed) - m_pio->port_b_write(pio_port_b_r()); -} - -/* cassette load circuit - This "emulates" U79 CD4046BCN PLL chip and U1 LM311P op-amp. U79 converts a frequency to a voltage, - and U1 amplifies that voltage to digital levels. U1 has a trimpot connected, to set the midpoint. - - The MDS homebrew input circuit consists of 2 op-amps followed by a D-flipflop. - The "read-any-system" cassette circuit is a CA3140 op-amp, the smarts being done in software. - - bit 0 = original system (U79 and U1) - bit 1 = MDS fast system - bit 2 = CA3140 */ -TIMER_DEVICE_CALLBACK_MEMBER( super80_state::kansas_r ) -{ - uint8_t cass_ws=0; - - m_cass_data[1]++; - cass_ws = ((m_cassette)->input() > +0.03) ? 4 : 0; - - if (cass_ws != m_cass_data[0]) - { - if (cass_ws) m_cass_data[3] ^= 2; // the MDS flipflop - m_cass_data[0] = cass_ws; - m_cass_data[2] = ((m_cass_data[1] < 0x0d) ? 1 : 0) | cass_ws | m_cass_data[3]; - m_cass_data[1] = 0; - } -} - - -TIMER_DEVICE_CALLBACK_MEMBER( super80_state::timer_h ) -{ - uint8_t go_fast = 0; - if ( (!BIT(m_portf0, 2)) || (!BIT(m_io_config->read(), 1)) ) // bit 2 of port F0 is low, OR user turned on config switch - go_fast++; // must be 1 at boot so banking works correctly - - /* code to slow down computer to 1 MHz by halting cpu on every second frame */ - if (!go_fast) - { - if (!m_int_sw) - m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); // if going, stop it - - m_int_sw++; - if (m_int_sw > 1) - { - m_maincpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE); // if stopped, start it - m_int_sw = 0; - } - } - else - { - if (m_int_sw < 8) // @2MHz, reset just once - { - m_maincpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE); - m_int_sw = 8; // ...not every time - } - } -} - -/*************************************** PRINTER ********************************************************/ - -/* The Super80 had an optional I/O card that plugged into the S-100 slot. The card had facility for running - an 8-bit Centronics printer, and a serial device at 300, 600, or 1200 baud. The I/O address range - was selectable via 4 dipswitches. The serial parameters (baud rate, parity, stop bits, etc) was - chosen with more dipswitches. Regretably, no parameters could be set by software. Currently, the - Centronics printer is emulated; the serial side of things may be done later, as will the dipswitches. - - The most commonly used I/O range is DC-DE (DC = centronics, DD = serial data, DE = serial control - All the home-brew roms use this, except for super80e which uses BC-BE. */ - -/**************************** I/O PORTS *****************************************************************/ - -u8 super80v_state::port3e_r() -{ - return 0xF8 | (m_fdc->intrq_r() << 0) | (m_fdc->drq_r() << 1) | 4; -} - -// UFDC board can support 4 drives; we support 2 -void super80v_state::port3f_w(u8 data) -{ - // m_fdc->58(BIT(data, 0)); 5/8 pin not emulated in wd_fdc - m_fdc->enmf_w(BIT(data,1)); - - floppy_image_device *floppy = nullptr; - if (BIT(data, 2)) floppy = m_floppy0->get_device(); - if (BIT(data, 3)) floppy = m_floppy1->get_device(); - if (BIT(data, 4)) floppy = m_floppy2->get_device(); - if (BIT(data, 5)) floppy = m_floppy3->get_device(); - - m_fdc->set_floppy(floppy); - - if (floppy) - { - floppy->mon_w(0); - floppy->ss_w(BIT(data, 6)); - } - - m_fdc->dden_w(BIT(data, 7)); -} - -u8 super80_state::portf2_r() -{ - u8 data = m_io_dsw->read() & 0xf0; // dip switches on pcb - data |= m_cass_data[2]; // bit 0 = output of U1, bit 1 = MDS cass state, bit 2 = current wave_state - data |= 0x08; // bit 3 - not used - return data; -} - -void super80_state::portdc_w(u8 data) -{ - // hardware strobe driven from port select, bit 7..0 = data - m_cent_data_out->write(data); - m_centronics->write_strobe(0); - m_centronics->write_strobe(1); -} - - -void super80_state::portf0_w(u8 data) -{ - u8 bits = data ^ m_last_data; - m_portf0 = data; - m_speaker->level_w(BIT(data, 3)); // bit 3 - speaker - if (BIT(bits, 1)) cassette_motor(BIT(data, 1)); // bit 1 - cassette motor - m_cassette->output( BIT(data, 0) ? -1.0 : +1.0); // bit 0 - cass out - - m_last_data = data; -} - - -/**************************** BASIC MACHINE CONSTRUCTION ***********************************************************/ - -void super80_state::machine_start_common() -{ - m_cass_led.resolve(); - - // register for savestates - save_item(NAME(m_portf0)); - save_item(NAME(m_s_options)); - save_item(NAME(m_palette_index)); - save_item(NAME(m_keylatch)); - save_item(NAME(m_cass_data)); - save_item(NAME(m_key_pressed)); - save_item(NAME(m_boot_in_progress)); - save_item(NAME(m_last_data)); -} - -void super80_state::machine_start() -{ - machine_start_common(); - save_item(NAME(m_int_sw)); - save_item(NAME(m_vidpg)); - save_item(NAME(m_current_charset)); -} - -void super80v_state::machine_start() -{ - // zerofill - m_vram = make_unique_clear(0x3000); - save_pointer(NAME(m_vram), 0x3000); - machine_start_common(); -} - -void super80_state::machine_reset_common() -{ - m_boot_in_progress = true; - m_portf0 = 0; // must be 0 like real machine, or banking breaks on 32-col systems - m_keylatch = 0xff; - m_key_pressed = 0; - m_palette_index = 0; - - address_space &program = m_maincpu->space(AS_PROGRAM); - program.install_rom(0x0000, 0x0fff, m_rom); // do it here for F3 - m_rom_shadow_tap.remove(); - m_rom_shadow_tap = program.install_read_tap( - 0xc000, 0xcfff, - "rom_shadow_r", - [this] (offs_t offset, u8 &data, u8 mem_mask) - { - if (!machine().side_effects_disabled()) - { - // delete this tap - m_rom_shadow_tap.remove(); - - // reinstall RAM over the ROM shadow - m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x0fff, m_ram); - } - }, - &m_rom_shadow_tap); -} - -void super80_state::machine_reset() -{ - machine_reset_common(); - m_vidpg = 0xfe00; -} - -void super80v_state::machine_reset() -{ - machine_reset_common(); -} - - -/*------------------------------------------------- - QUICKLOAD_LOAD_MEMBER( super80_state, super80 ) --------------------------------------------------*/ - -QUICKLOAD_LOAD_MEMBER(super80_state::quickload_cb) -{ - uint16_t exec_addr, start_addr, end_addr; - - // load the binary into memory - if (z80bin_load_file(image, m_maincpu->space(AS_PROGRAM), exec_addr, start_addr, end_addr) != image_init_result::PASS) - return image_init_result::FAIL; - - // is this file executable? - if (exec_addr != 0xffff) - // check to see if autorun is on - if (BIT(m_io_config->read(), 0)) - m_maincpu->set_pc(exec_addr); - - return image_init_result::PASS; -} diff --git a/src/mame/dicksmith/super80_v.cpp b/src/mame/dicksmith/super80_v.cpp deleted file mode 100644 index 5bdbf556c0b..00000000000 --- a/src/mame/dicksmith/super80_v.cpp +++ /dev/null @@ -1,420 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Robbbert -/* Super80.c written by Robbbert, 2005-2010. See the driver source for documentation. */ - - - -#include "emu.h" -#include "super80.h" - - - -/**************************** PALETTES for super80m and super80v ******************************************/ - -void super80_state::super80m_palette(palette_device &palette) const -{ - // RGB - palette.set_pen_color( 0, rgb_t(0x00, 0x00, 0x00)); // 0 Black - palette.set_pen_color( 1, rgb_t(0x00, 0x00, 0x00)); // 1 Black - palette.set_pen_color( 2, rgb_t(0x00, 0x00, 0x7f)); // 2 Blue - palette.set_pen_color( 3, rgb_t(0x00, 0x00, 0xff)); // 3 Light Blue - palette.set_pen_color( 4, rgb_t(0x00, 0x7f, 0x00)); // 4 Green - palette.set_pen_color( 5, rgb_t(0x00, 0xff, 0x00)); // 5 Bright Green - palette.set_pen_color( 6, rgb_t(0x00, 0x7f, 0x7f)); // 6 Cyan - palette.set_pen_color( 7, rgb_t(0x00, 0xff, 0xff)); // 7 Turquoise - palette.set_pen_color( 8, rgb_t(0x7f, 0x00, 0x00)); // 8 Dark Red - palette.set_pen_color( 9, rgb_t(0xff, 0x00, 0x00)); // 9 Red - palette.set_pen_color(10, rgb_t(0x7f, 0x00, 0x7f)); // 10 Purple - palette.set_pen_color(11, rgb_t(0xff, 0x00, 0xff)); // 11 Magenta - palette.set_pen_color(12, rgb_t(0x7f, 0x7f, 0x00)); // 12 Lime - palette.set_pen_color(13, rgb_t(0xff, 0xff, 0x00)); // 13 Yellow - palette.set_pen_color(14, rgb_t(0xbf, 0xbf, 0xbf)); // 14 Off White - palette.set_pen_color(15, rgb_t(0xff, 0xff, 0xff)); // 15 White - // Composite - palette.set_pen_color(16, rgb_t(0x00, 0x00, 0x00)); // 0 Black - palette.set_pen_color(17, rgb_t(0x80, 0x80, 0x80)); // 1 Grey - palette.set_pen_color(18, rgb_t(0x00, 0x00, 0xff)); // 2 Blue - palette.set_pen_color(19, rgb_t(0xff, 0xff, 0x80)); // 3 Light Yellow - palette.set_pen_color(20, rgb_t(0x00, 0xff, 0x00)); // 4 Green - palette.set_pen_color(21, rgb_t(0xff, 0x80, 0xff)); // 5 Light Magenta - palette.set_pen_color(22, rgb_t(0x00, 0xff, 0xff)); // 6 Cyan - palette.set_pen_color(23, rgb_t(0xff, 0x40, 0x40)); // 7 Light Red - palette.set_pen_color(24, rgb_t(0xff, 0x00, 0x00)); // 8 Red - palette.set_pen_color(25, rgb_t(0x00, 0x80, 0x80)); // 9 Dark Cyan - palette.set_pen_color(26, rgb_t(0xff, 0x00, 0xff)); // 10 Magenta - palette.set_pen_color(27, rgb_t(0x80, 0xff, 0x80)); // 11 Light Green - palette.set_pen_color(28, rgb_t(0xff, 0xff, 0x00)); // 12 Yellow - palette.set_pen_color(29, rgb_t(0x00, 0x00, 0x80)); // 13 Dark Blue - palette.set_pen_color(30, rgb_t(0xff, 0xff, 0xff)); // 14 White - palette.set_pen_color(31, rgb_t(0x00, 0x00, 0x00)); // 15 Black -} - - - -void super80_state::screen_vblank_super80m(bool state) -{ - // rising edge - if (state) - { - // if we chose another palette or colour mode, enable it - m_palette_index = (m_io_config->read() & 0x60) ? 0 : 16; - } -} - -uint32_t super80_state::screen_update_super80(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - address_space& program = m_maincpu->space(AS_PROGRAM); - - m_cass_led = BIT(m_portf0, 5); - - const uint8_t options = m_io_config->read(); - bool screen_on = BIT(m_portf0, 2) || !BIT(options, 2); // bit 2 of port F0 is high, OR user turned on config switch - - uint8_t fg = 0; - if (screen_on) - { - if (BIT(options, 5)) - fg = 15; // b&w - else - fg = 5; // green - } - - uint16_t sy = 0; - uint16_t ma = m_vidpg; - for (uint8_t y = 0; y < 16; y++) - { - for (uint8_t ra = 0; ra < 10; ra++) - { - uint16_t *p = &bitmap.pix(sy++); - - for (uint16_t x = 0; x < 32; x++) // done this way to avoid x overflowing on page FF - { - uint8_t chr = 32; - if (screen_on) - { - chr = program.read_byte(ma | x) & 0x7f; - if ((chr >= 0x61) && (chr <= 0x7a)) - chr &= 0x1f; - else - chr &= 0x3f; - } - - // get pattern of pixels for that character scanline - const uint8_t gfx = m_p_chargen[(chr<<4) | ((ra & 8) >> 3) | ((ra & 7) << 1)]; - - // Display a scanline of a character - *p++ = BIT(gfx, 7) ? fg : 0; - *p++ = BIT(gfx, 6) ? fg : 0; - *p++ = BIT(gfx, 5) ? fg : 0; - *p++ = BIT(gfx, 4) ? fg : 0; - *p++ = BIT(gfx, 3) ? fg : 0; - *p++ = BIT(gfx, 2) ? fg : 0; - *p++ = BIT(gfx, 1) ? fg : 0; - *p++ = BIT(gfx, 0) ? fg : 0; - } - } - ma += 32; - } - return 0; -} - -uint32_t super80_state::screen_update_super80d(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - address_space& program = m_maincpu->space(AS_PROGRAM); - m_cass_led = BIT(m_portf0, 5); - - const uint8_t options = m_io_config->read(); - bool screen_on = BIT(m_portf0, 2) || !BIT(options, 2); // bit 2 of port F0 is high, OR user turned on config switch - - uint8_t fg = 0; - if (screen_on) - { - if (BIT(options, 5)) - fg = 15; // b&w - else - fg = 5; // green - } - - uint16_t sy = 0; - uint16_t ma = m_vidpg; - for (uint8_t y = 0; y < 16; y++) - { - for (uint8_t ra = 0; ra < 10; ra++) - { - uint16_t *p = &bitmap.pix(sy++); - - for (uint16_t x = 0; x < 32; x++) - { - uint8_t chr = 32; - if (screen_on) - chr = program.read_byte(ma | x); - - // get pattern of pixels for that character scanline - const uint8_t gfx = m_p_chargen[((chr & 0x7f)<<4) | ((ra & 8) >> 3) | ((ra & 7) << 1)] ^ ((chr & 0x80) ? 0xff : 0); - - // Display a scanline of a character - *p++ = BIT(gfx, 7) ? fg : 0; - *p++ = BIT(gfx, 6) ? fg : 0; - *p++ = BIT(gfx, 5) ? fg : 0; - *p++ = BIT(gfx, 4) ? fg : 0; - *p++ = BIT(gfx, 3) ? fg : 0; - *p++ = BIT(gfx, 2) ? fg : 0; - *p++ = BIT(gfx, 1) ? fg : 0; - *p++ = BIT(gfx, 0) ? fg : 0; - } - } - ma+=32; - } - return 0; -} - -uint32_t super80_state::screen_update_super80e(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - address_space& program = m_maincpu->space(AS_PROGRAM); - m_cass_led = BIT(m_portf0, 5); - - const uint8_t options = m_io_config->read(); - bool screen_on = BIT(m_portf0, 2) || !BIT(options, 2); // bit 2 of port F0 is high, OR user turned on config switch - - uint8_t fg = 0; - if (screen_on) - { - if (BIT(options, 5)) - fg = 15; // b&w - else - fg = 5; // green - } - - uint16_t sy = 0; - uint16_t ma = m_vidpg; - for (uint8_t y = 0; y < 16; y++) - { - for (uint8_t ra = 0; ra < 10; ra++) - { - uint16_t *p = &bitmap.pix(sy++); - - for (uint16_t x = 0; x < 32; x++) - { - uint8_t chr = 32; - if (screen_on) - chr = program.read_byte(ma | x); - - // get pattern of pixels for that character scanline - const uint8_t gfx = m_p_chargen[(chr<<4) | ((ra & 8) >> 3) | ((ra & 7) << 1)]; - - // Display a scanline of a character - *p++ = BIT(gfx, 7) ? fg : 0; - *p++ = BIT(gfx, 6) ? fg : 0; - *p++ = BIT(gfx, 5) ? fg : 0; - *p++ = BIT(gfx, 4) ? fg : 0; - *p++ = BIT(gfx, 3) ? fg : 0; - *p++ = BIT(gfx, 2) ? fg : 0; - *p++ = BIT(gfx, 1) ? fg : 0; - *p++ = BIT(gfx, 0) ? fg : 0; - } - } - ma+=32; - } - return 0; -} - -uint32_t super80_state::screen_update_super80m(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - address_space& program = m_maincpu->space(AS_PROGRAM); - m_cass_led = BIT(m_portf0, 5); - - const uint8_t options = m_io_config->read(); - - // get selected character generator - const bool cgen = m_current_charset ^ BIT(options, 4); // bit 0 of port F1 and cgen config switch - - const bool screen_on = BIT(m_portf0, 2) || !BIT(options, 2); // bit 2 of port F0 is high, OR user turned on config switch - - uint8_t fg = 0; - if (screen_on) - { - if (BIT(options, 5)) - fg = 15; // b&w - else - fg = 5; // green - } - - uint16_t sy = 0; - uint16_t ma = m_vidpg; - for (uint8_t y = 0; y < 16; y++) - { - for (uint8_t ra = 0; ra < 10; ra++) - { - uint16_t *p = &bitmap.pix(sy++); - - for (uint16_t x = 0; x < 32; x++) - { - uint8_t chr = 32; - if (screen_on) - chr = program.read_byte(ma | x); - - uint8_t bg = 0; - if (!(options & 0x40)) - { - const uint8_t col = program.read_byte(0xfe00 | ma | x); // byte of colour to display - fg = m_palette_index + (col & 0x0f); - bg = m_palette_index + (col >> 4); - } - - // get pattern of pixels for that character scanline - uint8_t gfx; - if (cgen) - gfx = m_p_chargen[(chr<<4) | ((ra & 8) >> 3) | ((ra & 7) << 1)]; - else - gfx = m_p_chargen[0x1000 | ((chr & 0x7f)<<4) | ((ra & 8) >> 3) | ((ra & 7) << 1)] ^ ((chr & 0x80) ? 0xff : 0); - - // Display a scanline of a character - *p++ = BIT(gfx, 7) ? fg : bg; - *p++ = BIT(gfx, 6) ? fg : bg; - *p++ = BIT(gfx, 5) ? fg : bg; - *p++ = BIT(gfx, 4) ? fg : bg; - *p++ = BIT(gfx, 3) ? fg : bg; - *p++ = BIT(gfx, 2) ? fg : bg; - *p++ = BIT(gfx, 1) ? fg : bg; - *p++ = BIT(gfx, 0) ? fg : bg; - } - } - ma+=32; - } - return 0; -} - - -/**************************** I/O PORTS *****************************************************************/ - -void super80_state::portf1_w(u8 data) -{ - m_vidpg = (data & 0xfe) << 8; - m_current_charset = BIT(data, 0); -} - -/*--------------------------------------------------------------- - - Super-80R and Super-80V - ----------------------------------------------------------------*/ - -// we place videoram at 0x0000, colour ram at 0x1000, pcg at 0x2000 -u8 super80r_state::low_r(offs_t offset) -{ - return m_vram[offset]; -} - -void super80r_state::low_w(offs_t offset, u8 data) -{ - m_vram[offset] = data; // video -} - -u8 super80r_state::high_r(offs_t offset) -{ - return m_vram[offset+0x0800]; // video -} - -void super80r_state::high_w(offs_t offset, u8 data) -{ - m_vram[offset+0x0800] = data; // video - m_vram[offset+0x2800] = data; // pcg -} - -u8 super80v_state::low_r(offs_t offset) -{ - if (BIT(m_portf0, 2)) - return m_vram[offset]; // video - else - return m_vram[offset+0x1000]; // colour -} - -void super80v_state::low_w(offs_t offset, u8 data) -{ - if (BIT(m_portf0, 2)) - m_vram[offset] = data; // video - else - m_vram[offset+0x1000] = data; // colour -} - -u8 super80v_state::high_r(offs_t offset) -{ - if (!BIT(m_portf0, 2)) - return m_vram[offset+0x1800]; // colour - else - if (BIT(m_portf0, 4)) - return m_vram[offset+0x0800]; // video - else - return m_p_chargen[offset]; // char rom -} - -void super80v_state::high_w(offs_t offset, u8 data) -{ - if (!BIT(m_portf0, 2)) - m_vram[offset+0x1800] = data; // colour - else - { - m_vram[offset+0x0800] = data; // video - - if (BIT(m_portf0, 4)) - m_vram[offset+0x2800] = data; // pcg - } -} - -uint32_t super80v_state::screen_update_super80v(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - m_s_options = m_io_config->read(); - m_cass_led = BIT(m_portf0, 5); - m_crtc->screen_update(screen, bitmap, cliprect); - return 0; -} - -MC6845_UPDATE_ROW( super80v_state::crtc_update_row ) -{ - const rgb_t *palette = m_palette->palette()->entry_list_raw(); - uint32_t *p = &bitmap.pix(y); - - for (uint16_t x = 0; x < x_count; x++) // for each character - { - uint8_t inv = 0; - if (x == cursor_x) inv=0xff; - const uint16_t mem = (ma + x) & 0xfff; - uint8_t chr = m_vram[mem]; - - /* get colour or b&w */ - uint8_t fg = 5; // green - if ((m_s_options & 0x60) == 0x60) - fg = 15; // b&w - - uint8_t bg = 0; - if (~m_s_options & 0x40) - { - const uint8_t col = m_vram[mem+0x1000]; // byte of colour to display - fg = m_palette_index + (col & 0x0f); - bg = m_palette_index + (col >> 4); - } - - // if inverse mode, replace any pcgram chrs with inverse chrs - if (!BIT(m_portf0, 4) && BIT(chr, 7)) // is it a high chr in inverse mode - { - inv ^= 0xff; // invert the chr - chr &= 0x7f; // and drop bit 7 - } - - // get pattern of pixels for that character scanline - const uint8_t gfx = BIT(chr, 7) - ? m_vram[0x2000 | ((chr << 4) | ra)] ^ inv - : m_p_chargen[((chr << 4) | ra)] ^ inv; - - // Display a scanline of a character - *p++ = palette[BIT(gfx, 7) ? fg : bg]; - *p++ = palette[BIT(gfx, 6) ? fg : bg]; - *p++ = palette[BIT(gfx, 5) ? fg : bg]; - *p++ = palette[BIT(gfx, 4) ? fg : bg]; - *p++ = palette[BIT(gfx, 3) ? fg : bg]; - *p++ = palette[BIT(gfx, 2) ? fg : bg]; - *p++ = palette[BIT(gfx, 1) ? fg : bg]; - } -} - - diff --git a/src/mame/dulmont/magnum.cpp b/src/mame/dulmont/magnum.cpp deleted file mode 100644 index f6e17c87b27..00000000000 --- a/src/mame/dulmont/magnum.cpp +++ /dev/null @@ -1,337 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Carl - -// Dulmont Magnum -// Additional info https://www.youtube.com/watch?v=st7H_vqSaQc and -// http://www.eevblog.com/forum/blog/eevblog-949-vintage-australian-made-laptop-teardown/msg1080508/#msg1080508 -// TODO: cartridge dumps - -#include "emu.h" -#include "cpu/i86/i186.h" -#include "machine/cdp1879.h" -#include "machine/wd_fdc.h" -#include "video/hd61830.h" -#include "video/i8275.h" -#include "sound/beep.h" -#include "emupal.h" -#include "screen.h" -#include "speaker.h" - -class magnum_state : public driver_device -{ -public: - magnum_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_maincpu(*this, "maincpu") - , m_beep(*this, "beep") - , m_shift(*this, "SHIFT") - { - } - void magnum(machine_config &config); - DECLARE_INPUT_CHANGED_MEMBER(keypress); -protected: - virtual void machine_reset() override; - virtual void machine_start() override; - -private: - void beep_w(u8 data); - u8 sysctl_r(offs_t offset); - void sysctl_w(offs_t offset, u8 data); - u16 irqstat_r(); - void port50_w(u16 data); - DECLARE_WRITE_LINE_MEMBER(rtcirq_w); - - void check_irq(); - void magnum_io(address_map &map); - void magnum_map(address_map &map); - void magnum_lcdc(address_map &map); - - required_device m_maincpu; - required_device m_beep; - required_ioport m_shift; - - u8 m_key; - bool m_wake, m_rtcirq, m_keybirq; -}; - -void magnum_state::check_irq() -{ - if(m_rtcirq || m_keybirq) - { - m_maincpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); - m_maincpu->int0_w(ASSERT_LINE); - m_wake = true; - } - else - m_maincpu->int0_w(CLEAR_LINE); -} - -INPUT_CHANGED_MEMBER(magnum_state::keypress) -{ - if(newval != oldval) - { - m_key = (uint8_t)(param & 0xff) | (m_shift->read() & 0xc ? 0 : 0x80); - m_keybirq = true; - check_irq(); - } -} - -static INPUT_PORTS_START(magnum) - PORT_START("ROW.0") - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 0) - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 1) - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 4) - PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 5) - PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 8) - PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 9) - PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 12) - PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 13) - PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 2) // all 0x4 bits in every nibble also repeated in row 4+ - PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 3) // all 0x8 bits in every nibble also repeated in row 4+ - PORT_START("ROW.1") - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 16) - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 17) - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F11) PORT_CHAR(UCHAR_MAMEKEY(F11)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 20) - PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 21) - PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 24) - PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 25) - PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 28) - PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 29) - PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 18) - PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 19) - PORT_START("ROW.2") - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 32) - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 33) - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 36) - PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 37) - PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 40) - PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 41) - PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 44) - PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 45) - PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 34) - PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 35) - PORT_START("ROW.3") - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 48) - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 49) - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Help") PORT_CODE(KEYCODE_INSERT) PORT_CHAR(UCHAR_MAMEKEY(INSERT)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 52) - PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 53) - PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 56) - PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 57) - PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 60) - PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 61) - PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 50) - PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 51) - PORT_START("ROW.4") - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 64) - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 65) - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 68) - PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 69) - PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 72) - PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 73) - PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 76) - PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 77) - PORT_START("ROW.5") - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 80) - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 81) - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F12) PORT_CHAR(UCHAR_MAMEKEY(F12)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 84) - PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 85) - PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 88) - PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 89) - PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 92) - PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 93) - PORT_START("ROW.6") - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 96) - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_UNKNOWN) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 97) - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Line Feed") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 100) - PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 101) - PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 104) - PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 105) - PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 108) - PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 109) - PORT_START("ROW.7") - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 112) - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 113) - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 116) - PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F10) PORT_CHAR(UCHAR_MAMEKEY(F10)) PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 117) - PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 120) - PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 121) - PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 124) - PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_CHANGED_MEMBER(DEVICE_SELF, magnum_state, keypress, 125) - PORT_START("SHIFT") - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) - PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) - PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_MAMEKEY(RCONTROL)) -INPUT_PORTS_END - -void magnum_state::machine_start() -{ -} - -void magnum_state::machine_reset() -{ - m_wake = false; - m_rtcirq = false; - m_keybirq = false; -} - -void magnum_state::beep_w(u8 data) -{ - if (data & ~1) logerror("beep_w unmapped bits %02x\n", data); - m_beep->set_state(BIT(data, 0)); -} - -void magnum_state::magnum_map(address_map &map) -{ - map(0x00000, 0x3ffff).ram(); // fixed 256k for now - map(0xe0000, 0xfffff).rom().region("bios", 0); -} - -u8 magnum_state::sysctl_r(offs_t offset) -{ - switch(offset) - { - case 0: - return m_key; - case 1: - { - u8 ret = m_keybirq ? 1 : 0; - m_keybirq = false; - check_irq(); - return ret | (m_shift->read() & 3 ? 0 : 4); - } - } - return 0; -} - -void magnum_state::sysctl_w(offs_t offset, u8 data) -{ - switch(offset) - { - case 0: - break; - case 2: - m_maincpu->set_input_line(INPUT_LINE_RESET, data ? CLEAR_LINE : ASSERT_LINE); - break; - case 4: - break; - case 6: - break; - case 12: - break; - } -} - -/* IRQs - * bit 0 - - * 1 - - * 2 - - * 3 - - * 4 - - * 5 - Keyboard? - * 6 - RTC? - * 7 - - * 8 - UART1? - * 9 - UART2? - * 10- Reset? - * 11-14 ... - * 15- CRTC? - */ - -u16 magnum_state::irqstat_r() -{ - u16 ret = m_wake ? 0 : 0x400; - ret |= m_rtcirq ? 0x40 : 0; - ret |= m_keybirq ? 0x20 : 0; - m_wake = false; - return ret; -} - -void magnum_state::port50_w(u16 data) -{ -} - -WRITE_LINE_MEMBER(magnum_state::rtcirq_w) -{ - m_rtcirq = state == ASSERT_LINE; - check_irq(); -} - -void magnum_state::magnum_io(address_map &map) -{ - map.unmap_value_high(); - //map(0x000a, 0x000b) cdp1854 1 - //map(0x000e, 0x000f) cpd1854 2 - //map(0x0014, 0x0017).rw("crtc", FUNC(i8275_device::read), FUNC(i8275_device::write)).umask16(0x00ff); - map(0x0018, 0x0019).rw("lcdc2", FUNC(hd61830_device::data_r), FUNC(hd61830_device::data_w)).umask16(0x00ff); - map(0x001a, 0x001b).rw("lcdc2", FUNC(hd61830_device::status_r), FUNC(hd61830_device::control_w)).umask16(0x00ff); - map(0x001c, 0x001d).rw("lcdc1", FUNC(hd61830_device::data_r), FUNC(hd61830_device::data_w)).umask16(0x00ff); - map(0x001e, 0x001f).rw("lcdc1", FUNC(hd61830_device::status_r), FUNC(hd61830_device::control_w)).umask16(0x00ff); - map(0x0040, 0x004f).rw(FUNC(magnum_state::sysctl_r), FUNC(magnum_state::sysctl_w)); - map(0x0050, 0x0051).rw(FUNC(magnum_state::irqstat_r), FUNC(magnum_state::port50_w)); - map(0x0056, 0x0056).w(FUNC(magnum_state::beep_w)); - map(0x0080, 0x008f).rw("rtc", FUNC(cdp1879_device::read), FUNC(cdp1879_device::write)).umask16(0x00ff); - //map(0x0100, 0x0107).rw("fdc", FUNC(wd1793_device::read), FUNC(wd1793_device::write)).umask16(0x00ff); -} - -void magnum_state::magnum_lcdc(address_map &map) -{ - map(0x0000, 0x027f).ram(); -} - -void magnum_state::magnum(machine_config &config) -{ - I80186(config, m_maincpu, XTAL(12'000'000)); - m_maincpu->set_addrmap(AS_PROGRAM, &magnum_state::magnum_map); - m_maincpu->set_addrmap(AS_IO, &magnum_state::magnum_io); - - CDP1879(config, "rtc", XTAL(32'768)).irq_callback().set(FUNC(magnum_state::rtcirq_w)); - - screen_device &screen1(SCREEN(config, "screen1", SCREEN_TYPE_LCD)); - screen1.set_refresh_hz(50); - screen1.set_screen_update("lcdc1", FUNC(hd61830_device::screen_update)); - screen1.set_size(6*40, 9*16); - screen1.set_visarea(0, 6*40-1, 0, 8*16-1); - screen1.set_palette("palette"); - - screen_device &screen2(SCREEN(config, "screen2", SCREEN_TYPE_LCD)); - screen2.set_refresh_hz(50); - screen2.set_screen_update("lcdc2", FUNC(hd61830_device::screen_update)); - screen2.set_size(6*40, 9*16); - screen2.set_visarea(0, 6*40-1, 0, 8*16-1); - screen2.set_palette("palette"); - - hd61830_device &lcdc1(HD61830(config, "lcdc1", 1000000)); // unknown clock - lcdc1.set_addrmap(0, &magnum_state::magnum_lcdc); - lcdc1.set_screen("screen1"); - - hd61830_device &lcdc2(HD61830(config, "lcdc2", 1000000)); // unknown clock - lcdc2.set_addrmap(0, &magnum_state::magnum_lcdc); - lcdc2.set_screen("screen2"); - - //I8275(config, "crtc", 3000000); // unknown clock - - //WD1793(config, "fdc", 1000000); // nothing known, type or if any disks even exist, port 0x44 is possibly motor control - - PALETTE(config, "palette", palette_device::MONOCHROME_INVERTED); - - SPEAKER(config, "speaker").front_center(); - BEEP(config, m_beep, 500).add_route(ALL_OUTPUTS, "speaker", 0.50); // frequency is guessed -} - -ROM_START( magnum ) - ROM_REGION16_LE(0x20000, "bios", 0) - ROM_LOAD16_BYTE("a1.7.88.bin", 0x00000, 0x4000, CRC(57882427) SHA1(97637b65ca43eb9d3bba546fb8ca701ba25ade8d)) - ROM_LOAD16_BYTE("a1.7.81.bin", 0x00001, 0x4000, CRC(949f53a8) SHA1(b339f1495d9af7dfff0c3a2c24789631f9d1265b)) - ROM_LOAD16_BYTE("a1.7.87.bin", 0x08000, 0x4000, CRC(25036dda) SHA1(20bc3782a66855b20cb0abe1051fa2eb50c7a860)) - ROM_LOAD16_BYTE("a1.7.82.bin", 0x08001, 0x4000, CRC(ecf387d8) SHA1(8b42f6ab030afb51f21f4a56c62e5acf7d074066)) - ROM_LOAD16_BYTE("a1.7.86.bin", 0x10000, 0x4000, CRC(c80b3a6b) SHA1(0f0d2cb653bbeff8f3bab6d20dc30c220a67a315)) - ROM_LOAD16_BYTE("a1.7.83.bin", 0x10001, 0x4000, CRC(51f56d78) SHA1(df717eada5e6439b1c01d91bd0ea009cd0f8ddfa)) - ROM_LOAD16_BYTE("a1.7.85.bin", 0x18000, 0x4000, CRC(f5dd5407) SHA1(af2edf7a658bcf648acb8be9f13849f838d96214)) - ROM_LOAD16_BYTE("a1.7.84.bin", 0x18001, 0x4000, CRC(b3434bb0) SHA1(8000a7aca8fc505b136a618d9eb210c50393eff1)) - - ROM_REGION(0x1000, "char", 0) - ROM_LOAD("dulmontcharrom.bin", 0x0000, 0x1000, CRC(9dff89bf) SHA1(d359aeba7f0b0c81accf3bca25e7da636c033721)) -ROM_END - -COMP( 1983, magnum, 0, 0, magnum, magnum, magnum_state, empty_init, "Dulmont", "Magnum", MACHINE_IMPERFECT_SOUND) diff --git a/src/mame/labtam/labtam.cpp b/src/mame/labtam/labtam.cpp deleted file mode 100644 index cfcee9809f1..00000000000 --- a/src/mame/labtam/labtam.cpp +++ /dev/null @@ -1,114 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Patrick Mackinlay - -/* - * Labtam International 3000 Systems - * - * Sources: - * - - * - * TODO: - * - additional cards - */ - -/* -3000 1983 -??? - -3003 1983 -Desktop -Board: -one - Z80 SBC -one - 8086 VDU/COMM -one - WD1002-HDO (Like Kaypro-10) https://retrocmp.de/kaypro/kay-p2_hrdw.htm#hdc -one - FDD 5'25 - Connect to WD1002 board -one - MFM HDD 5'25 NEC D5124 10MB - Connect to WD1002 board - -3006 1983 -Monoblock -Board: -one - Z80 SBC -one - 8086 VDU/COMM -two - FDD 8" - Connect to Z80 SBC board (to WD2793A on board) -one - FDD 5"25 - Connect to Z80 SBC board (to WD2793A on board) - -3015-V32 1985 -Tower -Board: -one - Z80 SBC -four - 8086 VDU/COMM (one board with main ROM and others slave ROM) -one - V32 (main processor board on CPU - NS32032, MMU - NS32082, FPU - NS32081, 2 Megabyte RAM), Optional SCSI contoler on board. -one or two - Additional one or two RAM board with 6 Megabyte. -one - INTERPHASE SMD 2190 (Controller SMD HDD) -one - Xylogics 472 (Controller 1/2 inch TAPE with PERTEC interface) - */ - -#include "emu.h" - -#include "bus/multibus/multibus.h" - -#include "bus/multibus/labtam_3232.h" -#include "bus/multibus/labtam_vducom.h" -#include "bus/multibus/labtam_z80sbc.h" - -#define VERBOSE 0 -#include "logmacro.h" - -namespace { - -class labtam_state : public driver_device -{ -public: - labtam_state(machine_config const &mconfig, device_type type, char const *tag) - : driver_device(mconfig, type, tag) - , m_bus(*this, "slot") - { - } - -protected: - // driver_device overrides - virtual void machine_start() override; - virtual void machine_reset() override; - -public: - // machine config - void labtam(machine_config &config); - -private: - required_device m_bus; -}; - -void labtam_state::machine_start() -{ -} - -void labtam_state::machine_reset() -{ -} - -static void labtam_cards(device_slot_interface &device) -{ - device.option_add("labtam_3232", LABTAM_3232); - device.option_add("labtam_vducom", LABTAM_VDUCOM); - device.option_add("labtam_z80sbc", LABTAM_Z80SBC); -} - -void labtam_state::labtam(machine_config &config) -{ - MULTIBUS(config, m_bus, 10_MHz_XTAL); // FIXME: clock driven by bus master - - MULTIBUS_SLOT(config, "slot:0", m_bus, labtam_cards, nullptr, false); - MULTIBUS_SLOT(config, "slot:1", m_bus, labtam_cards, nullptr, false); - MULTIBUS_SLOT(config, "slot:2", m_bus, labtam_cards, nullptr, false); - MULTIBUS_SLOT(config, "slot:3", m_bus, labtam_cards, nullptr, false); - MULTIBUS_SLOT(config, "slot:4", m_bus, labtam_cards, "labtam_vducom", false); - MULTIBUS_SLOT(config, "slot:5", m_bus, labtam_cards, "labtam_z80sbc", false); -} - -ROM_START(labtam) -ROM_END - -} - -/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ -COMP(1983, labtam, 0, 0, labtam, 0, labtam_state, empty_init, "Labtam International", "3006", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW) diff --git a/src/mame/mame.lst b/src/mame/mame.lst index a6d47000c6d..38e7da3f529 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -1400,7 +1400,7 @@ kccomp // VEB KC compact amusco // 1987, Amusco. draw88pkr // 1988, BTE, Inc. -@source:skeleton/amust.cpp +@source:ausnz/amust.cpp amust // @source:misc/anes.cpp @@ -1507,7 +1507,7 @@ apple2gsr3p // ??? 198? Apple IIgs ROM03 prototype @source:apple/apple3.cpp apple3 // May 1980 Apple /// -@source:skeleton/applix.cpp +@source:ausnz/applix.cpp applix // @source:sanritsu/appoooh.cpp @@ -3234,7 +3234,7 @@ smashdrv // (c) 2000 smashdrvb // (c) 2000 smashdrvs // (c) 2000 -@source:skeleton/aussiebyte.cpp +@source:ausnz/aussiebyte.cpp aussieby // @source:atari/avalnche.cpp @@ -9372,7 +9372,7 @@ bigkarnkm // bigstrkb // bootleg on different hardware bigstrkba // alt set of 'bigstrkb' with Italian teams -@source:skeleton/binbug.cpp +@source:ausnz/binbug.cpp binbug // @source:pinball/bingo.cpp @@ -11805,7 +11805,7 @@ ckz80 // @source:skeleton/d400.cpp d461 // -@source:skeleton/d6800.cpp +@source:ausnz/d6800.cpp d6800 // Dream 6800 @source:homebrew/d6809.cpp @@ -11876,7 +11876,7 @@ thndzonej // MAJ (c) 1991 Data East Corporation (Japan) - @source:skeleton/datacast.cpp datacast // -@source:trainer/datum.cpp +@source:ausnz/datum.cpp datum // 1982 @source:excellent/dblcrown.cpp @@ -12453,7 +12453,7 @@ gemcrush @source:sony/dfs500.cpp dfs500 // 1994 Sony DFS-500 Video Mixer -@source:skeleton/dg680.cpp +@source:ausnz/dg680.cpp dg680 // @source:trs/dgn_beta.cpp @@ -12646,7 +12646,7 @@ dm7000 // @source:misc/dmainevent.cpp dmainevent // (c) 1983 Destron -@source:skeleton/dmax8000.cpp +@source:ausnz/dmax8000.cpp dmax8000 // @source:snk/dmndrby.cpp @@ -12891,7 +12891,7 @@ e100 // @source:ericsson/e9161.cpp e9161 // -@source:skeleton/eacc.cpp +@source:ausnz/eacc.cpp eacc // @source:skeleton/easy_karaoke.cpp @@ -13647,7 +13647,7 @@ turbosub7 // (c) 1985 Entertainment Sciences @source:heathkit/et3400.cpp et3400 // -@source:skeleton/eti660.cpp +@source:ausnz/eti660.cpp eti660 // @source:misc/ettrivia.cpp @@ -13681,7 +13681,7 @@ tms9995bb // TMS9995 breadboard @source:nec/ews4800.cpp ews4800_310 // NEC EWS4800/310 -@source:skeleton/excali64.cpp +@source:ausnz/excali64.cpp excali64 // @source:capcom/exedexes.cpp @@ -20036,7 +20036,7 @@ skywolf3 // bootleg sonofphx // bootleg srdmissn // (c) 1986 Taito Corporation -@source:labtam/labtam.cpp +@source:ausnz/labtam.cpp labtam // Labtam 3000 model 3006 @source:konami/labyrunr.cpp @@ -20856,7 +20856,7 @@ magictga // (c) 199? Acclaim magmax // (c) 1985 magmaxa // (c) 1985 -@source:dulmont/magnum.cpp +@source:ausnz/magnum.cpp magnum // @source:misc/magreel.cpp @@ -22914,7 +22914,7 @@ mbc200 // @source:sanyo/mbc55x.cpp mbc55x // Sanyo MBC-550, MBC-555 -@source:appliedtech/mbee.cpp +@source:ausnz/mbee.cpp mbee // Microbee 16 Standard or Plus mbee128 // Microbee 128K standard (CP/M) mbee128p // Microbee 128K premium (CP/M) @@ -35529,7 +35529,7 @@ pinkiri8 // ronjan // ronjans // -@source:skeleton/pipbug.cpp +@source:ausnz/pipbug.cpp pipbug // @source:vsystem/pipedrm.cpp @@ -35906,7 +35906,7 @@ sshooter11 // (c) 1998 P&P Marketing sshooter12 // (c) 1998 P&P Marketing sshooter17 // (c) 1998 P&P Marketing -@source:poly/poly.cpp +@source:ausnz/poly.cpp poly1 // Poly 1 poly1e // Poly 1 (early) poly2 // Poly 2 @@ -36185,7 +36185,7 @@ progolfa // (c) 1981 @source:sequential/prophet600.cpp prpht600 // 1983 Sequential Circuits -@source:poly/proteus.cpp +@source:ausnz/proteus.cpp proteus // Poly Proteus @source:skeleton/proteus3.cpp @@ -36312,7 +36312,7 @@ puckpkmn // (c) 2000 Genie puckpkmna // (c) 2000 IBS puckpkmnb // (c) 2000 IBS -@source:skeleton/pulsar.cpp +@source:ausnz/pulsar.cpp pulsarlb // @source:nintendo/punchout.cpp @@ -40416,7 +40416,7 @@ supduck // (c) Comad @source:adc/super6.cpp super6 // -@source:dicksmith/super80.cpp +@source:ausnz/super80.cpp super80 // super80d // super80e // @@ -41319,7 +41319,7 @@ tdv2324 // @source:misc/teamjocs.cpp diaelite // -@source:trainer/tec1.cpp +@source:ausnz/tec1.cpp tec1 // Talking Electronics Computer tecjmon // Talking Electronics Computer diff --git a/src/mame/mess.flt b/src/mame/mess.flt index 4103d5a761e..8b20aebfe1c 100644 --- a/src/mame/mess.flt +++ b/src/mame/mess.flt @@ -60,7 +60,6 @@ appliedconcepts/boris.cpp appliedconcepts/borisdpl.cpp appliedconcepts/ggm.cpp appliedconcepts/prodigy.cpp -appliedtech/mbee.cpp arcadia/arcadia.cpp atari/a2600.cpp atari/a7800.cpp @@ -74,6 +73,26 @@ att/att4425.cpp att/att610.cpp att/att630.cpp att/unixpc.cpp +ausnz/amust.cpp +ausnz/applix.cpp +ausnz/aussiebyte.cpp +ausnz/binbug.cpp +ausnz/d6800.cpp +ausnz/datum.cpp +ausnz/dg680.cpp +ausnz/dmax8000.cpp +ausnz/eacc.cpp +ausnz/eti660.cpp +ausnz/excali64.cpp +ausnz/labtam.cpp +ausnz/magnum.cpp +ausnz/mbee.cpp +ausnz/pipbug.cpp +ausnz/poly.cpp +ausnz/proteus.cpp +ausnz/pulsar.cpp +ausnz/super80.cpp +ausnz/tec1.cpp aviion/aviion88k.cpp banctec/banctec.cpp bandai/design_master.cpp @@ -115,9 +134,9 @@ ceres/ceres.cpp chess/ave_arb.cpp chess/cking_master.cpp chess/compuchess.cpp +chess/conchess.cpp chess/conic_cchess2.cpp chess/conic_cchess3.cpp -chess/conchess.cpp chess/regence.cpp chess/tasc.cpp chromatics/cgc7900.cpp @@ -191,12 +210,10 @@ dec/vt320.cpp dec/vt52.cpp dec/vt520.cpp dec/vt62.cpp -dicksmith/super80.cpp dms/dms5000.cpp dms/dms86.cpp dms/zsbc3.cpp drc/zrt80.cpp -dulmont/magnum.cpp eaca/cgenie.cpp elektor/avrmax.cpp elektor/ec65.cpp @@ -343,6 +360,7 @@ homebrew/z80dev.cpp homebrew/zexall.cpp homelab/braiplus.cpp homelab/homelab.cpp +hp/hp_ipc.cpp hp/hp16500.cpp hp/hp2100.cpp hp/hp2620.cpp @@ -357,7 +375,6 @@ hp/hp9825.cpp hp/hp9845.cpp hp/hp9k.cpp hp/hp9k_3xx.cpp -hp/hp_ipc.cpp hp/jornada.cpp husky/hawk.cpp husky/hunter16.cpp @@ -409,7 +426,6 @@ korg/polysix.cpp kurzweil/krz2000.cpp kyber/kminus.cpp kyocera/kyocera.cpp -labtam/labtam.cpp leapfrog/leapfrog_iquest.cpp leapfrog/leapfrog_leappad.cpp leapfrog/leapfrog_leapster_explorer.cpp @@ -523,8 +539,8 @@ nintendo/nes_vt369_vtunknown.cpp nintendo/pokemini.cpp nintendo/snes.cpp nintendo/vboy.cpp -nintendo/vt1682.cpp nintendo/vt_unknown.cpp +nintendo/vt1682.cpp nokia/dbox.cpp nokia/mikromik.cpp nokia/nokia_3310.cpp @@ -582,8 +598,6 @@ philips/p2000t.cpp philips/vg5k.cpp philips/yes.cpp pitronics/beta.cpp -poly/poly.cpp -poly/proteus.cpp poly88/poly88.cpp positron/positron.cpp psion/psion.cpp @@ -669,18 +683,18 @@ sanyo/mbc200.cpp sanyo/mbc55x.cpp sanyo/phc25.cpp saturn/st17xx.cpp -sega/saturn.cpp -sega/sms.cpp sega/dccons.cpp sega/mdconsole.cpp sega/megadriv_rad.cpp sega/megadriv_sunplus_hybrid.cpp sega/megadriv_vt_hybrid.cpp +sega/saturn.cpp sega/sega_beena.cpp sega/sega_sawatte.cpp sega/segapico.cpp sega/segapm.cpp sega/sg1000.cpp +sega/sms.cpp sega/svmu.cpp sequential/prophet600.cpp sfrj/galaxy.cpp @@ -694,8 +708,8 @@ sgi/4dpi.cpp sgi/crimson.cpp sgi/indigo.cpp sgi/indy_indigo2.cpp -sgi/iris3130.cpp sgi/iris_power.cpp +sgi/iris3130.cpp sgi/o2.cpp sgi/octane.cpp sharp/fontwriter.cpp @@ -744,16 +758,12 @@ skeleton/am1000.cpp skeleton/ampex.cpp skeleton/ampex210.cpp skeleton/ampscarp.cpp -skeleton/amust.cpp skeleton/anzterm.cpp -skeleton/applix.cpp skeleton/argox.cpp skeleton/attache.cpp -skeleton/aussiebyte.cpp skeleton/ax20.cpp skeleton/basf7100.cpp skeleton/bert.cpp -skeleton/binbug.cpp skeleton/bitgraph.cpp skeleton/blit.cpp skeleton/blw700i.cpp @@ -780,11 +790,9 @@ skeleton/cp1.cpp skeleton/ct909e_segadvd.cpp skeleton/cxhumax.cpp skeleton/d400.cpp -skeleton/d6800.cpp skeleton/daruma.cpp skeleton/datacast.cpp skeleton/design.cpp -skeleton/dg680.cpp skeleton/diablo1300.cpp skeleton/didact.cpp skeleton/digel804.cpp @@ -793,21 +801,17 @@ skeleton/digilog320.cpp skeleton/digilog400.cpp skeleton/dim68k.cpp skeleton/dm7000.cpp -skeleton/dmax8000.cpp skeleton/dmv.cpp skeleton/dps1.cpp skeleton/dsb46.cpp skeleton/dual68.cpp skeleton/e100.cpp -skeleton/eacc.cpp skeleton/easy_karaoke.cpp skeleton/elzet80.cpp skeleton/epic14e.cpp skeleton/esprit.cpp -skeleton/eti660.cpp skeleton/eurit.cpp skeleton/eurocom2.cpp -skeleton/excali64.cpp skeleton/facit4440.cpp skeleton/fanucs15.cpp skeleton/fanucspmg.cpp @@ -900,7 +904,6 @@ skeleton/perq.cpp skeleton/pes.cpp skeleton/philipsbo.cpp skeleton/picno.cpp -skeleton/pipbug.cpp skeleton/plan80.cpp skeleton/pm68k.cpp skeleton/pockchal.cpp @@ -908,7 +911,6 @@ skeleton/powerstack.cpp skeleton/proteus3.cpp skeleton/pt68k4.cpp skeleton/ptcsol.cpp -skeleton/pulsar.cpp skeleton/pv9234.cpp skeleton/pwp14.cpp skeleton/qtsbc.cpp @@ -1047,12 +1049,12 @@ ti/ti74.cpp ti/ti85.cpp ti/ti89.cpp ti/ti931.cpp -ti/ti990_10.cpp -ti/ti990_4.cpp ti/ti99_2.cpp ti/ti99_4p.cpp ti/ti99_4x.cpp ti/ti99_8.cpp +ti/ti990_10.cpp +ti/ti990_4.cpp ti/tm990189.cpp tiger/gamecom.cpp tiger/k28.cpp @@ -1068,7 +1070,6 @@ trainer/babbage.cpp trainer/bob85.cpp trainer/crei680.cpp trainer/cvicny.cpp -trainer/datum.cpp trainer/dolphunk.cpp trainer/emma2.cpp trainer/instruct.cpp @@ -1076,7 +1077,6 @@ trainer/mk14.cpp trainer/pro80.cpp trainer/savia84.cpp trainer/selz80.cpp -trainer/tec1.cpp trainer/tk80.cpp trainer/zapcomputer.cpp trs/coco12.cpp @@ -1097,6 +1097,7 @@ tvgames/actions_atj2279b.cpp tvgames/elan_ep3a19a.cpp tvgames/elan_eu3a05.cpp tvgames/elan_eu3a14.cpp +tvgames/generalplus_gpl_unknown.cpp tvgames/generalplus_gpl16250_mobigo.cpp tvgames/generalplus_gpl16250_nand.cpp tvgames/generalplus_gpl16250_rom.cpp @@ -1105,7 +1106,6 @@ tvgames/generalplus_gpl16250_spi.cpp tvgames/generalplus_gpl16250_spi_direct.cpp tvgames/generalplus_gpl162xx_lcdtype.cpp tvgames/generalplus_gpl32612.cpp -tvgames/generalplus_gpl_unknown.cpp tvgames/magiceyes_pollux_vr3520f.cpp tvgames/monkey_king_3b.cpp tvgames/pubint_storyreader.cpp @@ -1141,9 +1141,9 @@ tvgames/titan_soc.cpp tvgames/trkfldch.cpp tvgames/tvgame.cpp tvgames/xavix.cpp -tvgames/xavix2.cpp tvgames/xavix_2000.cpp tvgames/xavix_2002.cpp +tvgames/xavix2.cpp ultimachine/rambo.cpp ultratec/minicom.cpp unicard/bbcbc.cpp @@ -1217,10 +1217,10 @@ vtech/socrates.cpp vtech/storio.cpp vtech/vsmile.cpp vtech/vsmileb.cpp -vtech/vtech1.cpp -vtech/vtech2.cpp vtech/vtech_eu3a12.cpp vtech/vtech_innotab.cpp +vtech/vtech1.cpp +vtech/vtech2.cpp wang/wangpc.cpp wavemate/bullet.cpp wavemate/jupiter.cpp diff --git a/src/mame/poly/poly.cpp b/src/mame/poly/poly.cpp deleted file mode 100644 index e91b9869d1a..00000000000 --- a/src/mame/poly/poly.cpp +++ /dev/null @@ -1,449 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Robbbert,Nigel Barnes -// thanks-to:Andrew Trotman -/*************************************************************************** - - Poly 1/2 (New Zealand) - - 10/07/2011 Skeleton driver. - - http://www.cs.otago.ac.nz/homepages/andrew/poly/Poly.htm - - Andrew has supplied the roms for -bios 1 - - It uses a 6809 for all main functions. There is a Z80 for CP/M, but all - of the roms are 6809 code. - - The keyboard controller is one of those custom XR devices. - Will use the terminal keyboard instead. - - With bios 1, after entering your userid and password, you get a black - screen. This is normal, because it joins to a network which isn't there. - - TODO: - - Connect up the device ports & lines - - Find out about graphics mode and how it is selected - - Fix Keyboard with KR2376-12 encoder - - Poly 2 and Poly 1 (early) probably require a different keyboard matrix - - Find out how to make 2nd teletext screen to display - - Improve MC6854 emulation for network - -****************************************************************************/ - -#include "emu.h" -#include "poly.h" -#include "formats/flex_dsk.h" -#include "softlist_dev.h" - - -void poly_state::poly_bank(address_map &map) -{ - map.unmap_value_high(); - /* System mode */ - map(0x00000, 0x0ffff).rw(FUNC(poly_state::logical_mem_r), FUNC(poly_state::logical_mem_w)); // Logical Memory - map(0x0e000, 0x0e003).rw(m_pia[0], FUNC(pia6821_device::read), FUNC(pia6821_device::write)); // Video control PIA 6821 - map(0x0e004, 0x0e005).rw(m_acia, FUNC(acia6850_device::read), FUNC(acia6850_device::write)); // Optional RS232 Interface - map(0x0e006, 0x0e006).w(FUNC(poly_state::baud_rate_w)); // Baud rate controller - map(0x0e00c, 0x0e00f).rw(m_pia[1], FUNC(pia6821_device::read), FUNC(pia6821_device::write)); // Keyboard PIA 6821 - map(0x0e020, 0x0e027).rw(m_ptm, FUNC(ptm6840_device::read), FUNC(ptm6840_device::write)); // Timer 6840 - map(0x0e030, 0x0e036).rw(FUNC(poly_state::network_r), FUNC(poly_state::network_w)); // Data Link Controller 6854 - map(0x0e040, 0x0e040).w(FUNC(poly_state::set_protect_w)); // Set protect flip-flop after 1 E-cycle - map(0x0e050, 0x0e05f).ram().share("dat"); // Dynamic Address Translator - map(0x0e060, 0x0e060).rw(FUNC(poly_state::select_map_r), FUNC(poly_state::select_map1_w)); // Select Map 1 - map(0x0e070, 0x0e070).rw(FUNC(poly_state::select_map_r), FUNC(poly_state::select_map2_w)); // Select Map 2 - map(0x0e800, 0x0efff).ram().share("videoram"); // Teletext screens and System data - map(0x0f000, 0x0ffff).rom().region("system", 0); // System Program ROM - /* User mode */ - map(0x10000, 0x1ffff).rw(FUNC(poly_state::logical_mem_r), FUNC(poly_state::logical_mem_w)); // Logical Memory - map(0x1fff0, 0x1ffff).r(FUNC(poly_state::vector_r)); // Vector fetch (interrupt and reset) -} - -void polydev_state::poly_bank(address_map &map) -{ - poly_state::poly_bank(map); - map(0x0e014, 0x0e014).rw(FUNC(polydev_state::drive_register_r), FUNC(polydev_state::drive_register_w)); // Drive register - map(0x0e018, 0x0e01b).rw(FUNC(polydev_state::fdc_inv_r), FUNC(polydev_state::fdc_inv_w)); // Floppy controller -} - -void poly_state::poly_mem(address_map &map) -{ - map(0x0000, 0xffff).m(m_bankdev, FUNC(address_map_bank_device::amap8)); -} - - -static INPUT_PORTS_START( poly1 ) - PORT_START("MODIFIERS") - PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Ctrl") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) - PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) - PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Caps Lock") PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) - - PORT_START("X0") - PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_UNUSED) - PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_UNUSED) - PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("Keypad 1 Red") - PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_UNUSED) - PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("Keypad 0") - PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_HOME) PORT_NAME("Help Calc") - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_UNUSED) - PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL_PAD) PORT_NAME("Keypad .") - PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_UNUSED) - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_UNUSED) - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_UNUSED) - - PORT_START("X1") - PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("Keypad 3 Yellow") - PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_UNUSED) - PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("Keypad 4 Blue") - PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_UNUSED) - PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("Keypad 2 Green") - PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_UNUSED) - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_INSERT) PORT_NAME("Ins Char Line") - PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_PGDN) PORT_NAME("Repeat Next") - PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_UNUSED) - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_UNUSED) - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_UNUSED) - - PORT_START("X2") - PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("Keypad 6 Cyan") - PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_UNUSED) - PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("Keypad 7 White") - PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_UNUSED) - PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("Keypad 5 Magenta") - PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_UNUSED) - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL) PORT_NAME("Del Char Line") - PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_PGUP) PORT_NAME("Back Exit") - PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_UNUSED) - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_UNUSED) - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_UNUSED) - - PORT_START("X3") - PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("Keypad 9") - PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') - PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) - PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_UNUSED) - PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("Keypad 8 Flash") - PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('@') PORT_CHAR(0xa3) - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_END) PORT_NAME("Pause") - PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_NAME(UTF8_UP) - PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_NAME(UTF8_RIGHT) - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_NAME(UTF8_DOWN) - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_NAME(UTF8_LEFT) - - PORT_START("X4") - PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') - PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') - PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') - PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') - PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') - PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') - PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') - PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_UNUSED) - - PORT_START("X5") - PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') - PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') - PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') - PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') - PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') - PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') - PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') - PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('+') - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(':') PORT_CHAR('*') - - PORT_START("X6") - PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') - PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') - PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') - PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') - PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') - PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') - PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') - PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_NAME("EXP \xE2\x80\x96") - - PORT_START("X7") - PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') - PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"') - PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') - PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') - PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') - PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'') - PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') - PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('=') -INPUT_PORTS_END - -static INPUT_PORTS_START( poly1e ) - PORT_INCLUDE(poly1) - // TODO: unknown matrix, contains extra user definable keys -INPUT_PORTS_END - -static INPUT_PORTS_START( poly2 ) - PORT_INCLUDE(poly1) - // TODO: unknown matrix, seems to differ from poly1 -INPUT_PORTS_END - - -void poly_state::machine_start() -{ - m_dat_bank = 0; - m_protect_timer = timer_alloc(FUNC(poly_state::set_protect), this); -} - - -void poly_state::machine_reset() -{ - m_protect_timer->adjust(attotime::never); - - //m_kr2376->set_input_pin(kr2376_device::KR2376_DSII, 0); - //m_kr2376->set_input_pin(kr2376_device::KR2376_PII, 0); - - /* system mode is entered on Reset */ - m_bankdev->set_bank(0); -} - - -void poly_state::init_poly() -{ - uint8_t bitswapped[0x4000]; - uint8_t *rom; - - /* basic rom region */ - rom = m_user->base() + 0xc000; - - /* decrypt rom data lines */ - for (int i = 0x0000; i<0x4000; i++) - bitswapped[i] = bitswap<8>(rom[i], 3, 4, 2, 5, 1, 6, 0, 7); - - /* decrypt rom address lines */ - for (int i = 0x0000; i<0x4000; i++) - rom[i] = bitswapped[bitswap<16>(i, 15, 14, 13, 12, 10, 8, 4, 2, 0, 1, 3, 5, 6, 7, 9, 11)]; - - /* system rom region */ - rom = m_system->base(); - - /* decrypt rom data lines */ - for (int i = 0x0000; i<0x1000; i++) - bitswapped[i] = bitswap<8>(rom[i], 3, 4, 2, 5, 1, 6, 0, 7); - - /* decrypt rom address lines */ - for (int i = 0x0000; i<0x1000; i++) - rom[i] = bitswapped[bitswap<16>(i, 15, 14, 13, 12, 10, 8, 4, 2, 0, 1, 3, 5, 6, 7, 9, 11)]; -} - - -void polydev_state::floppy_formats(format_registration &fr) -{ - fr.add_fm_containers(); - fr.add(FLOPPY_FLEX_FORMAT); -} - -static void poly_floppies(device_slot_interface &device) -{ - device.option_add("8dssd", FLOPPY_8_DSSD); - device.option_add("525sd", FLOPPY_525_SD); -} - - -void poly_state::poly(machine_config &config) -{ - /* basic machine hardware */ - MC6809(config, m_maincpu, 12.0576_MHz_XTAL / 3); - m_maincpu->set_addrmap(AS_PROGRAM, &poly_state::poly_mem); - - ADDRESS_MAP_BANK(config, "bankdev").set_map(&poly_state::poly_bank).set_options(ENDIANNESS_LITTLE, 8, 17, 0x10000); - - INPUT_MERGER_ANY_HIGH(config, "irqs").output_handler().set_inputline(m_maincpu, M6809_IRQ_LINE); - - /* video hardware */ - screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_refresh_hz(50); - screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); - screen.set_size(40 * 12, 24 * 20); - screen.set_visarea(0, 40 * 12 - 1, 0, 24 * 20 - 1); - screen.set_screen_update(FUNC(poly_state::screen_update)); - - SAA5050(config, m_trom[0], 12.0576_MHz_XTAL / 2); - m_trom[0]->d_cb().set(FUNC(poly_state::videoram_1_r)); - m_trom[0]->set_screen_size(40, 24, 40); - - SAA5050(config, m_trom[1], 12.0576_MHz_XTAL / 2); - m_trom[1]->d_cb().set(FUNC(poly_state::videoram_2_r)); - m_trom[1]->set_screen_size(40, 24, 40); - - /* sound hardware */ - SPEAKER(config, "mono").front_center(); - SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.50); - - /* internal ram */ - RAM(config, m_ram).set_default_size("128K").set_extra_options("64K"); - - /* network */ - MC6854(config, m_adlc); - //m_adlc->out_txd_cb().set(NETWORK_TAG, FUNC(poly_network_device::data_w)); - //m_adlc->out_irq_cb().set("irqs", FUNC(input_merger_device::in_w<0>)); - - //MCFG_POLY_NETWORK_ADD() - //MCFG_POLY_NETWORK_CLK_CB(WRITELINE(*this, poly_state, network_clk_w)) - //MCFG_POLY_NETWORK_DATA_CB(WRITELINE("mc6854", mc6854_device, set_rx)) - //MCFG_POLY_NETWORK_SLOT_ADD("netup", poly_network_devices, "proteus") - //MCFG_POLY_NETWORK_SLOT_ADD("netdown", poly_network_devices, nullptr) - - /* timer */ - PTM6840(config, m_ptm, 12.0576_MHz_XTAL / 3); - m_ptm->set_external_clocks(0, 0, 0); - m_ptm->o2_callback().set(FUNC(poly_state::ptm_o2_callback)); - m_ptm->o3_callback().set(FUNC(poly_state::ptm_o3_callback)); - //m_ptm->irq_callback().set("irqs", FUNC(input_merger_device::in_w<1>)); - - /* keyboard encoder */ - //KR2376_12(config, m_kr2376, 50000); - //m_kr2376->x<0>().set_ioport("X0"); - //m_kr2376->x<1>().set_ioport("X1"); - //m_kr2376->x<2>().set_ioport("X2"); - //m_kr2376->x<3>().set_ioport("X3"); - //m_kr2376->x<4>().set_ioport("X4"); - //m_kr2376->x<5>().set_ioport("X5"); - //m_kr2376->x<6>().set_ioport("X6"); - //m_kr2376->x<7>().set_ioport("X7"); - //m_kr2376->shift().set(FUNC(poly_state::kbd_shift_r)); - //m_kr2376->control().set(FUNC(poly_state::kbd_control_r)); - //m_kr2376->strobe().set("pia1", FUNC(pia6821_device::cb1_w)); - - /* generic keyboard until ROM in KR2376-12 is known */ - generic_keyboard_device &keyboard(GENERIC_KEYBOARD(config, "keyboard", 0)); - keyboard.set_keyboard_callback(FUNC(poly_state::kbd_put)); - - /* video control */ - PIA6821(config, m_pia[0], 0); - m_pia[0]->writepa_handler().set(FUNC(poly_state::pia0_pa_w)); - m_pia[0]->writepb_handler().set(FUNC(poly_state::pia0_pb_w)); - m_pia[0]->irqa_handler().set("irqs", FUNC(input_merger_device::in_w<2>)); - m_pia[0]->irqb_handler().set("irqs", FUNC(input_merger_device::in_w<3>)); - - /* keyboard PIA */ - PIA6821(config, m_pia[1], 0); - m_pia[1]->readpb_handler().set(FUNC(poly_state::pia1_b_in)); - m_pia[1]->irqa_handler().set("irqs", FUNC(input_merger_device::in_w<4>)); - m_pia[1]->irqb_handler().set("irqs", FUNC(input_merger_device::in_w<5>)); - - /* optional rs232 interface */ - ACIA6850(config, m_acia, 0); - //m_acia->txd_handler().set("rs232", FUNC(rs232_port_device::write_txd)); - //m_acia->rts_handler().set("rs232", FUNC(rs232_port_device::write_rts)); - m_acia->irq_handler().set("irqs", FUNC(input_merger_device::in_w<6>)); - - CLOCK(config, m_acia_clock, 153600); - m_acia_clock->signal_handler().set(m_acia, FUNC(acia6850_device::write_txc)); - m_acia_clock->signal_handler().append(m_acia, FUNC(acia6850_device::write_rxc)); - - /* software lists */ - SOFTWARE_LIST(config, "flop_list").set_original("poly_flop").set_filter("POLY1"); -} - - -void poly_state::poly2(machine_config &config) -{ - poly(config); - - /* internal ram */ - m_ram->set_default_size("128K"); - - /* software lists */ - subdevice("flop_list")->set_filter("POLY2"); -} - - -void polydev_state::polydev(machine_config &config) -{ - poly(config); - - /* fdc */ - FD1771(config, m_fdc, 12.0_MHz_XTAL / 12); - m_fdc->hld_wr_callback().set(FUNC(polydev_state::motor_w)); - m_fdc->set_force_ready(true); - - FLOPPY_CONNECTOR(config, "fdc:0", poly_floppies, "525sd", polydev_state::floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "fdc:1", poly_floppies, nullptr, polydev_state::floppy_formats).enable_sound(true); - - /* remove devices*/ - //config.device_remove("netup"); - //config.device_remove("netdown"); -} - - -/* ROM definition */ -ROM_START( poly1 ) - ROM_REGION( 0x20000, "user", 0 ) - ROM_SYSTEM_BIOS(0, "bas34", "PolyBASIC 3.4") - ROMX_LOAD( "bas1.u92", 0xc000, 0x1000, CRC(04d96d81) SHA1(8d2d0980afb8c447cf235325e4dc15ed2a200f16), ROM_BIOS(0) ) - ROMX_LOAD( "bas2.u91", 0xd000, 0x1000, CRC(3e12f823) SHA1(0b37f2dfa241fac1bf06ca93b19e44a660c7758e), ROM_BIOS(0) ) - ROMX_LOAD( "bas3.u90", 0xe000, 0x1000, CRC(22759a84) SHA1(d22edea312567596b4ef92290ffe52a25de01487), ROM_BIOS(0) ) - ROMX_LOAD( "bas4.u89", 0xf000, 0x1000, CRC(30650d92) SHA1(4e41ea2ec127b9ed277f5a62d52cb3432d64aa84), ROM_BIOS(0) ) - - ROM_REGION( 0x1000, "system", 0 ) - ROMX_LOAD( "bios.u86", 0x0000, 0x1000, CRC(fc97cc6a) SHA1(103dce01a86a47e7e235c9d2f820fa1501ab9800), ROM_BIOS(0) ) -ROM_END - -ROM_START( poly1e ) - ROM_REGION( 0x20000, "user", 0 ) - ROM_SYSTEM_BIOS(0, "bas23", "PolyBASIC 2.3") - ROMX_LOAD( "v3bas1.u92", 0xc000, 0x1000, CRC(ee25fe89) SHA1(af1a73434c9f5524c5a1a5e19d06500ad1b643d1), ROM_BIOS(0) ) - ROMX_LOAD( "v3bas2.u91", 0xd000, 0x1000, CRC(6ca4a8b5) SHA1(54e71e34b55a5ee41a9e0da05d9c9cbcb2fb80c2), ROM_BIOS(0) ) - ROMX_LOAD( "v3bas3.u90", 0xe000, 0x1000, CRC(6021fc00) SHA1(214aab19e096ddfd417993d48c11f81ec139fef3), ROM_BIOS(0) ) - ROMX_LOAD( "v3bas4.u89", 0xf000, 0x1000, CRC(df071e52) SHA1(41482517a5dfc64f3728732b3907cee636674de4), ROM_BIOS(0) ) - - ROM_REGION( 0x1000, "system", 0 ) - ROMX_LOAD( "plrt16v3e9.u86", 0x0000, 0x1000, CRC(f7e3aa86) SHA1(b642c281e54ad9698cfaec19508ae8b4df50c296), ROM_BIOS(0) ) -ROM_END - -ROM_START( poly2 ) - ROM_DEFAULT_BIOS("bas31") - ROM_SYSTEM_BIOS(0, "bas31", "PolyBASIC 3.1") - ROM_SYSTEM_BIOS(1, "bas30", "PolyBASIC 3.0") - - ROM_REGION( 0x20000, "user", 0 ) - ROMX_LOAD( "bas1.u92", 0xc000, 0x1000, CRC(340b7d75) SHA1(330d31b5c90c82c08c62e2df40669ca62c8fffed), ROM_BIOS(0) ) - ROMX_LOAD( "bas2.u91", 0xd000, 0x1000, CRC(45152d26) SHA1(7da2663f253031a587705b9db9a18e93ba4db2cf), ROM_BIOS(0) ) - ROMX_LOAD( "bas3.u90", 0xe000, 0x1000, CRC(a6f70e62) SHA1(7912a9da29d682bb5922f3adf6136b4efc0494dc), ROM_BIOS(0) ) - ROMX_LOAD( "bas4.u89", 0xf000, 0x1000, CRC(72d21cea) SHA1(d413490d043845ce4a9cf5cc70bd92ddc931c837), ROM_BIOS(0) ) - - ROMX_LOAD( "bas1-12-12-84.u92", 0xc000, 0x1000, CRC(a3791342) SHA1(e801db28419eedf6eebdbb5a7eb551ba36c43cd6), ROM_BIOS(1) ) - ROMX_LOAD( "bas2-12-12-84.u91", 0xd000, 0x1000, CRC(3bb5849e) SHA1(71c47a0d3dba096a6a79300edf56ffedce276ac6), ROM_BIOS(1) ) - ROMX_LOAD( "bas3-12-12-84.u90", 0xe000, 0x1000, CRC(a6f70e62) SHA1(7912a9da29d682bb5922f3adf6136b4efc0494dc), ROM_BIOS(1) ) - ROMX_LOAD( "bas4-12-12-84.u89", 0xf000, 0x1000, CRC(8f736cee) SHA1(3ec5cc49a426fc921bbadb2bcc1b86b4768627fa), ROM_BIOS(1) ) - - - ROM_REGION( 0x1000, "system", 0 ) - ROMX_LOAD( "sys31.u86", 0x0000, 0x1000, CRC(fb54c36e) SHA1(934f84a7a99a76b0a017379a6ecd8a8e444cd085), ROM_BIOS(0) ) - ROMX_LOAD( "plrt17-5-11-84.u86", 0x0000, 0x1000, CRC(896165dd) SHA1(005584310f1c689a9b1bb549989c5fedabead6c4), ROM_BIOS(1) ) -ROM_END - -ROM_START( polydev ) - ROM_REGION( 0x20000, "user", 0 ) - ROM_SYSTEM_BIOS(0, "bas34", "PolyBASIC 3.4") - ROMX_LOAD( "v2bas1.bin", 0xc000, 0x1000, CRC(04d96d81) SHA1(8d2d0980afb8c447cf235325e4dc15ed2a200f16), ROM_BIOS(0) ) - ROMX_LOAD( "v2bas2.bin", 0xd000, 0x1000, CRC(3e12f823) SHA1(0b37f2dfa241fac1bf06ca93b19e44a660c7758e), ROM_BIOS(0) ) - ROMX_LOAD( "v2bas3.bin", 0xe000, 0x1000, CRC(22759a84) SHA1(d22edea312567596b4ef92290ffe52a25de01487), ROM_BIOS(0) ) - ROMX_LOAD( "v2bas4.bin", 0xf000, 0x1000, CRC(30650d92) SHA1(4e41ea2ec127b9ed277f5a62d52cb3432d64aa84), ROM_BIOS(0) ) - - ROM_REGION( 0x1000, "system", 0 ) - ROMX_LOAD( "slrt15_00f9.bin", 0x0000, 0x1000, CRC(046a9aef) SHA1(c5c74b0f66e8969c12db03899244e18228be38eb), ROM_BIOS(0) ) -ROM_END - -/* Driver */ - -/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ -COMP( 1981, poly1, 0, 0, poly, poly1, poly_state, init_poly, "Polycorp", "Poly 1 Educational Computer", MACHINE_NOT_WORKING ) -COMP( 1981, poly1e, poly1, 0, poly, poly1e, poly_state, init_poly, "Polycorp", "Poly 1 Educational Computer (early)", MACHINE_NOT_WORKING ) -COMP( 1984, poly2, poly1, 0, poly2, poly2, poly_state, init_poly, "Polycorp", "Poly 2 Learning System", MACHINE_NOT_WORKING ) -COMP( 1983, polydev, poly1, 0, polydev, poly1, polydev_state, init_poly, "Polycorp", "Poly Development System", MACHINE_NOT_WORKING ) diff --git a/src/mame/poly/poly.h b/src/mame/poly/poly.h deleted file mode 100644 index a39c91ef979..00000000000 --- a/src/mame/poly/poly.h +++ /dev/null @@ -1,187 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Robbbert,Nigel Barnes -// thanks-to:Andrew Trotman -/*************************************************************************** - - Poly/Proteus (New Zealand) - - 10/07/2011 Skeleton driver. - - http://www.cs.otago.ac.nz/homepages/andrew/poly/Poly.htm - - Andrew has supplied the roms for -bios 1 - - It uses a 6809 for all main functions. There is a Z80 for CP/M, but all - of the roms are 6809 code. - - The keyboard controller is one of those custom XR devices. - Will use the terminal keyboard instead. - - With bios 1, after entering your userid and password, you get a black - screen. This is normal, because it joins to a network which isn't there. - - ToDo: - - Almost Everything! - - Connect up the device ports & lines - - Find out about graphics mode and how it is selected - - Fix Keyboard so that the Enter key tells BASIC to do something - - Find out how to make 2nd teletext screen to display - - Banking - -****************************************************************************/ - -#ifndef MAME_INCLUDES_POLY_H -#define MAME_INCLUDES_POLY_H - -#pragma once - -#include "cpu/m6809/m6809.h" -#include "imagedev/floppy.h" -#include "machine/6821pia.h" -#include "machine/6840ptm.h" -#include "machine/6850acia.h" -#include "machine/kr2376.h" -#include "machine/clock.h" -#include "machine/mc6854.h" -#include "machine/bankdev.h" -#include "machine/ram.h" -#include "machine/input_merger.h" -#include "machine/wd_fdc.h" -#include "machine/keyboard.h" -#include "sound/spkrdev.h" -#include "video/saa5050.h" -#include "screen.h" -#include "speaker.h" - -//#include "bus/poly/network.h" - - -class poly_state : public driver_device -{ -public: - poly_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_maincpu(*this, "maincpu") - , m_bankdev(*this, "bankdev") - , m_ram(*this, RAM_TAG) - , m_trom(*this, "saa5050_%u", 1U) - , m_pia(*this, "pia%u", 0U) - , m_adlc(*this, "mc6854") - , m_ptm(*this, "ptm") - , m_irqs(*this, "irqs") -// , m_kr2376(*this, "kr2376") - , m_kbd(*this, "X%u", 0U) - , m_modifiers(*this, "MODIFIERS") - , m_speaker(*this, "speaker") - , m_user(*this, "user") - , m_system(*this, "system") - , m_videoram(*this, "videoram") - , m_dat(*this, "dat") - , m_acia(*this, "acia") - , m_acia_clock(*this, "acia_clock") - , m_protect_timer(nullptr) - { - } - - static constexpr feature_type imperfect_features() { return feature::KEYBOARD; } - - void poly(machine_config &config); - void poly2(machine_config &config); - - void init_poly(); - - virtual void poly_bank(address_map &map); - -private: - virtual void machine_start() override; - virtual void machine_reset() override; - - void poly_mem(address_map &map); - - uint8_t logical_mem_r(offs_t offset); - void logical_mem_w(offs_t offset, uint8_t data); - uint8_t vector_r(offs_t offset); - void kbd_put(u8 data); // remove when KR2376 is implemented - DECLARE_READ_LINE_MEMBER( kbd_shift_r ); - DECLARE_READ_LINE_MEMBER( kbd_control_r ); - void pia0_pa_w(uint8_t data); - void pia0_pb_w(uint8_t data); - uint8_t pia1_b_in(); - uint8_t videoram_1_r(offs_t offset); - uint8_t videoram_2_r(offs_t offset); - DECLARE_WRITE_LINE_MEMBER( ptm_o2_callback ); - DECLARE_WRITE_LINE_MEMBER( ptm_o3_callback ); - void baud_rate_w(uint8_t data); - TIMER_CALLBACK_MEMBER( set_protect ); - void set_protect_w(uint8_t data); - uint8_t select_map_r(); - void select_map1_w(uint8_t data); - void select_map2_w(uint8_t data); - uint8_t network_r(offs_t offset); - void network_w(offs_t offset, uint8_t data); - DECLARE_WRITE_LINE_MEMBER( network_clk_w ); - - uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - - required_device m_maincpu; - required_device m_bankdev; - required_device m_ram; - required_device_array m_trom; - required_device_array m_pia; - required_device m_adlc; - required_device m_ptm; - required_device m_irqs; - //required_device m_kr2376; - required_ioport_array<8> m_kbd; - required_ioport m_modifiers; - required_device m_speaker; - required_memory_region m_user; - required_memory_region m_system; - required_shared_ptr m_videoram; - required_shared_ptr m_dat; - optional_device m_acia; - optional_device m_acia_clock; - uint8_t m_video_pa = 0U; - uint8_t m_video_pb = 0U; - uint8_t m_term_data = 0U; - emu_timer *m_protect_timer; - - inline offs_t physical(offs_t offset); - - int m_dat_bank = 0; -}; - - -class polydev_state : public poly_state -{ -public: - polydev_state(const machine_config &mconfig, device_type type, const char *tag) - : poly_state(mconfig, type, tag) - , m_fdc(*this, "fdc") - , m_floppy(*this, "fdc:%u", 0U) - , m_current_floppy(nullptr) - { - } - - static constexpr feature_type imperfect_features() { return feature::KEYBOARD; } - - void polydev(machine_config &config); - -private: - void drive_register_w(uint8_t data); - uint8_t drive_register_r(); - DECLARE_WRITE_LINE_MEMBER(motor_w); - uint8_t fdc_inv_r(offs_t offset); - void fdc_inv_w(offs_t offset, uint8_t data); - - - virtual void poly_bank(address_map &map) override; - - static void floppy_formats(format_registration &fr); - - required_device m_fdc; - required_device_array m_floppy; - floppy_image_device *m_current_floppy; -}; - -#endif // MAME_INCLUDES_POLY_H diff --git a/src/mame/poly/poly_m.cpp b/src/mame/poly/poly_m.cpp deleted file mode 100644 index 815b6b758b5..00000000000 --- a/src/mame/poly/poly_m.cpp +++ /dev/null @@ -1,259 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Robbbert,Nigel Barnes -// thanks-to:Andrew Trotman -/*************************************************************************** - - Poly 1/2 (New Zealand) - -****************************************************************************/ - -#include "emu.h" -#include "poly.h" - - -inline offs_t poly_state::physical(offs_t offset) -{ - return (((~m_dat[(m_dat_bank << 3) | (offset >> 13)]) & 0x0f) << 13) | (offset & 0x1fff); -} - -uint8_t poly_state::logical_mem_r(offs_t offset) -{ - return m_user->base()[physical(offset)]; -} - -void poly_state::logical_mem_w(offs_t offset, uint8_t data) -{ - m_user->base()[physical(offset)] = data; -} - - -uint8_t poly_state::vector_r(offs_t offset) -{ - /* system mode is selected by a vector fetch (interrupt and reset) */ - m_bankdev->set_bank(0); - - return m_system->base()[0x0ff0 + offset]; -} - - -TIMER_CALLBACK_MEMBER(poly_state::set_protect) -{ - m_bankdev->set_bank(1); -} - -void poly_state::set_protect_w(uint8_t data) -{ - /* set protect after 1 E cycle */ - m_protect_timer->adjust(m_maincpu->cycles_to_attotime(2)); -} - - -uint8_t poly_state::select_map_r() -{ - return 0x00; -} - -void poly_state::select_map1_w(uint8_t data) -{ - m_dat_bank = 0; -} - -void poly_state::select_map2_w(uint8_t data) -{ - m_dat_bank = 1; -} - - -void poly_state::pia0_pa_w(uint8_t data) -{ - logerror("PIA0: Port A out: %02X\n", data); - m_video_pa = data; - m_ptm->set_g3(BIT(data, 7)); -} - -void poly_state::pia0_pb_w(uint8_t data) -{ - logerror("PIA0: Port B out: %02X\n", data); - m_video_pb = data; -} - - -uint8_t poly_state::pia1_b_in() -{ - // B1 - D0 - // B2 - D1 - // B3 - D2 - // B4 - D3 - // B5 - D4 - // B6 - // B7 - // B8 - D6 - // STROBE - D7 - - /* return key code */ - //data = m_kr2376->data_r(space, 0) & 0x7f; - /* bit 5 is derived from data bits 5,6 and caps lock */ - //data |= !(!(BIT(m_kr2376->data_r(space, 0), 6) && !caps_lock) && !(caps_lock && BIT(m_kr2376->data_r(space, 0), 5))) << 5; - /* bit 6 is data bit 7 */ - //data |= BIT(m_kr2376->data_r(space, 0), 7) << 6; - /* caps lock needs verifying */ - //data |= ((caps_lock && BIT(m_kr2376->data_r(space, 0), 6)) ? 0 : BIT(m_kr2376->data_r(space, 0), 5)) << 5; - /* bit 7 is the strobe value */ - //data |= m_kr2376->get_output_pin(kr2376_device::KR2376_SO) << 7; - - // return ascii key value, bit 7 is the strobe value - uint8_t data = m_term_data; - m_term_data &= 0x7f; - return data; -} - - -uint8_t poly_state::videoram_1_r(offs_t offset) -{ - return m_videoram[offset]; -} - -uint8_t poly_state::videoram_2_r(offs_t offset) -{ - return m_videoram[offset + 0x400]; -} - - -void poly_state::kbd_put(u8 data) -{ - m_term_data = data | 0x80; - - m_pia[1]->cb1_w(1); - m_pia[1]->cb1_w(0); -} - -READ_LINE_MEMBER(poly_state::kbd_shift_r) -{ - return BIT(m_modifiers->read(), 1); -} - -READ_LINE_MEMBER(poly_state::kbd_control_r) -{ - return BIT(m_modifiers->read(), 0); -} - - -WRITE_LINE_MEMBER(poly_state::ptm_o2_callback) -{ - m_ptm->set_c1(state); -} - -WRITE_LINE_MEMBER(poly_state::ptm_o3_callback) -{ - m_speaker->level_w(state); -} - -void poly_state::baud_rate_w (uint8_t data) -{ - /* baud rate controller (0=9600,2=4800,4=2400,6=1200,8=600,A=300) */ - int selector = (data & 0x0e) >> 1; - m_acia_clock->set_clock_scale((selector <= 5) ? 1.0 / (1 << selector) : 0.0); -} - -uint8_t poly_state::network_r(offs_t offset) -{ - return m_adlc->read(offset >> 1); -} - -void poly_state::network_w(offs_t offset, uint8_t data) -{ - m_adlc->write(offset >> 1, data); -} - -WRITE_LINE_MEMBER(poly_state::network_clk_w) -{ - m_adlc->rxc_w(state); - m_adlc->txc_w(state); -} - - -void polydev_state::drive_register_w(uint8_t data) -{ - /* drive select */ - switch (data & 0x03) - { - case 0: - m_current_floppy = m_floppy[0]->get_device(); - break; - - case 1: - m_current_floppy = m_floppy[1]->get_device(); - break; - - default: - m_current_floppy = nullptr; - break; - } - m_fdc->set_floppy(m_current_floppy); - - if (m_current_floppy) - { - /* side select */ - m_current_floppy->ss_w(BIT(data, 6)); - } -} - -uint8_t polydev_state::drive_register_r() -{ - /* disk change */ - return (m_current_floppy ? m_current_floppy->dskchg_r() : 1) << 1; -} - -WRITE_LINE_MEMBER(polydev_state::motor_w) -{ - if (m_current_floppy) m_current_floppy->mon_w(!state); -} - -uint8_t polydev_state::fdc_inv_r(offs_t offset) -{ - return m_fdc->read(offset) ^ 0xff; -} - -void polydev_state::fdc_inv_w(offs_t offset, uint8_t data) -{ - m_fdc->write(offset, data ^ 0xff); -} - - -uint32_t poly_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - /* - PA0 Not used. Connected to CA2. - PA1 ( Mix colour 0) Blue 1) Green 0) Red 1) No - PA2 ( Graphics 1 0) 0) 1) 1) Mix - PA3 1 = Enable Teletext 1 screen - PA4 1 = 480 Graphics mode. 0 = 240 Graphics mode. - PA5 1 = Enable Graphics 1 screen or 480 Graphics screen. - PA6 1 = Mix Mode 0 = Priority mode - PA7 Must be 0. Connected to PA7 and timer G3. - - PB0 1 = Enable Teletext 2 screen. - PB1 1 = Enable Graphics 2 (must be 0 for 480 Graphics) - PB2 ( Mix colour 0) Blue 1) Green 0) Red 1) No - PB3 ( Graphics 2 0) 0) 1) 1) Mix - PB4 1 = Enable Red Background - PB5 1 = Enable Green Background - PB6 1 = Enable Blue Background - PB7 Not used. - - CA1 Connected to PA7 and timer G3. Must be 0. - CA2 Not used. Connected to PA0. - CB1 Not used. - CB2 Not used. - */ - - /* Enable Teletext 1 screen */ - if (BIT(m_video_pa, 3)) - m_trom[0]->screen_update(screen, bitmap, cliprect); - - /* Enable Teletext 2 screen */ - if (BIT(m_video_pb, 0)) - m_trom[1]->screen_update(screen, bitmap, cliprect); - - return 0; -} diff --git a/src/mame/poly/proteus.cpp b/src/mame/poly/proteus.cpp deleted file mode 100644 index cccc4cc2cac..00000000000 --- a/src/mame/poly/proteus.cpp +++ /dev/null @@ -1,433 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Nigel Barnes -// thanks-to:Andrew Trotman -/********************************************************************** - - Poly Proteus Computer - - http://www.cs.otago.ac.nz/homepages/andrew/poly/Poly.htm - - Specifications: - - Processors 6809,Z80 - - RAM 64 Kbytes - - ROM 4 Kbytes - - Clock Z80 4 MHz (1 wait state per machine cycle) - 6809 4 MHz clock, 1 MHz cycle - - Disk Drives One or two 8" half height drives (Shugart SA860) - Double sided single density - Capacity 630 Kbytes per disk (CP/M) - 590 Kbytes (Flex,Polysys) - Single sided can be used for compatibility - - Ports Standard One RS232 - One Poly network - Optional Total 3 RS232 - One Poly network - One parallel - One disk drive extension - - Operating systems - CP/M. The standard operating system for 8080/Z80 micros. - FLEX. The standard operating system for 6809 micros. - POLYSYS. The operating system for the POLY network. - -**********************************************************************/ - - -#include "emu.h" -#include "cpu/m6809/m6809.h" -#include "cpu/z80/z80.h" -#include "imagedev/floppy.h" -#include "machine/6821pia.h" -#include "machine/6840ptm.h" -#include "machine/6850acia.h" -#include "machine/mc6854.h" -#include "machine/ram.h" -#include "machine/input_merger.h" -#include "machine/clock.h" -#include "machine/wd_fdc.h" -#include "bus/rs232/rs232.h" -#include "bus/centronics/ctronics.h" -#include "formats/flex_dsk.h" -#include "formats/poly_dsk.h" -#include "softlist_dev.h" - - -class proteus_state : public driver_device -{ -public: - proteus_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_maincpu(*this, "maincpu") - , m_z80(*this, "z80") - , m_adlc(*this, "mc6854") - , m_ptm(*this, "ptm") - , m_irqs(*this, "irqs") - , m_pia(*this, "pia") - , m_acia(*this, "acia%u", 0) - , m_fdc(*this, "fdc") - , m_floppy0(*this, "fdc:0") - , m_floppy1(*this, "fdc:1") - , m_floppy(nullptr) - { } - - void proteus(machine_config &config); - -private: - virtual void machine_reset() override; - virtual void machine_start() override; - - DECLARE_WRITE_LINE_MEMBER(ptm_o2_callback); - DECLARE_WRITE_LINE_MEMBER(ptm_o3_callback); - uint8_t network_r(offs_t offset); - void network_w(offs_t offset, uint8_t data); - - uint8_t drive_register_r(); - void drive_register_w(uint8_t data); - DECLARE_WRITE_LINE_MEMBER(motor_w); - uint8_t fdc_inv_r(offs_t offset); - void fdc_inv_w(offs_t offset, uint8_t data); - static void floppy_formats(format_registration &fr); - - void enable_z80_w(uint8_t data); - void enable_6809_w(uint8_t data); - - void proteus_6809_mem(address_map &map); - void proteus_z80_mem(address_map &map); - void proteus_z80_io(address_map &map); - - required_device m_maincpu; - required_device m_z80; - required_device m_adlc; - required_device m_ptm; - required_device m_irqs; - required_device m_pia; - required_device_array m_acia; - required_device m_fdc; - required_device m_floppy0; - required_device m_floppy1; - floppy_image_device *m_floppy = nullptr; -}; - - -void proteus_state::machine_start() -{ - uint8_t bitswapped[0x1000]; - uint8_t *rom; - - /* bios rom region */ - rom = memregion("bios")->base(); - - /* decrypt rom data lines */ - for (int i = 0x0000; i<0x1000; i++) - bitswapped[i] = bitswap<8>(rom[i], 3, 4, 2, 5, 1, 6, 0, 7); - - /* decrypt rom address lines */ - for (int i = 0x0000; i<0x1000; i++) - rom[i] = bitswapped[bitswap<16>(i, 15, 14, 13, 12, 10, 8, 4, 2, 0, 1, 3, 5, 6, 7, 9, 11)]; - - /* - The Proteus BIOS contains a serial ID for copy protection. Disks also contain the - OS serial ID which must match the BIOS serial ID. This can be negated by patching the - serial in the BIOS to 0x0000. - */ - rom[0x02] = 0x00; - rom[0x03] = 0x00; -} - - -void proteus_state::machine_reset() -{ - /* system starts with 6809 running and the Z80 remains reset */ - m_z80->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); -} - - -WRITE_LINE_MEMBER(proteus_state::ptm_o2_callback) -{ - m_ptm->set_c1(state); -} - -WRITE_LINE_MEMBER(proteus_state::ptm_o3_callback) -{ - m_adlc->txc_w(state); - m_adlc->rxc_w(!state); -} - - -uint8_t proteus_state::network_r(offs_t offset) -{ - return m_adlc->read(offset >> 1); -} - -void proteus_state::network_w(offs_t offset, uint8_t data) -{ - m_adlc->write(offset >> 1, data); -} - - -void proteus_state::drive_register_w(uint8_t data) -{ - /* drive select */ - switch (data & 0x03) - { - case 0: - m_floppy = m_floppy0->get_device(); - break; - - case 1: - m_floppy = m_floppy1->get_device(); - break; - - default: - m_floppy = nullptr; - break; - } - m_fdc->set_floppy(m_floppy); - - if (m_floppy) - { - /* side select */ - m_floppy->ss_w(BIT(data, 6)); - } -} - -uint8_t proteus_state::drive_register_r() -{ - /* disk change */ - return (m_floppy ? m_floppy->dskchg_r() : 1) << 1; -} - -WRITE_LINE_MEMBER(proteus_state::motor_w) -{ - if (m_floppy) m_floppy->mon_w(!state); -} - -uint8_t proteus_state::fdc_inv_r(offs_t offset) -{ - return m_fdc->read(offset) ^ 0xff; -} - -void proteus_state::fdc_inv_w(offs_t offset, uint8_t data) -{ - m_fdc->write(offset, data ^ 0xff); -} - - -void proteus_state::enable_z80_w(uint8_t data) -{ - logerror("%04X enable z80\n", m_maincpu->pc()); - // Enable Z80 (store an address at E060 and when the 6809 comes back it'll load PC with that address) - m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); - m_z80->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); -} - -void proteus_state::enable_6809_w(uint8_t data) -{ - logerror("%04X enable 6809\n", m_z80->pc()); - // TODO: this is untested, not aware of any software that uses it - m_z80->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); - m_maincpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE); -} - - -void proteus_state::proteus_6809_mem(address_map &map) -{ - map(0x0000, 0xffff).ram().share(RAM_TAG); - map(0xe000, 0xe003).rw(m_pia, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); // Parallel port - map(0xe004, 0xe005).rw(m_acia[0], FUNC(acia6850_device::read), FUNC(acia6850_device::write)); // Terminal - map(0xe008, 0xe009).rw(m_acia[1], FUNC(acia6850_device::read), FUNC(acia6850_device::write)); // Printer - map(0xe00c, 0xe00d).rw(m_acia[2], FUNC(acia6850_device::read), FUNC(acia6850_device::write)); // Modem - map(0xe014, 0xe014).rw(FUNC(proteus_state::drive_register_r), FUNC(proteus_state::drive_register_w)); - map(0xe018, 0xe01b).rw(FUNC(proteus_state::fdc_inv_r), FUNC(proteus_state::fdc_inv_w)); // Floppy control - map(0xe020, 0xe027).rw(m_ptm, FUNC(ptm6840_device::read), FUNC(ptm6840_device::write)); // Timer - map(0xe030, 0xe036).rw(FUNC(proteus_state::network_r), FUNC(proteus_state::network_w)); // Poly network - map(0xe060, 0xe060).w(FUNC(proteus_state::enable_z80_w)); - map(0xf000, 0xffff).rom().region("bios", 0); -} - - -void proteus_state::proteus_z80_mem(address_map &map) -{ - map(0x0000, 0xffff).ram().share(RAM_TAG); -} - - -void proteus_state::proteus_z80_io(address_map &map) -{ - map(0x00, 0x03).mirror(0xff00).rw(m_pia, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); // Parallel port - map(0x04, 0x05).mirror(0xff00).rw(m_acia[0], FUNC(acia6850_device::read), FUNC(acia6850_device::write)); // Terminal - map(0x08, 0x09).mirror(0xff00).rw(m_acia[1], FUNC(acia6850_device::read), FUNC(acia6850_device::write)); // Printer - map(0x0c, 0x0d).mirror(0xff00).rw(m_acia[2], FUNC(acia6850_device::read), FUNC(acia6850_device::write)); // Modem - map(0x14, 0x14).mirror(0xff00).rw(FUNC(proteus_state::drive_register_r), FUNC(proteus_state::drive_register_w)); - map(0x18, 0x1b).mirror(0xff00).rw(FUNC(proteus_state::fdc_inv_r), FUNC(proteus_state::fdc_inv_w)); // Floppy control - map(0x20, 0x27).mirror(0xff00).rw(m_ptm, FUNC(ptm6840_device::read), FUNC(ptm6840_device::write)); // Timer - map(0x30, 0x36).mirror(0xff00).rw(FUNC(proteus_state::network_r), FUNC(proteus_state::network_w)); // Poly network - map(0x50, 0x50).mirror(0xff00).w(FUNC(proteus_state::enable_6809_w)); -} - - -//Parameter 1: Baud Rate from BIOS -// 00 = 9600 -// 02 = 4800 -// 04 = 2400 -// 06 = 1200 -// 08 = 600 -// 0A = 300 -static INPUT_PORTS_START(proteus) - PORT_START("TERM_BAUD") - PORT_CONFNAME(0x07, 0x00, "Terminal Baud Rate") - PORT_CONFSETTING(0x00, "9600") - PORT_CONFSETTING(0x01, "4800") - PORT_CONFSETTING(0x02, "2400") - PORT_CONFSETTING(0x03, "1200") - PORT_CONFSETTING(0x04, "600") - PORT_CONFSETTING(0x05, "300") - PORT_CONFSETTING(0x06, "150") - - PORT_START("J1") - PORT_CONFNAME(0x07, 0x00, "J1 Modem Baud Rate") - PORT_CONFSETTING(0x00, "9600") - PORT_CONFSETTING(0x01, "4800") - PORT_CONFSETTING(0x02, "2400") - PORT_CONFSETTING(0x03, "1200") - PORT_CONFSETTING(0x04, "600") - PORT_CONFSETTING(0x05, "300") - - PORT_START("J2") - PORT_CONFNAME(0x07, 0x00, "J2 Printer Baud Rate") - PORT_CONFSETTING(0x00, "9600") - PORT_CONFSETTING(0x01, "4800") - PORT_CONFSETTING(0x02, "2400") - PORT_CONFSETTING(0x03, "1200") - PORT_CONFSETTING(0x04, "600") - PORT_CONFSETTING(0x05, "300") -INPUT_PORTS_END - - -void proteus_state::floppy_formats(format_registration &fr) -{ - fr.add_fm_containers(); - fr.add(FLOPPY_FLEX_FORMAT); - fr.add(FLOPPY_POLY_CPM_FORMAT); -} - -static void proteus_floppies(device_slot_interface &device) -{ - device.option_add("8dssd", FLOPPY_8_DSSD); // Shugart SA-860 -} - - -void proteus_state::proteus(machine_config &config) -{ - /* basic machine hardware */ - MC6809(config, m_maincpu, 4_MHz_XTAL); - m_maincpu->set_addrmap(AS_PROGRAM, &proteus_state::proteus_6809_mem); - - Z80(config, m_z80, 4_MHz_XTAL); - m_z80->set_addrmap(AS_PROGRAM, &proteus_state::proteus_z80_mem); - m_z80->set_addrmap(AS_IO, &proteus_state::proteus_z80_io); - - INPUT_MERGER_ANY_HIGH(config, m_irqs); - m_irqs->output_handler().set_inputline(m_maincpu, M6809_IRQ_LINE); - m_irqs->output_handler().append_inputline(m_z80, INPUT_LINE_IRQ0); - - /* fdc */ - FD1771(config, m_fdc, 4_MHz_XTAL / 2); - m_fdc->hld_wr_callback().set(FUNC(proteus_state::motor_w)); - m_fdc->set_force_ready(true); - - FLOPPY_CONNECTOR(config, "fdc:0", proteus_floppies, "8dssd", proteus_state::floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "fdc:1", proteus_floppies, "8dssd", proteus_state::floppy_formats).enable_sound(true); - - /* ram */ - RAM(config, RAM_TAG).set_default_size("64K"); - - /* network */ - MC6854(config, m_adlc); - m_adlc->out_irq_cb().set("irqs", FUNC(input_merger_device::in_w<0>)); - - PTM6840(config, m_ptm, 4_MHz_XTAL / 2); - m_ptm->set_external_clocks(0, 0, 0); - m_ptm->o2_callback().set(FUNC(proteus_state::ptm_o2_callback)); - m_ptm->o3_callback().set(FUNC(proteus_state::ptm_o3_callback)); - m_ptm->irq_callback().set("irqs", FUNC(input_merger_device::in_w<1>)); - - /* parallel port */ - PIA6821(config, m_pia, 0); - //m_pia->readpb_handler().set(FUNC(proteus_state::pia_pb_r)); - //m_pia->writepa_handler().set(FUNC(proteus_state::pia_pa_w)); - //m_pia->writepb_handler().set(FUNC(proteus_state::pia_pb_w)); - //m_pia->ca2_handler().set(CENTRONICS_TAG, FUNC(centronics_device::write_strobe)); - m_pia->irqa_handler().set("irqs", FUNC(input_merger_device::in_w<2>)); - m_pia->irqb_handler().set("irqs", FUNC(input_merger_device::in_w<3>)); - - centronics_device ¶llel(CENTRONICS(config, "parallel", centronics_devices, "printer")); - parallel.ack_handler().set(m_pia, FUNC(pia6821_device::ca1_w)); - output_latch_device ¢_data_out(OUTPUT_LATCH(config, "cent_data_out")); - parallel.set_output_latch(cent_data_out); - - /* terminal port */ - ACIA6850(config, m_acia[0], 0); - m_acia[0]->txd_handler().set("terminal", FUNC(rs232_port_device::write_txd)); - m_acia[0]->rts_handler().set("terminal", FUNC(rs232_port_device::write_rts)); - m_acia[0]->irq_handler().set("irqs", FUNC(input_merger_device::in_w<4>)); - - rs232_port_device &terminal(RS232_PORT(config, "terminal", default_rs232_devices, "terminal")); // TODO: ADM-31 terminal required - terminal.rxd_handler().set(m_acia[0], FUNC(acia6850_device::write_rxd)); - terminal.cts_handler().set(m_acia[0], FUNC(acia6850_device::write_cts)); - - clock_device &acia0_clock(CLOCK(config, "acia0_clock", 4_MHz_XTAL / 2 / 13)); // TODO: this is set using jumpers - acia0_clock.signal_handler().set(m_acia[0], FUNC(acia6850_device::write_txc)); - acia0_clock.signal_handler().append(m_acia[0], FUNC(acia6850_device::write_rxc)); - - /* printer port */ - ACIA6850(config, m_acia[1], 0); - m_acia[1]->txd_handler().set("printer", FUNC(rs232_port_device::write_txd)); - m_acia[1]->rts_handler().set("printer", FUNC(rs232_port_device::write_rts)); - m_acia[1]->irq_handler().set("irqs", FUNC(input_merger_device::in_w<5>)); - - rs232_port_device &printer(RS232_PORT(config, "printer", default_rs232_devices, nullptr)); - printer.rxd_handler().set(m_acia[1], FUNC(acia6850_device::write_rxd)); - printer.cts_handler().set(m_acia[1], FUNC(acia6850_device::write_cts)); - - clock_device &acia1_clock(CLOCK(config, "acia1_clock", 4_MHz_XTAL / 2 / 13)); // TODO: this is set using jumpers J2 - acia1_clock.signal_handler().set(m_acia[1], FUNC(acia6850_device::write_txc)); - acia1_clock.signal_handler().append(m_acia[1], FUNC(acia6850_device::write_rxc)); - - /* modem port */ - ACIA6850(config, m_acia[2], 0); - m_acia[2]->txd_handler().set("modem", FUNC(rs232_port_device::write_txd)); - m_acia[2]->rts_handler().set("modem", FUNC(rs232_port_device::write_rts)); - m_acia[2]->irq_handler().set("irqs", FUNC(input_merger_device::in_w<6>)); - - rs232_port_device &modem(RS232_PORT(config, "modem", default_rs232_devices, nullptr)); - modem.rxd_handler().set(m_acia[2], FUNC(acia6850_device::write_rxd)); - modem.cts_handler().set(m_acia[2], FUNC(acia6850_device::write_cts)); - - clock_device &acia2_clock(CLOCK(config, "acia2_clock", 4_MHz_XTAL / 2 / 13)); // TODO: this is set using jumpers J1 - acia2_clock.signal_handler().set(m_acia[2], FUNC(acia6850_device::write_txc)); - acia2_clock.signal_handler().append(m_acia[2], FUNC(acia6850_device::write_rxc)); - - /* software lists */ - SOFTWARE_LIST(config, "flop_list").set_original("poly_flop").set_filter("PROTEUS"); -} - - -ROM_START(proteus) - ROM_REGION(0x1000, "bios", 0) - ROM_DEFAULT_BIOS("82") - ROM_SYSTEM_BIOS(0, "82", "030982") - ROMX_LOAD("proteusv30.u28", 0x0000, 0x1000, CRC(ad02dc36) SHA1(f73aff8b3d85448f603a2fe807e3a7e02550db27), ROM_BIOS(0)) - ROM_SYSTEM_BIOS(1, "86", "300986") - ROMX_LOAD("300986.u28", 0x0000, 0x1000, CRC(f607d396) SHA1(0b9d9d3178b5587e60da56885b9e8a83f7d5dd26), ROM_BIOS(1)) -ROM_END - - -/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ -COMP( 1982, proteus, 0, 0, proteus, proteus, proteus_state, empty_init, "Polycorp", "Poly Proteus (Standalone)", MACHINE_NOT_WORKING ) diff --git a/src/mame/skeleton/amust.cpp b/src/mame/skeleton/amust.cpp deleted file mode 100644 index b2f1e6fd22f..00000000000 --- a/src/mame/skeleton/amust.cpp +++ /dev/null @@ -1,550 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Robbbert -/***************************************************************************************** - -Amust Compak - also known as Amust Executive 816. - -2014-03-21 Skeleton driver. [Robbbert] - -An unusual-looking CP/M computer. The screen is a tiny CRT not much bigger -than a modern smartphone. - -Z-80A @ 4MHz; 64KB dynamic RAM (8x 4164); 2KB video ram (6116); 2x 13cm drives; -80 track DD with data capacity of 790KB; in a lockable Samsonite briefcase. - -There are no manuals or schematics known to exist. -The entire driver is guesswork. -The board has LH0080 (Z80A), 2x 8251, 2x 8255, 8253, uPD765A and a HD46505SP-2. -There is a piezo beeper. There are 3 crystals, X1 = 4.9152 (serial chips), -X2 = 16 (CPU), X3 = 14.31818 MHz (Video). -There are numerous jumpers, all of which perform unknown functions. - -The keyboard is a plug-in unit, same idea as Kaypro and Zorba. It has these -chips: INS8035N-6, F74145, 74LS373N, SN75451BP, 2716 rom with label KBD-3. -Crystal: 3.579545 MHz - -The main rom is identical between the 2 halves, except that the initial -crtc parameters are slightly different. I've chosen to ignore the first -half. (perhaps 50/60 Hz selectable by jumper?) - -Preliminary I/O ports ---------------------- -00-01 uart 1 -02-03 uart 2 -04-07 ppi 1 -08-0b ppi 2 -0d-0f crtc -10-11 fdc -14-17 pit - -PIT. -Having the PIT on ports 14-17 seems to make sense. It sets counters 1 and 2 -to mode 3, binary, initial count = 0x80. Counter 0 not used? - - -Floppy Parameters: ------------------- -Double Density -Two Side -80 track -1024 byte sectors -5 sectors/track -800k capacity -128 directory entries -2k block size -Skew 1,3,5,2,4 - - -Monitor Commands: ------------------ -B = Boot from floppy -(YES! Most useless monitor ever) - - -ToDo: -- Everything -- Floppy issues: - - The loop to read a sector has no escape. The interrupt handler (which can't be found) - needs to take another path when the sector is complete. - - The loop uses "ini" to read a byte, but this doesn't clear DRQ, so memory rapidly fills - up with garbage, mostly FF. -- Keyboard controller needs to be emulated. -- If booting straight to CP/M, the load message should be in the middle of the screen. -- Looks like port 5 has a row of function keys or similar. Need to be added. - - -*******************************************************************************************/ - -#include "emu.h" - -#include "bus/rs232/rs232.h" -#include "cpu/z80/z80.h" -#include "imagedev/floppy.h" -#include "machine/clock.h" -#include "machine/i8251.h" -#include "machine/i8255.h" -#include "machine/pit8253.h" -#include "machine/timer.h" -#include "machine/upd765.h" -#include "sound/beep.h" -#include "video/mc6845.h" - -#include "emupal.h" -#include "screen.h" -#include "speaker.h" - - -namespace { - -class amust_state : public driver_device -{ -public: - amust_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_palette(*this, "palette") - , m_maincpu(*this, "maincpu") - , m_rom(*this, "maincpu") - , m_ram(*this, "mainram") - , m_bank1(*this, "bank1") - , m_p_chargen(*this, "chargen") - , m_beep(*this, "beeper") - , m_fdc (*this, "fdc") - , m_floppy0(*this, "fdc:0") - , m_floppy1(*this, "fdc:1") - , m_beep_timer(*this, "beep_timer") - { } - - void amust(machine_config &config); - -private: - u8 port04_r(); - void port04_w(u8 data); - u8 port05_r(); - u8 port06_r(); - void port06_w(u8 data); - u8 port08_r(); - void port08_w(u8 data); - u8 port09_r(); - u8 port0a_r(); - void port0a_w(u8 data); - void port0d_w(u8 data); - DECLARE_WRITE_LINE_MEMBER(hsync_w); - DECLARE_WRITE_LINE_MEMBER(vsync_w); - DECLARE_WRITE_LINE_MEMBER(drq_w); - DECLARE_WRITE_LINE_MEMBER(intrq_w); - void kbd_put(u8 data); - MC6845_UPDATE_ROW(crtc_update_row); - TIMER_DEVICE_CALLBACK_MEMBER(beep_timer); - - void io_map(address_map &map); - void mem_map(address_map &map); - void machine_reset() override; - void machine_start() override; - void do_int(); - - u8 m_port04 = 0U; - u8 m_port06 = 0U; - u8 m_port08 = 0U; - u8 m_port09 = 0U; - u8 m_port0a = 0U; - u8 m_term_data = 0U; - bool m_drq = 0; - //bool m_intrq = 0; - bool m_hsync = 0; - bool m_vsync = 0; - std::unique_ptr m_vram; - memory_passthrough_handler m_rom_shadow_tap; - required_device m_palette; - required_device m_maincpu; - required_region_ptr m_rom; - required_shared_ptr m_ram; - required_memory_bank m_bank1; - required_region_ptr m_p_chargen; - required_device m_beep; - required_device m_fdc; - required_device m_floppy0; - required_device m_floppy1; - required_device m_beep_timer; -}; - -TIMER_DEVICE_CALLBACK_MEMBER(amust_state::beep_timer) -{ - m_beep->set_state(0); -} - -//void amust_state::port00_w(u8 data) -//{ -// membank("bankr0")->set_entry(BIT(data, 6)); -// m_fdc->dden_w(BIT(data, 5)); -// floppy_image_device *floppy = nullptr; -// if (BIT(data, 0)) floppy = m_floppy0->get_device(); -// m_fdc->set_floppy(floppy); -// if (floppy) -// floppy->ss_w(BIT(data, 4)); -//} - -void amust_state::mem_map(address_map &map) -{ - map(0x0000, 0xffff).ram().share("mainram"); - map(0xf800, 0xffff).bankr("bank1"); -} - -void amust_state::io_map(address_map &map) -{ - map.unmap_value_high(); - map.global_mask(0xff); - map(0x00, 0x01).rw("uart1", FUNC(i8251_device::read), FUNC(i8251_device::write)); - map(0x02, 0x03).rw("uart2", FUNC(i8251_device::read), FUNC(i8251_device::write)); - map(0x04, 0x07).rw("ppi1", FUNC(i8255_device::read), FUNC(i8255_device::write)); - map(0x08, 0x0b).rw("ppi2", FUNC(i8255_device::read), FUNC(i8255_device::write)); - map(0x0d, 0x0d).nopr().w(FUNC(amust_state::port0d_w)); - map(0x0e, 0x0e).rw("crtc", FUNC(mc6845_device::status_r), FUNC(mc6845_device::address_w)); - map(0x0f, 0x0f).rw("crtc", FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w)); - map(0x10, 0x11).m(m_fdc, FUNC(upd765a_device::map)); - map(0x14, 0x17).rw("pit", FUNC(pit8253_device::read), FUNC(pit8253_device::write)); -} - -static void amust_floppies(device_slot_interface &device) -{ - device.option_add("525qd", FLOPPY_525_QD); -} - -/* Input ports */ -static INPUT_PORTS_START( amust ) - PORT_START("P9") - // bits 6,7 not used? - // bit 5 - fdc intrq - PORT_DIPNAME( 0x01, 0x01, "Bit0" ) // code @ FC99 - PORT_DIPSETTING( 0x01, DEF_STR( On ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPNAME( 0x02, 0x02, "Bit1" ) - PORT_DIPSETTING( 0x02, DEF_STR( On ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPNAME( 0x04, 0x04, "Bit2" ) - PORT_DIPSETTING( 0x04, DEF_STR( On ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPNAME( 0x08, 0x08, "Bit3" ) - PORT_DIPSETTING( 0x08, DEF_STR( On ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPNAME( 0x10, 0x10, "Boot to Monitor" ) // code @ F895 - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x10, DEF_STR( On ) ) -INPUT_PORTS_END - -void amust_state::do_int() -{ - bool sync = m_hsync | m_vsync; - - if ((BIT(m_port0a, 3) && sync) // when writing to the screen, only do it during blanking - || (BIT(m_port0a, 5) && m_drq)) // when reading from floppy, only do it when DRQ is high. - { - //printf("%X,%X,%X ",m_port0a,sync,m_drq); - m_maincpu->set_input_line_and_vector(INPUT_LINE_IRQ0, ASSERT_LINE, 0x00); // Z80 - } - else - m_maincpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE); -} - -WRITE_LINE_MEMBER( amust_state::drq_w ) -{ - m_drq = state; - do_int(); - m_fdc->tc_w(1); -} - -WRITE_LINE_MEMBER( amust_state::intrq_w ) -{ - m_port09 = (m_port09 & 0xdf) | (state ? 0x20 : 0); -} - -WRITE_LINE_MEMBER( amust_state::hsync_w ) -{ - m_hsync = state; - do_int(); -} - -WRITE_LINE_MEMBER( amust_state::vsync_w ) -{ - m_vsync = state; - do_int(); -} - -u8 amust_state::port04_r() -{ - return m_port04; -} - -void amust_state::port04_w(u8 data) -{ - m_port04 = data; -} - -u8 amust_state::port05_r() -{ - return 0; -} - -u8 amust_state::port06_r() -{ - return m_port06; -} - -// BIT 5 low while writing to screen -void amust_state::port06_w(u8 data) -{ - m_port06 = data; -} - -u8 amust_state::port08_r() -{ - return m_port08; -} - -// lower 8 bits of video address -void amust_state::port08_w(u8 data) -{ - m_port08 = data; -} - -/* -d0 - something to do with type of disk -d1 - -d2 - -d3 - -d4 - H = go to monitor; L = boot from disk -d5 - status of fdc intrq; loops till NZ -d6 - -d7 - -*/ -u8 amust_state::port09_r() -{ - logerror("%s\n",machine().describe_context()); - return (ioport("P9")->read() & 0x1f) | m_port09; -} - -u8 amust_state::port0a_r() -{ - return m_port0a; -} - -/* Bits 7,6,5,3 something to do -with selecting which device causes interrupt? -50, 58 = video sync -70 disk -D0 ? -Bit 4 low = beeper. -Lower 3 bits = upper part of video address */ -void amust_state::port0a_w(u8 data) -{ - m_port0a = data; - - if (!BIT(data, 4)) - { - m_beep->set_state(1); - m_beep_timer->adjust(attotime::from_msec(150)); - } - floppy_image_device *floppy = m_floppy0->get_device(); - m_fdc->set_floppy(floppy); - if (floppy) - { - floppy->mon_w(0); - - //floppy->ss_w(0); // side 0? hopefully fdc does this - } -} - -void amust_state::port0d_w(u8 data) -{ - uint16_t video_address = m_port08 | ((m_port0a & 7) << 8); - m_vram[video_address] = data; -} - -/* F4 Character Displayer */ -static const gfx_layout charlayout = -{ - 8, 8, /* 8 x 8 characters */ - 256, /* 256 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 8 bytes */ -}; - -static GFXDECODE_START( gfx_amust ) - GFXDECODE_ENTRY( "chargen", 0x0000, charlayout, 0, 1 ) -GFXDECODE_END - -MC6845_UPDATE_ROW( amust_state::crtc_update_row ) -{ - rgb_t const *const palette = m_palette->palette()->entry_list_raw(); - u32 *p = &bitmap.pix(y); - - for (u16 x = 0; x < x_count; x++) - { - u8 inv = (x == cursor_x) ? 0xff : 0; - u16 mem = (ma + x) & 0x7ff; - u8 chr = m_vram[mem]; - u8 gfx; - if (ra < 8) - gfx = m_p_chargen[(chr<<3) | ra] ^ inv; - else - gfx = inv; - - /* Display a scanline of a character (8 pixels) */ - *p++ = palette[BIT(gfx, 7)]; - *p++ = palette[BIT(gfx, 6)]; - *p++ = palette[BIT(gfx, 5)]; - *p++ = palette[BIT(gfx, 4)]; - *p++ = palette[BIT(gfx, 3)]; - *p++ = palette[BIT(gfx, 2)]; - *p++ = palette[BIT(gfx, 1)]; - *p++ = palette[BIT(gfx, 0)]; - } -} - -void amust_state::machine_reset() -{ - m_bank1->set_entry(1); - m_port04 = 0; - m_port06 = 0; - m_port08 = 0; - m_port09 = 0; - m_port0a = 0; - m_hsync = false; - m_vsync = false; - m_drq = false; - m_fdc->set_ready_line_connected(1); // always ready for minifloppy; controlled by fdc for 20cm - m_fdc->set_unscaled_clock(4000000); // 4MHz for minifloppy; 8MHz for 20cm - - address_space &program = m_maincpu->space(AS_PROGRAM); - program.install_rom(0x0000, 0x07ff, m_rom); // do it here for F3 - m_rom_shadow_tap.remove(); - m_rom_shadow_tap = program.install_read_tap( - 0xf800, 0xffff, - "rom_shadow_r", - [this] (offs_t offset, u8 &data, u8 mem_mask) - { - if (!machine().side_effects_disabled()) - { - // delete this tap - m_rom_shadow_tap.remove(); - - // reinstall RAM over the ROM shadow - m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram); - } - }, - &m_rom_shadow_tap); -} - -void amust_state::machine_start() -{ - m_vram = make_unique_clear(0x800); - save_pointer(NAME(m_vram), 0x800); - save_item(NAME(m_port04)); - save_item(NAME(m_port06)); - save_item(NAME(m_port08)); - save_item(NAME(m_port09)); - save_item(NAME(m_port0a)); - save_item(NAME(m_term_data)); - save_item(NAME(m_drq)); - //save_item(NAME(m_intrq)); - save_item(NAME(m_hsync)); - save_item(NAME(m_vsync)); - m_bank1->configure_entry(0, m_ram+0xf800); - m_bank1->configure_entry(1, m_rom); -} - -void amust_state::amust(machine_config &config) -{ - /* basic machine hardware */ - Z80(config, m_maincpu, XTAL(16'000'000) / 4); - m_maincpu->set_addrmap(AS_PROGRAM, &amust_state::mem_map); - m_maincpu->set_addrmap(AS_IO, &amust_state::io_map); - - /* video hardware */ - screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER, rgb_t::green())); - screen.set_refresh_hz(50); - screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */ - screen.set_size(640, 480); - screen.set_visarea(0, 640-1, 0, 480-1); - screen.set_screen_update("crtc", FUNC(mc6845_device::screen_update)); - PALETTE(config, m_palette, palette_device::MONOCHROME); - GFXDECODE(config, "gfxdecode", m_palette, gfx_amust); - - /* sound hardware */ - SPEAKER(config, "mono").front_center(); - BEEP(config, m_beep, 800).add_route(ALL_OUTPUTS, "mono", 0.50); - TIMER(config, m_beep_timer).configure_generic(FUNC(amust_state::beep_timer)); - - /* Devices */ - hd6845s_device &crtc(HD6845S(config, "crtc", XTAL(14'318'181) / 8)); - crtc.set_screen("screen"); - crtc.set_show_border_area(false); - crtc.set_char_width(8); - crtc.set_update_row_callback(FUNC(amust_state::crtc_update_row)); - crtc.out_hsync_callback().set(FUNC(amust_state::hsync_w)); - crtc.out_vsync_callback().set(FUNC(amust_state::vsync_w)); - - UPD765A(config, m_fdc, 8'000'000, true, true); - m_fdc->drq_wr_callback().set(FUNC(amust_state::drq_w)); - m_fdc->intrq_wr_callback().set(FUNC(amust_state::intrq_w)); - FLOPPY_CONNECTOR(config, "fdc:0", amust_floppies, "525qd", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "fdc:1", amust_floppies, "525qd", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); - - clock_device &uart_clock(CLOCK(config, "uart_clock", 153600)); - uart_clock.signal_handler().set("uart1", FUNC(i8251_device::write_txc)); - uart_clock.signal_handler().append("uart1", FUNC(i8251_device::write_rxc)); - - i8251_device &uart1(I8251(config, "uart1", 0)); - uart1.txd_handler().set("rs232", FUNC(rs232_port_device::write_txd)); - uart1.dtr_handler().set("rs232", FUNC(rs232_port_device::write_dtr)); - uart1.rts_handler().set("rs232", FUNC(rs232_port_device::write_rts)); - - rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, "keyboard")); - rs232.rxd_handler().set("uart1", FUNC(i8251_device::write_rxd)); - rs232.cts_handler().set("uart1", FUNC(i8251_device::write_cts)); - rs232.dsr_handler().set("uart1", FUNC(i8251_device::write_dsr)); - - I8251(config, "uart2", 0); - //uart2.txd_handler().set("rs232", FUNC(rs232_port_device::write_txd)); - //uart2.dtr_handler().set("rs232", FUNC(rs232_port_device::write_dtr)); - //uart2.rts_handler().set("rs232", FUNC(rs232_port_device::write_rts)); - - PIT8253(config, "pit", 0); - - i8255_device &ppi1(I8255A(config, "ppi1")); - ppi1.in_pa_callback().set(FUNC(amust_state::port04_r)); - ppi1.out_pa_callback().set(FUNC(amust_state::port04_w)); - ppi1.in_pb_callback().set(FUNC(amust_state::port05_r)); - ppi1.in_pc_callback().set(FUNC(amust_state::port06_r)); - ppi1.out_pc_callback().set(FUNC(amust_state::port06_w)); - - i8255_device &ppi2(I8255A(config, "ppi2")); - ppi2.in_pa_callback().set(FUNC(amust_state::port08_r)); - ppi2.out_pa_callback().set(FUNC(amust_state::port08_w)); - ppi2.in_pb_callback().set(FUNC(amust_state::port09_r)); - ppi2.in_pc_callback().set(FUNC(amust_state::port0a_r)); - ppi2.out_pc_callback().set(FUNC(amust_state::port0a_w)); -} - -/* ROM definition */ -ROM_START( amust ) - ROM_REGION( 0x1000, "maincpu", 0 ) - ROM_LOAD( "mon_h.ic25", 0x0000, 0x1000, CRC(10dceac6) SHA1(1ef80039063f7a6455563d59f1bcc23e09eca369) ) - - ROM_REGION( 0x800, "chargen", 0 ) - ROM_LOAD( "cg4.ic74", 0x000, 0x800, CRC(52e7b9d8) SHA1(cc6d457634eb688ccef471f72bddf0424e64b045) ) - - ROM_REGION( 0x800, "keyboard", 0 ) - ROM_LOAD( "kbd_3.rom", 0x000, 0x800, CRC(d9441b35) SHA1(ce250ab1e892a13fd75182703f259855388c6bf4) ) -ROM_END - -} // anonymous namespace - -/* Driver */ - -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1983, amust, 0, 0, amust, amust, amust_state, empty_init, "Amust", "Amust Executive 816", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/skeleton/applix.cpp b/src/mame/skeleton/applix.cpp deleted file mode 100644 index b1fed2a8d84..00000000000 --- a/src/mame/skeleton/applix.cpp +++ /dev/null @@ -1,1181 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Robbbert -/*************************************************************************** - - Applix 1616 computer - - See for docs: http://psiphi.server101.com/applix/ - - First revealed to the world in December 1986 issue of Electronics Today - International (ETI) an Australian electronics magazine which is now defunct. - - The main articles appeared in ETI February/March/April 1987, followed by - other articles in various issues after that. - - Current Status: - After 60 seconds, boots to the ramdisk. You can enter commands. - If you have a floppy mounted, it will boot from the disk. - - The system could support 1 or 2 5.25 or 3.5 floppy drives, although 3.5 - was the recommended hardware. Format is similar to the PC 720kb, except - it has 5 sectors of 1024 bytes, giving 800kb total. We only support the - 3.5-sized disks. - - TODO: - - Cassette interface (coded but not working) - - Use kbtro device (tried and failed) - - Optional SCSI controller NCR5380 and hard drive (max 40mb) - - Joystick - - Audio: it could be better - - DAC output is used to compare against analog inputs; core doesn't permit - audio outputs to be used for non-speaker purposes. - - Bios 5 crashes MAME after scrolling about half a screen - -****************************************************************************/ - -#include "emu.h" - -#include "bus/centronics/ctronics.h" -#include "bus/rs232/rs232.h" -#include "cpu/m68000/m68000.h" -#include "cpu/mcs51/mcs51.h" -#include "cpu/z80/z80.h" -#include "imagedev/cassette.h" -#include "imagedev/floppy.h" -#include "machine/6522via.h" -#include "machine/timer.h" -#include "machine/wd_fdc.h" -#include "machine/z80scc.h" -#include "sound/dac.h" -#include "video/mc6845.h" - -#include "emupal.h" -#include "screen.h" -#include "softlist_dev.h" -#include "speaker.h" - -#include "formats/applix_dsk.h" - - - -class applix_state : public driver_device -{ -public: - applix_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_base(*this, "base") - , m_maincpu(*this, "maincpu") - , m_crtc(*this, "crtc") - , m_via(*this, "via6522") - , m_centronics(*this, "centronics") - , m_cent_data_out(*this, "cent_data_out") - , m_fdc(*this, "fdc") - , m_floppy0(*this, "fdc:0") - , m_floppy1(*this, "fdc:1") - , m_ldac(*this, "ldac") - , m_rdac(*this, "rdac") - , m_cass(*this, "cassette") - , m_io_dsw(*this, "DSW") - , m_io_fdc(*this, "FDC") - , m_io_k0f(*this, "K0f") - , m_io_k300(*this, "K30_0") - , m_io_k301(*this, "K30_1") - , m_io_k310(*this, "K31_0") - , m_io_k311(*this, "K31_1") - , m_io_k320(*this, "K32_0") - , m_io_k321(*this, "K32_1") - , m_io_k330(*this, "K33_0") - , m_io_k331(*this, "K33_1") - , m_io_k340(*this, "K34_0") - , m_io_k341(*this, "K34_1") - , m_io_k350(*this, "K35_0") - , m_io_k351(*this, "K35_1") - , m_io_k360(*this, "K36_0") - , m_io_k361(*this, "K36_1") - , m_io_k370(*this, "K37_0") - , m_io_k371(*this, "K37_1") - , m_io_k380(*this, "K38_0") - , m_io_k390(*this, "K39_0") - , m_io_k3a0(*this, "K3a_0") - , m_io_k3b0(*this, "K3b_0") - , m_io_k0b(*this, "K0b") - , m_expansion(*this, "expansion") - , m_palette(*this, "palette") - { } - - void applix(machine_config &config); - - void init_applix(); - -private: - virtual void machine_reset() override; - virtual void machine_start() override; - u16 applix_inputs_r(); - void palette_w(offs_t offset, u16 data, u16 mem_mask = ~0); - void analog_latch_w(u16 data); - void dac_latch_w(u16 data); - void video_latch_w(offs_t offset, u16 data, u16 mem_mask = ~0); - u8 applix_pb_r(); - void applix_pa_w(u8 data); - void applix_pb_w(u8 data); - DECLARE_WRITE_LINE_MEMBER(vsync_w); - u8 port00_r(); - u8 port08_r(); - u8 port10_r(); - u8 port18_r(); - u8 port20_r(); - u8 port60_r(); - void port08_w(u8 data); - void port10_w(u8 data); - void port18_w(offs_t offset, u8 data); - void port20_w(u8 data); - void port60_w(u8 data); - u16 fdc_data_r(); - u16 fdc_stat_r(offs_t offset); - void fdc_data_w(u16 data); - void fdc_cmd_w(u16 data); - static void floppy_formats(format_registration &fr); - u8 internal_data_read(offs_t offset); - void internal_data_write(offs_t offset, u8 data); - u8 p1_read(); - void p1_write(u8 data); - u8 p2_read(); - void p2_write(u8 data); - u8 p3_read(); - void p3_write(u8 data); - TIMER_DEVICE_CALLBACK_MEMBER(cass_timer); - - MC6845_UPDATE_ROW(crtc_update_row); - MC6845_BEGIN_UPDATE(crtc_update_border); - void applix_palette(palette_device &palette) const; - - u8 m_video_latch = 0U; - u8 m_pa = 0U; - u8 m_palette_latch[4]{}; - required_shared_ptr m_base; - - void main_mem(address_map &map); - void keytronic_pc3270_io(address_map &map); - void keytronic_pc3270_program(address_map &map); - void sub_io(address_map &map); - void sub_mem(address_map &map); - - u8 m_pb = 0U; - u8 m_analog_latch = 0U; - u8 m_dac_latch = 0U; - u8 m_port08 = 0U; - u8 m_data_to_fdc = 0U; - u8 m_data_from_fdc = 0U; - bool m_data = 0; - bool m_data_or_cmd = 0; - bool m_buffer_empty = 0; - bool m_fdc_cmd = 0; - u8 m_clock_count = 0U; - bool m_cp = 0; - u8 m_p1 = 0U; - u8 m_p1_data = 0U; - u8 m_p2 = 0U; - u8 m_p3 = 0U; - u16 m_last_write_addr = 0U; - u8 m_cass_data[4]{}; - required_device m_maincpu; - required_device m_crtc; - required_device m_via; - required_device m_centronics; - required_device m_cent_data_out; - required_device m_fdc; - required_device m_floppy0; - required_device m_floppy1; - required_device m_ldac; - required_device m_rdac; - required_device m_cass; - required_ioport m_io_dsw; - required_ioport m_io_fdc; - required_ioport m_io_k0f; - required_ioport m_io_k300; - required_ioport m_io_k301; - required_ioport m_io_k310; - required_ioport m_io_k311; - required_ioport m_io_k320; - required_ioport m_io_k321; - required_ioport m_io_k330; - required_ioport m_io_k331; - required_ioport m_io_k340; - required_ioport m_io_k341; - required_ioport m_io_k350; - required_ioport m_io_k351; - required_ioport m_io_k360; - required_ioport m_io_k361; - required_ioport m_io_k370; - required_ioport m_io_k371; - required_ioport m_io_k380; - required_ioport m_io_k390; - required_ioport m_io_k3a0; - required_ioport m_io_k3b0; - required_ioport m_io_k0b; - required_shared_ptr m_expansion; - - required_device m_palette; -}; - -/* -d0,1,2 = joystick -d3 = cassette LED, low=on -d4,5,6 = audio select -d7 = cassette relay, low=on -*/ -void applix_state::analog_latch_w(u16 data) -{ - data &= 0xff; - if (data != m_analog_latch) - { - m_cass->change_state( - (BIT(data,7)) ? CASSETTE_MOTOR_DISABLED : CASSETTE_MOTOR_ENABLED, CASSETTE_MASK_MOTOR); - - m_analog_latch = data; - } -} - -void applix_state::dac_latch_w(u16 data) -{ - data &= 0xff; - m_dac_latch = data; - - if ((m_analog_latch & 0x70) == 0) // right - m_rdac->write(m_dac_latch); - else - if ((m_analog_latch & 0x70) == 0x10) // left - m_ldac->write(m_dac_latch); -} - -//cent = odd, video = even -void applix_state::palette_w(offs_t offset, u16 data, u16 mem_mask) -{ - offset >>= 4; - if (ACCESSING_BITS_0_7) - { - m_cent_data_out->write(data); - } - else - m_palette_latch[offset] = (data >> 8) & 15; -} - -void applix_state::video_latch_w(offs_t offset, u16 data, u16 mem_mask) -{ - if (ACCESSING_BITS_0_7) - m_video_latch = data; -} - -/* -d0 = dac output + external signal = analog input -d1 = cassette in -d2,3 = joystick in -d4-7 = SW2 dipswitch block -*/ -u16 applix_state::applix_inputs_r() -{ - return m_io_dsw->read() | m_cass_data[2]; -} - -u8 applix_state::applix_pb_r() -{ - return m_pb; -} - -/* -d0 = /(in) printer busy signal -d1 = /(out) printer strobe -d2 = /(out) enable cassette write IRQ -d3 = (out) H = 640 video mode -d4 = /(out) enable cassette read IRQ -d5 = /(out) clear cass IRQ and output line -d6 = /(out) reset keyboard by pulling kbd clock low -d7 = /(out) reset keyboard flipflop -*/ -void applix_state::applix_pa_w(u8 data) -{ - // Reset flipflop counter - if (!BIT(data, 7)) - m_clock_count = 0; - - // Reset keyboard - if (!BIT(data, 6)) - { - m_p3 = 0xff; - m_last_write_addr = 0; - } - m_cass->output(BIT(data, 5) ? -1.0 : +1.0); - - // high-to-low of PA5 when reading cassette - /PRE on IC32b - if (BIT(m_pa, 5) && !BIT(data, 5) && !BIT(data, 4)) - m_maincpu->set_input_line(M68K_IRQ_4, CLEAR_LINE); - - // low-to-high of PA2 when writing cassette - /PRE on IC49 - if (!BIT(m_pa, 2) && BIT(data, 2)) - m_maincpu->set_input_line(M68K_IRQ_4, CLEAR_LINE); - - m_centronics->write_strobe(BIT(data, 1)); - - m_pa = data; -} - -/* -d0-6 = user -d7 = square wave output for cassette IRQ -*/ -void applix_state::applix_pb_w(u8 data) -{ - // low-to-high of PB7 when writing cassette - CLK on IC49 - if (!BIT(m_pb, 7) && BIT(data, 7)) - if (!BIT(m_pa, 2)) - m_maincpu->set_input_line(M68K_IRQ_4, ASSERT_LINE); - - m_pb = data; -} - -/* -d0 = H if 68000 sent a command -d1 = H if 68000 sent a byte -d2 = H if 68000 has read last byte -d3 = test switch -*/ -u8 applix_state::port00_r() -{ - return (u8)m_data_or_cmd | ((u8)m_data << 1) | ((u8)m_buffer_empty << 2) | m_io_fdc->read(); -} - -/* -d0 = /RDY -d1 = /DISC CHANGE -d2 = DS0 -d3 = DS1 -d4 = MOTORON -d5 = SIDE -d6 = BANK -d7 = MAP -*/ -u8 applix_state::port08_r() -{ - return m_port08 | 3; -} - -/* -d0 = /INUSE -d1 = /EJECT -d2-7 same as for port08_r -*/ -void applix_state::port08_w(u8 data) -{ - m_port08 = data; - membank("bank1")->set_entry(BIT(data, 6)); - - floppy_image_device *floppy = nullptr; - if (BIT(data, 2)) floppy = m_floppy0->get_device(); - if (BIT(data, 3)) floppy = m_floppy1->get_device(); - - m_fdc->set_floppy(floppy); - - if (floppy) - { - floppy->mon_w(0); - floppy->ss_w(BIT(data, 5)); - } -} - -u8 applix_state::port10_r() -{ - return 0; -} - -void applix_state::port10_w(u8 data) -{ -} - -u8 applix_state::port18_r() -{ - m_data = 0; - return m_data_to_fdc; -} - -void applix_state::port18_w(offs_t offset, u8 data) -{ - m_data_from_fdc = data; - m_buffer_empty = 0; - m_fdc_cmd = BIT(offset, 2); -} - -u8 applix_state::port20_r() -{ - return 0; -} - -void applix_state::port20_w(u8 data) -{ -} - -u8 applix_state::port60_r() -{ - return 0; -} - -void applix_state::port60_w(u8 data) -{ -} - -u16 applix_state::fdc_stat_r(offs_t offset) -{ - u8 data = 0; - switch (offset) - { - case 0: data = (u8)m_buffer_empty^1; break; - case 1: data = (u8)m_data^1; break; - default: data = (u8)m_fdc_cmd; // case 2 - } - return data << 7; -} - -u16 applix_state::fdc_data_r() -{ - m_buffer_empty = 1; - return m_data_from_fdc; -} - -void applix_state::fdc_data_w(u16 data) -{ - m_data_to_fdc = data; - m_data = 1; - m_data_or_cmd = 0; -} - -void applix_state::fdc_cmd_w(u16 data) -{ - m_data_to_fdc = data; - m_data = 1; - m_data_or_cmd = 1; -} - -void applix_state::main_mem(address_map &map) -{ - map.unmap_value_high(); - map.global_mask(0xffffff); - map(0x000000, 0x3fffff).ram().share("expansion"); // Expansion - map(0x400000, 0x47ffff).ram().mirror(0x80000).share("base"); // Main ram - map(0x500000, 0x51ffff).rom().region("maincpu", 0); - map(0x600000, 0x60007f).w(FUNC(applix_state::palette_w)); - map(0x600080, 0x6000ff).w(FUNC(applix_state::dac_latch_w)); - map(0x600100, 0x60017f).w(FUNC(applix_state::video_latch_w)); //video latch (=border colour, high nybble; video base, low nybble) (odd) - map(0x600180, 0x6001ff).w(FUNC(applix_state::analog_latch_w)); - map(0x700000, 0x700007).mirror(0x78).rw("scc", FUNC(scc8530_device::ab_dc_r), FUNC(scc8530_device::ab_dc_w)).umask16(0xff00).cswidth(16); - map(0x700080, 0x7000ff).r(FUNC(applix_state::applix_inputs_r)); - map(0x700100, 0x70011f).mirror(0x60).m(m_via, FUNC(via6522_device::map)).umask16(0xff00).cswidth(16); - map(0x700180, 0x700180).mirror(0x7c).rw(m_crtc, FUNC(mc6845_device::status_r), FUNC(mc6845_device::address_w)).cswidth(16); - map(0x700182, 0x700182).mirror(0x7c).rw(m_crtc, FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w)).cswidth(16); - map(0xffffc0, 0xffffc1).rw(FUNC(applix_state::fdc_data_r), FUNC(applix_state::fdc_data_w)); - //map(0xffffc2, 0xffffc3).rw(FUNC(applix_state::fdc_int_r) , FUNC(applix_state::fdc_int_w)); // optional - map(0xffffc8, 0xffffcd).r(FUNC(applix_state::fdc_stat_r)); - map(0xffffd0, 0xffffd1).w(FUNC(applix_state::fdc_cmd_w)); - //600000, 6FFFFF io ports and latches - //700000, 7FFFFF peripheral chips and devices - //800000, FFC000 optional roms - //FFFFC0, FFFFFF disk controller board -} - -void applix_state::sub_mem(address_map &map) -{ - map(0x0000, 0x5fff).rom(); - map(0x6000, 0x7fff).ram(); - map(0x8000, 0xffff).bankrw("bank1"); -} - -void applix_state::sub_io(address_map &map) -{ - map.global_mask(0xff); - map(0x00, 0x07).r(FUNC(applix_state::port00_r)); //PORTR - map(0x08, 0x0f).rw(FUNC(applix_state::port08_r), FUNC(applix_state::port08_w)); //Disk select - map(0x10, 0x17).rw(FUNC(applix_state::port10_r), FUNC(applix_state::port10_w)); //IRQ - map(0x18, 0x1f).rw(FUNC(applix_state::port18_r), FUNC(applix_state::port18_w)); //data&command - map(0x20, 0x27).mirror(0x18).rw(FUNC(applix_state::port20_r), FUNC(applix_state::port20_w)); //SCSI NCR5380 - map(0x40, 0x43).mirror(0x1c).rw(m_fdc, FUNC(wd1772_device::read), FUNC(wd1772_device::write)); //FDC - map(0x60, 0x63).mirror(0x1c).rw(FUNC(applix_state::port60_r), FUNC(applix_state::port60_w)); //anotherZ80SCC -} - -void applix_state::keytronic_pc3270_program(address_map &map) -{ - map(0x0000, 0x0fff).rom().region("kbdcpu", 0); -} - -void applix_state::keytronic_pc3270_io(address_map &map) -{ - map(0x0000, 0xffff).rw(FUNC(applix_state::internal_data_read), FUNC(applix_state::internal_data_write)); -} - -// io priorities: -// 4 cassette -// 3 scc -// 2 via - -/* Input ports */ -static INPUT_PORTS_START( applix ) - PORT_START( "K0f" ) - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') /* 06 */ - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') /* 05 */ - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') /* 14 */ - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') /* 13 */ - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') /* 22 */ - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') /* 21 */ - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F7 (IRMA)") /* 41 */ - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?6a?") /* 6a */ - - PORT_START( "K30_0" ) - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') /* 31 */ - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') /* 32 */ - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') /* 30 */ - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') /* 2f */ - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') /* 2e */ - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') /* 33 */ - PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START( "K30_1" ) - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) /* 58 */ - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) /* 59 */ - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) /* 5a */ - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) /* 5b */ - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) /* 5c */ - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) /* 5d */ - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?6b?") /* 6b */ - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F8 (IRMA)") /* 42 */ - - PORT_START( "K31_0" ) - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') /* 07 */ - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') /* 08 */ - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') /* 15 */ - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') /* 16 */ - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') /* 23 */ - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') /* 24 */ - PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START( "K31_1" ) - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) /* 37 */ - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) /* 5f */ - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LSHIFT) PORT_NAME("LShift") PORT_CHAR(UCHAR_SHIFT_1) /* 2a */ - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("<") /* 70 */ - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') /* 2c */ - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') /* 2d */ - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?6c?") /* 6c */ - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F9 (IRMA)") /* 43 */ - - PORT_START( "K32_0" ) - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') /* 0a */ - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') /* 09 */ - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') /* 18 */ - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') /* 17 */ - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') /* 26 */ - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') /* 25 */ - PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START( "K32_1" ) - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) /* 57 */ - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F10) PORT_CHAR(UCHAR_MAMEKEY(F10)) /* 1d */ - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) /* 71 */ - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LALT) PORT_NAME("LAlt") /* 38 */ - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') /* 39 */ - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RALT) PORT_NAME("RAlt") /* 38 */ - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?69?") /* 69 */ - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F6 (IRMA)") /* 40 */ - - PORT_START( "K33_0" ) - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2_PAD) PORT_CODE(KEYCODE_DOWN) PORT_NAME("KP 2") /* 50 */ - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1_PAD) PORT_CODE(KEYCODE_END) PORT_NAME("KP 1") /* 4f */ - PORT_BIT( 0x0c, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Down") /* 55 */ - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Enter") /* 75 */ - PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START( "K33_1" ) - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') /* 02 */ - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~') /* 29 */ - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') /* 10 */ - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) /* 0f */ - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') /* 1e */ - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CAPSLOCK) PORT_NAME("Caps") /* 3a */ - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?68?") /* 68 */ - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F5 (IRMA)") /* 3f */ - - PORT_START( "K34_0" ) - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') /* 35 */ - PORT_BIT( 0x0c, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_MAMEKEY(RSHIFT)) /* 36 */ - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Left") /* 56 */ - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') /* 34 */ - PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START( "K34_1" ) - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') /* 02 */ - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') /* 03 */ - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') /* 11 */ - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') /* 12 */ - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') /* 1f */ - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') /* 20 */ - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?67?") /* 67 */ - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F4 (IRMA)") /* 3e */ - - PORT_START( "K35_0" ) - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') /* 0b */ - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') /* 0c */ - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') /* 19 */ - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') /* 1a */ - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') /* 27 */ - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"') /* 28 */ - PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START( "K35_1" ) - PORT_BIT( 0x3f, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?66?") /* 66 */ - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F3 (IRMA)") /* 3d */ - - PORT_START( "K36_0" ) - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) /* 0e */ - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') /* 0d */ - PORT_BIT( 0x14, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) /* 1c */ - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') /* 2b */ - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') /* 1b */ - PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START( "K36_1" ) - PORT_BIT( 0x7f, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F2 (IRMA)") /* 3c */ - - PORT_START( "K37_0" ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("PA1") /* 7b */ - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("|<--") /* 7e */ - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("/a\\") /* 7a */ - PORT_BIT( 0x30, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_PLUS_PAD) PORT_NAME("KP +") /* 4e */ - PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START( "K37_1" ) - PORT_BIT( 0x3f, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?64?") /* 64 */ - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F1 (IRMA)") /* 3b */ - - PORT_START( "K38_0" ) - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SysReq") /* 54 */ - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) /*PORT_CODE(KEYCODE_SCRLOCK)*/ PORT_NAME("ScrLock") /* 46 */ - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("-->|") /* 7c */ - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9_PAD) PORT_CODE(KEYCODE_PGUP) PORT_NAME("KP 9") /* 49 */ - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS_PAD) PORT_NAME("KP -") /* 4a */ - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6_PAD) PORT_CODE(KEYCODE_RIGHT) PORT_NAME("KP 6") /* 4d */ - PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START( "K39_0" ) - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ESC) PORT_NAME("Esc") /* 01 */ - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_NUMLOCK) PORT_NAME("NumLock") /* 45 */ - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7_PAD) PORT_CODE(KEYCODE_HOME) PORT_NAME("KP 7") /* 47 */ - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8_PAD) PORT_CODE(KEYCODE_UP) PORT_NAME("KP 8") /* 48 */ - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4_PAD) PORT_CODE(KEYCODE_LEFT) PORT_NAME("KP 4") /* 4b */ - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("KP 5") /* 4c */ - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?76?") /* 76 */ - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?63?") /* 63 */ - - PORT_START( "K3a_0" ) - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("PrtSc *") /* 6f */ - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("PA2") /* 7f */ - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Right") /* 7d */ - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("/a") /* 79 */ - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Center") /* 77 */ - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?6e?") /* 6e */ - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?62?") /* 62 */ - - PORT_START( "K3b_0" ) - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3_PAD) PORT_CODE(KEYCODE_PGDN) PORT_NAME("KP 3") /* 51 */ - PORT_BIT( 0x06, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0_PAD) PORT_CODE(KEYCODE_INSERT) PORT_NAME("KP 0") /* 52 */ - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DEL_PAD) PORT_CODE(KEYCODE_DEL) PORT_NAME("KP .") /* 53 */ - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Up") /* 78 */ - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("?6d?") /* 6d */ - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F10 (IRMA)") /* 44 */ - - PORT_START( "K0b" ) - PORT_DIPNAME( 0x01, 0x01, "Protocol selection" ) - PORT_DIPSETTING( 0x00, "Enhanced XT, AT and PS/2 models" ) - PORT_DIPSETTING( 0x01, "Standard PC and XT" ) - PORT_DIPNAME( 0x02, 0x00, "IRMA/Native scan code set" ) - PORT_DIPSETTING( 0x00, "Native scan code set" ) - PORT_DIPSETTING( 0x02, "IRMA Emulation" ) - PORT_DIPNAME( 0x04, 0x04, "Enhanced 101/Native scan code set" ) - PORT_DIPSETTING( 0x00, "Native scan code set" ) - PORT_DIPSETTING( 0x04, "Enhanced 101 scan code set" ) - PORT_DIPNAME( 0x08, 0x08, "Enable E0" ) - PORT_DIPSETTING( 0x00, "Enable E0" ) - PORT_DIPSETTING( 0x08, "Disable E0" ) - PORT_DIPNAME( 0x10, 0x10, "Code tables" ) - PORT_DIPSETTING( 0x00, "U.S. code tables" ) - PORT_DIPSETTING( 0x10, "International code tables" ) - PORT_BIT( 0x60, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_DIPNAME( 0x80, 0x80, "Key click" ) - PORT_DIPSETTING( 0x00, "No key click" ) - PORT_DIPSETTING( 0x80, "Key click" ) - - PORT_START("DSW") - PORT_BIT( 0xf, 0, IPT_UNUSED ) - PORT_DIPNAME( 0x10, 0x00, "Switch 0") PORT_DIPLOCATION("SW2:1") - PORT_DIPSETTING( 0x10, DEF_STR(Off)) - PORT_DIPSETTING( 0x00, DEF_STR(On)) - PORT_DIPNAME( 0x20, 0x00, "Switch 1") PORT_DIPLOCATION("SW2:2") - PORT_DIPSETTING( 0x20, DEF_STR(Off)) - PORT_DIPSETTING( 0x00, DEF_STR(On)) - PORT_DIPNAME( 0x40, 0x00, "Switch 2") PORT_DIPLOCATION("SW2:3") - PORT_DIPSETTING( 0x40, DEF_STR(Off)) - PORT_DIPSETTING( 0x00, DEF_STR(On)) - PORT_DIPNAME( 0x80, 0x80, "Switch 3") PORT_DIPLOCATION("SW2:4") - PORT_DIPSETTING( 0x80, DEF_STR(Off)) - PORT_DIPSETTING( 0x00, DEF_STR(On)) - - PORT_START("FDC") - PORT_BIT( 0xf7, 0, IPT_UNUSED ) - PORT_DIPNAME( 0x08, 0x08, "FDC Test") PORT_DIPLOCATION("SW3:1") - PORT_DIPSETTING( 0x08, DEF_STR(Off)) - PORT_DIPSETTING( 0x00, DEF_STR(On)) -INPUT_PORTS_END - - -void applix_state::machine_reset() -{ - u8* ROM = memregion("maincpu")->base(); - memcpy(m_expansion, ROM, 8); - membank("bank1")->set_entry(0); - m_p3 = 0xff; - m_last_write_addr = 0; - m_maincpu->reset(); -} - -void applix_state::floppy_formats(format_registration &fr) -{ - fr.add_mfm_containers(); - fr.add(FLOPPY_APPLIX_FORMAT); -} - -static void applix_floppies(device_slot_interface &device) -{ - device.option_add("35dd", FLOPPY_35_DD); -} - - -void applix_state::applix_palette(palette_device &palette) const -{ - // shades need to be verified - the names on the right are from the manual - constexpr rgb_t colors[16] = { - { 0x00, 0x00, 0x00 }, // 0 Black - { 0x40, 0x40, 0x40 }, // 1 Dark Grey - { 0x00, 0x00, 0x80 }, // 2 Dark Blue - { 0x00, 0x00, 0xff }, // 3 Mid Blue - { 0x00, 0x80, 0x00 }, // 4 Dark Green - { 0x00, 0xff, 0x00 }, // 5 Green - { 0x00, 0xff, 0xff }, // 6 Blue Grey - { 0x00, 0x7f, 0x7f }, // 7 Light Blue - { 0x7f, 0x00, 0x00 }, // 8 Dark Red - { 0xff, 0x00, 0x00 }, // 9 Red - { 0x7f, 0x00, 0x7f }, // 10 Dark Violet - { 0xff, 0x00, 0xff }, // 11 Violet - { 0x7f, 0x7f, 0x00 }, // 12 Brown - { 0xff, 0xff, 0x00 }, // 13 Yellow - { 0xbf, 0xbf, 0xbf }, // 14 Light Grey - { 0xff, 0xff, 0xff } }; // 15 White - - palette.set_pen_colors(0, colors); -} - - -void applix_state::machine_start() -{ - std::fill(std::begin(m_palette_latch), std::end(m_palette_latch), 0); - - save_item(NAME(m_video_latch)); - save_item(NAME(m_pa)); - save_item(NAME(m_palette_latch)); - save_item(NAME(m_pb)); - save_item(NAME(m_analog_latch)); - save_item(NAME(m_dac_latch)); - save_item(NAME(m_port08)); - save_item(NAME(m_data_to_fdc)); - save_item(NAME(m_data_from_fdc)); - save_item(NAME(m_data)); - save_item(NAME(m_data_or_cmd)); - save_item(NAME(m_buffer_empty)); - save_item(NAME(m_fdc_cmd)); - save_item(NAME(m_clock_count)); - save_item(NAME(m_cp)); - save_item(NAME(m_p1)); - save_item(NAME(m_p1_data)); - save_item(NAME(m_p2)); - save_item(NAME(m_p3)); - save_item(NAME(m_last_write_addr)); - save_item(NAME(m_cass_data)); -} - -MC6845_UPDATE_ROW( applix_state::crtc_update_row ) -{ - if (!de) - return; - // The display is bitmapped. 2 modes are supported here, 320x200x16 and 640x200x4. - // There is a monochrome mode, but no info found as yet. - // The 6845 cursor signal is not used at all. - rgb_t const *const palette = m_palette->palette()->entry_list_raw(); - u32 const vidbase = (m_video_latch & 15) << 14 | (ra & 7) << 12; - u32 *p = &bitmap.pix(y + vbp, hbp); - - for (u16 x = 0; x < x_count; x++) - { - u32 const mem = vidbase | ((ma + x) & 0xfff); - u16 chr = m_base[mem]; - - if (BIT(m_pa, 3)) - { - // 640 x 200 x 4of16 mode - for (int i = 0; i < 8; i++) - { - *p++ = palette[m_palette_latch[chr>>14]]; - chr <<= 2; - } - } - else - { - // 320 x 200 x 16 mode - for (int i = 0; i < 4; i++) - { - *p++ = palette[chr>>12]; - *p++ = palette[chr>>12]; - chr <<= 4; - } - } - } -} - -MC6845_BEGIN_UPDATE( applix_state::crtc_update_border ) -{ - bitmap.fill(m_palette->pen(m_video_latch >> 4), cliprect); -} - -WRITE_LINE_MEMBER( applix_state::vsync_w ) -{ - m_via->write_ca2(state); -} - -TIMER_DEVICE_CALLBACK_MEMBER(applix_state::cass_timer) -{ - /* cassette - turn 2500/5000Hz to a bit */ - m_cass_data[1]++; - u8 cass_ws = (m_cass->input() > +0.03) ? 1 : 0; - - if (cass_ws != m_cass_data[0]) - { - m_cass_data[0] = cass_ws; - m_cass_data[2] = ((m_cass_data[1] < 12) ? 2 : 0); - m_cass_data[1] = 0; - // low-to-high transition when reading cassette - CLK on IC32b - if ((cass_ws) && !BIT(m_pa, 4)) - m_maincpu->set_input_line(M68K_IRQ_4, ASSERT_LINE); - } -} - -void applix_state::applix(machine_config &config) -{ - /* basic machine hardware */ - M68000(config, m_maincpu, 30_MHz_XTAL / 4); // MC68000-P10 @ 7.5 MHz - m_maincpu->set_addrmap(AS_PROGRAM, &applix_state::main_mem); - - z80_device &subcpu(Z80(config, "subcpu", 16_MHz_XTAL / 2)); // Z80H - subcpu.set_addrmap(AS_PROGRAM, &applix_state::sub_mem); - subcpu.set_addrmap(AS_IO, &applix_state::sub_io); - - i8051_device &kbdcpu(I8051(config, "kbdcpu", 11060250)); - kbdcpu.set_addrmap(AS_PROGRAM, &applix_state::keytronic_pc3270_program); - kbdcpu.set_addrmap(AS_IO, &applix_state::keytronic_pc3270_io); - kbdcpu.port_in_cb<1>().set(FUNC(applix_state::p1_read)); - kbdcpu.port_out_cb<1>().set(FUNC(applix_state::p1_write)); - kbdcpu.port_in_cb<2>().set(FUNC(applix_state::p2_read)); - kbdcpu.port_out_cb<2>().set(FUNC(applix_state::p2_write)); - kbdcpu.port_in_cb<3>().set(FUNC(applix_state::p3_read)); - kbdcpu.port_out_cb<3>().set(FUNC(applix_state::p3_write)); - - /* video hardware */ - screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_refresh_hz(50); - screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */ - screen.set_size(640, 200); - screen.set_visarea_full(); - screen.set_screen_update("crtc", FUNC(mc6845_device::screen_update)); - PALETTE(config, m_palette, FUNC(applix_state::applix_palette), 16); - - /* sound hardware */ - SPEAKER(config, "lspeaker").front_left(); - SPEAKER(config, "rspeaker").front_right(); - DAC0800(config, "ldac", 0).add_route(ALL_OUTPUTS, "lspeaker", 1.0); // 74ls374.u20 + dac0800.u21 + 4052.u23 - DAC0800(config, "rdac", 0).add_route(ALL_OUTPUTS, "rspeaker", 1.0); // 74ls374.u20 + dac0800.u21 + 4052.u23 - - /* Devices */ - MC6845(config, m_crtc, 30_MHz_XTAL / 16); // MC6545 @ 1.875 MHz - m_crtc->set_screen("screen"); - m_crtc->set_show_border_area(true); - m_crtc->set_char_width(8); - m_crtc->set_update_row_callback(FUNC(applix_state::crtc_update_row)); - m_crtc->set_begin_update_callback(FUNC(applix_state::crtc_update_border)); - m_crtc->out_vsync_callback().set(FUNC(applix_state::vsync_w)); - - MOS6522(config, m_via, 30_MHz_XTAL / 4 / 10); // VIA uses 68000 E clock - m_via->readpb_handler().set(FUNC(applix_state::applix_pb_r)); - // in CB1 kbd clk - // in CA2 vsync - // in CB2 kdb data - m_via->writepa_handler().set(FUNC(applix_state::applix_pa_w)); - m_via->writepb_handler().set(FUNC(applix_state::applix_pb_w)); - m_via->irq_handler().set_inputline("maincpu", M68K_IRQ_2); - - CENTRONICS(config, m_centronics, centronics_devices, "printer"); - m_centronics->ack_handler().set(m_via, FUNC(via6522_device::write_ca1)); - m_centronics->busy_handler().set(m_via, FUNC(via6522_device::write_pa0)); - - OUTPUT_LATCH(config, m_cent_data_out); - m_centronics->set_output_latch(*m_cent_data_out); - - CASSETTE(config, m_cass); - m_cass->set_default_state(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED); - m_cass->add_route(ALL_OUTPUTS, "lspeaker", 0.10); - - WD1772(config, m_fdc, 16_MHz_XTAL / 2); //connected to Z80H clock pin - FLOPPY_CONNECTOR(config, "fdc:0", applix_floppies, "35dd", applix_state::floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "fdc:1", applix_floppies, "35dd", applix_state::floppy_formats).enable_sound(true); - TIMER(config, "applix_c").configure_periodic(FUNC(applix_state::cass_timer), attotime::from_hz(100000)); - - scc8530_device &scc(SCC8530N(config, "scc", 30_MHz_XTAL / 8)); - scc.out_txda_callback().set("serial_a", FUNC(rs232_port_device::write_txd)); - scc.out_rtsa_callback().set("serial_a", FUNC(rs232_port_device::write_rts)); - scc.out_dtra_callback().set("serial_a", FUNC(rs232_port_device::write_dtr)); - scc.out_txdb_callback().set("serial_b", FUNC(rs232_port_device::write_txd)); - scc.out_rtsb_callback().set("serial_b", FUNC(rs232_port_device::write_rts)); - scc.out_dtrb_callback().set("serial_b", FUNC(rs232_port_device::write_dtr)); - scc.out_int_callback().set_inputline("maincpu", M68K_IRQ_3); - - rs232_port_device &serial_a(RS232_PORT(config, "serial_a", default_rs232_devices, nullptr)); - serial_a.rxd_handler().set("scc", FUNC(scc8530_device::rxa_w)); - serial_a.cts_handler().set("scc", FUNC(scc8530_device::ctsa_w)); - serial_a.cts_handler().set("scc", FUNC(scc8530_device::dcda_w)); - - rs232_port_device &serial_b(RS232_PORT(config, "serial_b", default_rs232_devices, nullptr)); - serial_b.rxd_handler().set("scc", FUNC(scc8530_device::rxb_w)); - serial_b.cts_handler().set("scc", FUNC(scc8530_device::ctsb_w)); - serial_b.cts_handler().set("scc", FUNC(scc8530_device::dcdb_w)); - - SOFTWARE_LIST(config, "flop_list").set_original("applix_flop"); -} - -/* ROM definition */ -ROM_START( applix ) - ROM_REGION16_BE(0x20000, "maincpu", 0) - ROM_SYSTEM_BIOS(0, "v4.5a", "V4.5a") - ROMX_LOAD( "1616osl.45a", 0x00000, 0x10000, CRC(9dfb3224) SHA1(5223833a357f90b147f25826c01713269fc1945f), ROM_SKIP(1) | ROM_BIOS(0) ) - ROMX_LOAD( "1616osh.45a", 0x00001, 0x10000, CRC(951bd441) SHA1(e0a38c8d0d38d84955c1de3f6a7d56ce06b063f6), ROM_SKIP(1) | ROM_BIOS(0) ) - ROM_SYSTEM_BIOS(1, "v4.4a", "V4.4a") - ROMX_LOAD( "1616osl.44a", 0x00000, 0x10000, CRC(4a1a90d3) SHA1(4df504bbf6fc5dad76c29e9657bfa556500420a6), ROM_SKIP(1) | ROM_BIOS(1) ) - ROMX_LOAD( "1616osh.44a", 0x00001, 0x10000, CRC(ef619994) SHA1(ff16fe9e2c99a1ffc855baf89278a97a2a2e881a), ROM_SKIP(1) | ROM_BIOS(1) ) - ROM_SYSTEM_BIOS(2, "v4.3a", "V4.3a") - ROMX_LOAD( "1616osl.43a", 0x00000, 0x10000, CRC(c09b9ff8) SHA1(c46f2a98470d2d09cf9f9eec0f4096ab762407b5), ROM_SKIP(1) | ROM_BIOS(2) ) - ROMX_LOAD( "1616osh.43a", 0x00001, 0x10000, CRC(071a2505) SHA1(42c4cc6e3e78b6a5320f9d9c858fc9f4e6220857), ROM_SKIP(1) | ROM_BIOS(2) ) - ROM_SYSTEM_BIOS(3, "v4.0c", "V4.0c") - ROMX_LOAD( "1616osl.40c", 0x00000, 0x10000, CRC(6a517b5d) SHA1(e0f4eba0cb8d273ba681b9d2c6d4b1beff9ef325), ROM_SKIP(1) | ROM_BIOS(3) ) - ROMX_LOAD( "1616osh.40c", 0x00001, 0x10000, CRC(7851651f) SHA1(d7d329aa7fe9f4418de0cdf813b61e70243e0e77), ROM_SKIP(1) | ROM_BIOS(3) ) - ROM_SYSTEM_BIOS(4, "v3.0b", "V3.0b") - ROMX_LOAD( "1616osl.30b", 0x00000, 0x10000, CRC(fb9198c3) SHA1(e0e7a1dd176c1cbed063df1c405821c261d48f3a), ROM_SKIP(1) | ROM_BIOS(4) ) - ROMX_LOAD( "1616osh.30b", 0x00001, 0x10000, CRC(a279e1d7) SHA1(3451b2cae87a9ccee5f579fd1d49cf52d9f97b83), ROM_SKIP(1) | ROM_BIOS(4) ) - ROM_SYSTEM_BIOS(5, "v2.4a", "V2.4a") - ROMX_LOAD( "1616osl.24a", 0x00000, 0x08000, CRC(b155830b) SHA1(b32db6a06c8a3c544210ba9faba7c49497c504fb), ROM_SKIP(1) | ROM_BIOS(5) ) - ROMX_LOAD( "1616osh.24a", 0x00001, 0x08000, CRC(6d9fc0e0) SHA1(07111f46386494ed3f426c1e50308f0209587f06), ROM_SKIP(1) | ROM_BIOS(5) ) - - ROM_REGION(0x18000, "subcpu", 0) - ROM_LOAD( "1616ssdv.022", 0x0000, 0x8000, CRC(6d8e413a) SHA1(fc27d92c34f231345a387b06670f36f8c1705856) ) - - ROM_REGION(0x20000, "user1", 0) - ROM_LOAD( "ssdcromv.22", 0x0000, 0x8000, CRC(c85c47fb) SHA1(6f0bb3753fc0d74ee5901d71d05a74ec6a4a1d05) ) - ROM_LOAD( "ssddromv.14a", 0x8000, 0x8000, CRC(8fe2db78) SHA1(487484003aba4d8960101ced6a689dc81676235d) ) - - ROM_REGION(0x2000, "kbdcpu", 0) - ROM_LOAD( "14166.bin", 0x0000, 0x2000, CRC(1aea1b53) SHA1(b75b6d4509036406052157bc34159f7039cdc72e) ) -ROM_END - - -void applix_state::init_applix() -{ - u8 *RAM = memregion("subcpu")->base(); - membank("bank1")->configure_entries(0, 2, &RAM[0x8000], 0x8000); -} - - -/* Driver */ - -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1986, applix, 0, 0, applix, applix, applix_state, init_applix, "Applix Pty Ltd", "Applix 1616", MACHINE_SUPPORTS_SAVE ) - - - -/**************************************************** KEYBOARD MODULE *****************************************/ - -u8 applix_state::internal_data_read(offs_t offset) -{ - m_via->write_cb2( BIT(offset, 8) ); // data - bool cp = !BIT(offset, 9); // clock pulses //TODO tidy this up with real flipflops - if (cp != m_cp) - { - m_cp = cp; - if (cp) - m_clock_count++; - } - if (m_clock_count > 1) - m_via->write_cb1( cp ); - - return 0xff; -} - - -void applix_state::internal_data_write(offs_t offset, u8 data) -{ - /* Check for low->high transition on AD8 */ - if ( ! ( m_last_write_addr & 0x0100 ) && ( offset & 0x0100 ) ) - { - switch (m_p1) - { - case 0x0e: - break; - case 0x0f: - m_p1_data = m_io_k0f->read(); - break; - case 0x30: - m_p1_data = m_io_k300->read(); - break; - case 0x31: - m_p1_data = m_io_k310->read(); - break; - case 0x32: - m_p1_data = m_io_k320->read(); - break; - case 0x33: - m_p1_data = m_io_k330->read(); - break; - case 0x34: - m_p1_data = m_io_k340->read(); - break; - case 0x35: - m_p1_data = m_io_k350->read(); - break; - case 0x36: - m_p1_data = m_io_k360->read(); - break; - case 0x37: - m_p1_data = m_io_k370->read() | (m_io_k360->read() & 0x01); - break; - case 0x38: - m_p1_data = m_io_k380->read(); - break; - case 0x39: - m_p1_data = m_io_k390->read(); - break; - case 0x3a: - m_p1_data = m_io_k3a0->read(); - break; - case 0x3b: - m_p1_data = m_io_k3b0->read(); - break; - } - } - - /* Check for low->high transition on AD9 */ - if ( ! ( m_last_write_addr & 0x0200 ) && ( offset & 0x0200 ) ) - { - switch (m_p1) - { - case 0x0b: - m_p1_data = m_io_k0b->read(); - break; - case 0x30: - m_p1_data = m_io_k301->read(); - break; - case 0x31: - m_p1_data = m_io_k311->read(); - break; - case 0x32: - m_p1_data = m_io_k321->read(); - break; - case 0x33: - m_p1_data = m_io_k331->read(); - break; - case 0x34: - m_p1_data = m_io_k341->read(); - break; - case 0x35: - m_p1_data = m_io_k351->read(); - break; - case 0x36: - m_p1_data = m_io_k361->read(); - break; - case 0x37: - m_p1_data = m_io_k371->read(); - break; - case 0x38: - m_p1_data = 0xff; - break; - case 0x39: - m_p1_data = 0xff; - break; - case 0x3a: - m_p1_data = 0xff; - break; - } - } - - m_last_write_addr = offset; -} - - -u8 applix_state::p1_read() -{ - return m_p1 & m_p1_data; -} - - -void applix_state::p1_write(u8 data) -{ - m_p1 = data; -} - - -u8 applix_state::p2_read() -{ - return m_p2; -} - - -void applix_state::p2_write(u8 data) -{ - m_p2 = data; -} - - -u8 applix_state::p3_read() -{ - u8 data = m_p3; - - data &= ~0x14; - - /* -INT0 signal */ - data |= 4; - - /* T0 signal */ - data |= 0; - - return data; -} - - -void applix_state::p3_write(u8 data) -{ - m_p3 = data; -} diff --git a/src/mame/skeleton/aussiebyte.cpp b/src/mame/skeleton/aussiebyte.cpp deleted file mode 100644 index 3d452580ed7..00000000000 --- a/src/mame/skeleton/aussiebyte.cpp +++ /dev/null @@ -1,619 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Robbbert -/************************************************************************************************* - - The Aussie Byte II Single-Board Computer, created by SME Systems, Melbourne, Australia. - Also known as the Knight 2000 Microcomputer. - - Status: - Boots up from floppy. - Output to serial terminal and to 6545 are working. Serial keyboard works. - - Developed in conjunction with members of the MSPP. Written in July, 2015. - - ToDo: - - CRT8002 attributes controller - - Graphics - - Hard drive controllers and drives - - Test Centronics printer - - PIO connections - - Note of MAME restrictions: - - Votrax doesn't sound anything like the real thing - - WD1001/WD1002 device is not emulated - - CRT8002 device is not emulated - -**************************************************************************************************/ - -/*********************************************************** - - Includes - -************************************************************/ -#include "emu.h" -#include "aussiebyte.h" - -#include "screen.h" -#include "softlist_dev.h" -#include "speaker.h" - - -/*********************************************************** - - Address Maps - -************************************************************/ - -void aussiebyte_state::mem_map(address_map &map) -{ - map(0x0000, 0x3fff).bankr("bankr0").bankw("bankw0"); - map(0x4000, 0x7fff).bankrw("bank1"); - map(0x8000, 0xbfff).bankrw("bank2"); - map(0xc000, 0xffff).ram(); -} - -void aussiebyte_state::io_map(address_map &map) -{ - map.global_mask(0xff); - map.unmap_value_high(); - map(0x00, 0x03).rw("sio1", FUNC(z80sio_device::ba_cd_r), FUNC(z80sio_device::ba_cd_w)); - map(0x04, 0x07).rw(m_pio1, FUNC(z80pio_device::read), FUNC(z80pio_device::write)); - map(0x08, 0x0b).rw(m_ctc, FUNC(z80ctc_device::read), FUNC(z80ctc_device::write)); - map(0x0c, 0x0f).noprw(); // winchester interface - map(0x10, 0x13).rw(m_fdc, FUNC(wd2797_device::read), FUNC(wd2797_device::write)); - map(0x14, 0x14).rw(m_dma, FUNC(z80dma_device::read), FUNC(z80dma_device::write)); - map(0x15, 0x15).w(FUNC(aussiebyte_state::port15_w)); // boot rom disable - map(0x16, 0x16).w(FUNC(aussiebyte_state::port16_w)); // fdd select - map(0x17, 0x17).w(FUNC(aussiebyte_state::port17_w)); // DMA mux - map(0x18, 0x18).w(FUNC(aussiebyte_state::port18_w)); // fdc select - map(0x19, 0x19).r(FUNC(aussiebyte_state::port19_r)); // info port - map(0x1a, 0x1a).w(FUNC(aussiebyte_state::port1a_w)); // membank - map(0x1b, 0x1b).w(FUNC(aussiebyte_state::port1b_w)); // winchester control - map(0x1c, 0x1f).w(FUNC(aussiebyte_state::port1c_w)); // gpebh select - map(0x20, 0x23).rw(m_pio2, FUNC(z80pio_device::read), FUNC(z80pio_device::write)); - map(0x24, 0x27).rw("sio2", FUNC(z80sio_device::ba_cd_r), FUNC(z80sio_device::ba_cd_w)); - map(0x28, 0x28).r(FUNC(aussiebyte_state::port28_r)).w(m_votrax, FUNC(votrax_sc01_device::write)); - map(0x2c, 0x2c).w(m_votrax, FUNC(votrax_sc01_device::inflection_w)); - map(0x30, 0x30).w(FUNC(aussiebyte_state::address_w)); - map(0x31, 0x31).r(m_crtc, FUNC(mc6845_device::status_r)); - map(0x32, 0x32).w(FUNC(aussiebyte_state::register_w)); - map(0x33, 0x33).r(FUNC(aussiebyte_state::port33_r)); - map(0x34, 0x34).w(FUNC(aussiebyte_state::port34_w)); // video control - map(0x35, 0x35).w(FUNC(aussiebyte_state::port35_w)); // data to vram and aram - map(0x36, 0x36).r(FUNC(aussiebyte_state::port36_r)); // data from vram and aram - map(0x37, 0x37).r(FUNC(aussiebyte_state::port37_r)); // read dispen flag - map(0x40, 0x4f).rw(FUNC(aussiebyte_state::rtc_r), FUNC(aussiebyte_state::rtc_w)); -} - -/*********************************************************** - - Keyboard - -************************************************************/ -static INPUT_PORTS_START( aussiebyte ) -INPUT_PORTS_END - -/*********************************************************** - - I/O Ports - -************************************************************/ -void aussiebyte_state::port15_w(u8 data) -{ - m_bankr0->set_entry(m_port15); // point at ram - m_port15 = true; -} - -/* FDD select -0 Drive Select bit O -1 Drive Select bit 1 -2 Drive Select bit 2 -3 Drive Select bit 3 - - These bits connect to a 74LS145 binary to BCD converter. - - Drives 0 to 3 are 5.25 inch, 4 to 7 are 8 inch, 9 and 0 are not used. - - Currently we only support drive 0. -4 Side Select to Disk Drives. -5 Disable 5.25 inch floppy spindle motors. -6 Unused. -7 Enable write precompensation on WD2797 controller. */ -void aussiebyte_state::port16_w(u8 data) -{ - floppy_image_device *m_floppy = nullptr; - if ((data & 15) == 0) - m_floppy = m_floppy0->get_device(); - else - if ((data & 15) == 1) - m_floppy = m_floppy1->get_device(); - - m_fdc->set_floppy(m_floppy); - - if (m_floppy) - { - m_floppy->mon_w(BIT(data, 5)); - m_floppy->ss_w(BIT(data, 4)); - } -} - -/* DMA select -0 - FDC -1 - SIO Ch A -2 - SIO Ch B -3 - Winchester bus -4 - SIO Ch C -5 - SIO Ch D -6 - Ext ready 1 -7 - Ext ready 2 */ -void aussiebyte_state::port17_w(u8 data) -{ - m_port17 = data & 7; - m_dma->rdy_w(BIT(m_port17_rdy, data)); -} - -/* FDC params -2 EXC: WD2797 clock frequency. H = 5.25"; L = 8" -3 WIEN: WD2797 Double density select. */ -void aussiebyte_state::port18_w(u8 data) -{ - m_fdc->set_unscaled_clock(BIT(data, 2) ? 1e6 : 2e6); - m_fdc->dden_w(BIT(data, 3)); -} - -u8 aussiebyte_state::port19_r() -{ - return m_port19; -} - -// Memory banking -void aussiebyte_state::port1a_w(u8 data) -{ - data &= 7; - switch (data) - { - case 0: - case 1: - case 2: - case 3: - case 4: - m_port1a = data*3+1; - if (m_port15) - m_bankr0->set_entry(data*3+1); - m_bankw0->set_entry(data*3+1); - m_bank1->set_entry(data*3+2); - m_bank2->set_entry(data*3+3); - break; - case 5: - m_port1a = 1; - if (m_port15) - m_bankr0->set_entry(1); - m_bankw0->set_entry(1); - m_bank1->set_entry(2); - m_bank2->set_entry(13); - break; - case 6: - m_port1a = 14; - if (m_port15) - m_bankr0->set_entry(14); - m_bankw0->set_entry(14); - m_bank1->set_entry(15); - //m_bank2->set_entry(0); // open bus - break; - case 7: - m_port1a = 1; - if (m_port15) - m_bankr0->set_entry(1); - m_bankw0->set_entry(1); - m_bank1->set_entry(4); - m_bank2->set_entry(13); - break; - } -} - -// Winchester control -void aussiebyte_state::port1b_w(u8 data) -{ -} - -// GPEHB control -void aussiebyte_state::port1c_w(u8 data) -{ -} - -void aussiebyte_state::port20_w(u8 data) -{ - m_speaker->level_w(BIT(data, 7)); - m_rtc->cs_w(BIT(data, 0)); - m_rtc->hold_w(BIT(data, 0)); -} - -u8 aussiebyte_state::port28_r() -{ - return m_port28; -} - -/*********************************************************** - - RTC - -************************************************************/ -u8 aussiebyte_state::rtc_r(offs_t offset) -{ - m_rtc->read_w(1); - m_rtc->address_w(offset); - u8 data = m_rtc->data_r(); - m_rtc->read_w(0); - return data; -} - -void aussiebyte_state::rtc_w(offs_t offset, u8 data) -{ - m_rtc->address_w(offset); - m_rtc->data_w(data); - m_rtc->write_w(1); - m_rtc->write_w(0); -} - -/*********************************************************** - - DMA - -************************************************************/ -u8 aussiebyte_state::memory_read_byte(offs_t offset) -{ - address_space& prog_space = m_maincpu->space(AS_PROGRAM); - return prog_space.read_byte(offset); -} - -void aussiebyte_state::memory_write_byte(offs_t offset, u8 data) -{ - address_space& prog_space = m_maincpu->space(AS_PROGRAM); - prog_space.write_byte(offset, data); -} - -u8 aussiebyte_state::io_read_byte(offs_t offset) -{ - address_space& prog_space = m_maincpu->space(AS_IO); - return prog_space.read_byte(offset); -} - -void aussiebyte_state::io_write_byte(offs_t offset, u8 data) -{ - address_space& prog_space = m_maincpu->space(AS_IO); - prog_space.write_byte(offset, data); -} - -WRITE_LINE_MEMBER( aussiebyte_state::busreq_w ) -{ -// since our Z80 has no support for BUSACK, we assume it is granted immediately - m_maincpu->set_input_line(Z80_INPUT_LINE_BUSRQ, state); - m_dma->bai_w(state); // tell dma that bus has been granted -} - -/*********************************************************** - - DMA selector - -************************************************************/ -WRITE_LINE_MEMBER( aussiebyte_state::sio1_rdya_w ) -{ - m_port17_rdy = (m_port17_rdy & 0xfd) | (u8)(state << 1); - if (m_port17 == 1) - m_dma->rdy_w(state); -} - -WRITE_LINE_MEMBER( aussiebyte_state::sio1_rdyb_w ) -{ - m_port17_rdy = (m_port17_rdy & 0xfb) | (u8)(state << 2); - if (m_port17 == 2) - m_dma->rdy_w(state); -} - -WRITE_LINE_MEMBER( aussiebyte_state::sio2_rdya_w ) -{ - m_port17_rdy = (m_port17_rdy & 0xef) | (u8)(state << 4); - if (m_port17 == 4) - m_dma->rdy_w(state); -} - -WRITE_LINE_MEMBER( aussiebyte_state::sio2_rdyb_w ) -{ - m_port17_rdy = (m_port17_rdy & 0xdf) | (u8)(state << 5); - if (m_port17 == 5) - m_dma->rdy_w(state); -} - - -/*********************************************************** - - Video - -************************************************************/ - -/* F4 Character Displayer */ -static const gfx_layout crt8002_charlayout = -{ - 8, 12, /* 7 x 11 characters */ - 128, /* 128 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, 9*8, 10*8, 11*8 }, - 8*16 /* every char takes 16 bytes */ -}; - -static GFXDECODE_START( gfx_crt8002 ) - GFXDECODE_ENTRY( "chargen", 0x0000, crt8002_charlayout, 0, 1 ) -GFXDECODE_END - -/*************************************************************** - - Daisy Chain - -****************************************************************/ - -static const z80_daisy_config daisy_chain_intf[] = -{ - { "dma" }, - { "pio2" }, - { "sio1" }, - { "sio2" }, - { "pio1" }, - { "ctc" }, - { nullptr } -}; - - -/*********************************************************** - - Floppy Disk - -************************************************************/ - -WRITE_LINE_MEMBER( aussiebyte_state::fdc_intrq_w ) -{ - u8 data = (m_port19 & 0xbf) | (state ? 0x40 : 0); - m_port19 = data; -} - -WRITE_LINE_MEMBER( aussiebyte_state::fdc_drq_w ) -{ - u8 data = (m_port19 & 0x7f) | (state ? 0x80 : 0); - m_port19 = data; - state ^= 1; // inverter on pin38 of fdc - m_port17_rdy = (m_port17_rdy & 0xfe) | (u8)state; - if (m_port17 == 0) - m_dma->rdy_w(state); -} - -static void aussiebyte_floppies(device_slot_interface &device) -{ - device.option_add("525qd", FLOPPY_525_QD); -} - - -/*********************************************************** - - Quickload - - This loads a .COM file to address 0x100 then jumps - there. Sometimes .COM has been renamed to .CPM to - prevent windows going ballistic. These can be loaded - as well. - -************************************************************/ - -QUICKLOAD_LOAD_MEMBER(aussiebyte_state::quickload_cb) -{ - address_space& prog_space = m_maincpu->space(AS_PROGRAM); - - if (image.length() >= 0xfd00) - return image_init_result::FAIL; - - /* RAM must be banked in */ - m_port15 = true; // disable boot rom - m_port1a = 4; - m_bankr0->set_entry(m_port1a); /* enable correct program bank */ - m_bankw0->set_entry(m_port1a); - - /* Avoid loading a program if CP/M-80 is not in memory */ - if ((prog_space.read_byte(0) != 0xc3) || (prog_space.read_byte(5) != 0xc3)) - { - machine_reset(); - return image_init_result::FAIL; - } - - /* Load image to the TPA (Transient Program Area) */ - u16 quickload_size = image.length(); - for (u16 i = 0; i < quickload_size; i++) - { - u8 data; - if (image.fread( &data, 1) != 1) - return image_init_result::FAIL; - prog_space.write_byte(i+0x100, data); - } - - /* clear out command tail */ - prog_space.write_byte(0x80, 0); prog_space.write_byte(0x81, 0); - - /* Roughly set SP basing on the BDOS position */ - m_maincpu->set_state_int(Z80_SP, 256 * prog_space.read_byte(7) - 0x400); - m_maincpu->set_pc(0x100); // start program - - return image_init_result::PASS; -} - -/*********************************************************** - - Machine Driver - -************************************************************/ -void aussiebyte_state::machine_reset() -{ - m_port15 = false; - m_port17 = 0; - m_port17_rdy = 0; - m_port1a = 1; - m_alpha_address = 0; - m_graph_address = 0; - m_bankr0->set_entry(16); // point at rom - m_bankw0->set_entry(1); // always write to ram - m_bank1->set_entry(2); - m_bank2->set_entry(3); - m_maincpu->reset(); -} - -void aussiebyte_state::machine_start() -{ - m_vram = std::make_unique(0x10000); - m_aram = std::make_unique(0x800); - m_ram = make_unique_clear(0x40000); - save_pointer(NAME(m_vram), 0x10000); - save_pointer(NAME(m_aram), 0x800); - save_pointer(NAME(m_ram), 0x40000); - save_item(NAME(m_port15)); - save_item(NAME(m_port17)); - save_item(NAME(m_port17_rdy)); - save_item(NAME(m_port19)); - save_item(NAME(m_port1a)); - save_item(NAME(m_port28)); - save_item(NAME(m_port34)); - save_item(NAME(m_port35)); - save_item(NAME(m_video_index)); - save_item(NAME(m_cnt)); - save_item(NAME(m_alpha_address)); - save_item(NAME(m_graph_address)); - save_item(NAME(m_centronics_busy)); - - // Main ram is divided into 16k blocks (0-15). The boot rom is block number 16. - // For convenience, bank 0 is permanently assigned to C000-FFFF - - m_bankr0->configure_entries(0, 16, m_p_mram, 0x4000); - m_bankw0->configure_entries(0, 16, m_p_mram, 0x4000); - m_bank1->configure_entries(0, 16, m_p_mram, 0x4000); - m_bank2->configure_entries(0, 16, m_p_mram, 0x4000); - m_bankr0->configure_entry(16, memregion("roms")->base()); - - m_cnt = 0; -} - - -void aussiebyte_state::aussiebyte(machine_config &config) -{ - /* basic machine hardware */ - Z80(config, m_maincpu, 16_MHz_XTAL / 4); - m_maincpu->set_addrmap(AS_PROGRAM, &aussiebyte_state::mem_map); - m_maincpu->set_addrmap(AS_IO, &aussiebyte_state::io_map); - m_maincpu->set_daisy_config(daisy_chain_intf); - - /* video hardware */ - screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_raw(16_MHz_XTAL, 952, 0, 640, 336, 0, 288); - screen.set_screen_update("crtc", FUNC(sy6545_1_device::screen_update)); - - GFXDECODE(config, "gfxdecode", "palette", gfx_crt8002); - PALETTE(config, m_palette, palette_device::MONOCHROME); - - /* sound hardware */ - SPEAKER(config, "mono").front_center(); - SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.50); - VOTRAX_SC01(config, m_votrax, 720000); // 720kHz? needs verify - m_votrax->ar_callback().set([this] (bool state) { m_port28 = state ? 0 : 1; }); - m_votrax->add_route(ALL_OUTPUTS, "mono", 1.00); - - /* devices */ - CENTRONICS(config, m_centronics, centronics_devices, "printer"); - m_centronics->set_data_input_buffer("cent_data_in"); - m_centronics->busy_handler().set([this] (bool state) { m_centronics_busy = state; }); - INPUT_BUFFER(config, "cent_data_in"); - output_latch_device ¢_data_out(OUTPUT_LATCH(config, "cent_data_out")); - m_centronics->set_output_latch(cent_data_out); - - Z80CTC(config, m_ctc, 16_MHz_XTAL / 4); - m_ctc->intr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); - m_ctc->set_clk<0>(4.9152_MHz_XTAL / 4); - m_ctc->set_clk<1>(4.9152_MHz_XTAL / 4); - m_ctc->set_clk<2>(4.9152_MHz_XTAL / 4); - m_ctc->zc_callback<0>().set("sio1", FUNC(z80sio_device::rxca_w)); - m_ctc->zc_callback<0>().append("sio1", FUNC(z80sio_device::txca_w)); - m_ctc->zc_callback<1>().set("sio1", FUNC(z80sio_device::rxtxcb_w)); - m_ctc->zc_callback<1>().append("sio2", FUNC(z80sio_device::rxca_w)); - m_ctc->zc_callback<1>().append("sio2", FUNC(z80sio_device::txca_w)); - m_ctc->zc_callback<2>().set("ctc", FUNC(z80ctc_device::trg3)); - m_ctc->zc_callback<2>().append("sio2", FUNC(z80sio_device::rxtxcb_w)); - - Z80DMA(config, m_dma, 16_MHz_XTAL / 4); - m_dma->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); - m_dma->out_busreq_callback().set(FUNC(aussiebyte_state::busreq_w)); - // BAO, not used - m_dma->in_mreq_callback().set(FUNC(aussiebyte_state::memory_read_byte)); - m_dma->out_mreq_callback().set(FUNC(aussiebyte_state::memory_write_byte)); - m_dma->in_iorq_callback().set(FUNC(aussiebyte_state::io_read_byte)); - m_dma->out_iorq_callback().set(FUNC(aussiebyte_state::io_write_byte)); - - Z80PIO(config, m_pio1, 16_MHz_XTAL / 4); - m_pio1->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); - m_pio1->out_pa_callback().set("cent_data_out", FUNC(output_latch_device::write)); - m_pio1->in_pb_callback().set("cent_data_in", FUNC(input_buffer_device::read)); - m_pio1->out_ardy_callback().set(m_centronics, FUNC(centronics_device::write_strobe)).invert(); - - Z80PIO(config, m_pio2, 16_MHz_XTAL / 4); - m_pio2->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); - m_pio2->out_pa_callback().set(FUNC(aussiebyte_state::port20_w)); - - z80sio_device& sio1(Z80SIO(config, "sio1", 16_MHz_XTAL / 4)); - sio1.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); - sio1.out_wrdya_callback().set(FUNC(aussiebyte_state::sio1_rdya_w)); - sio1.out_wrdyb_callback().set(FUNC(aussiebyte_state::sio1_rdyb_w)); - - z80sio_device& sio2(Z80SIO(config, "sio2", 16_MHz_XTAL / 4)); - sio2.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); - sio2.out_wrdya_callback().set(FUNC(aussiebyte_state::sio2_rdya_w)); - sio2.out_wrdyb_callback().set(FUNC(aussiebyte_state::sio2_rdyb_w)); - sio2.out_txda_callback().set("rs232", FUNC(rs232_port_device::write_txd)); - sio2.out_dtra_callback().set("rs232", FUNC(rs232_port_device::write_dtr)); - sio2.out_rtsa_callback().set("rs232", FUNC(rs232_port_device::write_rts)); - - RS232_PORT(config, m_rs232, default_rs232_devices, "keyboard"); - m_rs232->rxd_handler().set("sio2", FUNC(z80sio_device::rxa_w)); - - WD2797(config, m_fdc, 16_MHz_XTAL / 16); - m_fdc->intrq_wr_callback().set(FUNC(aussiebyte_state::fdc_intrq_w)); - m_fdc->drq_wr_callback().set(FUNC(aussiebyte_state::fdc_drq_w)); - FLOPPY_CONNECTOR(config, "fdc:0", aussiebyte_floppies, "525qd", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "fdc:1", aussiebyte_floppies, "525qd", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); - - /* devices */ - SY6545_1(config, m_crtc, 16_MHz_XTAL / 8); - m_crtc->set_screen("screen"); - m_crtc->set_show_border_area(false); - m_crtc->set_char_width(8); - m_crtc->set_update_row_callback(FUNC(aussiebyte_state::crtc_update_row)); - m_crtc->set_on_update_addr_change_callback(FUNC(aussiebyte_state::crtc_update_addr)); - - MSM5832(config, m_rtc, 32.768_kHz_XTAL); - - /* quickload */ - QUICKLOAD(config, "quickload", "com,cpm", attotime::from_seconds(3)).set_load_callback(FUNC(aussiebyte_state::quickload_cb)); - - SOFTWARE_LIST(config, "flop_list").set_original("aussiebyte"); -} - - -/*********************************************************** - - Game driver - -************************************************************/ - - -ROM_START(aussieby) - ROM_REGION(0x4000, "roms", 0) // Size of bank 16 - ROM_LOAD( "knight_boot_0000.u27", 0x0000, 0x1000, CRC(1f200437) SHA1(80d1d208088b325c16a6824e2da605fb2b00c2ce) ) - - ROM_REGION(0x800, "chargen", 0) - ROM_LOAD( "8002.bin", 0x0000, 0x0800, CRC(fdd6eb13) SHA1(a094d416e66bdab916e72238112a6265a75ca690) ) -ROM_END - -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1984, aussieby, 0, 0, aussiebyte, aussiebyte, aussiebyte_state, empty_init, "SME Systems", "Aussie Byte II", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/skeleton/aussiebyte.h b/src/mame/skeleton/aussiebyte.h deleted file mode 100644 index 046307795b2..00000000000 --- a/src/mame/skeleton/aussiebyte.h +++ /dev/null @@ -1,157 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Robbbert -#ifndef MAME_INCLUDES_AUSSIEBYTE_H -#define MAME_INCLUDES_AUSSIEBYTE_H - -#pragma once - -/*********************************************************** - - Includes - -************************************************************/ -#include "bus/centronics/ctronics.h" -#include "bus/rs232/rs232.h" - -#include "cpu/z80/z80.h" -#include "machine/z80daisy.h" - -#include "imagedev/floppy.h" -#include "machine/msm5832.h" -#include "machine/wd_fdc.h" -#include "machine/z80ctc.h" -#include "machine/z80sio.h" -#include "machine/z80dma.h" -#include "machine/z80pio.h" - -#include "sound/spkrdev.h" -#include "sound/votrax.h" - -#include "video/mc6845.h" - -#include "imagedev/snapquik.h" - -#include "emupal.h" - - - -/*********************************************************** - - Class - -************************************************************/ -class aussiebyte_state : public driver_device -{ -public: - aussiebyte_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_palette(*this, "palette") - , m_maincpu(*this, "maincpu") - , m_bankr0(*this, "bankr0") - , m_bankw0(*this, "bankw0") - , m_bank1(*this, "bank1") - , m_bank2(*this, "bank2") - , m_p_chargen(*this, "chargen") - , m_p_mram(*this, "mram", 0x40000, ENDIANNESS_LITTLE) - , m_p_videoram(*this, "vram", 0x10000, ENDIANNESS_LITTLE) - , m_p_attribram(*this, "aram", 0x800, ENDIANNESS_LITTLE) - , m_ctc(*this, "ctc") - , m_dma(*this, "dma") - , m_pio1(*this, "pio1") - , m_pio2(*this, "pio2") - , m_centronics(*this, "centronics") - , m_rs232(*this, "rs232") - , m_fdc(*this, "fdc") - , m_floppy0(*this, "fdc:0") - , m_floppy1(*this, "fdc:1") - , m_crtc(*this, "crtc") - , m_speaker(*this, "speaker") - , m_votrax(*this, "votrax") - , m_rtc(*this, "rtc") - { } - - void aussiebyte(machine_config &config); - - DECLARE_QUICKLOAD_LOAD_MEMBER(quickload_cb); - -protected: - virtual void machine_start() override; - virtual void machine_reset() override; - -private: - u8 memory_read_byte(offs_t offset); - void memory_write_byte(offs_t offset, u8 data); - u8 io_read_byte(offs_t offset); - void io_write_byte(offs_t offset, u8 data); - void port15_w(u8 data); - void port16_w(u8 data); - void port17_w(u8 data); - void port18_w(u8 data); - u8 port19_r(); - void port1a_w(u8 data); - void port1b_w(u8 data); - void port1c_w(u8 data); - void port20_w(u8 data); - u8 port28_r(); - u8 port33_r(); - void port34_w(u8 data); - void port35_w(u8 data); - u8 port36_r(); - u8 port37_r(); - u8 rtc_r(offs_t offset); - void rtc_w(offs_t offset, u8 data); - DECLARE_WRITE_LINE_MEMBER(fdc_intrq_w); - DECLARE_WRITE_LINE_MEMBER(fdc_drq_w); - DECLARE_WRITE_LINE_MEMBER(busreq_w); - DECLARE_WRITE_LINE_MEMBER(sio1_rdya_w); - DECLARE_WRITE_LINE_MEMBER(sio1_rdyb_w); - DECLARE_WRITE_LINE_MEMBER(sio2_rdya_w); - DECLARE_WRITE_LINE_MEMBER(sio2_rdyb_w); - void address_w(u8 data); - void register_w(u8 data); - MC6845_UPDATE_ROW(crtc_update_row); - MC6845_ON_UPDATE_ADDR_CHANGED(crtc_update_addr); - - void io_map(address_map &map); - void mem_map(address_map &map); - - u8 crt8002(u8 ac_ra, u8 ac_chr, u8 ac_attr, u16 ac_cnt, bool ac_curs); - bool m_port15 = false; // rom switched in (0), out (1) - u8 m_port17 = 0U; - u8 m_port17_rdy = 0U; - u8 m_port19 = 0U; - u8 m_port1a = 0U; // bank to switch to when write to port 15 happens - u8 m_port28 = 0U; - u8 m_port34 = 0U; - u8 m_port35 = 0U; // byte to be written to vram or aram - u8 m_video_index = 0U; - u16 m_cnt = 0U; - u16 m_alpha_address = 0U; - u16 m_graph_address = 0U; - bool m_centronics_busy = false; - std::unique_ptr m_vram; // video ram, 64k dynamic - std::unique_ptr m_aram; // attribute ram, 2k static - std::unique_ptr m_ram; // main ram, 256k dynamic - required_device m_palette; - required_device m_maincpu; - required_memory_bank m_bankr0, m_bankw0, m_bank1, m_bank2; - required_region_ptr m_p_chargen; - memory_share_creator m_p_mram; - memory_share_creator m_p_videoram; - memory_share_creator m_p_attribram; - required_device m_ctc; - required_device m_dma; - required_device m_pio1; - required_device m_pio2; - required_device m_centronics; - required_device m_rs232; - required_device m_fdc; - required_device m_floppy0; - optional_device m_floppy1; - required_device m_crtc; - required_device m_speaker; - required_device m_votrax; - required_device m_rtc; -}; - -#endif // MAME_INCLUDES_AUSSIEBYTE_H diff --git a/src/mame/skeleton/aussiebyte_v.cpp b/src/mame/skeleton/aussiebyte_v.cpp deleted file mode 100644 index 9348d7c96a3..00000000000 --- a/src/mame/skeleton/aussiebyte_v.cpp +++ /dev/null @@ -1,196 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Robbbert -/*********************************************************** - - Video - Graphics not working properly. - Mode 0 - lores (wide, chunky) - Mode 1 - external, *should* be ok - Mode 2 - thin graphics, not explained well enough to code - Mode 3 - alphanumeric, works - - - -************************************************************/ -#include "emu.h" -#include "aussiebyte.h" -/*********************************************************** - - I/O Ports - -************************************************************/ - -// dummy read port, forces requested action to happen -u8 aussiebyte_state::port33_r() -{ - return 0xff; -} - -/* -Video control - needs to be fully understood -d0, d1, d2, d3 - can replace RA0-3 in graphics mode -d4 - GS - unknown -d5 - /SRRD - controls write of data to either vram or aram (1=vram, 0=aram) -d6 - /VWR - 0 = enable write vdata to vram, read from aram to vdata ; 1 = enable write to aram from vdata -d7 - OE on port 35 -*/ -void aussiebyte_state::port34_w(u8 data) -{ - m_port34 = data; -} - -void aussiebyte_state::port35_w(u8 data) -{ - m_port35 = data; -} - -u8 aussiebyte_state::port36_r() -{ - if (BIT(m_port34, 5)) - { - if (BIT(m_aram[m_alpha_address & 0x7ff], 7)) - return m_vram[m_alpha_address]; - else - return m_vram[m_graph_address]; - } - else - return m_aram[m_alpha_address & 0x7ff]; -} - -u8 aussiebyte_state::port37_r() -{ - return m_crtc->de_r() ? 0xff : 0xfe; -} - - -/*********************************************************** - - Video - -************************************************************/ -MC6845_ON_UPDATE_ADDR_CHANGED( aussiebyte_state::crtc_update_addr ) -{ -/* not sure what goes in here - parameters passed are device, address, strobe */ -// m_video_address = address;// & 0x7ff; -} - -void aussiebyte_state::address_w(u8 data) -{ - m_crtc->address_w(data); - - m_video_index = data & 0x1f; - - if (m_video_index == 31) - { - m_alpha_address++; - m_alpha_address &= 0x3fff; - m_graph_address = (m_alpha_address << 4) | (m_port34 & 15); - - if (BIT(m_port34, 5)) - { - if (BIT(m_aram[m_alpha_address & 0x7ff], 7)) - m_vram[m_alpha_address] = m_port35; - else - m_vram[m_graph_address] = m_port35; - } - else - m_aram[m_alpha_address & 0x7ff] = m_port35; - } -} - -void aussiebyte_state::register_w(u8 data) -{ - m_crtc->register_w(data); - u16 temp = m_alpha_address; - - // Get transparent address - if (m_video_index == 18) - m_alpha_address = (data << 8 ) | (temp & 0xff); - else - if (m_video_index == 19) - m_alpha_address = data | (temp & 0xff00); -} - -u8 aussiebyte_state::crt8002(u8 ac_ra, u8 ac_chr, u8 ac_attr, u16 ac_cnt, bool ac_curs) -{ - u8 gfx = 0; - switch (ac_attr & 3) - { - case 0: // lores gfx - switch (ac_ra) - { - case 0: - case 1: - case 2: - gfx = (BIT(ac_chr, 7) ? 0xf8 : 0) | (BIT(ac_chr, 3) ? 7 : 0); - break; - case 3: - case 4: - case 5: - gfx = (BIT(ac_chr, 6) ? 0xf8 : 0) | (BIT(ac_chr, 2) ? 7 : 0); - break; - case 6: - case 7: - case 8: - gfx = (BIT(ac_chr, 5) ? 0xf8 : 0) | (BIT(ac_chr, 1) ? 7 : 0); - break; - default: - gfx = (BIT(ac_chr, 4) ? 0xf8 : 0) | (BIT(ac_chr, 0) ? 7 : 0); - break; - } - break; - case 1: // external mode - gfx = bitswap<8>(ac_chr, 0,1,2,3,4,5,6,7); - break; - case 2: // thin gfx - break; - case 3: // alpha - gfx = m_p_chargen[((ac_chr & 0x7f)<<4) | ac_ra]; - break; - } - - if (BIT(ac_attr, 3) & (ac_ra == 11)) // underline - gfx = 0xff; - if (BIT(ac_attr, 2) & ((ac_ra == 5) | (ac_ra == 6))) // strike-through - gfx = 0xff; - if (BIT(ac_attr, 6) & BIT(ac_cnt, 13)) // flash - gfx = 0; - if (BIT(ac_attr, 5)) // blank - gfx = 0; - if (ac_curs && BIT(ac_cnt, 14)) // cursor - gfx ^= 0xff; - if (BIT(ac_attr, 4)) // reverse video - gfx ^= 0xff; - return gfx; -} - -MC6845_UPDATE_ROW( aussiebyte_state::crtc_update_row ) -{ - rgb_t const *const palette = m_palette->palette()->entry_list_raw(); - u32 *p = &bitmap.pix(y); - ra &= 15; - m_cnt++; - - for (u16 x = 0; x < x_count; x++) - { - u16 mem = ma + x; - u8 attr = m_aram[mem & 0x7ff]; - u8 chr; - if (BIT(attr, 7)) - chr = m_vram[mem & 0x3fff]; // alpha - else - chr = m_vram[(mem << 4) | ra]; // gfx - - u8 gfx = crt8002(ra, chr, attr, m_cnt, (x==cursor_x)); - - /* Display a scanline of a character (8 pixels) */ - *p++ = palette[BIT(gfx, 7)]; - *p++ = palette[BIT(gfx, 6)]; - *p++ = palette[BIT(gfx, 5)]; - *p++ = palette[BIT(gfx, 4)]; - *p++ = palette[BIT(gfx, 3)]; - *p++ = palette[BIT(gfx, 2)]; - *p++ = palette[BIT(gfx, 1)]; - *p++ = palette[BIT(gfx, 0)]; - } -} diff --git a/src/mame/skeleton/binbug.cpp b/src/mame/skeleton/binbug.cpp deleted file mode 100644 index 300af799dd4..00000000000 --- a/src/mame/skeleton/binbug.cpp +++ /dev/null @@ -1,294 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Robbbert -/*************************************************************************** - - BINBUG - - 2013-01-14 Driver created - - All input must be in uppercase. - - Commands: - A - See and alter memory - B - Set breakpoint (2 permitted) - C - Clear breakpoint - D - cassette save - G - Go to address, run - L - cassette load - S - See and alter registers - - BINBUG is an alternate bios to PIPBUG, however it uses its own - video output. Method of output is through a DG640 board. - - Keyboard input, like PIPBUG, is via a serial device. - The baud rate is 300, 8N1. - - The SENSE and FLAG lines are used for 300 baud cassette, in - conjunction with unknown hardware. - - There are 3 versions of BINBUG: - - - 3.6 300 baud tape routines, 300 baud keyboard, memory-mapped VDU - - - 4.4 300 baud keyboard, ACOS tape system, advanced video routines - - - 5.2 ACOS tape system, 1200 baud terminal - - - ToDo: - - Need dumps of 4.4 and 5.2. - -****************************************************************************/ - -#include "emu.h" -#include "bus/rs232/keyboard.h" -#include "cpu/s2650/s2650.h" -#include "imagedev/cassette.h" -#include "imagedev/snapquik.h" -#include "machine/clock.h" -#include "machine/timer.h" -#include "bus/s100/s100.h" -#include "bus/s100/dg640.h" -#include "speaker.h" - - -class binbug_state : public driver_device -{ -public: - binbug_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_maincpu(*this, "maincpu") - , m_cass(*this, "cassette") - , m_rs232(*this, "keyboard") - , m_clock(*this, "cass_clock") - , m_s100(*this, "s100") - { } - - void binbug(machine_config &config); - -private: - u8 mem_r(offs_t offset); - void mem_w(offs_t offset, u8 data); - DECLARE_WRITE_LINE_MEMBER(kansas_w); - DECLARE_READ_LINE_MEMBER(serial_r); - DECLARE_WRITE_LINE_MEMBER(serial_w); - DECLARE_QUICKLOAD_LOAD_MEMBER(quickload_cb); - TIMER_DEVICE_CALLBACK_MEMBER(kansas_r); - - u8 m_cass_data[4]{}; - bool m_cassold = 0, m_cassinbit = 0, m_cassoutbit = 0; - - void mem_map(address_map &map); - void machine_start() override; - - required_device m_maincpu; - required_device m_cass; - required_device m_rs232; - required_device m_clock; - required_device m_s100; -}; - -WRITE_LINE_MEMBER( binbug_state::kansas_w ) -{ - if ((m_cass->get_state() & CASSETTE_MASK_UISTATE) != CASSETTE_RECORD) - return; - - u8 twobit = m_cass_data[3] & 15; - - if (state) - { - if (twobit == 0) - m_cassold = m_cassoutbit; - - if (m_cassold) - m_cass->output(BIT(m_cass_data[3], 0) ? -1.0 : +1.0); // 2400Hz - else - m_cass->output(BIT(m_cass_data[3], 1) ? -1.0 : +1.0); // 1200Hz - - m_cass_data[3]++; - } -} - -TIMER_DEVICE_CALLBACK_MEMBER( binbug_state::kansas_r ) -{ - // no tape - set to idle - m_cass_data[1]++; - if (m_cass_data[1] > 32) - { - m_cass_data[1] = 32; - m_cassinbit = 1; - } - - if ((m_cass->get_state() & CASSETTE_MASK_UISTATE) != CASSETTE_PLAY) - return; - - /* cassette - turn 1200/2400Hz to a bit */ - u8 cass_ws = (m_cass->input() > +0.04) ? 1 : 0; - - if (cass_ws != m_cass_data[0]) - { - m_cass_data[0] = cass_ws; - m_cassinbit = (m_cass_data[1] < 12) ? 1 : 0; - m_cass_data[1] = 0; - } -} - -READ_LINE_MEMBER( binbug_state::serial_r ) -{ - return m_rs232->rxd_r() & m_cassinbit; -} - -WRITE_LINE_MEMBER( binbug_state::serial_w ) -{ - m_cassoutbit = state; -} - -u8 binbug_state::mem_r(offs_t offset) -{ - return m_s100->smemr_r(offset + 0x7800); -} - -void binbug_state::mem_w(offs_t offset, u8 data) -{ - m_s100->mwrt_w(offset + 0x7800, data); -} - -void binbug_state::machine_start() -{ - save_item(NAME(m_cass_data)); - save_item(NAME(m_cassold)); - save_item(NAME(m_cassinbit)); - save_item(NAME(m_cassoutbit)); -} - -void binbug_state::mem_map(address_map &map) -{ - map.unmap_value_high(); - map(0x0000, 0x03ff).rom(); - map(0x0400, 0x77ff).ram(); - map(0x7800, 0x7fff).rw(FUNC(binbug_state::mem_r),FUNC(binbug_state::mem_w)); -} - - -/* Input ports */ -static INPUT_PORTS_START( binbug ) -INPUT_PORTS_END - - -QUICKLOAD_LOAD_MEMBER(binbug_state::quickload_cb) -{ - address_space &space = m_maincpu->space(AS_PROGRAM); - int i; - int quick_addr = 0x440; - int exec_addr; - int quick_length; - std::vector quick_data; - int read_; - image_init_result result = image_init_result::FAIL; - - quick_length = image.length(); - if (quick_length < 0x0444) - { - image.seterror(image_error::INVALIDIMAGE, "File too short"); - image.message(" File too short"); - } - else if (quick_length > 0x8000) - { - image.seterror(image_error::INVALIDIMAGE, "File too long"); - image.message(" File too long"); - } - else - { - quick_data.resize(quick_length); - read_ = image.fread( &quick_data[0], quick_length); - if (read_ != quick_length) - { - image.seterror(image_error::INVALIDIMAGE, "Cannot read the file"); - image.message(" Cannot read the file"); - } - else if (quick_data[0] != 0xc4) - { - image.seterror(image_error::INVALIDIMAGE, "Invalid header"); - image.message(" Invalid header"); - } - else - { - exec_addr = quick_data[1] * 256 + quick_data[2]; - - if (exec_addr >= quick_length) - { - image.seterror(image_error::INVALIDIMAGE, "Exec address beyond end of file"); - image.message(" Exec address beyond end of file"); - } - else - { - for (i = quick_addr; i < read_; i++) - space.write_byte(i, quick_data[i]); - - /* display a message about the loaded quickload */ - image.message(" Quickload: size=%04X : exec=%04X",quick_length,exec_addr); - - // Start the quickload - m_maincpu->set_state_int(S2650_PC, exec_addr); - - result = image_init_result::PASS; - } - } - } - - return result; -} - -static DEVICE_INPUT_DEFAULTS_START( keyboard ) - DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_300 ) - DEVICE_INPUT_DEFAULTS( "RS232_DATABITS", 0xff, RS232_DATABITS_8 ) - DEVICE_INPUT_DEFAULTS( "RS232_PARITY", 0xff, RS232_PARITY_NONE ) - DEVICE_INPUT_DEFAULTS( "RS232_STOPBITS", 0xff, RS232_STOPBITS_1 ) -DEVICE_INPUT_DEFAULTS_END - -static void binbug_s100_devices(device_slot_interface &device) -{ - device.option_add("dg640", S100_DG640); -} - -void binbug_state::binbug(machine_config &config) -{ - SPEAKER(config, "mono").front_center(); - - /* Cassette */ - CASSETTE(config, m_cass); - m_cass->set_default_state(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED); - m_cass->add_route(ALL_OUTPUTS, "mono", 0.05); - TIMER(config, "kansas_r").configure_periodic(FUNC(binbug_state::kansas_r), attotime::from_hz(40000)); - - CLOCK(config, m_clock, 4'800); // 300 baud x 16(divider) = 4800 - m_clock->signal_handler().set(FUNC(binbug_state::kansas_w)); - - /* basic machine hardware */ - s2650_device &maincpu(S2650(config, m_maincpu, XTAL(1'000'000))); - maincpu.set_addrmap(AS_PROGRAM, &binbug_state::mem_map); - maincpu.sense_handler().set(FUNC(binbug_state::serial_r)); - maincpu.flag_handler().set(FUNC(binbug_state::serial_w)); - - /* Keyboard */ - RS232_PORT(config, m_rs232, default_rs232_devices, "keyboard").set_option_device_input_defaults("keyboard", DEVICE_INPUT_DEFAULTS_NAME(keyboard)); - - /* quickload */ - QUICKLOAD(config, "quickload", "pgm", attotime::from_seconds(1)).set_load_callback(FUNC(binbug_state::quickload_cb)); - - S100_BUS(config, m_s100, 0); - S100_SLOT(config, "s100:1", binbug_s100_devices, "dg640"); -} - - -/* ROM definition */ -ROM_START( binbug ) - ROM_REGION( 0x0400, "maincpu", ROMREGION_ERASEFF ) - ROM_LOAD( "binbug.rom", 0x0000, 0x0400, CRC(2cb1ac6e) SHA1(a969883fc767484d6b0fa103cfa4b4129b90441b) ) -ROM_END - -/* Driver */ - -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1980, binbug, pipbug, 0, binbug, binbug, binbug_state, empty_init, "MicroByte", "BINBUG 3.6", MACHINE_SUPPORTS_SAVE ) - diff --git a/src/mame/skeleton/d6800.cpp b/src/mame/skeleton/d6800.cpp deleted file mode 100644 index a0981b8ad48..00000000000 --- a/src/mame/skeleton/d6800.cpp +++ /dev/null @@ -1,434 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Robbbert -/******************************************************************************** - - The Dream 6800 is a CHIP-8 computer roughly modelled on the Cosmac VIP. - It was described in Electronics Australia magazine in 4 articles starting - in May 1979. It has 1k of ROM and 1k of RAM. The video consists of 64x32 - pixels. The keyboard is a hexcode 4x4 matrix, plus a Function key. - - Designed by Michael Bauer, of the Division of Computing and Mathematics - at Deakin University, Australia. - - NOTE that the display only updates after each 4 digits is entered, and - you can't see what you type as you change bytes. This is by design. - - The cassette has no checksum, header or blocks. It is simply a stream - of pulses. The successful loading of a tape is therefore a matter of luck. - - To modify memory, press RST, then enter the 4-digit address (nothing happens - until the 4th digit is pressed), then press FN, then 0, then the 2 digit data. - It will enter the data (you won't see anything), then the address will increment. - Enter the data for this new address. If you want to skip this address, press FN. - When you're done, press RST. NOTE!!! Do NOT change any of these addresses: - 0000,0001,0006-007F, or the system may crash. It's recommended to start all - your programs at 0200. - - Function keys: - FN 0 - Modify memory - see above paragraph. - - FN 1 - Tape load. You must have entered the start address at 0002, and - the end address+1 at 0004 (big-endian). - - FN 2 - Tape save. You must have entered the start address at 0002, and - the end address+1 at 0004 (big-endian). - - FN 3 - Run. To use, press RST, then enter the 4-digit start address - (nothing happens until the 4th digit is pressed), then FN, then 3. - - All CHIP-8 programs load at 0200 (max size 4k), and exec address - is C000. - - Information and programs can be found at http://chip8.com/?page=78 - - Due to the way the keyboard is scanned, Natural Keyboard/Paste is not possible. - -**********************************************************************************/ - - -#include "emu.h" -#include "cpu/m6800/m6800.h" -#include "imagedev/cassette.h" -#include "imagedev/snapquik.h" -#include "machine/6821pia.h" -#include "machine/timer.h" -#include "sound/beep.h" -#include "emupal.h" -#include "screen.h" -#include "softlist_dev.h" -#include "speaker.h" - - -class d6800_state : public driver_device -{ -public: - d6800_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_maincpu(*this, "maincpu") - , m_cass(*this, "cassette") - , m_pia(*this, "pia") - , m_beeper(*this, "beeper") - , m_videoram(*this, "videoram") - , m_io_keyboard(*this, "X%u", 0U) - , m_io_shift(*this, "SHIFT") - { } - - - void d6800(machine_config &config); - - DECLARE_INPUT_CHANGED_MEMBER(reset_button); - -private: - uint8_t d6800_cassette_r(); - void d6800_cassette_w(uint8_t data); - uint8_t d6800_keyboard_r(); - void d6800_keyboard_w(uint8_t data); - DECLARE_WRITE_LINE_MEMBER( d6800_screen_w ); - uint32_t screen_update_d6800(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - INTERRUPT_GEN_MEMBER(rtc_interrupt); - TIMER_DEVICE_CALLBACK_MEMBER(kansas_w); - TIMER_DEVICE_CALLBACK_MEMBER(kansas_r); - DECLARE_QUICKLOAD_LOAD_MEMBER(quickload_cb); - - void d6800_map(address_map &map); - - bool m_cb2 = 0; - bool m_cassold = 0; - uint8_t m_cass_data[4]{}; - uint8_t m_portb = 0U; - virtual void machine_start() override; - virtual void machine_reset() override; - required_device m_maincpu; - required_device m_cass; - required_device m_pia; - required_device m_beeper; - required_shared_ptr m_videoram; - required_ioport_array<4> m_io_keyboard; - required_ioport m_io_shift; -}; - - -/* Memory Maps */ - -void d6800_state::d6800_map(address_map &map) -{ - map(0x0000, 0x00ff).ram(); - map(0x0100, 0x01ff).ram().share("videoram"); - map(0x0200, 0x17ff).ram(); - //map(0x1800, 0x1fff).rom().region("maincpu",0x800); // for dreamsoft_1, if we can find a good copy - map(0x8010, 0x8013).rw(m_pia, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); - map(0xc000, 0xc7ff).mirror(0x3800).rom().region("maincpu",0); -} - -/* Input Ports */ - -static INPUT_PORTS_START( d6800 ) - PORT_START("X0") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_NAME("0") // ee - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_NAME("1") // ed - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_UP) PORT_NAME("2") // eb - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_NAME("3") // e7 - PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START("X1") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_LEFT) PORT_NAME("4") // de - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_NAME("5") // dd - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_RIGHT) PORT_NAME("6") // db - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_NAME("7") // d7 - PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START("X2") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_DOWN) PORT_NAME("8") // be - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_NAME("9") // bd - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_NAME("A") // bb - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_NAME("B") // b7 - PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START("X3") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_NAME("C") // 7e - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_NAME("D") // 7d - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_NAME("E") // 7b - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_NAME("F") // 77 - PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START("SHIFT") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("FN") PORT_CODE(KEYCODE_LSHIFT) - - PORT_START("RESET") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RST") PORT_CODE(KEYCODE_LALT) PORT_CHANGED_MEMBER(DEVICE_SELF, d6800_state, reset_button, 0) - - PORT_START("VS") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_CUSTOM) PORT_VBLANK("screen") -INPUT_PORTS_END - -INPUT_CHANGED_MEMBER(d6800_state::reset_button) -{ - // RESET button wired to POR on the mc6875, which activates the Reset output pin which in turn connects to the CPU's Reset pin. - if (newval) - m_pia->reset(); - m_maincpu->set_input_line(INPUT_LINE_RESET, newval ? ASSERT_LINE : CLEAR_LINE); -} - -/* Video */ -uint32_t d6800_state::screen_update_d6800(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - uint8_t gfx=0; - - for (uint8_t y = 0; y < 32; y++) - { - uint16_t *p = &bitmap.pix(y); - - for (uint8_t x = 0; x < 8; x++) - { - if (m_cb2) - gfx = m_videoram[x | (y<<3)]; - - *p++ = BIT(gfx, 7); - *p++ = BIT(gfx, 6); - *p++ = BIT(gfx, 5); - *p++ = BIT(gfx, 4); - *p++ = BIT(gfx, 3); - *p++ = BIT(gfx, 2); - *p++ = BIT(gfx, 1); - *p++ = BIT(gfx, 0); - } - } - return 0; -} - -/* NE556 */ - -TIMER_DEVICE_CALLBACK_MEMBER(d6800_state::kansas_w) -{ - m_cass_data[3]++; - - if (BIT(m_portb, 0) != m_cassold) - { - m_cass_data[3] = 0; - m_cassold = BIT(m_portb, 0); - } - - if (BIT(m_portb, 0)) - m_cass->output(BIT(m_cass_data[3], 0) ? -1.0 : +1.0); // 2400Hz - else - m_cass->output(BIT(m_cass_data[3], 1) ? -1.0 : +1.0); // 1200Hz -} - -/* PIA6821 Interface */ - -TIMER_DEVICE_CALLBACK_MEMBER(d6800_state::kansas_r) -{ - uint8_t data = m_io_keyboard[0]->read() & m_io_keyboard[1]->read() & m_io_keyboard[2]->read() & m_io_keyboard[3]->read(); - int ca1 = (data == 255) ? 0 : 1; - int ca2 = m_io_shift->read(); - - m_pia->ca1_w(ca1); - m_pia->ca2_w(ca2); - - /* cassette - turn 1200/2400Hz to a bit */ - m_cass_data[1]++; - uint8_t cass_ws = (m_cass->input() > +0.03) ? 1 : 0; - - if (cass_ws != m_cass_data[0]) - { - m_cass_data[0] = cass_ws; - m_cass_data[2] = ((m_cass_data[1] < 12) ? 128 : 0); - m_cass_data[1] = 0; - } -} - - -WRITE_LINE_MEMBER( d6800_state::d6800_screen_w ) -{ - m_cb2 = state; - m_maincpu->set_unscaled_clock(state ? 589744 : 1e6); // effective clock is ~590kHz while screen is on -} - -uint8_t d6800_state::d6800_cassette_r() -{ - /* - Cassette circuit consists of a 741 op-amp, a 74121 oneshot, and a 74LS74. - When a pulse arrives, the oneshot is set. After a preset time, it triggers - and the 74LS74 compares this pulse to the output of the 741. Therefore it - knows if the tone is 1200 or 2400 Hz. Input to PIA is bit 7. - */ - - return m_cass_data[2] | m_portb; -} - -void d6800_state::d6800_cassette_w(uint8_t data) -{ - /* - A NE556 runs at either 1200 or 2400 Hz, depending on the state of bit 0. - This output drives the speaker and the output signal to the cassette player. - Bit 6 enables the speaker. Also the speaker is silenced when cassette operations - are in progress (DMA/CB2 line low). - */ - - m_beeper->set_clock(BIT(data, 0) ? 2400 : 1200); - m_beeper->set_state(BIT(data, 6) & (m_cb2 ? 1 : 0)); - - m_portb = data & 0x7f; -} - -uint8_t d6800_state::d6800_keyboard_r() -{ - /* - This system reads the key matrix one way, then swaps the input and output - lines around and reads it another way. This isolates the key that was pressed. - */ - - u8 y = 8; - for (u8 i = 0; i < 4; i++) - { - u8 data = m_io_keyboard[i]->read() & 15; - y <<= 1; - if (data < 15) - for (u8 j = 0; j < 4; j++) - if (!BIT(data, j)) - return data | (0xf0 - y); - } - - return 0xff; -} - -void d6800_state::d6800_keyboard_w(uint8_t data) -{ - /* - - bit description - - PA0 keyboard column 0 - PA1 keyboard column 1 - PA2 keyboard column 2 - PA3 keyboard column 3 - PA4 keyboard row 0 - PA5 keyboard row 1 - PA6 keyboard row 2 - PA7 keyboard row 3 - - */ - -} - -INTERRUPT_GEN_MEMBER(d6800_state::rtc_interrupt) -{ - m_pia->cb1_w(1); - m_pia->cb1_w(0); -} - -/* Machine Initialization */ - -void d6800_state::machine_start() -{ - save_item(NAME(m_cb2)); - save_item(NAME(m_cassold)); - save_item(NAME(m_cass_data)); - save_item(NAME(m_portb)); -} - -void d6800_state::machine_reset() -{ - m_beeper->set_state(0); - m_cass_data[0] = 0; - m_cass_data[1] = 0; - m_cass_data[2] = 128; - m_cass_data[3] = 0; -} - -/* Machine Drivers */ - -QUICKLOAD_LOAD_MEMBER(d6800_state::quickload_cb) -{ - address_space &space = m_maincpu->space(AS_PROGRAM); - u8 ch; - u16 quick_addr = 0x200; - u16 exec_addr = 0xc000; - u32 quick_length = image.length(); - if (quick_length > 0xe00) - { - image.seterror(image_error::INVALIDIMAGE, "File exceeds 3584 bytes"); - image.message(" File exceeds 3584 bytes"); - return image_init_result::FAIL; - } - - for (u32 i = 0; i < quick_length; i++) - { - image.fread(&ch, 1); - space.write_byte(i + quick_addr, ch); - } - - if (image.is_filetype("bin")) - exec_addr = quick_addr; - - /* display a message about the loaded quickload */ - image.message(" Quickload: size=%04X : start=%04X : end=%04X : exec=%04X",quick_length,quick_addr,quick_addr+quick_length,exec_addr); - - // Start the quickload - m_maincpu->set_pc(exec_addr); - - return image_init_result::PASS; -} - -void d6800_state::d6800(machine_config &config) -{ - /* basic machine hardware */ - M6800(config, m_maincpu, XTAL(4'000'000)/4); - m_maincpu->set_addrmap(AS_PROGRAM, &d6800_state::d6800_map); - m_maincpu->set_vblank_int("screen", FUNC(d6800_state::rtc_interrupt)); - - /* video hardware */ - screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_refresh_hz(50); - screen.set_size(64, 32); - screen.set_visarea_full(); - screen.set_screen_update(FUNC(d6800_state::screen_update_d6800)); - screen.set_vblank_time(ATTOSECONDS_IN_USEC(300)); // verified - screen.set_palette("palette"); - - PALETTE(config, "palette", palette_device::MONOCHROME); - - /* sound hardware */ - SPEAKER(config, "mono").front_center(); - BEEP(config, "beeper", 1200).add_route(ALL_OUTPUTS, "mono", 0.50); - - /* devices */ - PIA6821(config, m_pia, 0); - m_pia->readpa_handler().set(FUNC(d6800_state::d6800_keyboard_r)); - m_pia->readpb_handler().set(FUNC(d6800_state::d6800_cassette_r)); - m_pia->writepa_handler().set(FUNC(d6800_state::d6800_keyboard_w)); - m_pia->writepb_handler().set(FUNC(d6800_state::d6800_cassette_w)); - m_pia->cb2_handler().set(FUNC(d6800_state::d6800_screen_w)); - m_pia->irqa_handler().set_inputline("maincpu", M6800_IRQ_LINE); - m_pia->irqb_handler().set_inputline("maincpu", M6800_IRQ_LINE); - - CASSETTE(config, m_cass); - m_cass->set_default_state(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED); - m_cass->add_route(ALL_OUTPUTS, "mono", 0.05); - - TIMER(config, "kansas_w").configure_periodic(FUNC(d6800_state::kansas_w), attotime::from_hz(4800)); - TIMER(config, "kansas_r").configure_periodic(FUNC(d6800_state::kansas_r), attotime::from_hz(40000)); - - /* quickload */ - quickload_image_device &quickload(QUICKLOAD(config, "quickload", "bin,c8", attotime::from_seconds(2))); - quickload.set_load_callback(FUNC(d6800_state::quickload_cb)); - quickload.set_interface("chip8quik"); - SOFTWARE_LIST(config, "quik_list").set_original("chip8_quik").set_filter("D"); -} - -/* ROMs */ - -ROM_START( d6800 ) - ROM_REGION( 0x1000, "maincpu", ROMREGION_ERASEFF ) - ROM_SYSTEM_BIOS(0, "0", "Original") // "chipos" - ROMX_LOAD( "d6800.bin", 0x0000, 0x0400, CRC(3f97ca2e) SHA1(60f26e57a058262b30befceceab4363a5d65d877), ROM_BIOS(0) ) - ROM_RELOAD( 0x0400, 0x0400 ) - //ROMX_LOAD( "d6800d1.bin", 0x0800, 0x0800, BAD_DUMP CRC(e552cae3) SHA1(0b90504922d46b9c46278924768c45b1b276709f), ROM_BIOS(0) ) // need a good dump, this one is broken - ROM_SYSTEM_BIOS(1, "d2", "Dreamsoft2") - ROMX_LOAD( "d6800d2.bin", 0x0000, 0x0800, CRC(ded5712f) SHA1(f594f313a74d7135c9fdd0bcb0093fc5771a9b7d), ROM_BIOS(1) ) - ROM_SYSTEM_BIOS(2, "d2m", "Dreamsoft2m") - ROMX_LOAD( "d6800d2m.bin", 0x0000, 0x0800, CRC(eec8e56f) SHA1(f587ccbc0872f2982d61120d033f481a862b902b), ROM_BIOS(2) ) -ROM_END - -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1979, d6800, 0, 0, d6800, d6800, d6800_state, empty_init, "Michael Bauer", "Dream 6800", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/skeleton/dg680.cpp b/src/mame/skeleton/dg680.cpp deleted file mode 100644 index ccb6b441e00..00000000000 --- a/src/mame/skeleton/dg680.cpp +++ /dev/null @@ -1,337 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Robbbert -/*************************************************************************** - -DG680 - -2013-01-14 Driver created - -All input must be in uppercase. - -DG680 (ETI-680), using the DGOS-Z80 operating system. - -This is a S100 card. - -In some ways, this system is the ancestor of the original Microbee. - -No schematic available, most of this is guesswork. - -Port 0 is the input from an ascii keyboard. - -Port 2 is the cassette interface. - -Port 8 controls some kind of memory protection scheme. -The code indicates that B is the page to protect, and -A is the code (0x08 = inhibit; 0x0B = unprotect; -0x0C = enable; 0x0E = protect). There are 256 pages so -each page is 256 bytes. - -The clock is controlled by the byte in D80D. - -Monitor Commands: -C (compare)* -E (edit)* -F (fill)* -G - Go to address -I - Inhibit CTC -M (move)* -P (clear screen)* -R (read tape)* -S (search)* -T hhmm [ss] - Set the time -W (write tape)* -X - protection status -XC - clear ram -XD - same as X -XE - enable facilities -XF - disable facilities -XP - protect block -XU - unprotect block -Z - go to 0000. - -* These commands are identical to the Microbee ones. - -ToDo: -- dips -- leds -- need schematic to find out what else is missing - -****************************************************************************/ - -#include "emu.h" -#include "machine/keyboard.h" -#include "machine/z80daisy.h" -#include "cpu/z80/z80.h" -#include "imagedev/cassette.h" -#include "machine/clock.h" -#include "machine/timer.h" -#include "machine/z80ctc.h" -#include "machine/z80pio.h" -#include "bus/s100/s100.h" -#include "bus/s100/dg640.h" -#include "speaker.h" - - -class dg680_state : public driver_device -{ -public: - dg680_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_maincpu(*this, "maincpu") - , m_cass(*this, "cassette") - , m_pio(*this, "pio") - , m_ctc(*this, "ctc") - , m_clock(*this, "cass_clock") - , m_s100(*this, "s100") - { } - - void dg680(machine_config &config); - -private: - u8 porta_r(); - u8 portb_r(); - void portb_w(u8 data); - u8 port08_r(); - void port08_w(u8 data); - u8 mem_r(offs_t offset); - void mem_w(offs_t offset, u8 data); - DECLARE_WRITE_LINE_MEMBER(kansas_w); - TIMER_DEVICE_CALLBACK_MEMBER(kansas_r); - void kbd_put(u8 data); - - void io_map(address_map &map); - void mem_map(address_map &map); - void machine_reset() override; - void machine_start() override; - - u8 m_pio_b = 0U; - u8 m_term_data = 0U; - u8 m_protection[0x100]{}; - u8 m_cass_data[4]{}; - bool m_cassold = 0, m_cassinbit = 0, m_cassoutbit = 0; - - required_device m_maincpu; - required_device m_cass; - required_device m_pio; - required_device m_ctc; - required_device m_clock; - required_device m_s100; -}; - -WRITE_LINE_MEMBER( dg680_state::kansas_w ) -{ - if ((m_cass->get_state() & CASSETTE_MASK_UISTATE) != CASSETTE_RECORD) - return; - - u8 twobit = m_cass_data[3] & 15; - - if (state) - { - if (twobit == 0) - m_cassold = m_cassoutbit; - - if (m_cassold) - m_cass->output(BIT(m_cass_data[3], 0) ? -1.0 : +1.0); // 2400Hz - else - m_cass->output(BIT(m_cass_data[3], 1) ? -1.0 : +1.0); // 1200Hz - - m_cass_data[3]++; - } -} - -TIMER_DEVICE_CALLBACK_MEMBER( dg680_state::kansas_r ) -{ - // no tape - set to idle - m_cass_data[1]++; - if (m_cass_data[1] > 32) - { - m_cass_data[1] = 32; - m_cassinbit = 1; - } - - if ((m_cass->get_state() & CASSETTE_MASK_UISTATE) != CASSETTE_PLAY) - return; - - /* cassette - turn 1200/2400Hz to a bit */ - u8 cass_ws = (m_cass->input() > +0.04) ? 1 : 0; - - if (cass_ws != m_cass_data[0]) - { - m_cass_data[0] = cass_ws; - m_cassinbit = (m_cass_data[1] < 12) ? 1 : 0; - m_cass_data[1] = 0; - m_pio->pb0_w(m_cassinbit); - } -} - -u8 dg680_state::mem_r(offs_t offset) -{ - return m_s100->smemr_r(offset + 0xf000); -} - -void dg680_state::mem_w(offs_t offset, u8 data) -{ - m_s100->mwrt_w(offset + 0xf000, data); -} - - -void dg680_state::mem_map(address_map &map) -{ - map.unmap_value_high(); - map(0x0000, 0xcfff).ram(); - map(0xd000, 0xd7ff).rom().region("maincpu", 0); - map(0xd800, 0xefff).ram(); - map(0xf000, 0xffff).rw(FUNC(dg680_state::mem_r),FUNC(dg680_state::mem_w)); -} - -void dg680_state::io_map(address_map &map) -{ - map.unmap_value_high(); - map.global_mask(0xff); - map(0x00, 0x03).rw(m_pio, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt)); - map(0x04, 0x07).rw(m_ctc, FUNC(z80ctc_device::read), FUNC(z80ctc_device::write)); - map(0x08, 0x08).rw(FUNC(dg680_state::port08_r), FUNC(dg680_state::port08_w)); //SWP Control and Status - //map(0x09,0x09) parallel input port - // Optional AM9519 Programmable Interrupt Controller (port c = data, port d = control) - //map(0x0c,0x0d).rw("am9519", FUNC(am9519_device::read), FUNC(am9519_device::write)); -} - -void dg680_state::machine_start() -{ - save_item(NAME(m_pio_b)); - save_item(NAME(m_term_data)); - save_item(NAME(m_protection)); - save_item(NAME(m_cass_data)); - save_item(NAME(m_cassold)); - save_item(NAME(m_cassinbit)); - save_item(NAME(m_cassoutbit)); -} - -void dg680_state::machine_reset() -{ - m_maincpu->set_pc(0xd000); - m_pio_b = 0xFF; -} - -// this is a guess there is no information available -static const z80_daisy_config dg680_daisy_chain[] = -{ - { "ctc" }, - { "pio" }, - { 0x00 } -}; - - -/* Input ports */ -static INPUT_PORTS_START( dg680 ) -INPUT_PORTS_END - -void dg680_state::kbd_put(u8 data) -{ - if (data == 8) - data = 127; // fix backspace - m_term_data = data; - /* strobe in keyboard data */ - m_pio->strobe_a(0); - m_pio->strobe_a(1); -} - -u8 dg680_state::porta_r() -{ - u8 data = m_term_data; - m_term_data = 0; - return data; -} - -u8 dg680_state::portb_r() -{ - return m_pio_b | m_cassinbit; -} - -// bit 1 = cassout; bit 2 = motor on -void dg680_state::portb_w(u8 data) -{ - if (BIT(m_pio_b ^ data, 2)) - m_cass->change_state(BIT(data, 2) ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR); - m_pio_b = data & 0xfe; - m_cassoutbit = BIT(data, 1); -} - -u8 dg680_state::port08_r() -{ - u8 breg = m_maincpu->state_int(Z80_B); - return m_protection[breg]; -} - -void dg680_state::port08_w(u8 data) -{ - u8 breg = m_maincpu->state_int(Z80_B); - m_protection[breg] = data; -} - - -static void dg680_s100_devices(device_slot_interface &device) -{ - device.option_add("dg640", S100_DG640); -} - -DEVICE_INPUT_DEFAULTS_START(dg680_dg640_f000) - DEVICE_INPUT_DEFAULTS("DSW", 0x1f, 0x1e) // F000-F7FF -DEVICE_INPUT_DEFAULTS_END - -void dg680_state::dg680(machine_config &config) -{ - SPEAKER(config, "mono").front_center(); - - /* Cassette */ - CASSETTE(config, m_cass); - m_cass->set_default_state(CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED); - m_cass->add_route(ALL_OUTPUTS, "mono", 0.05); - TIMER(config, "kansas_r").configure_periodic(FUNC(dg680_state::kansas_r), attotime::from_hz(40000)); - - CLOCK(config, m_clock, 4'800); // 300 baud x 16(divider) = 4800 - m_clock->signal_handler().set(FUNC(dg680_state::kansas_w)); - m_clock->signal_handler().append(m_ctc, FUNC(z80ctc_device::trg2)); - m_clock->signal_handler().append(m_ctc, FUNC(z80ctc_device::trg3)); - - /* basic machine hardware */ - z80_device& maincpu(Z80(config, m_maincpu, XTAL(8'000'000) / 4)); - maincpu.set_addrmap(AS_PROGRAM, &dg680_state::mem_map); - maincpu.set_addrmap(AS_IO, &dg680_state::io_map); - maincpu.set_daisy_config(dg680_daisy_chain); - - /* Keyboard */ - generic_keyboard_device &keyb(GENERIC_KEYBOARD(config, "keyb", 0)); - keyb.set_keyboard_callback(FUNC(dg680_state::kbd_put)); - - /* Devices */ - Z80CTC(config, m_ctc, XTAL(8'000'000) / 4); - m_ctc->intr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); - m_ctc->set_clk<0>(200); - m_ctc->zc_callback<0>().set(m_ctc, FUNC(z80ctc_device::trg1)); - - Z80PIO(config, m_pio, XTAL(8'000'000) / 4); - m_pio->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); - m_pio->in_pa_callback().set(FUNC(dg680_state::porta_r)); - // OUT_ARDY - this activates to ask for kbd data but not known if actually used - m_pio->in_pb_callback().set(FUNC(dg680_state::portb_r)); - m_pio->out_pb_callback().set(FUNC(dg680_state::portb_w)); - - S100_BUS(config, m_s100, 1_MHz_XTAL); - S100_SLOT(config, "s100:1", dg680_s100_devices, "dg640") - .set_option_device_input_defaults("dg640", DEVICE_INPUT_DEFAULTS_NAME(dg680_dg640_f000)); -} - -/* ROM definition */ -ROM_START( dg680 ) - ROM_REGION( 0x0800, "maincpu", 0 ) - ROM_LOAD( "dg680.rom", 0x0000, 0x0800, BAD_DUMP CRC(c1aaef6a) SHA1(1508ca8315452edfb984718e795ccbe79a0c0b58) ) - - ROM_REGION( 0x0020, "proms", 0 ) - ROM_LOAD( "82s123.bin", 0x0000, 0x0020, NO_DUMP ) -ROM_END - -/* Driver */ - -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1980, dg680, 0, 0, dg680, dg680, dg680_state, empty_init, "David Griffiths", "DG680 with DGOS-Z80 1.4", MACHINE_NO_SOUND_HW | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/skeleton/dmax8000.cpp b/src/mame/skeleton/dmax8000.cpp deleted file mode 100644 index d63b2224d45..00000000000 --- a/src/mame/skeleton/dmax8000.cpp +++ /dev/null @@ -1,211 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Robbbert -/****************************************************************************************************************** - -Datamax 8000 - -2016-07-24 Skeleton driver - -This computer was designed and made by Datamax Pty Ltd, in Manly, Sydney, Australia. - -It could have up to 4x 8 inch floppy drives, in the IBM format. -There were a bunch of optional extras such as 256kB RAM, numeric coprocessor, RTC, etc. - - -ToDo: -- Parallel port -- Centronics port -- AUX serial port -- FDC/FDD/HD setup - no schematics available of this section, so guessing... - -What there is of the schematic shows no sign of a daisy chain or associated interrupts. - - -****************************************************************************************************************/ - -#include "emu.h" -#include "cpu/z80/z80.h" -#include "imagedev/floppy.h" -#include "machine/wd_fdc.h" -#include "machine/z80daisy.h" -#include "machine/z80pio.h" -#include "machine/z80sio.h" -#include "machine/z80ctc.h" -#include "machine/mm58174.h" -#include "bus/rs232/rs232.h" - -namespace { - -class dmax8000_state : public driver_device -{ -public: - dmax8000_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_maincpu(*this, "maincpu") - , m_rom(*this, "maincpu") - , m_ram(*this, "mainram") - , m_bank1(*this, "bank1") - , m_fdc(*this, "fdc") - , m_floppy0(*this, "fdc:0") - { } - - void dmax8000(machine_config &config); - -private: - void machine_reset() override; - void machine_start() override; - void port0c_w(u8 data); - void port0d_w(u8 data); - void port14_w(u8 data); - void port40_w(u8 data); - DECLARE_WRITE_LINE_MEMBER(fdc_drq_w); - - void io_map(address_map &map); - void mem_map(address_map &map); - - required_device m_maincpu; - required_region_ptr m_rom; - required_shared_ptr m_ram; - required_memory_bank m_bank1; - required_device m_fdc; - required_device m_floppy0; -}; - - -WRITE_LINE_MEMBER( dmax8000_state::fdc_drq_w ) -{ - if (state) printf("DRQ "); -} - -void dmax8000_state::port0c_w(u8 data) -{ - printf("Port0c=%X\n", data); - m_fdc->dden_w(BIT(data, 6)); - floppy_image_device *floppy = nullptr; - if (BIT(data, 0)) floppy = m_floppy0->get_device(); - m_fdc->set_floppy(floppy); - if (floppy) - { - floppy->mon_w(0); - floppy->ss_w(0); // no idea - } -} - -void dmax8000_state::port0d_w(u8 data) -{ - printf("Port0d=%X\n", data); -} - -void dmax8000_state::port14_w(u8 data) -{ - printf("Port14=%X\n", data); -} - -void dmax8000_state::port40_w(u8 data) -{ - m_bank1->set_entry(BIT(~data, 0)); -} - -void dmax8000_state::mem_map(address_map &map) -{ - map(0x0000, 0xffff).ram().share("mainram"); - map(0x0000, 0x0fff).bankr("bank1"); -} - -void dmax8000_state::io_map(address_map &map) -{ - map.global_mask(0xff); - map.unmap_value_high(); - map(0x00, 0x03).rw(m_fdc, FUNC(fd1793_device::read), FUNC(fd1793_device::write)); - map(0x04, 0x07).rw("dart1", FUNC(z80dart_device::ba_cd_r), FUNC(z80dart_device::ba_cd_w)); - map(0x08, 0x0b).rw("ctc", FUNC(z80ctc_device::read), FUNC(z80ctc_device::write)); - map(0x0c, 0x0f).rw("pio1", FUNC(z80pio_device::read), FUNC(z80pio_device::write)); // fdd controls - map(0x10, 0x13).rw("pio2", FUNC(z80pio_device::read), FUNC(z80pio_device::write)); // centronics & parallel ports - map(0x14, 0x17).w(FUNC(dmax8000_state::port14_w)); // control lines for the centronics & parallel ports - //map(0x18, 0x19).mirror(2).rw("am9511", FUNC(am9512_device::read), FUNC(am9512_device::write)); // optional numeric coprocessor - //map(0x1c, 0x1d).mirror(2); // optional hard disk controller (1C=status, 1D=data) - map(0x20, 0x23).rw("dart2", FUNC(z80dart_device::ba_cd_r), FUNC(z80dart_device::ba_cd_w)); - map(0x40, 0x40).w(FUNC(dmax8000_state::port40_w)); // memory bank control - //map(0x60, 0x67) // optional IEEE488 GPIB - map(0x70, 0x7f).rw("rtc", FUNC(mm58174_device::read), FUNC(mm58174_device::write)); // optional RTC -} - -/* Input ports */ -static INPUT_PORTS_START( dmax8000 ) -INPUT_PORTS_END - -void dmax8000_state::machine_reset() -{ - m_bank1->set_entry(1); - m_maincpu->set_input_line_vector(0, 0xee); // Z80 - fdc vector -} - -void dmax8000_state::machine_start() -{ - m_bank1->configure_entry(0, m_ram); - m_bank1->configure_entry(1, m_rom); -} - -static void floppies(device_slot_interface &device) -{ - device.option_add("8dsdd", FLOPPY_8_DSDD); -} - - -void dmax8000_state::dmax8000(machine_config &config) -{ - /* basic machine hardware */ - Z80(config, m_maincpu, 4'000'000); // no idea what crystal is used, but 4MHz clock is confirmed - m_maincpu->set_addrmap(AS_PROGRAM, &dmax8000_state::mem_map); - m_maincpu->set_addrmap(AS_IO, &dmax8000_state::io_map); - - z80ctc_device &ctc(Z80CTC(config, "ctc", 4_MHz_XTAL)); - ctc.set_clk<0>(4_MHz_XTAL / 2); // 2MHz - ctc.zc_callback<0>().set("dart1", FUNC(z80dart_device::rxca_w)); - ctc.zc_callback<0>().append("dart1", FUNC(z80dart_device::txca_w)); - ctc.zc_callback<0>().append("dart2", FUNC(z80dart_device::rxca_w)); - ctc.zc_callback<0>().append("dart2", FUNC(z80dart_device::txca_w)); - ctc.set_clk<1>(4_MHz_XTAL / 2); // 2MHz - ctc.zc_callback<1>().set("dart2", FUNC(z80dart_device::rxtxcb_w)); - ctc.set_clk<2>(4_MHz_XTAL / 2); // 2MHz - ctc.zc_callback<2>().set("dart1", FUNC(z80dart_device::rxtxcb_w)); - - z80dart_device& dart1(Z80DART(config, "dart1", 4'000'000)); // A = terminal; B = aux - dart1.out_txda_callback().set("rs232", FUNC(rs232_port_device::write_txd)); - dart1.out_dtra_callback().set("rs232", FUNC(rs232_port_device::write_dtr)); - dart1.out_rtsa_callback().set("rs232", FUNC(rs232_port_device::write_rts)); - - rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, "terminal")); - rs232.rxd_handler().set("dart1", FUNC(z80dart_device::rxa_w)); - rs232.dcd_handler().set("dart1", FUNC(z80dart_device::dcda_w)); - rs232.ri_handler().set("dart1", FUNC(z80dart_device::ria_w)); - rs232.cts_handler().set("dart1", FUNC(z80dart_device::ctsa_w)); - - Z80DART(config, "dart2", 4'000'000); // RS232 ports - - z80pio_device& pio1(Z80PIO(config, "pio1", 4'000'000)); - pio1.out_pa_callback().set(FUNC(dmax8000_state::port0c_w)); - pio1.out_pb_callback().set(FUNC(dmax8000_state::port0d_w)); - - Z80PIO(config, "pio2", 4'000'000); - - FD1793(config, m_fdc, 2'000'000); // no idea - m_fdc->intrq_wr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); - m_fdc->drq_wr_callback().set(FUNC(dmax8000_state::fdc_drq_w)); - FLOPPY_CONNECTOR(config, "fdc:0", floppies, "8dsdd", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); - - MM58174(config, "rtc", 0); -} - - -/* ROM definition */ -ROM_START( dmax8000 ) - ROM_REGION( 0x1000, "maincpu", 0 ) - ROM_LOAD( "rev1_0.rom", 0x0000, 0x001000, CRC(acbec83f) SHA1(fce0a4307a791250dbdc6bb6a190f7fec3619d82) ) - // ROM_LOAD( "rev1_1.rom", 0x0000, 0x001000, CRC(2eb98a61) SHA1(cdd9a58f63ee7e3d3dd1c4ae3fd4376b308fd10f) ) // this is a hacked rom to speed up the serial port -ROM_END - -} // Anonymous namespace - -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1981, dmax8000, 0, 0, dmax8000, dmax8000, dmax8000_state, empty_init, "Datamax", "Datamax 8000", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/skeleton/eacc.cpp b/src/mame/skeleton/eacc.cpp deleted file mode 100644 index 57102dac044..00000000000 --- a/src/mame/skeleton/eacc.cpp +++ /dev/null @@ -1,302 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Robbbert -/****************************************************************************** -* -* EA Car Computer -* by Robbbert, March 2011. -* -* Described in Electronics Australia magazine during 1982. -* Construction and usage: http://messui.polygonal-moogle.com/comp/eacc.pdf -* -* The only RAM is the 128 bytes that comes inside the CPU. -* -* This computer is mounted in a car, and various sensors (fuel flow, etc) -* are connected up. By pressing the appropriate buttons various statistics -* may be obtained. -* -* Memory Map -* 0000-007F internal ram -* 4000-7FFF ROM -* 8000-BFFF 6821 -* C000-FFFF ROM (mirror) -* -* The ROM was typed in twice from the dump in the magazine article, and the -* results compared. Only one byte was different, so I can be confident that -* it has been typed in properly. -* -* Setting up: You need to enter the number of expected pulses from the fuel -* and distance sensors. Paste this: 5 6M123N 7M400N (start, set litres cal to -* 123 pulses. set km cal to 400 pulses). Then paste this: 1950M0N 1845M0N (set -* petrol tank capacity to 50 litres, set current amount of petrol to 45). -* Now enter: 28M100N (the journey is 100km). Press 5 to start the journey. -* All settings are saved in nvram. -* -* Stats you can see while travelling: -* 0 - time elapsed -* 08 - time remaining -* 1 - fuel used -* 18 - fuel left -* 2 - km travelled -* 28 - km remaining -* 29 - km that could be travelled with the fuel you have left -* 3 - speed now -* 39 - average speed -* 4 - fuel consumption now (litres per 100km) -* 49 - fuel average consumption -* -******************************************************************************/ - -/* Core includes */ -#include "emu.h" -#include "cpu/m6800/m6800.h" -#include "eacc.lh" -#include "machine/6821pia.h" -#include "machine/7474.h" -#include "machine/clock.h" -#include "machine/nvram.h" - - -class eacc_state : public driver_device -{ -public: - eacc_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_maincpu(*this, "maincpu") - , m_pia(*this, "pia") - , m_p_nvram(*this, "nvram") - , m_7474(*this, "7474") - , m_io_keyboard(*this, "X%u", 0U) - , m_digits(*this, "digit%u", 0U) - , m_leds(*this, "led%u", 0U) - { } - - void eacc(machine_config &config); - -protected: - virtual void machine_reset() override; - virtual void machine_start() override; - -private: - DECLARE_WRITE_LINE_MEMBER(scan_w); - DECLARE_WRITE_LINE_MEMBER(cb2_w); - DECLARE_WRITE_LINE_MEMBER(inputs_w); - uint8_t keyboard_r(); - void digit_w(uint8_t data); - void segment_w(uint8_t data); - void mem_map(address_map &map); - void do_nmi(bool, bool); - uint8_t m_digit = 0U; - bool m_cb2 = false; - bool m_scan = false; - bool m_disp = false; - - required_device m_maincpu; - required_device m_pia; - required_shared_ptr m_p_nvram; - required_device m_7474; - required_ioport_array<4> m_io_keyboard; - output_finder<7> m_digits; - output_finder<8> m_leds; -}; - - - - -/****************************************************************************** - Address Maps -******************************************************************************/ - -void eacc_state::mem_map(address_map &map) -{ - map.unmap_value_high(); - map.global_mask(0xc7ff); // A11,A12,A13 not connected - map(0x0000, 0x001f).ram().share("nvram"); // inside cpu, battery-backed - map(0x0020, 0x007f).ram(); // inside cpu - map(0x4000, 0x47ff).rom().mirror(0x8000).region("maincpu",0); - map(0x8000, 0x8003).mirror(0x7fc).rw(m_pia, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); -} - - -/****************************************************************************** - Input Ports -******************************************************************************/ - -static INPUT_PORTS_START(eacc) - PORT_START("X0") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("6 Litres Cal") PORT_CODE(KEYCODE_6_PAD) PORT_CHAR('6') - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("ENTER") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR('M') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("2 km") PORT_CODE(KEYCODE_2_PAD) PORT_CHAR('2') - PORT_BIT( 0xf8, 0, IPT_UNUSED ) - - PORT_START("X1") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("5 START") PORT_CODE(KEYCODE_5_PAD) PORT_CHAR('5') - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("END") PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR('N') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("3 km/h") PORT_CODE(KEYCODE_3_PAD) PORT_CHAR('3') - PORT_BIT( 0xf8, 0, IPT_UNUSED ) - - PORT_START("X2") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("7 Km Cal") PORT_CODE(KEYCODE_7_PAD) PORT_CHAR('7') - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("0 hour.min") PORT_CODE(KEYCODE_0_PAD) PORT_CHAR('0') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("4 l/100km") PORT_CODE(KEYCODE_4_PAD) PORT_CHAR('4') - PORT_BIT( 0xf8, 0, IPT_UNUSED ) - - PORT_START("X3") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("8 REM") PORT_CODE(KEYCODE_8_PAD) PORT_CHAR('8') - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("1 litres") PORT_CODE(KEYCODE_1_PAD) PORT_CHAR('1') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("9 AV") PORT_CODE(KEYCODE_9_PAD) PORT_CHAR('9') - PORT_BIT( 0xf8, 0, IPT_UNUSED ) -INPUT_PORTS_END - -void eacc_state::machine_reset() -{ - m_cb2 = false; // pia is supposed to set this low at reset - m_digit = 0; -} - -void eacc_state::machine_start() -{ - m_digits.resolve(); - m_leds.resolve(); - - save_item(NAME(m_cb2)); - save_item(NAME(m_scan)); - save_item(NAME(m_digit)); - save_item(NAME(m_disp)); -} - -WRITE_LINE_MEMBER( eacc_state::inputs_w ) -{ - if (state) - m_pia->ca1_w(machine().rand() & 1); // movement - else - m_pia->ca2_w(machine().rand() & 1); // fuel usage -} - -void eacc_state::do_nmi(bool in_scan, bool in_cb2) -{ - if (in_scan && in_cb2) - { - m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE); - m_7474->clock_w(0); - } - else - { - m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE); - m_7474->clock_w(1); - } -} - -WRITE_LINE_MEMBER( eacc_state::cb2_w ) -{ - m_cb2 = state ? 1 : 0; - do_nmi(m_scan, m_cb2); -} - -WRITE_LINE_MEMBER( eacc_state::scan_w ) -{ - m_scan = state ? 1 : 0; - do_nmi(m_scan, m_cb2); -} - -uint8_t eacc_state::keyboard_r() -{ - uint8_t data = m_digit; - - for (uint8_t i = 3; i < 7; i++) - if (BIT(m_digit, i)) - data |= m_io_keyboard[i - 3]->read(); - - return data; -} - -void eacc_state::segment_w(uint8_t data) -{ - //d7 segment dot - //d6 segment c - //d5 segment d - //d4 segment e - //d3 segment a - //d2 segment b - //d1 segment f - //d0 segment g - - if (m_disp) - { - m_disp = false; - if (BIT(m_digit, 7)) - { - data ^= 0xff; - - for (uint8_t i = 0; i < 8; i++) - m_leds[i] = BIT(data, i); - } - else - { - for (uint8_t i = 3; i < 7; i++) - if (BIT(m_digit, i)) - m_digits[i] = bitswap<8>(data, 7, 0, 1, 4, 5, 6, 2, 3); - } - } -} - -void eacc_state::digit_w(uint8_t data) -{ - m_digit = data & 0xf8; - m_disp = true; -} - - -/****************************************************************************** - Machine Drivers -******************************************************************************/ - -void eacc_state::eacc(machine_config &config) -{ - /* basic machine hardware */ - M6802(config, m_maincpu, XTAL(3'579'545)); /* Divided by 4 inside the m6802*/ - m_maincpu->set_ram_enable(false); // FIXME: needs standby support - m_maincpu->set_addrmap(AS_PROGRAM, &eacc_state::mem_map); - - config.set_default_layout(layout_eacc); - - PIA6821(config, m_pia, 0); - m_pia->readpb_handler().set(FUNC(eacc_state::keyboard_r)); - m_pia->writepa_handler().set(FUNC(eacc_state::segment_w)); - m_pia->writepb_handler().set(FUNC(eacc_state::digit_w)); - m_pia->cb2_handler().set(FUNC(eacc_state::cb2_w)); - m_pia->irqa_handler().set_inputline("maincpu", M6802_IRQ_LINE); - m_pia->irqb_handler().set_inputline("maincpu", M6802_IRQ_LINE); - - NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); - - TTL7474(config, m_7474, 0); - m_7474->output_cb().set(m_pia, FUNC(pia6821_device::cb1_w)); - - clock_device &eacc_scan(CLOCK(config, "eacc_scan", 600)); // 74C14 with 100k & 10nF = 1200Hz, but article says 600. - eacc_scan.signal_handler().set(FUNC(eacc_state::scan_w)); - - clock_device &eacc_cb1(CLOCK(config, "eacc_cb1", 15)); // cpu E -> MM5369 -> 15Hz - eacc_cb1.signal_handler().set(m_7474, FUNC(ttl7474_device::d_w)); - - clock_device &eacc_rnd(CLOCK(config, "eacc_rnd", 30)); // random pulse for distance and fuel - eacc_rnd.signal_handler().set(FUNC(eacc_state::inputs_w)); -} - - - -/****************************************************************************** - ROM Definitions -******************************************************************************/ - -ROM_START(eacc) - ROM_REGION(0x0800, "maincpu", 0) - ROM_LOAD("eacc.bin", 0x0000, 0x0800, CRC(287a63c0) SHA1(f61b397d33ea40e5742e34d5f5468572125e8b39) ) -ROM_END - - -/****************************************************************************** - Drivers -******************************************************************************/ - -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1982, eacc, 0, 0, eacc, eacc, eacc_state, empty_init, "Electronics Australia", "EA Car Computer", MACHINE_NO_SOUND_HW | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/skeleton/eti660.cpp b/src/mame/skeleton/eti660.cpp deleted file mode 100644 index df72dd86e63..00000000000 --- a/src/mame/skeleton/eti660.cpp +++ /dev/null @@ -1,411 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Curt Coder, Robbbert -/***************************************************************************************** - - ETI project 660, featured in the Australian magazine Electronics Today International. - - Commands: - R - Reset (use this before any other instruction) - S - Step - 0 - Enter modify memory mode - 2 - Save memory to cassette - 4 - Load memory from cassette - 6 - start binary program - 8 - start chip-8 program. - - To modify memory, press R, 0, enter 4-digit address, S, enter data, S, continue on. - R to escape. - - To save a tape, enter the start address into 0400,0401 (big endian), and the end - address into 0402,0403. Press R. Press record on the tape, press 2. - - To load a tape, enter the start and end addresses as above. Press R, 4. Screen goes - black. Press play on tape. If the screen is still black after the tape ends, press R. - - All chip-8 programs start at 0600. The manual says the max end address is 7FF (gives - 512 bytes), but you can fill up all of memory (gives 2560 bytes). - - TODO: - - sometimes there's no sound when started. You may need to hard reset until it beeps. - - doesn't run programs for other chip-8 computers (this might be normal?) - - we support BIN files, but have none to test with. - - possible CPU bugs?: - - in Invaders, can't shoot them - - in Maze, the result is rubbish (works in Emma02 emulator v1.21, but not in v1.30) - -**************************************************************************************************/ - -#include "emu.h" -#include "cpu/cosmac/cosmac.h" -#include "machine/ram.h" -#include "machine/6821pia.h" -#include "machine/rescap.h" -#include "sound/cdp1864.h" -#include "imagedev/cassette.h" -#include "imagedev/snapquik.h" -#include "screen.h" -#include "softlist_dev.h" -#include "speaker.h" - -#define CDP1802_TAG "ic3" -#define CDP1864_TAG "ic4" -#define MC6821_TAG "ic5" - -enum -{ - LED_POWER = 0, - LED_PULSE -}; - -class eti660_state : public driver_device -{ -public: - eti660_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_p_videoram(*this, "videoram") - , m_maincpu(*this, CDP1802_TAG) - , m_cti(*this, CDP1864_TAG) - , m_pia(*this, MC6821_TAG) - , m_cassette(*this, "cassette") - , m_io_keyboard(*this, "X%d", 0U) - , m_special(*this, "SPECIAL") - , m_leds(*this, "led%d", 0U) - { } - - void eti660(machine_config &config); - -private: - u8 pia_r(); - void pia_w(u8 data); - void colorram_w(offs_t offset, u8 data); - DECLARE_READ_LINE_MEMBER( clear_r ); - DECLARE_READ_LINE_MEMBER( ef2_r ); - DECLARE_READ_LINE_MEMBER( ef4_r ); - DECLARE_WRITE_LINE_MEMBER( q_w ); - DECLARE_WRITE_LINE_MEMBER( ca2_w ); - void dma_w(offs_t offset, u8 data); - u8 pia_pa_r(); - void pia_pa_w(u8 data); - DECLARE_QUICKLOAD_LOAD_MEMBER(quickload_cb); - required_shared_ptr m_p_videoram; - - void io_map(address_map &map); - void mem_map(address_map &map); - - required_device m_maincpu; - required_device m_cti; - required_device m_pia; - required_device m_cassette; - required_ioport_array<4> m_io_keyboard; - required_ioport m_special; - output_finder<2> m_leds; - - virtual void machine_start() override; - virtual void machine_reset() override; - uint16_t m_resetcnt; - - /* keyboard state */ - u8 m_keylatch = 0U; - - /* video state */ - u8 m_color_ram[0xc0]{}; - u8 m_color = 0U; -}; - - -/* Read/Write Handlers */ -// Schematic is wrong, PCB layout is correct: D0-7 swapped around on PIA. -u8 eti660_state::pia_r() -{ - u8 pia_offset = m_maincpu->get_memory_address() & 0x03; - - return bitswap<8>(m_pia->read(pia_offset), 0,1,2,3,4,5,6,7); -} - -void eti660_state::pia_w(u8 data) -{ - u8 pia_offset = m_maincpu->get_memory_address() & 0x03; - data = bitswap<8>(data,0,1,2,3,4,5,6,7); - m_pia->write(pia_offset, data); -} - -WRITE_LINE_MEMBER( eti660_state::ca2_w ) // test with Wipeout game - it should start up in colour -{ - m_cti->con_w(state); -} - -void eti660_state::colorram_w(offs_t offset, u8 data) -{ - offset = m_maincpu->get_memory_address() - 0xc80; - - u8 colorram_offset = (((offset & 0x1f0) >> 1) | (offset & 0x07)); - - if (colorram_offset < 0xc0) - m_color_ram[colorram_offset] = data; -} - -/* Memory Maps */ - -void eti660_state::mem_map(address_map &map) -{ - map.global_mask(0xfff); - map(0x0000, 0x03ff).rom(); - map(0x0400, 0x047f).ram(); - map(0x0480, 0x05ff).ram().share("videoram"); - map(0x0600, 0x0fff).ram(); -} - -void eti660_state::io_map(address_map &map) -{ - map(0x01, 0x01).rw(m_cti, FUNC(cdp1864_device::dispon_r), FUNC(cdp1864_device::step_bgcolor_w)); - map(0x02, 0x02).rw(FUNC(eti660_state::pia_r), FUNC(eti660_state::pia_w)); - map(0x03, 0x03).w(FUNC(eti660_state::colorram_w)); - map(0x04, 0x04).rw(m_cti, FUNC(cdp1864_device::dispoff_r), FUNC(cdp1864_device::tone_latch_w)); -} - -/* Input Ports */ -static INPUT_PORTS_START( eti660 ) - PORT_START("X0") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') - PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START("X1") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') - PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START("X2") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') - PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START("X3") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_F) PORT_CHAR('F') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_E) PORT_CHAR('E') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') - PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START("SPECIAL") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("RESET") PORT_CODE(KEYCODE_R) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("STEP") PORT_CODE(KEYCODE_S) -INPUT_PORTS_END - -/* CDP1802 Interface */ - -READ_LINE_MEMBER( eti660_state::clear_r ) -{ - // A hack to make the machine reset itself on - // boot, like the real one does. - if (m_resetcnt < 0xffff) - m_resetcnt++; - if (m_resetcnt == 0xf000) - return 0; - return BIT(m_special->read(), 0); // R key -} - -READ_LINE_MEMBER( eti660_state::ef2_r ) -{ - return m_cassette->input() < 0; -} - -READ_LINE_MEMBER( eti660_state::ef4_r ) -{ - return BIT(m_special->read(), 1); // S key -} - -WRITE_LINE_MEMBER( eti660_state::q_w ) -{ - /* CDP1864 audio output enable */ - m_cti->aoe_w(state); - - /* PULSE led */ - m_leds[LED_PULSE] = state ? 1 : 0; - - /* tape output */ - m_cassette->output(state ? 1.0 : -1.0); -} - -void eti660_state::dma_w(offs_t offset, u8 data) -{ - offset -= 0x480; - - m_color = 7; - - u8 colorram_offset = ((offset & 0x1f0) >> 1) | (offset & 0x07); - - if (colorram_offset < 0xc0) - m_color = m_color_ram[colorram_offset]; - - m_cti->dma_w(data); -} - -/* PIA6821 Interface */ - -u8 eti660_state::pia_pa_r() -{ - /* - - bit description - - PA0 keyboard row 0 - PA1 keyboard row 1 - PA2 keyboard row 2 - PA3 keyboard row 3 - PA4 keyboard column 0 - PA5 keyboard column 1 - PA6 keyboard column 2 - PA7 keyboard column 3 - - */ - - u8 i, data = 0xff; - - for (i = 0; i < 4; i++) - if (BIT(m_keylatch, i)) - return m_io_keyboard[i]->read(); - - return data; -} - -void eti660_state::pia_pa_w(u8 data) -{ - /* - - bit description - - PA0 keyboard row 0 - PA1 keyboard row 1 - PA2 keyboard row 2 - PA3 keyboard row 3 - PA4 keyboard column 0 - PA5 keyboard column 1 - PA6 keyboard column 2 - PA7 keyboard column 3 - - */ - - m_keylatch = bitswap<8>(data,0,1,2,3,4,5,6,7) ^ 0xff; -} - -void eti660_state::machine_reset() -{ - m_resetcnt = 0; - m_maincpu->reset(); // needed -} - -void eti660_state::machine_start() -{ - m_leds.resolve(); - - save_item(NAME(m_color_ram)); - save_item(NAME(m_color)); - save_item(NAME(m_keylatch)); - save_item(NAME(m_resetcnt)); -} - -QUICKLOAD_LOAD_MEMBER(eti660_state::quickload_cb) -{ - address_space &space = m_maincpu->space(AS_PROGRAM); - int i; - int quick_addr = 0x600; - int quick_length; - std::vector quick_data; - int read_; - image_init_result result = image_init_result::FAIL; - - quick_length = image.length(); - quick_data.resize(quick_length); - read_ = image.fread( &quick_data[0], quick_length); - if (read_ != quick_length) - { - image.seterror(image_error::INVALIDIMAGE, "Cannot read the file"); - image.message(" Cannot read the file"); - } - else - { - for (i = 0; i < quick_length; i++) - if ((quick_addr + i) < 0x1000) - space.write_byte(i + quick_addr, quick_data[i]); - - /* display a message about the loaded quickload */ - if (image.is_filetype("bin")) - image.message(" Quickload: size=%04X : start=%04X : end=%04X : Press 6 to start",quick_length,quick_addr,quick_addr+quick_length); - else - image.message(" Quickload: size=%04X : start=%04X : end=%04X : Press 8 to start",quick_length,quick_addr,quick_addr+quick_length); - - result = image_init_result::PASS; - } - - return result; -} - -/* Machine Drivers */ - -void eti660_state::eti660(machine_config &config) -{ - /* basic machine hardware */ - CDP1802(config, m_maincpu, XTAL(8'867'238)/5); - m_maincpu->set_addrmap(AS_PROGRAM, &eti660_state::mem_map); - m_maincpu->set_addrmap(AS_IO, &eti660_state::io_map); - m_maincpu->wait_cb().set_constant(1); - m_maincpu->clear_cb().set(FUNC(eti660_state::clear_r)); - m_maincpu->ef2_cb().set(FUNC(eti660_state::ef2_r)); - m_maincpu->ef4_cb().set(FUNC(eti660_state::ef4_r)); - m_maincpu->q_cb().set(FUNC(eti660_state::q_w)); - m_maincpu->dma_wr_cb().set(FUNC(eti660_state::dma_w)); - - /* video hardware */ - SCREEN(config, "screen", SCREEN_TYPE_RASTER); - - /* sound hardware */ - SPEAKER(config, "mono").front_center(); - CDP1864(config, m_cti, XTAL(8'867'238)/5).set_screen("screen"); - m_cti->inlace_cb().set_constant(0); - m_cti->int_cb().set_inputline(m_maincpu, COSMAC_INPUT_LINE_INT); - m_cti->dma_out_cb().set_inputline(m_maincpu, COSMAC_INPUT_LINE_DMAOUT); - m_cti->efx_cb().set_inputline(m_maincpu, COSMAC_INPUT_LINE_EF1); - m_cti->rdata_cb().set([this] () { return BIT(m_color, 0); }); - m_cti->bdata_cb().set([this] () { return BIT(m_color, 1); }); - m_cti->gdata_cb().set([this] () { return BIT(m_color, 2); }); - m_cti->set_chrominance(RES_K(2.2), RES_K(1), RES_K(4.7), RES_K(4.7)); // R7, R5, R6, R4 - m_cti->add_route(ALL_OUTPUTS, "mono", 0.25); - - /* devices */ - PIA6821(config, m_pia, 0); - m_pia->readpa_handler().set(FUNC(eti660_state::pia_pa_r)); - m_pia->writepa_handler().set(FUNC(eti660_state::pia_pa_w)); - m_pia->ca2_handler().set(FUNC(eti660_state::ca2_w)); // not working, bug in pia - m_pia->irqa_handler().set_inputline(m_maincpu, COSMAC_INPUT_LINE_INT).invert(); // FIXME: use an input merger for these lines - m_pia->irqb_handler().set_inputline(m_maincpu, COSMAC_INPUT_LINE_INT).invert(); - - 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); - - /* internal ram */ - RAM(config, RAM_TAG).set_default_size("3K"); - - /* quickload */ - quickload_image_device &quickload(QUICKLOAD(config, "quickload", "bin,c8,ch8", attotime::from_seconds(2))); - quickload.set_load_callback(FUNC(eti660_state::quickload_cb)); - quickload.set_interface("etiquik"); - SOFTWARE_LIST(config, "quik_list").set_original("eti660_quik"); -} - -/* ROMs */ - -ROM_START( eti660 ) - ROM_REGION( 0x10000, CDP1802_TAG, 0 ) - ROM_LOAD( "eti660.bin", 0x0000, 0x0400, CRC(811dfa62) SHA1(c0c4951e02f873f15560bdc3f35cdf3f99653922) ) -ROM_END - -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1981, eti660, 0, 0, eti660, eti660, eti660_state, empty_init, "Electronics Today International", "ETI-660 Learners' Microcomputer", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/skeleton/excali64.cpp b/src/mame/skeleton/excali64.cpp deleted file mode 100644 index d0e78a93245..00000000000 --- a/src/mame/skeleton/excali64.cpp +++ /dev/null @@ -1,694 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Robbbert -/*************************************************************************** - -Excalibur 64 kit computer, designed and sold in Australia by BGR Computers. -The official schematics have a LOT of errors and omissions. - -Skeleton driver created on 2014-12-09. - -Chips: Z80A, 8251, 8253, 8255, 6845 -We have Basic 1.1. Other known versions are 1.01, 2.1 -There are 2 versions of the colour prom, which have different palettes. -We have the later version. - -Notes: -- When booted it asks for a disk. Press enter to start ROM BASIC. -- Control W then Enter will switch between 40 and 80 characters per line. -- Control V turns cursor on -- Graphics commands such as LINE, CIRCLE, HGRCLS, HGRSET etc only work with disk basic - -ToDo: -- Colours are approximate. -- Hardware supports 20cm and 13cm floppies, but we only support 13cm as this - is the only software that exists. -- The schematic shows the audio counter connected to 2MHz, but this produces - sounds that are too high. Connected to 1MHz for now. -- Serial -- Pasting can sometimes drop a character. - -****************************************************************************/ - - -#include "emu.h" - -#include "bus/centronics/ctronics.h" -#include "bus/rs232/rs232.h" -#include "cpu/z80/z80.h" -#include "imagedev/cassette.h" -#include "imagedev/floppy.h" -#include "machine/74123.h" -#include "machine/i8251.h" -#include "machine/i8255.h" -#include "machine/pit8253.h" -#include "machine/rescap.h" -#include "machine/wd_fdc.h" -#include "machine/z80dma.h" -#include "sound/spkrdev.h" -#include "video/mc6845.h" - -#include "emupal.h" -#include "screen.h" -#include "softlist_dev.h" -#include "speaker.h" - -#include "formats/excali64_dsk.h" - - -namespace { - -class excali64_state : public driver_device -{ -public: - excali64_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_palette(*this, "palette") - , m_maincpu(*this, "maincpu") - , m_p_chargen(*this, "chargen") - , m_bankr(*this, "bankr%u", 1U) - , m_bankw(*this, "bankw%u", 1U) - , m_cass(*this, "cassette") - , m_crtc(*this, "crtc") - , m_io_keyboard(*this, "KEY.%u", 0) - , m_dma(*this, "dma") - , m_u12(*this, "u12") - , m_centronics(*this, "centronics") - , m_fdc(*this, "fdc") - , m_floppy0(*this, "fdc:0") - , m_floppy1(*this, "fdc:1") - { } - - void excali64(machine_config &config); - -protected: - virtual void machine_reset() override; - virtual void machine_start() override; - -private: - void excali64_palette(palette_device &palette); - void ppib_w(u8 data); - u8 ppic_r(); - void ppic_w(u8 data); - u8 port00_r(); - u8 port50_r(); - void port70_w(u8 data); - void porte4_w(u8 data); - u8 porte8_r(); - void portec_w(u8 data); - static void floppy_formats(format_registration &fr); - DECLARE_WRITE_LINE_MEMBER(cent_busy_w); - DECLARE_WRITE_LINE_MEMBER(busreq_w); - u8 memory_read_byte(offs_t offset); - void memory_write_byte(offs_t offset, u8 data); - u8 io_read_byte(offs_t offset); - void io_write_byte(offs_t offset, u8 data); - MC6845_UPDATE_ROW(update_row); - DECLARE_WRITE_LINE_MEMBER(crtc_hs); - DECLARE_WRITE_LINE_MEMBER(crtc_vs); - DECLARE_WRITE_LINE_MEMBER(motor_w); - - void io_map(address_map &map); - void mem_map(address_map &map); - - u8 m_sys_status = 0U; - u8 m_kbdrow = 0U; - bool m_crtc_vs = 0; - bool m_crtc_hs = 0; - bool m_motor = 0; - bool m_centronics_busy = 0; - std::unique_ptr m_vram; - std::unique_ptr m_hram; - std::unique_ptr m_ram; - required_device m_palette; - required_device m_maincpu; - required_region_ptr m_p_chargen; - required_memory_bank_array<4> m_bankr; - required_memory_bank_array<4> m_bankw; - required_device m_cass; - required_device m_crtc; - required_ioport_array<8> m_io_keyboard; - required_device m_dma; - required_device m_u12; - required_device m_centronics; - required_device m_fdc; - required_device m_floppy0; - required_device m_floppy1; -}; - -void excali64_state::mem_map(address_map &map) -{ - map(0x0000, 0x1fff).bankr(m_bankr[0]).bankw(m_bankw[0]); - map(0x2000, 0x2fff).bankr(m_bankr[1]).bankw(m_bankw[1]); - map(0x3000, 0x3fff).bankr(m_bankr[2]).bankw(m_bankw[2]); - map(0x4000, 0xbfff).bankr(m_bankr[3]).bankw(m_bankw[3]); - map(0xc000, 0xffff).ram(); -} - -void excali64_state::io_map(address_map &map) -{ - map.global_mask(0xff); - map(0x00, 0x0f).r(FUNC(excali64_state::port00_r)); - map(0x10, 0x11).mirror(0x0e).rw("uart", FUNC(i8251_device::read), FUNC(i8251_device::write)); - map(0x20, 0x23).mirror(0x0c).rw("pit", FUNC(pit8253_device::read), FUNC(pit8253_device::write)); - map(0x30, 0x30).mirror(0x0e).rw(m_crtc, FUNC(mc6845_device::status_r), FUNC(mc6845_device::address_w)); - map(0x31, 0x31).mirror(0x0e).rw(m_crtc, FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w)); - map(0x50, 0x5f).r(FUNC(excali64_state::port50_r)); - map(0x60, 0x63).mirror(0x0c).rw("ppi", FUNC(i8255_device::read), FUNC(i8255_device::write)); - map(0x70, 0x7f).w(FUNC(excali64_state::port70_w)); - map(0xe0, 0xe3).rw(m_dma, FUNC(z80dma_device::read), FUNC(z80dma_device::write)); - map(0xe4, 0xe7).w(FUNC(excali64_state::porte4_w)); - map(0xe8, 0xeb).r(FUNC(excali64_state::porte8_r)); - map(0xec, 0xef).w(FUNC(excali64_state::portec_w)); - map(0xf0, 0xf3).rw(m_fdc, FUNC(wd2793_device::read), FUNC(wd2793_device::write)); -} - - -static INPUT_PORTS_START( excali64 ) - PORT_START("KEY.0") /* line 0 */ - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') PORT_CHAR(0x12) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') PORT_CHAR(0x17) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') PORT_CHAR(0x05) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("TAB") PORT_CODE(KEYCODE_TAB) PORT_CHAR(0x09) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CAPSLOCK") PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') PORT_CHAR(0x01) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') PORT_CHAR(0x11) - - PORT_START("KEY.1") /* line 1 */ - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F3") PORT_CODE(KEYCODE_F3) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F2") PORT_CODE(KEYCODE_F2) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F4") PORT_CODE(KEYCODE_F4) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_SHIFT_2) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) // space - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F1") PORT_CODE(KEYCODE_F1) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) // F1 - - PORT_START("KEY.2") /* line 2 */ - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(". >") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') PORT_CHAR(0x0d) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("/ ?") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(", <") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') PORT_CHAR(0x02) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) //B - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') PORT_CHAR(0x0e) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) //N - - PORT_START("KEY.3") /* line 3 */ - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("' \"") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(0x27) PORT_CHAR(0x22) PORT_CHAR(0x27) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') PORT_CHAR(0x0c) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(0x0d) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("; :") PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') PORT_CHAR(0x0a) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') PORT_CHAR(0x07) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') PORT_CHAR(0x0b) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') PORT_CHAR(0x08) - - PORT_START("KEY.4") /* line 4 */ - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4 $") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2 @") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5 %") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3 #") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("DEL") PORT_CODE(KEYCODE_DEL) PORT_CHAR(0x7f) PORT_CHAR(0x7f) PORT_CHAR(0x1f) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("ESC") PORT_CODE(KEYCODE_ESC) PORT_CHAR(0x1b) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1 !") PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("INS") PORT_CODE(KEYCODE_INSERT) - - PORT_START("KEY.5") /* line 5 */ - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("[ {") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') PORT_CHAR(0x1b) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') PORT_CHAR(0x0f) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("] }") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') PORT_CHAR(0x1d) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') PORT_CHAR(0x10) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') PORT_CHAR(0x15) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') PORT_CHAR(0x14) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') PORT_CHAR(0x09) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') PORT_CHAR(0x19) - - PORT_START("KEY.6") /* line 6 */ - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') PORT_CHAR(0x06) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') PORT_CHAR(0x18) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') PORT_CHAR(0x16) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') PORT_CHAR(0x03) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') PORT_CHAR(0x04) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') PORT_CHAR(0x13) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') PORT_CHAR(0x1a) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) //Z - - PORT_START("KEY.7") /* line 7 */ - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("= +") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') PORT_CHAR('=') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0 )") PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Backspace") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(0x08) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("- _") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8 *") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6 ^") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9 (") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7 &") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') -INPUT_PORTS_END - -WRITE_LINE_MEMBER( excali64_state::cent_busy_w ) -{ - m_centronics_busy = state; -} - -void excali64_state::floppy_formats(format_registration &fr) -{ - fr.add_mfm_containers(); - fr.add(FLOPPY_EXCALI64_FORMAT); -} - -static void excali64_floppies(device_slot_interface &device) -{ - device.option_add("525qd", FLOPPY_525_QD); -} - -// pulses from port E4 bit 5 restart the 74123. After 3.6 secs without a pulse, the motor gets turned off. -WRITE_LINE_MEMBER( excali64_state::motor_w ) -{ - m_motor = state; - m_floppy1->get_device()->mon_w(!m_motor); - m_floppy0->get_device()->mon_w(!m_motor); -} - -u8 excali64_state::porte8_r() -{ - return 0xfc | (u8)m_motor; -} - -void excali64_state::porte4_w(u8 data) -{ - floppy_image_device *floppy = nullptr; - if (BIT(data, 0)) - floppy = m_floppy0->get_device(); - - if (BIT(data, 1)) - floppy = m_floppy1->get_device(); - - m_fdc->set_floppy(floppy); - if (floppy) - floppy->ss_w(BIT(data, 4)); - - m_u12->b_w(BIT(data, 5)); // motor pulse -} - -/* -d0 = precomp (selectable by jumper) -d1 = size select -d2 = density select (0 = double) -*/ -void excali64_state::portec_w(u8 data) -{ - m_fdc->enmf_w(BIT(data, 1)); - m_fdc->dden_w(BIT(data, 2)); -} - -WRITE_LINE_MEMBER( excali64_state::busreq_w ) -{ -// since our Z80 has no support for BUSACK, we assume it is granted immediately - m_maincpu->set_input_line(Z80_INPUT_LINE_BUSRQ, state); - m_dma->bai_w(state); // tell dma that bus has been granted -} - -u8 excali64_state::memory_read_byte(offs_t offset) -{ - address_space& prog_space = m_maincpu->space(AS_PROGRAM); - return prog_space.read_byte(offset); -} - -void excali64_state::memory_write_byte(offs_t offset, u8 data) -{ - address_space& prog_space = m_maincpu->space(AS_PROGRAM); - prog_space.write_byte(offset, data); -} - -u8 excali64_state::io_read_byte(offs_t offset) -{ - address_space& prog_space = m_maincpu->space(AS_IO); - return prog_space.read_byte(offset); -} - -void excali64_state::io_write_byte(offs_t offset, u8 data) -{ - address_space& prog_space = m_maincpu->space(AS_IO); - prog_space.write_byte(offset, data); -} - -void excali64_state::ppib_w(u8 data) -{ - m_kbdrow = data; -} - -u8 excali64_state::ppic_r() -{ - u8 data = 0xf4; // READY line must be low to print - data |= (u8)m_centronics_busy; - data |= (m_cass->input() > 0.1) << 3; - return data; -} - -void excali64_state::ppic_w(u8 data) -{ - m_cass->output(BIT(data, 7) ? -1.0 : +1.0); - m_centronics->write_strobe(BIT(data, 4)); -} - -u8 excali64_state::port00_r() -{ - u8 data = 0xff; - - for (int i = 0; i < 8; i++) - { - if (!BIT(m_kbdrow, i)) - data &= m_io_keyboard[i]->read(); - } - - return data; -} - -/* -d0 : /rom ; screen -d1 : ram on -d2 : /low ; high res -d3 : 2nd colour set (previously, dispen, which is a mistake in hardware and schematic) -d4 : vsync -d5 : rombank -*/ -u8 excali64_state::port50_r() -{ - u8 data = m_sys_status & 0x2f; - bool csync = m_crtc_hs | m_crtc_vs; - data |= (u8)csync << 4; - return data; -} - -/* -d0,1,2,3,5 : same as port50 -(schematic wrongly says d7 used for 2nd colour set) -*/ -void excali64_state::port70_w(u8 data) -{ - m_sys_status = data; - m_crtc->set_unscaled_clock(BIT(data, 2) ? 2e6 : 1e6); - if (BIT(data, 1)) - { - // select 64k ram - m_bankr[0]->set_entry(0); - m_bankr[1]->set_entry(0); - m_bankr[2]->set_entry(0); - m_bankr[3]->set_entry(0); - - m_bankw[1]->set_entry(0); - m_bankw[2]->set_entry(0); - m_bankw[3]->set_entry(0); - } - else if (BIT(data, 0)) - { - // select videoram and hiresram - m_bankr[0]->set_entry(1); - m_bankr[1]->set_entry(2); - m_bankr[2]->set_entry(2); - m_bankr[3]->set_entry(2); - - m_bankw[1]->set_entry(2); - m_bankw[2]->set_entry(2); - m_bankw[3]->set_entry(2); - } - else - { - // select rom, videoram, and main ram - m_bankr[0]->set_entry(1); - m_bankr[1]->set_entry(1); - m_bankr[2]->set_entry(1); - m_bankr[3]->set_entry(0); - - m_bankw[1]->set_entry(2); - m_bankw[2]->set_entry(2); - m_bankw[3]->set_entry(0); - } - - // other half of ROM_1 - if ((data & 0x22) == 0x20) - m_bankr[0]->set_entry(2); -} - -void excali64_state::machine_reset() -{ - m_bankr[0]->set_entry(1); // read from ROM - m_bankr[1]->set_entry(1); // read from ROM - m_bankr[2]->set_entry(1); // read from ROM - m_bankr[3]->set_entry(0); // read from RAM - - m_bankw[0]->set_entry(0); // write to RAM - m_bankw[1]->set_entry(2); // write to videoram - m_bankw[2]->set_entry(2); // write to videoram hires pointers - m_bankw[3]->set_entry(0); // write to RAM - - m_maincpu->reset(); -} - -void excali64_state::machine_start() -{ - save_pointer(NAME(m_vram), 0x2000); - save_pointer(NAME(m_hram), 0x8000); - save_pointer(NAME(m_ram), 0xc000); - save_item(NAME(m_sys_status)); - save_item(NAME(m_kbdrow)); - save_item(NAME(m_crtc_vs)); - save_item(NAME(m_crtc_hs)); - save_item(NAME(m_motor)); - save_item(NAME(m_centronics_busy)); - - m_sys_status = 0; -} -WRITE_LINE_MEMBER( excali64_state::crtc_hs ) -{ - m_crtc_hs = state; -} - -WRITE_LINE_MEMBER( excali64_state::crtc_vs ) -{ - m_crtc_vs = state; -} - -/* F4 Character Displayer */ -static const gfx_layout excali64_charlayout = -{ - 8, 12, /* 8 x 12 characters */ - 256, /* 256 characters */ - 1, /* 1 bits per pixel */ - { 0 }, /* no bitplanes */ - /* x offsets */ - { 7, 6, 5, 4, 3, 2, 1, 0 }, - /* y offsets */ - { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8, 10*8, 11*8 }, - 8*16 /* every char takes 16 bytes */ -}; - -static GFXDECODE_START( gfx_excali64 ) - GFXDECODE_ENTRY( "chargen", 0x0000, excali64_charlayout, 0, 1 ) -GFXDECODE_END - -// The prom, the schematic, and the manual all contradict each other, -// so the colours can only be described as wild guesses. Further, the 38 -// colour-load resistors are missing labels and values. -void excali64_state::excali64_palette(palette_device &palette) -{ - // do this here because driver_init hasn't run yet - m_vram = make_unique_clear(0x2000); - m_hram = make_unique_clear(0x8000); - m_ram = make_unique_clear(0xc000); - u8 *v = m_vram.get(); - u8 *h = m_hram.get(); - u8 *r = m_ram.get(); - u8 *main = memregion("roms")->base(); - - // main ram (cp/m mode) - m_bankr[0]->configure_entry(0, r); - m_bankr[1]->configure_entry(0, r+0x2000); - m_bankr[2]->configure_entry(0, r+0x3000); - m_bankr[3]->configure_entry(0, r+0x4000);//boot - m_bankw[0]->configure_entry(0, r);//boot - m_bankw[1]->configure_entry(0, r+0x2000); - m_bankw[2]->configure_entry(0, r+0x3000); - m_bankw[3]->configure_entry(0, r+0x4000);//boot - // rom_1 - m_bankr[0]->configure_entry(1, &main[0x0000]);//boot - m_bankr[0]->configure_entry(2, &main[0x2000]); - // rom_2 - m_bankr[1]->configure_entry(1, &main[0x4000]);//boot - m_bankr[2]->configure_entry(1, &main[0x5000]);//boot - // videoram - m_bankr[1]->configure_entry(2, v); - m_bankw[1]->configure_entry(2, v);//boot - // hiresram - m_bankr[2]->configure_entry(2, v+0x1000); - m_bankw[2]->configure_entry(2, v+0x1000);//boot - m_bankr[3]->configure_entry(2, h); - m_bankw[3]->configure_entry(2, h); - - // Set up foreground colours - for (u8 i = 0; i < 32; i++) - { - u8 const code = m_p_chargen[0x1000+i]; - u8 const r = (BIT(code, 0) ? 38 : 0) + (BIT(code, 1) ? 73 : 0) + (BIT(code, 2) ? 144 : 0); - u8 const b = (BIT(code, 3) ? 38 : 0) + (BIT(code, 4) ? 73 : 0) + (BIT(code, 5) ? 144 : 0); - u8 const g = (BIT(code, 6) ? 85 : 0) + (BIT(code, 7) ? 170 : 0); - palette.set_pen_color(i, r, g, b); - } - - // Background - palette.set_pen_color(32, 0x00, 0x00, 0x00); // 0 Black - palette.set_pen_color(33, 0xff, 0x00, 0x00); // 1 Red - palette.set_pen_color(34, 0x00, 0x00, 0xff); // 2 Blue - palette.set_pen_color(35, 0xff, 0x00, 0xff); // 3 Magenta - palette.set_pen_color(36, 0x00, 0xff, 0x00); // 4 Green - palette.set_pen_color(37, 0xff, 0xff, 0x00); // 5 Yellow - palette.set_pen_color(38, 0x00, 0xff, 0xff); // 6 Cyan - palette.set_pen_color(39, 0xff, 0xff, 0xff); // 7 White -} - -MC6845_UPDATE_ROW( excali64_state::update_row ) -{ - rgb_t const *const palette = m_palette->palette()->entry_list_raw(); - u8 const col_base = BIT(m_sys_status, 3) ? 16 : 0; - u32 *p = &bitmap.pix(y); - - for (u16 x = 0; x < x_count; x++) - { - u16 const mem = (ma + x) & 0x7ff; - u8 const chr = m_vram[mem]; - u8 const col = m_vram[mem+0x800]; - u8 const fg = col_base + (col >> 4); - u8 const bg = 32 + ((col >> 1) & 7); - - u8 gfx; - if (BIT(col, 0)) - { - u8 h = m_vram[mem+0x1000] - 4; - if (h > 5) - h = 0; // keep us in bounds - // hires definition - pixels are opposite order to characters - gfx = bitswap<8>(m_hram[(h << 12) | (chr<<4) | ra], 0, 1, 2, 3, 4, 5, 6, 7); - } - else - gfx = m_p_chargen[(chr<<4) | ra]; // normal character - - gfx ^= (x == cursor_x) ? 0xff : 0; - - /* Display a scanline of a character */ - *p++ = palette[BIT(gfx, 0) ? fg : bg]; - *p++ = palette[BIT(gfx, 1) ? fg : bg]; - *p++ = palette[BIT(gfx, 2) ? fg : bg]; - *p++ = palette[BIT(gfx, 3) ? fg : bg]; - *p++ = palette[BIT(gfx, 4) ? fg : bg]; - *p++ = palette[BIT(gfx, 5) ? fg : bg]; - *p++ = palette[BIT(gfx, 6) ? fg : bg]; - *p++ = palette[BIT(gfx, 7) ? fg : bg]; - } -} - -void excali64_state::excali64(machine_config &config) -{ - /* basic machine hardware */ - Z80(config, m_maincpu, 16_MHz_XTAL / 4); - m_maincpu->set_addrmap(AS_PROGRAM, &excali64_state::mem_map); - m_maincpu->set_addrmap(AS_IO, &excali64_state::io_map); - - I8251(config, "uart", 0); - //uart.txd_handler().set("rs232", FUNC(rs232_port_device::write_txd)); - //uart.rts_handler().set("rs232", FUNC(rs232_port_device::write_rts)); - - pit8253_device &pit(PIT8253(config, "pit", 0)); - pit.set_clk<0>(16_MHz_XTAL / 16); /* Timer 0: tone gen for speaker */ - pit.out_handler<0>().set("speaker", FUNC(speaker_sound_device::level_w)); - //pit.set_clk<1>(16_MHz_XTAL / 16); /* Timer 1: baud rate gen for 8251 */ - //pit.out_handler<1>().set(FUNC(excali64_state::write_uart_clock)); - //pit.set_clk<2>(16_MHz_XTAL / 16); /* Timer 2: not used */ - - i8255_device &ppi(I8255A(config, "ppi")); - ppi.out_pa_callback().set("cent_data_out", FUNC(output_latch_device::write)); // parallel port - ppi.out_pb_callback().set(FUNC(excali64_state::ppib_w)); - ppi.in_pc_callback().set(FUNC(excali64_state::ppic_r)); - ppi.out_pc_callback().set(FUNC(excali64_state::ppic_w)); - - /* sound hardware */ - SPEAKER(config, "mono").front_center(); - SPEAKER_SOUND(config, "speaker").add_route(ALL_OUTPUTS, "mono", 0.50); - - /* Video hardware */ - screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_refresh_hz(50); - screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */ - screen.set_size(80*8, 24*12); - screen.set_visarea_full(); - screen.set_screen_update("crtc", FUNC(mc6845_device::screen_update)); - - PALETTE(config, m_palette, FUNC(excali64_state::excali64_palette), 40); - GFXDECODE(config, "gfxdecode", m_palette, gfx_excali64); - - MC6845(config, m_crtc, 16_MHz_XTAL / 16); // 1MHz for lowres; 2MHz for highres - m_crtc->set_screen("screen"); - m_crtc->set_show_border_area(false); - m_crtc->set_char_width(8); - m_crtc->set_update_row_callback(FUNC(excali64_state::update_row)); - m_crtc->out_hsync_callback().set(FUNC(excali64_state::crtc_hs)); - m_crtc->out_vsync_callback().set(FUNC(excali64_state::crtc_vs)); - - /* Devices */ - CASSETTE(config, m_cass); - m_cass->add_route(ALL_OUTPUTS, "mono", 0.05); - - WD2793(config, m_fdc, 16_MHz_XTAL / 8); - m_fdc->drq_wr_callback().set(m_dma, FUNC(z80dma_device::rdy_w)); - FLOPPY_CONNECTOR(config, "fdc:0", excali64_floppies, "525qd", excali64_state::floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "fdc:1", excali64_floppies, "525qd", excali64_state::floppy_formats).enable_sound(true); - - Z80DMA(config, m_dma, 16_MHz_XTAL / 4); - m_dma->out_busreq_callback().set(FUNC(excali64_state::busreq_w)); - m_dma->in_mreq_callback().set(FUNC(excali64_state::memory_read_byte)); - m_dma->out_mreq_callback().set(FUNC(excali64_state::memory_write_byte)); - m_dma->in_iorq_callback().set(FUNC(excali64_state::io_read_byte)); - m_dma->out_iorq_callback().set(FUNC(excali64_state::io_write_byte)); - - TTL74123(config, m_u12, 0); - m_u12->set_connection_type(TTL74123_GROUNDED); /* Hook up type (no idea what this means) */ - m_u12->set_resistor_value(RES_K(100)); /* resistor connected between RCext & 5v */ - m_u12->set_capacitor_value(CAP_U(100)); /* capacitor connected between Cext and RCext */ - m_u12->set_a_pin_value(0); /* A pin - grounded */ - m_u12->set_b_pin_value(1); /* B pin - driven by port e4 bit 5 */ - m_u12->set_clear_pin_value(1); /* Clear pin - pulled high */ - m_u12->out_cb().set(FUNC(excali64_state::motor_w)); - - CENTRONICS(config, m_centronics, centronics_devices, "printer"); - m_centronics->busy_handler().set(FUNC(excali64_state::cent_busy_w)); - - output_latch_device ¢_data_out(OUTPUT_LATCH(config, "cent_data_out")); - m_centronics->set_output_latch(cent_data_out); - - SOFTWARE_LIST(config, "flop_list").set_original("excalibur64"); -} - -/* ROM definition */ -ROM_START( excali64 ) - ROM_REGION(0x6000, "roms", 0) - ROM_LOAD( "rom_1.ic17", 0x0000, 0x4000, CRC(e129a305) SHA1(e43ec7d040c2b2e548d22fd6bbc7df8b45a26e5a) ) - ROM_LOAD( "rom_2.ic24", 0x4000, 0x2000, CRC(916d9f5a) SHA1(91c527cce963481b7bebf077e955ca89578bb553) ) - // fix a bug that causes screen to be filled with 'p' - ROM_FILL(0x4ee, 1, 0) - ROM_FILL(0x4ef, 1, 8) - ROM_FILL(0x4f6, 1, 0) - ROM_FILL(0x4f7, 1, 8) - // patch out the protection - ROM_FILL(0x3ce7, 1, 0) - - ROM_REGION(0x1020, "chargen", 0) - ROM_LOAD( "genex_3.ic43", 0x0000, 0x1000, CRC(b91619a9) SHA1(2ced636cb7b94ba9d329868d7ecf79963cefe9d9) ) - ROM_LOAD( "hm7603.ic55", 0x1000, 0x0020, CRC(c74f47dc) SHA1(331ff3c913846191ddd97cacb80bd19438c1ff71) ) -ROM_END - -} // Anonymous namespace - - -/* Driver */ - -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1984, excali64, 0, 0, excali64, excali64, excali64_state, empty_init, "BGR Computers", "Excalibur 64", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/skeleton/pipbug.cpp b/src/mame/skeleton/pipbug.cpp deleted file mode 100644 index 9c56eac0505..00000000000 --- a/src/mame/skeleton/pipbug.cpp +++ /dev/null @@ -1,248 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Robbbert -/*************************************************************************** - -PIPBUG - -2010-04-08 Skeleton driver. -2012-05-16 Connected to serial terminal.. working -2019-07-17 Added cassette onto L command - -All input must be in UPPER case. - -Commands: -A - See and alter memory -B - Set breakpoint (2 permitted) -C - Clear breakpoint -D - Dump memory to paper tape -G - Go to address, run -L - Load memory from paper tape -S - See and alter registers - -PIPBUG isn't a computer; it is a the name of the bios used -in a number of small 2650-based computers from 1976 to 1978. -Examples include Baby 2650, Eurocard 2650, etc., plus Signetics -own PC1001, PC1500, and KT9500 systems. PIPBUG was written by Signetics. - -The sole means of communication is via a serial terminal. -PIPBUG uses the SENSE and FLAG pins as serial lines, thus -there is no need for a UART. The baud rate is 110. - -The Baby 2650 (featured in Electronics Australia magazine in -March 1977) has 256 bytes of RAM. - -The terminal is expected to have a papertape device attached, and -use it to save and load programs. PIPBUG still thinks it is talking -to the terminal, when in fact the data is flowing to the papertape -reader and punch. - -Cassette: -There is software available at 110 baud, using 1200/2400 Hz. This has -been hooked up to the otherwise-useless L command. Baud rate = 110. -After load completes, G440 to run. - -****************************************************************************/ - -#include "emu.h" -#include "bus/rs232/rs232.h" -#include "cpu/s2650/s2650.h" -#include "imagedev/cassette.h" -#include "machine/terminal.h" -#include "imagedev/snapquik.h" -#include "machine/timer.h" -#include "speaker.h" - - -class pipbug_state : public driver_device -{ -public: - pipbug_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_rs232(*this, "rs232") - , m_maincpu(*this, "maincpu") - , m_cass(*this, "cassette") - { } - - void pipbug(machine_config &config); - -private: - virtual void machine_start() override; - void pipbug_ctrl_w(u8 data); - DECLARE_READ_LINE_MEMBER(serial_r); - TIMER_DEVICE_CALLBACK_MEMBER(kansas_r); - required_device m_rs232; - required_device m_maincpu; - required_device m_cass; - DECLARE_QUICKLOAD_LOAD_MEMBER(quickload_cb); - void data_map(address_map &map); - void mem_map(address_map &map); - u8 m_cass_data[4]{}; - bool m_cassold = false, m_cassinbit = false; -}; - -void pipbug_state::pipbug_ctrl_w(u8 data) -{ -// 0x80 is written here - not connected in the baby 2650 -} - -TIMER_DEVICE_CALLBACK_MEMBER( pipbug_state::kansas_r ) -{ - // no tape - set to idle - m_cass_data[1]++; - if (m_cass_data[1] > 32) - { - m_cass_data[1] = 32; - m_cassinbit = 1; - } - - if ((m_cass->get_state() & CASSETTE_MASK_UISTATE) != CASSETTE_PLAY) - return; - - /* cassette - turn 1200/2400Hz to a bit */ - bool cass_ws = (m_cass->input() > +0.04) ? 1 : 0; - - if (cass_ws != m_cassold) - { - m_cassold = cass_ws; - m_cassinbit = (m_cass_data[1] < 12) ? 1 : 0; - m_cass_data[1] = 0; - } -} - -READ_LINE_MEMBER( pipbug_state::serial_r ) -{ - return m_rs232->rxd_r() & m_cassinbit; -} - -void pipbug_state::machine_start() -{ - save_pointer(NAME(m_cass_data), 4); - save_item(NAME(m_cassold)); - save_item(NAME(m_cassinbit)); -} - -void pipbug_state::mem_map(address_map &map) -{ - map.unmap_value_high(); - map(0x0000, 0x03ff).rom(); - map(0x0400, 0x7fff).ram(); -} - -void pipbug_state::data_map(address_map &map) -{ -// map.unmap_value_high(); - map(S2650_CTRL_PORT, S2650_CTRL_PORT).w(FUNC(pipbug_state::pipbug_ctrl_w)); -} - -/* Input ports */ -static INPUT_PORTS_START( pipbug ) -INPUT_PORTS_END - -static DEVICE_INPUT_DEFAULTS_START( terminal ) - DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_110 ) - DEVICE_INPUT_DEFAULTS( "RS232_RXBAUD", 0xff, RS232_BAUD_110 ) - DEVICE_INPUT_DEFAULTS( "RS232_DATABITS", 0xff, RS232_DATABITS_7 ) - DEVICE_INPUT_DEFAULTS( "RS232_PARITY", 0xff, RS232_PARITY_EVEN ) - DEVICE_INPUT_DEFAULTS( "RS232_STOPBITS", 0xff, RS232_STOPBITS_1 ) -DEVICE_INPUT_DEFAULTS_END - -QUICKLOAD_LOAD_MEMBER(pipbug_state::quickload_cb) -{ - address_space &space = m_maincpu->space(AS_PROGRAM); - int i; - int quick_addr = 0x440; - int exec_addr; - int quick_length; - std::vector quick_data; - int read_; - image_init_result result = image_init_result::FAIL; - - quick_length = image.length(); - if (quick_length < 0x0444) - { - image.seterror(image_error::INVALIDIMAGE, "File too short"); - image.message(" File too short"); - } - else if (quick_length > 0x8000) - { - image.seterror(image_error::INVALIDIMAGE, "File too long"); - image.message(" File too long"); - } - else - { - quick_data.resize(quick_length); - read_ = image.fread( &quick_data[0], quick_length); - if (read_ != quick_length) - { - image.seterror(image_error::INVALIDIMAGE, "Cannot read the file"); - image.message(" Cannot read the file"); - } - else if (quick_data[0] != 0xc4) - { - image.seterror(image_error::INVALIDIMAGE, "Invalid header"); - image.message(" Invalid header"); - } - else - { - exec_addr = quick_data[1] * 256 + quick_data[2]; - - if (exec_addr >= quick_length) - { - image.seterror(image_error::INVALIDIMAGE, "Exec address beyond end of file"); - image.message(" Exec address beyond end of file"); - } - else - { - for (i = quick_addr; i < read_; i++) - space.write_byte(i, quick_data[i]); - - /* display a message about the loaded quickload */ - image.message(" Quickload: size=%04X : exec=%04X",quick_length,exec_addr); - - // Start the quickload - m_maincpu->set_state_int(S2650_PC, exec_addr); - - result = image_init_result::PASS; - } - } - } - - return result; -} - -void pipbug_state::pipbug(machine_config &config) -{ - /* basic machine hardware */ - S2650(config, m_maincpu, XTAL(1'000'000)); - m_maincpu->set_addrmap(AS_PROGRAM, &pipbug_state::mem_map); - m_maincpu->set_addrmap(AS_DATA, &pipbug_state::data_map); - m_maincpu->flag_handler().set("rs232", FUNC(rs232_port_device::write_txd)); - m_maincpu->sense_handler().set(FUNC(pipbug_state::serial_r)); - - /* video hardware */ - RS232_PORT(config, m_rs232, default_rs232_devices, "terminal"); - m_rs232->set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(terminal)); - - /* quickload */ - QUICKLOAD(config, "quickload", "pgm", attotime::from_seconds(1)).set_load_callback(FUNC(pipbug_state::quickload_cb)); - - SPEAKER(config, "mono").front_center(); - - /* Cassette */ - CASSETTE(config, m_cass); - m_cass->set_default_state(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED); - m_cass->add_route(ALL_OUTPUTS, "mono", 0.05); - TIMER(config, "kansas_r").configure_periodic(FUNC(pipbug_state::kansas_r), attotime::from_hz(40000)); -} - - -/* ROM definition */ -ROM_START( pipbug ) - ROM_REGION( 0x0400, "maincpu", 0 ) - ROM_LOAD( "pipbug.rom", 0x0000, 0x0400, CRC(f242b93e) SHA1(f82857cc882e6b5fc9f00b20b375988024f413ff)) -ROM_END - -/* Driver */ - -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1979, pipbug, 0, 0, pipbug, pipbug, pipbug_state, empty_init, "Signetics", "PIPBUG", MACHINE_NO_SOUND_HW | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/skeleton/pulsar.cpp b/src/mame/skeleton/pulsar.cpp deleted file mode 100644 index f5cbab47b88..00000000000 --- a/src/mame/skeleton/pulsar.cpp +++ /dev/null @@ -1,278 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Robbbert -/*************************************************************************** - -Pulsar Little Big Board (6000 series) - -2013-12-29 Skeleton driver. - -Chips: Z80A @4MHz, Z80DART, FD1797-02, 8255A-5, AY-5-8116, MSM5832. -Crystals: 4 MHz, 5.0688 MHz, 32768. - -This is a complete CP/M single-board computer. You needed to supply your own -power supply and serial terminal. - -The terminal must be set for 9600 baud, 7 bits, even parity, 1 stop bit. - - -ToDo: -- Fix floppy. It needs to WAIT the cpu whenever port 0xD3 is read, wait - for either DRQ or INTRQ to assert, then release the cpu and then do the - actual port read. Our Z80 cannot do that. -- Fix FDC so MAME doesn't crash when a certain disk is inserted. - - -Monitor Commands: -B - Boot from disk -D - Dump memory -F - Fill memory -G - Go -I - In port -L - Load bootstrap from drive A to 0x80 -M - Modify memory -O - Out port -P - choose which rs232 channel for the console -T - Test memory -V - Move memory -X - Test off-board memory banks - -****************************************************************************/ - -#include "emu.h" - -#include "bus/rs232/rs232.h" -#include "cpu/z80/z80.h" -#include "imagedev/floppy.h" -#include "machine/com8116.h" -#include "machine/i8255.h" -#include "machine/msm5832.h" -#include "machine/wd_fdc.h" -#include "machine/z80daisy.h" -#include "machine/z80sio.h" - - -namespace { - -class pulsar_state : public driver_device -{ -public: - pulsar_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_maincpu(*this, "maincpu") - , m_rom(*this, "maincpu") - , m_ram(*this, "mainram") - , m_bank1(*this, "bank1") - , m_fdc (*this, "fdc") - , m_floppy0(*this, "fdc:0") - , m_floppy1(*this, "fdc:1") - , m_rtc(*this, "rtc") - { } - - void pulsar(machine_config &config); - -private: - virtual void machine_reset() override; - virtual void machine_start() override; - - void ppi_pa_w(u8 data); - void ppi_pb_w(u8 data); - void ppi_pc_w(u8 data); - u8 ppi_pc_r(); - - void io_map(address_map &map); - void mem_map(address_map &map); - - floppy_image_device *m_floppy; - memory_passthrough_handler m_rom_shadow_tap; - required_device m_maincpu; - required_region_ptr m_rom; - required_shared_ptr m_ram; - required_memory_bank m_bank1; - required_device m_fdc; - required_device m_floppy0; - required_device m_floppy1; - required_device m_rtc; -}; - -void pulsar_state::mem_map(address_map &map) -{ - map(0x0000, 0xffff).ram().share("mainram"); - map(0xf800, 0xffff).bankr("bank1"); -} - -void pulsar_state::io_map(address_map &map) -{ - map.unmap_value_high(); - map.global_mask(0xff); - map(0xc0, 0xc3).mirror(0x0c).rw("dart", FUNC(z80dart_device::ba_cd_r), FUNC(z80dart_device::ba_cd_w)); - map(0xd0, 0xd3).mirror(0x0c).rw(m_fdc, FUNC(fd1797_device::read), FUNC(fd1797_device::write)); - map(0xe0, 0xe3).mirror(0x0c).rw("ppi", FUNC(i8255_device::read), FUNC(i8255_device::write)); - map(0xf0, 0xf0).mirror(0x0f).w("brg", FUNC(com8116_device::stt_str_w)); -} - - -/* -d0..d3 Drive select 0-3 (we only emulate 1 drive) -d4 Side select 0=side0 -d5 /DDEN -d6 /DSK_WAITEN (don't know what this is, not emulated) -d7 XMEMEX line (for external memory, not emulated) -*/ -void pulsar_state::ppi_pa_w(u8 data) -{ - m_floppy = nullptr; - if (BIT(data, 0)) - m_floppy = m_floppy0->get_device(); - else - if (BIT(data, 1)) - m_floppy = m_floppy1->get_device(); - m_fdc->set_floppy(m_floppy); - m_fdc->dden_w(BIT(data, 5)); - if (m_floppy) - m_floppy->mon_w(0); -} - -/* -d0..d3 RTC address -d4 RTC read line -d5 RTC write line -d6 RTC hold line -d7 Allow 64k of ram -*/ -void pulsar_state::ppi_pb_w(u8 data) -{ - m_rtc->address_w(data & 0x0f); - m_rtc->read_w(BIT(data, 4)); - m_rtc->write_w(BIT(data, 5)); - m_rtc->hold_w(BIT(data, 6)); - m_bank1->set_entry(BIT(data, 7)); -} - -// d0..d3 Data lines to rtc -void pulsar_state::ppi_pc_w(u8 data) -{ - m_rtc->data_w(data & 15); -} - -// d7 /2 SIDES -u8 pulsar_state::ppi_pc_r() -{ - uint8_t data = 0; - if (m_floppy) - data = m_floppy->twosid_r() << 7; - return m_rtc->data_r() | data; -} - -static const z80_daisy_config daisy_chain_intf[] = -{ - { "dart" }, - { nullptr } -}; - -static DEVICE_INPUT_DEFAULTS_START( terminal ) - DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_9600 ) - DEVICE_INPUT_DEFAULTS( "RS232_RXBAUD", 0xff, RS232_BAUD_9600 ) - DEVICE_INPUT_DEFAULTS( "RS232_DATABITS", 0xff, RS232_DATABITS_7 ) - DEVICE_INPUT_DEFAULTS( "RS232_PARITY", 0xff, RS232_PARITY_EVEN ) - DEVICE_INPUT_DEFAULTS( "RS232_STOPBITS", 0xff, RS232_STOPBITS_1 ) -DEVICE_INPUT_DEFAULTS_END - -static void pulsar_floppies(device_slot_interface &device) -{ - device.option_add("flop", FLOPPY_8_DSDD); -} - -/* Input ports */ -static INPUT_PORTS_START( pulsar ) -INPUT_PORTS_END - -void pulsar_state::machine_reset() -{ - - m_bank1->set_entry(1); - m_rtc->cs_w(1); // always enabled - - address_space &program = m_maincpu->space(AS_PROGRAM); - program.install_rom(0x0000, 0x07ff, m_rom); // do it here for F3 - m_rom_shadow_tap.remove(); - m_rom_shadow_tap = program.install_read_tap( - 0xf800, 0xffff, - "rom_shadow_r", - [this] (offs_t offset, u8 &data, u8 mem_mask) - { - if (!machine().side_effects_disabled()) - { - // delete this tap - m_rom_shadow_tap.remove(); - - // reinstall ram over the rom shadow - m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x07ff, m_ram); - } - }, - &m_rom_shadow_tap); -} - -void pulsar_state::machine_start() -{ - // register for savestates - m_bank1->configure_entry(0, m_ram+0xf800); - m_bank1->configure_entry(1, m_rom); -} - -void pulsar_state::pulsar(machine_config &config) -{ - /* basic machine hardware */ - Z80(config, m_maincpu, 4_MHz_XTAL); - m_maincpu->set_addrmap(AS_PROGRAM, &pulsar_state::mem_map); - m_maincpu->set_addrmap(AS_IO, &pulsar_state::io_map); - m_maincpu->set_daisy_config(daisy_chain_intf); - - - /* Devices */ - i8255_device &ppi(I8255(config, "ppi")); - ppi.out_pa_callback().set(FUNC(pulsar_state::ppi_pa_w)); - ppi.out_pb_callback().set(FUNC(pulsar_state::ppi_pb_w)); - ppi.in_pc_callback().set(FUNC(pulsar_state::ppi_pc_r)); - ppi.out_pc_callback().set(FUNC(pulsar_state::ppi_pc_w)); - - MSM5832(config, "rtc", 32.768_kHz_XTAL); - - z80dart_device& dart(Z80DART(config, "dart", 4_MHz_XTAL)); - dart.out_txda_callback().set("rs232", FUNC(rs232_port_device::write_txd)); - dart.out_dtra_callback().set("rs232", FUNC(rs232_port_device::write_dtr)); - dart.out_rtsa_callback().set("rs232", FUNC(rs232_port_device::write_rts)); - dart.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); - - rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, "terminal")); - rs232.rxd_handler().set("dart", FUNC(z80dart_device::rxa_w)); - rs232.cts_handler().set("dart", FUNC(z80dart_device::ctsa_w)); - rs232.set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(terminal)); - - com8116_device &brg(COM8116(config, "brg", 5.0688_MHz_XTAL)); - // Schematic has the labels for FT and FR the wrong way around, but the pin numbers are correct. - brg.fr_handler().set("dart", FUNC(z80dart_device::txca_w)); - brg.fr_handler().append("dart", FUNC(z80dart_device::rxca_w)); - brg.ft_handler().set("dart", FUNC(z80dart_device::txcb_w)); - brg.ft_handler().append("dart", FUNC(z80dart_device::rxcb_w)); - - FD1797(config, m_fdc, 4_MHz_XTAL / 2); - FLOPPY_CONNECTOR(config, "fdc:0", pulsar_floppies, "flop", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "fdc:1", pulsar_floppies, "flop", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); -} - -/* ROM definition */ -ROM_START( pulsarlb ) - ROM_REGION( 0x0800, "maincpu", 0 ) - ROM_SYSTEM_BIOS(0, "mon7", "MP7A") - ROMX_LOAD( "mp7a.u2", 0x0000, 0x0800, CRC(726b8a19) SHA1(43b2af84d5622c1f67584c501b730acf002a6113), ROM_BIOS(0)) - ROM_SYSTEM_BIOS(1, "mon6", "LBOOT6") // Blank screen until floppy boots - ROMX_LOAD( "lboot6.u2", 0x0000, 0x0800, CRC(3bca9096) SHA1(ff99288e51a9e832785ce8e3ab5a9452b1064231), ROM_BIOS(1)) -ROM_END - -} // anonymous namespace - -/* Driver */ - -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1981, pulsarlb, 0, 0, pulsar, pulsar, pulsar_state, empty_init, "Pulsar", "Little Big Board (6000 series)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW | MACHINE_SUPPORTS_SAVE ) - diff --git a/src/mame/trainer/datum.cpp b/src/mame/trainer/datum.cpp deleted file mode 100644 index e8763504aca..00000000000 --- a/src/mame/trainer/datum.cpp +++ /dev/null @@ -1,233 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Robbbert -/********************************************************************************************** - -Gammatron Datum (1982) - -2016-10-28. - -Described in Electronics Australia magazine in 1982/1983. - -- The ROM was keyed in by hand from a printout, so is therefore considered a bad dump. -- It has routines for adc, dac, cassette, but there's no hardware to support these. -- The basic machine is fully emulated as per the schematic. - -Memory Map: -0000-007F = RAM inside the cpu -1000-13FF = RAM (2x 2114) -3E00-3E01 = ADC (in monitor as EQU but not further referenced) not in schematic -3F00-3F01 = 10-bit DAC (supported in monitor with routines for the user) not in schematic -4000-4001 = ACIA (in monitor for cassette usage, but schematic shows it for rs232) - Schematic has no provision of baud clocks -5000-5003 = PIA2 for expansion, monitor does not use it at all. -6000-6003 = PIA1 for keyboard and display -7000-77FF = ROM - -Note about the acia6850: The monitor sends it a master reset, then ignores it thereafter. - None of the pins are connected to anything - including the clocks. - It's up to the owner to write a TTY interface, and wire it up. - -Sample program to paste in: Pick-up-sticks (Nim) All inputs are in HEX. -1. Paste this in -2. Enter number of sticks to begin with (2 digits) -3. Enter max number of sticks to be removed per turn (1 digit) -4. Your turn - remove some sticks -5. After a pause, player's turn. -6. Keep doing steps 4 and 5 till you lose (it says 10b3 3F) -7. When tested, the game seems buggy - prepare to lose sooner than expected - -1000M -BD^71^07^CE^00^10^86^7E^A7^01^A7^05^BD^71^5E^B7^12^00^BD^72^7D^97^10^BD^71^5E^ -B7^12^01^BD^72^7D^97^11^CE^12^00^BD^72^4D^B7^12^00^BD^71^5E^B7^12^02^BD^72^7D^ -97^15^BD^71^5E^B7^12^03^27^08^7C^12^02^B1^12^02^2B^18^CE^00^10^86^06^97^12^ -86^15^97^13^8D^61^CE^00^10^86^7F^A7^02^A7^03^20^D8^B6^12^00^B0^12^03^B7^12^00^ -BD^72^6E^D7^10^97^11^8D^44^B6^12^00^4A^27^3C^7F^12^05^7C^12^02^7C^12^05^ -B0^12^02^2E^F8^7A^12^05^5F^FB^12^02^7A^12^05^26^F8^B6^12^00^10^16^5A^ -26^02^C6^01^B6^12^00^10^B7^12^00^BD^72^6E^D7^10^97^11^B6^12^00^81^01^27^04^ -7E^10^36^3F^3F^86^80^B7^12^04^BD^71^DD^7A^12^04^26^F8^39^ -Z1000G - - -*******************************************************************************************/ - -#include "emu.h" -#include "cpu/m6800/m6800.h" -#include "machine/6821pia.h" -#include "machine/6850acia.h" -#include "bus/rs232/rs232.h" -#include "video/pwm.h" -#include "datum.lh" - - -class datum_state : public driver_device -{ -public: - datum_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_pia1(*this, "pia1") - , m_pia2(*this, "pia2") - , m_acia(*this, "acia") - , m_maincpu(*this, "maincpu") - , m_display(*this, "display") - , m_io_keyboard(*this, "X%u", 0U) - { } - - void datum(machine_config &config); - DECLARE_INPUT_CHANGED_MEMBER(trigger_reset); - DECLARE_INPUT_CHANGED_MEMBER(trigger_nmi); - -private: - uint8_t pa_r(); - void pa_w(uint8_t data); - void pb_w(uint8_t data); - void datum_mem(address_map &map); - uint8_t m_digit = 0U; - uint8_t m_seg = 0U; - virtual void machine_start() override; - virtual void machine_reset() override; - required_device m_pia1; - required_device m_pia2; - required_device m_acia; - required_device m_maincpu; - required_device m_display; - required_ioport_array<4> m_io_keyboard; -}; - - -void datum_state::datum_mem(address_map &map) -{ - map.unmap_value_high(); - map(0x1000, 0x13ff).mirror(0x8c00).ram(); // main ram 2x 2114 - map(0x4000, 0x4001).mirror(0x8ffe).rw(m_acia, FUNC(acia6850_device::read), FUNC(acia6850_device::write)); - map(0x5000, 0x5003).mirror(0x8ffc).rw(m_pia2, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); - map(0x6000, 0x6003).mirror(0x8ffc).rw(m_pia1, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); - map(0x7000, 0x77ff).mirror(0x8800).rom().region("roms", 0); -} - - -/* Input ports */ -static INPUT_PORTS_START( datum ) - PORT_START("X0") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('E') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('F') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("2F") PORT_CODE(KEYCODE_S) PORT_CHAR('S') // "Second Function" i.e Shift-lock - PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START("X1") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("M/R") PORT_CODE(KEYCODE_M) PORT_CHAR('M') // "Memory / Registers" - PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START("X2") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("I/D") PORT_CODE(KEYCODE_UP) PORT_CHAR('^') // "Increment / Decrement" - PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START("X3") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("G/S") PORT_CODE(KEYCODE_G) PORT_CHAR('G') // "Goto / Single-step" - PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START("SPECIAL") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Reset") PORT_CODE(KEYCODE_F3) PORT_CHANGED_MEMBER(DEVICE_SELF, datum_state, trigger_reset, 0) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Escape") PORT_CODE(KEYCODE_ESC) PORT_CHAR('Z') PORT_CHANGED_MEMBER(DEVICE_SELF, datum_state, trigger_nmi, 0) -INPUT_PORTS_END - -INPUT_CHANGED_MEMBER( datum_state::trigger_reset ) -{ - m_maincpu->set_input_line(INPUT_LINE_RESET, newval ? CLEAR_LINE : ASSERT_LINE); -} - -INPUT_CHANGED_MEMBER( datum_state::trigger_nmi ) -{ - m_maincpu->set_input_line(INPUT_LINE_NMI, newval ? CLEAR_LINE : ASSERT_LINE); -} - - -void datum_state::machine_start() -{ - save_item(NAME(m_digit)); - save_item(NAME(m_seg)); -} - -void datum_state::machine_reset() -{ - m_digit = 0; - m_seg = 0; -} - -// read keyboard -uint8_t datum_state::pa_r() -{ - if (m_digit < 4) - return m_io_keyboard[m_digit]->read(); - - return 0xff; -} - -// write display segments -void datum_state::pa_w(uint8_t data) -{ - m_seg = bitswap<8>(~data, 7, 0, 5, 6, 4, 2, 1, 3); - m_display->matrix(1<(data, 7, 6, 5, 4, 0, 1, 2, 3) & 15; - m_display->matrix(1<set_addrmap(AS_PROGRAM, &datum_state::datum_mem); - - /* video hardware */ - config.set_default_layout(layout_datum); - PWM_DISPLAY(config, m_display).set_size(10, 7); - m_display->set_segmask(0x3f0, 0x7f); - - /* Devices */ - PIA6821(config, m_pia1, 0); // keyboard & display - m_pia1->readpa_handler().set(FUNC(datum_state::pa_r)); - m_pia1->writepa_handler().set(FUNC(datum_state::pa_w)); - m_pia1->writepb_handler().set(FUNC(datum_state::pb_w)); - m_pia1->irqa_handler().set_inputline("maincpu", M6802_IRQ_LINE); - m_pia1->irqb_handler().set_inputline("maincpu", M6802_IRQ_LINE); - - PIA6821(config, m_pia2, 0); // expansion - m_pia2->irqa_handler().set_inputline("maincpu", M6802_IRQ_LINE); - m_pia2->irqb_handler().set_inputline("maincpu", M6802_IRQ_LINE); - - ACIA6850(config, m_acia, 0); // rs232 - m_acia->txd_handler().set("rs232", FUNC(rs232_port_device::write_txd)); - m_acia->rts_handler().set("rs232", FUNC(rs232_port_device::write_rts)); - rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, nullptr)); - rs232.rxd_handler().set(m_acia, FUNC(acia6850_device::write_rxd)); - rs232.cts_handler().set(m_acia, FUNC(acia6850_device::write_cts)); -} - - -/* ROM definition */ -ROM_START( datum ) - ROM_REGION( 0x800, "roms", 0 ) - ROM_LOAD( "datum.bin", 0x0000, 0x0800, BAD_DUMP CRC(6fb11628) SHA1(8a77a846b62eee0d12848da76e16b4c66ef445d8) ) -ROM_END - -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1982, datum, 0, 0, datum, datum, datum_state, empty_init, "Gammatron", "Datum", MACHINE_NO_SOUND_HW | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/trainer/tec1.cpp b/src/mame/trainer/tec1.cpp deleted file mode 100644 index eb3a3ff630c..00000000000 --- a/src/mame/trainer/tec1.cpp +++ /dev/null @@ -1,410 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Robbbert -/*************************************************************************** - -TEC-1 driver, written by Robbbert in April, 2009. - -The TEC-1 was a single-board "computer" described in Talking Electronics -magazine, issues number 10 and 11. Talking Electronics do not have dates on -their issues, so the date is uncertain, although 1984 seems a reasonable -guess. Talking Electronics operated from Cheltenham, a suburb of Melbourne. - -The hardware is quite simple, consisting of a Z80 cpu, 2x 8212 8-bit latch, -74C923 keyboard scanner, 20 push-button keys, 6-digit LED display, a speaker, -a 2k EPROM and sundry parts. - -The cpu speed could be adjusted by using a potentiometer, the range being -250 kHz to 2MHz. This is a simple method of adjusting a game's difficulty. - -We emulate the original version. Later enhancements included more RAM, speech -synthesis and various attachments, however I have no information on these. - -2018-11-08 Obtained fresh dumps from the original designers. - -Pasting: - 0-F : as is - + (inc) : ^ - - (dec) : V - AD : - - GO : X - -Keys: -0 to 9, A to F are on the key of the same name. -AD (input an address) is the '-' key. -+ and - (increment / decrement address) are the up and down-arrow keys. -GO (execute program at current address) is the X key. -SHIFT - later monitor versions utilised an extra shift button. Hold - it down and press another key (use Left Shift). - -Whenever a program listing mentions RESET, press Left-Alt key. - -Each key causes a beep to be heard. You may need to press more than once -to get it to register. - -Inbuilt games - press the following sequence of keys: -- Invaders: RESET AD 0 0 0 8 GO GO (Paste: -0008XX) -- Nim: RESET AD 0 0 1 0 GO GO (Paste: -0010XX) -- Lunar Lander: RESET AD 0 0 1 8 GO GO (Paste: -0018XX) -Tunes: -- Bealach An Doirin: RESET AD 0 0 2 8 GO GO (Paste: -0028XX) -- Biking up the strand: RESET AD 0 0 3 0 GO GO (Paste: -0030XX) - -Thanks to Chris Schwartz who dumped his ROM for me way back in the old days. -It's only taken 25 years to get around to emulating it... - - -Differences between tec1 and tecjmon: - -On the tec1 a keypress is indicated by an NMI from the 74C923; but on -the jmon it sets bit 6 of port 3 low instead. The NMI code is simply -a 'retn' in the jmon rom, so we can use the same code. -The jmon includes a cassette interface, a serial input connection, -and an optional LCD, but the games of the tec1 have been removed. - - - -JMON ToDo: -- Add LCD display (2 rows by 16 characters) - - -***************************************************************************/ - -#include "emu.h" -#include "cpu/z80/z80.h" -#include "imagedev/cassette.h" -#include "machine/mm74c922.h" -#include "machine/rescap.h" -#include "sound/spkrdev.h" -#include "speaker.h" -#include "video/pwm.h" - -#include "tec1.lh" - - -class tec1_state : public driver_device -{ -public: - tec1_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_maincpu(*this, "maincpu") - , m_speaker(*this, "speaker") - , m_cass(*this, "cassette") - , m_kb(*this, "keyboard") - , m_io_shift(*this, "SHIFT") - , m_display(*this, "display") - { } - - void tec1(machine_config &config); - void tecjmon(machine_config &config); - - DECLARE_INPUT_CHANGED_MEMBER(reset_button); - -private: - virtual void machine_start() override; - u8 kbd_r(); - u8 latch_r(); - void tec1_digit_w(u8 data); - void tecjmon_digit_w(u8 data); - void segment_w(u8 data); - DECLARE_WRITE_LINE_MEMBER(da_w); - bool m_key_pressed = 0; - u8 m_seg = 0U; - u8 m_digit = 0U; - void tec1_io(address_map &map); - void tec1_map(address_map &map); - void tecjmon_io(address_map &map); - void tecjmon_map(address_map &map); - required_device m_maincpu; - required_device m_speaker; - optional_device m_cass; - required_device m_kb; - required_ioport m_io_shift; - required_device m_display; -}; - - - - -/*************************************************************************** - - Display - -***************************************************************************/ - -void tec1_state::segment_w(u8 data) -{ -/* d7 segment d - d6 segment e - d5 segment c - d4 segment dot - d3 segment b - d2 segment g - d1 segment f - d0 segment a */ - - m_seg = bitswap<8>(data, 4, 2, 1, 6, 7, 5, 3, 0); - m_display->matrix(m_digit, m_seg); -} - -void tec1_state::tec1_digit_w(u8 data) -{ -/* d7 speaker - d6 not used - d5 data digit 1 - d4 data digit 2 - d3 address digit 1 - d2 address digit 2 - d1 address digit 3 - d0 address digit 4 */ - - m_speaker->level_w(BIT(data, 7)); - - m_digit = data; - m_display->matrix(m_digit, m_seg); -} - -void tec1_state::tecjmon_digit_w(u8 data) -{ -/* d7 speaker & cassout - d6 not used - d5 data digit 1 - d4 data digit 2 - d3 address digit 1 - d2 address digit 2 - d1 address digit 3 - d0 address digit 4 */ - - m_speaker->level_w(BIT(data, 7)); - m_cass->output(BIT(data, 7) ? -1.0 : +1.0); - m_digit = data; - m_display->matrix(m_digit, m_seg); -} - - -/*************************************************************************** - - Keyboard - -***************************************************************************/ - -u8 tec1_state::latch_r() -{ -// bit 7 - cass in ; bit 6 low = key pressed - u8 data = (m_key_pressed) ? 0 : 0x40; - - if (m_cass->input() > 0.03) - data |= 0x80; - - return data; -} - - -u8 tec1_state::kbd_r() -{ - return m_kb->read() | m_io_shift->read(); -} - -WRITE_LINE_MEMBER( tec1_state::da_w ) -{ - m_key_pressed = state; - m_maincpu->set_input_line(INPUT_LINE_NMI, state ? ASSERT_LINE : CLEAR_LINE); -} - - -/*************************************************************************** - - Machine - -***************************************************************************/ - -void tec1_state::machine_start() -{ - save_item(NAME(m_key_pressed)); - save_item(NAME(m_seg)); - save_item(NAME(m_digit)); -} - -/*************************************************************************** - - Address Map - -***************************************************************************/ - -void tec1_state::tec1_map(address_map &map) -{ - map.global_mask(0x3fff); - map(0x0000, 0x07ff).rom(); - map(0x0800, 0x0fff).ram(); // on main board - map(0x1000, 0x3fff).ram(); // expansion -} - -void tec1_state::tec1_io(address_map &map) -{ - map.global_mask(0x07); - map(0x00, 0x00).r(FUNC(tec1_state::kbd_r)); - map(0x01, 0x01).w(FUNC(tec1_state::tec1_digit_w)); - map(0x02, 0x02).w(FUNC(tec1_state::segment_w)); -} - - -void tec1_state::tecjmon_map(address_map &map) -{ - map.global_mask(0x3fff); - map(0x0000, 0x07ff).rom(); - map(0x0800, 0x37ff).ram(); - map(0x3800, 0x3fff).rom().region("maincpu", 0x0800); -} - -void tec1_state::tecjmon_io(address_map &map) -{ - map.global_mask(0xff); - map(0x00, 0x00).r(FUNC(tec1_state::kbd_r)); - map(0x01, 0x01).w(FUNC(tec1_state::tecjmon_digit_w)); - map(0x02, 0x02).w(FUNC(tec1_state::segment_w)); - map(0x03, 0x03).r(FUNC(tec1_state::latch_r)); - //map(0x04, 0x04).w(FUNC(tec1_state::lcd_en_w)); - //map(0x84, 0x84).w(FUNC(tec1_state::lcd_2nd_w)); -} - - -/************************************************************************** - - Keyboard Layout - -***************************************************************************/ - -static INPUT_PORTS_START( tec1 ) - PORT_START("LINE0") /* KEY ROW 0 */ - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4) PORT_CHAR('4') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8) PORT_CHAR('8') - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('C') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("+") PORT_CODE(KEYCODE_UP) PORT_CHAR('^') - - PORT_START("LINE1") /* KEY ROW 1 */ - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1) PORT_CHAR('1') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5) PORT_CHAR('5') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) PORT_CHAR('9') - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('D') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("-") PORT_CODE(KEYCODE_DOWN) PORT_CHAR('V') - - PORT_START("LINE2") /* KEY ROW 2 */ - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2) PORT_CHAR('2') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6) PORT_CHAR('6') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('A') - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('E') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("GO") PORT_CODE(KEYCODE_X) PORT_CHAR('X') - - PORT_START("LINE3") /* KEY ROW 3 */ - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) PORT_CHAR('3') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7) PORT_CHAR('7') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('B') - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('F') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("AD") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') - - PORT_START("SHIFT") - PORT_BIT(0x1f, IP_ACTIVE_HIGH, IPT_UNUSED) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT) - PORT_BIT(0xc0, IP_ACTIVE_LOW, IPT_UNUSED) - - PORT_START("RESET") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RESET") PORT_CODE(KEYCODE_LALT) PORT_CHANGED_MEMBER(DEVICE_SELF, tec1_state, reset_button, 0) -INPUT_PORTS_END - -INPUT_CHANGED_MEMBER(tec1_state::reset_button) -{ - m_maincpu->set_input_line(INPUT_LINE_RESET, newval ? ASSERT_LINE : CLEAR_LINE); -} - - -/*************************************************************************** - - Machine driver - -***************************************************************************/ - -void tec1_state::tec1(machine_config &config) -{ - /* basic machine hardware */ - Z80(config, m_maincpu, 1000000); /* speed can be varied between 250kHz and 2MHz */ - m_maincpu->set_addrmap(AS_PROGRAM, &tec1_state::tec1_map); - m_maincpu->set_addrmap(AS_IO, &tec1_state::tec1_io); - - /* video hardware */ - config.set_default_layout(layout_tec1); - PWM_DISPLAY(config, m_display).set_size(6, 8); - m_display->set_segmask(0x3f, 0xff); - - MM74C923(config, m_kb, 0); - m_kb->set_cap_osc(CAP_N(100)); - m_kb->set_cap_debounce(CAP_U(1)); - m_kb->da_wr_callback().set(FUNC(tec1_state::da_w)); - m_kb->x1_rd_callback().set_ioport("LINE0"); - m_kb->x2_rd_callback().set_ioport("LINE1"); - m_kb->x3_rd_callback().set_ioport("LINE2"); - m_kb->x4_rd_callback().set_ioport("LINE3"); - - /* sound hardware */ - SPEAKER(config, "mono").front_center(); - SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.50); -} - -void tec1_state::tecjmon(machine_config &config) -{ - /* basic machine hardware */ - Z80(config, m_maincpu, XTAL(3'579'545) / 2); - m_maincpu->set_addrmap(AS_PROGRAM, &tec1_state::tecjmon_map); - m_maincpu->set_addrmap(AS_IO, &tec1_state::tecjmon_io); - - /* video hardware */ - config.set_default_layout(layout_tec1); - PWM_DISPLAY(config, m_display).set_size(6, 8); - m_display->set_segmask(0x3f, 0xff); - - MM74C923(config, m_kb, 0); - m_kb->set_cap_osc(CAP_N(100)); - m_kb->set_cap_debounce(CAP_U(1)); - m_kb->da_wr_callback().set(FUNC(tec1_state::da_w)); - m_kb->x1_rd_callback().set_ioport("LINE0"); - m_kb->x2_rd_callback().set_ioport("LINE1"); - m_kb->x3_rd_callback().set_ioport("LINE2"); - m_kb->x4_rd_callback().set_ioport("LINE3"); - - /* sound hardware */ - SPEAKER(config, "mono").front_center(); - SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.50); - - /* Devices */ - CASSETTE(config, m_cass); - m_cass->set_default_state(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED); -} - - -/*************************************************************************** - - Game driver - -***************************************************************************/ - -ROM_START(tec1) - ROM_REGION(0x0800, "maincpu", 0 ) - ROM_SYSTEM_BIOS(0, "mon1", "MON1") - ROMX_LOAD( "mon1.rom", 0x0000, 0x0800, CRC(5d379e6c) SHA1(5c810885a3f0d03c54aea74aaaa8fae8a2fd9ad4), ROM_BIOS(0) ) - ROM_SYSTEM_BIOS(1, "mon1a", "MON1A") - ROMX_LOAD("mon1a.rom", 0x0000, 0x0800, CRC(b3390c36) SHA1(18aabc68d473206b7fc4e365c6b57a4e218482c3), ROM_BIOS(1)) - ROM_SYSTEM_BIOS(2, "mon1b", "MON1B") - //ROMX_LOAD("mon1b.rom", 0x0000, 0x0800, CRC(60daea3c) SHA1(383b7e7f02e91fb18c87eb03c5949e31156771d4), ROM_BIOS(2)) - ROMX_LOAD("mon1b.rom", 0x0000, 0x0800, CRC(6088811d) SHA1(2cec14a24fae769f22f6598b5a63fc79d90db394), ROM_BIOS(2)) // redump - ROM_SYSTEM_BIOS(3, "mon2", "MON2") - ROMX_LOAD("mon2.rom", 0x0000, 0x0800, CRC(082fd7e7) SHA1(7659add30ca22b15a03d1cbac0892a5c25e47ecd), ROM_BIOS(3)) -ROM_END - -ROM_START(tecjmon) - ROM_REGION(0x1000, "maincpu", 0 ) - ROM_LOAD("jmon.rom", 0x0000, 0x0800, CRC(202c47a2) SHA1(701588ec5640d633d90d94b2ccd6f65422e19a70) ) - ROM_LOAD("util.rom", 0x0800, 0x0800, CRC(7c19700d) SHA1(dc5b3ade66bb11c54430056966ed99cdd299d82b) ) -ROM_END - -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1984, tec1, 0, 0, tec1, tec1, tec1_state, empty_init, "Talking Electronics magazine", "TEC-1", MACHINE_SUPPORTS_SAVE ) -COMP( 1984, tecjmon, tec1, 0, tecjmon, tec1, tec1_state, empty_init, "Talking Electronics magazine", "TEC-1A with JMON", MACHINE_SUPPORTS_SAVE ) -- cgit v1.2.3