From 81bf76a0992aed198b5f4e0a3fd3fed9b5e0cf0b Mon Sep 17 00:00:00 2001 From: hap Date: Sat, 2 Jul 2022 12:42:08 +0200 Subject: source org: remove some 8.3 folder name truncations --- 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/dicksmth/super80.cpp | 995 ------------------------------ src/mame/dicksmth/super80.h | 188 ------ src/mame/dicksmth/super80_m.cpp | 284 --------- src/mame/dicksmth/super80_v.cpp | 420 ------------- src/mame/mame.lst | 22 +- src/mame/mess.flt | 22 +- src/mame/tangerin/alphatan.cpp | 231 ------- src/mame/tangerin/hhtiger.cpp | 599 ------------------ src/mame/tangerin/microtan.cpp | 484 --------------- src/mame/tangerin/microtan.h | 136 ---- src/mame/tangerin/microtan_m.cpp | 712 --------------------- src/mame/tangerin/microtan_v.cpp | 66 -- src/mame/tangerin/oric.cpp | 1005 ------------------------------ src/mame/tangerine/alphatan.cpp | 231 +++++++ src/mame/tangerine/hhtiger.cpp | 599 ++++++++++++++++++ src/mame/tangerine/microtan.cpp | 484 +++++++++++++++ src/mame/tangerine/microtan.h | 136 ++++ src/mame/tangerine/microtan_m.cpp | 712 +++++++++++++++++++++ src/mame/tangerine/microtan_v.cpp | 66 ++ src/mame/tangerine/oric.cpp | 1005 ++++++++++++++++++++++++++++++ src/mame/tektroni/tek405x.cpp | 1193 ------------------------------------ src/mame/tektroni/tek405x.h | 176 ------ src/mame/tektroni/tek410x.cpp | 378 ------------ src/mame/tektroni/tek410x_kbd.cpp | 385 ------------ src/mame/tektroni/tek410x_kbd.h | 69 --- src/mame/tektroni/tek43xx.cpp | 70 --- src/mame/tektroni/tek440x.cpp | 432 ------------- src/mame/tektroni/tekigw.cpp | 967 ----------------------------- src/mame/tektroni/tekxp33x.cpp | 132 ---- src/mame/tektronix/tek405x.cpp | 1193 ++++++++++++++++++++++++++++++++++++ src/mame/tektronix/tek405x.h | 176 ++++++ src/mame/tektronix/tek410x.cpp | 378 ++++++++++++ src/mame/tektronix/tek410x_kbd.cpp | 385 ++++++++++++ src/mame/tektronix/tek410x_kbd.h | 69 +++ src/mame/tektronix/tek43xx.cpp | 70 +++ src/mame/tektronix/tek440x.cpp | 432 +++++++++++++ src/mame/tektronix/tekigw.cpp | 967 +++++++++++++++++++++++++++++ src/mame/tektronix/tekxp33x.cpp | 132 ++++ 42 files changed, 8944 insertions(+), 8944 deletions(-) create mode 100644 src/mame/dicksmith/super80.cpp create mode 100644 src/mame/dicksmith/super80.h create mode 100644 src/mame/dicksmith/super80_m.cpp create mode 100644 src/mame/dicksmith/super80_v.cpp delete mode 100644 src/mame/dicksmth/super80.cpp delete mode 100644 src/mame/dicksmth/super80.h delete mode 100644 src/mame/dicksmth/super80_m.cpp delete mode 100644 src/mame/dicksmth/super80_v.cpp delete mode 100644 src/mame/tangerin/alphatan.cpp delete mode 100644 src/mame/tangerin/hhtiger.cpp delete mode 100644 src/mame/tangerin/microtan.cpp delete mode 100644 src/mame/tangerin/microtan.h delete mode 100644 src/mame/tangerin/microtan_m.cpp delete mode 100644 src/mame/tangerin/microtan_v.cpp delete mode 100644 src/mame/tangerin/oric.cpp create mode 100644 src/mame/tangerine/alphatan.cpp create mode 100644 src/mame/tangerine/hhtiger.cpp create mode 100644 src/mame/tangerine/microtan.cpp create mode 100644 src/mame/tangerine/microtan.h create mode 100644 src/mame/tangerine/microtan_m.cpp create mode 100644 src/mame/tangerine/microtan_v.cpp create mode 100644 src/mame/tangerine/oric.cpp delete mode 100644 src/mame/tektroni/tek405x.cpp delete mode 100644 src/mame/tektroni/tek405x.h delete mode 100644 src/mame/tektroni/tek410x.cpp delete mode 100644 src/mame/tektroni/tek410x_kbd.cpp delete mode 100644 src/mame/tektroni/tek410x_kbd.h delete mode 100644 src/mame/tektroni/tek43xx.cpp delete mode 100644 src/mame/tektroni/tek440x.cpp delete mode 100644 src/mame/tektroni/tekigw.cpp delete mode 100644 src/mame/tektroni/tekxp33x.cpp create mode 100644 src/mame/tektronix/tek405x.cpp create mode 100644 src/mame/tektronix/tek405x.h create mode 100644 src/mame/tektronix/tek410x.cpp create mode 100644 src/mame/tektronix/tek410x_kbd.cpp create mode 100644 src/mame/tektronix/tek410x_kbd.h create mode 100644 src/mame/tektronix/tek43xx.cpp create mode 100644 src/mame/tektronix/tek440x.cpp create mode 100644 src/mame/tektronix/tekigw.cpp create mode 100644 src/mame/tektronix/tekxp33x.cpp diff --git a/src/mame/dicksmith/super80.cpp b/src/mame/dicksmith/super80.cpp new file mode 100644 index 00000000000..a4c1999d72f --- /dev/null +++ b/src/mame/dicksmith/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/dicksmith/super80.h b/src/mame/dicksmith/super80.h new file mode 100644 index 00000000000..a8a74191a55 --- /dev/null +++ b/src/mame/dicksmith/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/dicksmith/super80_m.cpp b/src/mame/dicksmith/super80_m.cpp new file mode 100644 index 00000000000..5b14c8cb6d3 --- /dev/null +++ b/src/mame/dicksmith/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/dicksmith/super80_v.cpp b/src/mame/dicksmith/super80_v.cpp new file mode 100644 index 00000000000..5bdbf556c0b --- /dev/null +++ b/src/mame/dicksmith/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/dicksmth/super80.cpp b/src/mame/dicksmth/super80.cpp deleted file mode 100644 index a4c1999d72f..00000000000 --- a/src/mame/dicksmth/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/dicksmth/super80.h b/src/mame/dicksmth/super80.h deleted file mode 100644 index a8a74191a55..00000000000 --- a/src/mame/dicksmth/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/dicksmth/super80_m.cpp b/src/mame/dicksmth/super80_m.cpp deleted file mode 100644 index 5b14c8cb6d3..00000000000 --- a/src/mame/dicksmth/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/dicksmth/super80_v.cpp b/src/mame/dicksmth/super80_v.cpp deleted file mode 100644 index 5bdbf556c0b..00000000000 --- a/src/mame/dicksmth/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/mame.lst b/src/mame/mame.lst index 4aa4d641cee..1832f43784c 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -1224,7 +1224,7 @@ asmapro // (c) 1995 Intelligent Peripheral Devices @source:skeleton/alphasma3k.cpp asma3k // (c) 2000 AlphaSmart, Inc. -@source:tangerin/alphatan.cpp +@source:tangerine/alphatan.cpp alphatan // 1981 AlphaTantel @source:ta/alphatpx.cpp @@ -16892,7 +16892,7 @@ tmscramb // Tomy tmtennis // Tomy ufombs // Bambino -@source:tangerin/hhtiger.cpp +@source:tangerine/hhtiger.cpp hhtiger // 1983 H/H Tiger @source:misc/hideseek.cpp @@ -23703,7 +23703,7 @@ micronic // pentacup // pentacup2 // -@source:tangerin/microtan.cpp +@source:tangerine/microtan.cpp mt65 // 1979 Microtan 65 micron // 1980 Micron spinveti // 1980 Space Invasion (ETI) @@ -33973,7 +33973,7 @@ orao103 // @source:atari/orbit.cpp orbit // 033689-033702 1978/11 [6800] -@source:tangerin/oric.cpp +@source:tangerine/oric.cpp oric1 // 1983 Oric 1 orica // 1984 Oric Atmos prav8d // 1985 Pravetz 8D @@ -40414,7 +40414,7 @@ supduck // (c) Comad @source:adc/super6.cpp super6 // -@source:dicksmth/super80.cpp +@source:dicksmith/super80.cpp super80 // super80d // super80e // @@ -41371,25 +41371,25 @@ tehkanwcc // bootleg tehkanwcd // (c) 1985 Tehkan tehkanwch // (c) 1986 (hack) -@source:tektroni/tek405x.cpp +@source:tektronix/tek405x.cpp tek4051 // tek4052a // -@source:tektroni/tek410x.cpp +@source:tektronix/tek410x.cpp tek4107a // tek4109a // -@source:tektroni/tek43xx.cpp +@source:tektronix/tek43xx.cpp tek4319 // -@source:tektroni/tek440x.cpp +@source:tektronix/tek440x.cpp tek4404 // (c) 1984 Tektronix -@source:tektroni/tekigw.cpp +@source:tektronix/tekigw.cpp tek4132 // Tektronix 4132 tek6130 // Tektronix 6130 -@source:tektroni/tekxp33x.cpp +@source:tektronix/tekxp33x.cpp tekxp330 // @source:skeleton/teleray10.cpp diff --git a/src/mame/mess.flt b/src/mame/mess.flt index 6dccb17a0d2..2e5ef3afa5f 100644 --- a/src/mame/mess.flt +++ b/src/mame/mess.flt @@ -192,7 +192,7 @@ dec/vt320.cpp dec/vt52.cpp dec/vt520.cpp dec/vt62.cpp -dicksmth/super80.cpp +dicksmith/super80.cpp dms/dms5000.cpp dms/dms86.cpp dms/zsbc3.cpp @@ -1008,19 +1008,19 @@ ta/alphatpx.cpp ta/alphatro.cpp tab/tabe22.cpp tandberg/tdv2324.cpp -tangerin/alphatan.cpp -tangerin/hhtiger.cpp -tangerin/microtan.cpp -tangerin/oric.cpp +tangerine/alphatan.cpp +tangerine/hhtiger.cpp +tangerine/microtan.cpp +tangerine/oric.cpp tatung/einstein.cpp teamconcepts/comquest.cpp tectoy/pensebem.cpp -tektroni/tek405x.cpp -tektroni/tek410x.cpp -tektroni/tek43xx.cpp -tektroni/tek440x.cpp -tektroni/tekigw.cpp -tektroni/tekxp33x.cpp +tektronix/tek405x.cpp +tektronix/tek410x.cpp +tektronix/tek43xx.cpp +tektronix/tek440x.cpp +tektronix/tekigw.cpp +tektronix/tekxp33x.cpp telenova/compis.cpp telercas/tmc1800.cpp telercas/tmc2000e.cpp diff --git a/src/mame/tangerin/alphatan.cpp b/src/mame/tangerin/alphatan.cpp deleted file mode 100644 index 0bf5eb7ed1f..00000000000 --- a/src/mame/tangerin/alphatan.cpp +++ /dev/null @@ -1,231 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Nigel Barnes -/********************************************************************** - - Tantel AlphaTantel - - - Hardware: - --------- - CPU: R6504 - - RAM: M6810 - M5101 - battery backed - 2114 x 2 - video RAM - - Video: SAA5020 VTC - SAA5050 VCG - SAA5070 VIOP - TEA1002 - - TODO: - - implement SAA5070 (datasheet required) - - keyboard matrix (probably via SAA5070) - - cassette interface (via SAA5070) - - program mode switch - -**********************************************************************/ - -#include "emu.h" -#include "cpu/m6502/m6504.h" -#include "machine/nvram.h" -#include "machine/output_latch.h" -#include "video/tea1002.h" -#include "video/saa5050.h" -#include "bus/centronics/ctronics.h" -#include "imagedev/cassette.h" - -#include "emupal.h" -#include "screen.h" - - -class alphatan_state : public driver_device -{ -public: - alphatan_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_maincpu(*this, "maincpu") - , m_videoram(*this, "videoram") - , m_nvram(*this, "nvram") - , m_screen(*this, "screen") - , m_tea1002(*this, "encoder") - , m_palette(*this, "palette") - , m_trom(*this, "saa5050") - , m_centronics(*this, "centronics") - , m_cent_data_out(*this, "cent_data_out") - , m_cassette(*this, "cassette") - , m_config(*this, "CONFIG") - { } - - void alphatan(machine_config &config); - - uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - -protected: - virtual void machine_start() override; - -private: - required_device m_maincpu; - required_shared_ptr m_videoram; - required_device m_nvram; - required_device m_screen; - required_device m_tea1002; - required_device m_palette; - required_device m_trom; - required_device m_centronics; - required_device m_cent_data_out; - required_device m_cassette; - required_ioport m_config; - - void alphatan_map(address_map &map); - - uint8_t saa5070_r(offs_t offset); - void saa5070_w(offs_t offset, uint8_t data); - void write400(offs_t offset, uint8_t data); - void write600(offs_t offset, uint8_t data); - - void palette_init(palette_device &palette) const; -}; - -void alphatan_state::alphatan_map(address_map &map) -{ - map.unmap_value_high(); - map(0x0000, 0x007f).ram().mirror(0x0180); // MCM6810 - map(0x0200, 0x027f).ram().share("nvram"); // MCM5101 - map(0x0300, 0x0300).rw(FUNC(alphatan_state::saa5070_r), FUNC(alphatan_state::saa5070_w)); // write 0x20, 0x14, 0x0c, 0x18, 0x40, 0x90, 0x1f, 0xd4, 0x0f - map(0x0400, 0x0400).w(FUNC(alphatan_state::write400)); // write 0x03, 0x06, 0x08, 0x00, 0x04, 0x07, 0x01, 0x05 - map(0x0500, 0x0500).w(m_cent_data_out, FUNC(output_latch_device::write)); - map(0x0600, 0x0600).w(FUNC(alphatan_state::write600)); // unknown, writes only 0x01, 0x02, or 0x03 - map(0x0700, 0x0700).portr("CONFIG"); - map(0x0800, 0x0fff).ram().share("videoram"); // 2x2114 - map(0x1000, 0x1fff).rom().region("maincpu", 0); -} - - -static INPUT_PORTS_START( alphatan ) - PORT_START("CONFIG") - PORT_CONFNAME(0x10, 0x10, "Banner") - PORT_CONFSETTING(0x00, "Granada") - PORT_CONFSETTING(0x10, "Tantel") -INPUT_PORTS_END - - -uint8_t alphatan_state::saa5070_r(offs_t offset) -{ - uint8_t data = 0x00; - - //logerror("saa5070_r: %02x\n", data); - - return data; -} - -void alphatan_state::saa5070_w(offs_t offset, uint8_t data) -{ - //logerror("saa5070_w: %02x\n", data); -} - -void alphatan_state::write400(offs_t offset, uint8_t data) -{ - //logerror("write400: %02x\n", data); -} - -void alphatan_state::write600(offs_t offset, uint8_t data) -{ - //logerror("write600: %02x\n", data); -} - - -void alphatan_state::palette_init(palette_device &palette) const -{ - for (int i = 0; i < 8; i++) - palette.set_indirect_color(i, m_tea1002->color(i)); -} - -uint32_t alphatan_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - const rgb_t *palette = m_palette->palette()->entry_list_raw(); - - m_trom->dew_w(1); - m_trom->dew_w(0); - - for (int y = 0; y < 24 * 20; y++) - { - int sy = y / 20; - int x = 0; - - m_trom->lose_w(1); - m_trom->lose_w(0); - - int ssy = m_trom->tlc_r() ? sy : sy - 1; - offs_t video_ram_addr = ssy * 64; - - for (int sx = 0; sx < 40; sx++) - { - uint8_t code = m_videoram[video_ram_addr++]; - - m_trom->write(code & 0x7f); - - m_trom->f1_w(1); - m_trom->f1_w(0); - - for (int bit = 0; bit < 12; bit++) - { - m_trom->tr6_w(1); - m_trom->tr6_w(0); - - int color = m_trom->get_rgb(); - - if (BIT(code, 7)) color ^= 0x07; - - bitmap.pix(y, x++) = palette[color]; - } - } - } - - return 0; -} - - -void alphatan_state::machine_start() -{ -} - - -void alphatan_state::alphatan(machine_config &config) -{ - M6504(config, m_maincpu, 8.86_MHz_XTAL / 2); - m_maincpu->set_addrmap(AS_PROGRAM, &alphatan_state::alphatan_map); - - NVRAM(config, m_nvram, nvram_device::DEFAULT_ALL_0); - - SCREEN(config, m_screen, SCREEN_TYPE_RASTER); - //m_screen->set_raw(6_MHz_XTAL, 768, 0, 480, 625, 0, 480); - m_screen->set_refresh_hz(50); - m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500)); - m_screen->set_size(768, 480); - m_screen->set_visarea(0, 480-1, 0, 480-1); - m_screen->set_screen_update(FUNC(alphatan_state::screen_update)); - - TEA1002(config, m_tea1002, 8.86_MHz_XTAL); - PALETTE(config, m_palette, FUNC(alphatan_state::palette_init), 8, 8); - - SAA5050(config, m_trom, 6_MHz_XTAL); - - CENTRONICS(config, m_centronics, centronics_devices, "printer"); - - OUTPUT_LATCH(config, m_cent_data_out); - m_centronics->set_output_latch(*m_cent_data_out); - - CASSETTE(config, m_cassette); - m_cassette->set_default_state(CASSETTE_STOPPED); -} - - -ROM_START(alphatan) - ROM_REGION(0x1000, "maincpu", 0) - ROM_LOAD("tantel2732.bin", 0x0000, 0x1000, CRC(875c1ce9) SHA1(76e874cbc5d1341b09f57424181f24bdb31da210)) -ROM_END - - -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1981, alphatan, 0, 0, alphatan, alphatan, alphatan_state, empty_init, "Tantel", "AlphaTantel", MACHINE_NO_SOUND_HW | MACHINE_NOT_WORKING ) diff --git a/src/mame/tangerin/hhtiger.cpp b/src/mame/tangerin/hhtiger.cpp deleted file mode 100644 index 739887f9377..00000000000 --- a/src/mame/tangerin/hhtiger.cpp +++ /dev/null @@ -1,599 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Nigel Barnes -/********************************************************************** - - http://www.computinghistory.org.uk/det/52264/HH-Tiger/ - - SPECIFICATION - Processors: Z80A (4MHz) plus 6809 I/O processor (2MHz) plus 7220 - graphics processor. - RAM: 64K with Z80, 2K with 6809, 96K with 7220, plus 0.5K CMOS - RAM with battery back-up. 62K available to CP/M. - ROM: 2K with Z80, 16K with 6809. - Text screen: 80 x 24 or teletext-type 40 x 24, 8 colours. - Graphic screen: 512 x 512 pixels, 8 colours. - Keyboard: 88 keys in unit with CPU, numeric/cursor pad. 10 function - keys. - Storage: 2 x 1 MB (unformatted) floppies - Interfaces: RS232, Centronics parallel, IEEE488, networking, light pen, - cassette, disk expansion (5.25" or 8"), optional UHF or - additional video monitor -Operating system: CP/M - - TODO: - - nothing is known so emulation is very incomplete. - -**********************************************************************/ - - -#include "emu.h" -#include "cpu/z80/z80.h" -#include "machine/z80dma.h" -#include "machine/z80pio.h" -#include "machine/z80daisy.h" -#include "machine/ram.h" -#include "emupal.h" -#include "screen.h" -#include "speaker.h" - -#include "cpu/m6809/m6809.h" -#include "machine/input_merger.h" -#include "machine/nvram.h" -#include "machine/6522via.h" -#include "machine/mc6854.h" -#include "machine/mos6551.h" -#include "machine/tms9914.h" -#include "sound/spkrdev.h" -#include "video/upd7220.h" -#include "imagedev/cassette.h" -#include "imagedev/floppy.h" -#include "bus/ieee488/ieee488.h" -#include "bus/rs232/rs232.h" -#include "bus/centronics/ctronics.h" - -// Debugging -#define VERBOSE 1 -#include "logmacro.h" - - -class hhtiger_state : public driver_device -{ -public: - hhtiger_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_maincpu(*this, "z80") - , m_rom_z80(*this, "rom_z80") - , m_ram(*this, RAM_TAG) - , m_dma(*this, "dma") - , m_pio(*this, "pio") - , m_subcpu(*this, "m6809") - , m_rom_m6809(*this, "rom_m6809") - , m_screen(*this, "screen") - , m_gdc(*this, "upd7220") - , m_palette(*this, "palette") - , m_video_ram(*this, "video_ram") - , m_nvram(*this, "nvram") - , m_via(*this, "via%u", 0) - , m_adlc(*this, "adlc") - , m_acia(*this, "acia") - , m_ieee(*this, IEEE488_TAG) - , m_tms9914(*this, "hpib") - , m_speaker(*this, "speaker") - , m_cassette(*this, "cassette") - , m_irqs(*this, "irqs") - , m_rom_mirror(true) - { } - - void hhtiger(machine_config &config); - -private: - virtual void machine_reset() override; - virtual void machine_start() override; - - uint8_t disable_rom_r(); - uint8_t read(offs_t offset); - void write(offs_t offset, uint8_t data); - 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); - - UPD7220_DISPLAY_PIXELS_MEMBER(display_pixels); - UPD7220_DRAW_TEXT_LINE_MEMBER(draw_text); - - /* handlers for logging only, can be removed when more is known */ - uint8_t pio_pa_r(); - void pio_pa_w(uint8_t data); - void pio_pb_w(uint8_t data); - DECLARE_WRITE_LINE_MEMBER(ardy_w); - DECLARE_WRITE_LINE_MEMBER(brdy_w); - - uint8_t via_0_in_a(); - void via_0_out_a(uint8_t data); - void via_0_out_b(uint8_t data); - DECLARE_WRITE_LINE_MEMBER(via_0_out_ca2); - DECLARE_WRITE_LINE_MEMBER(via_0_out_cb2); - - void via_1_out_a(uint8_t data); - void via_1_out_b(uint8_t data); - DECLARE_WRITE_LINE_MEMBER(via_1_out_ca2); - DECLARE_WRITE_LINE_MEMBER(via_1_out_cb2); - - void z80_mem(address_map &map); - void z80_io(address_map &map); - void m6809_mem(address_map &map); - void upd7220_map(address_map &map); - - required_device m_maincpu; - required_memory_region m_rom_z80; - required_device m_ram; - required_device m_dma; - required_device m_pio; - - required_device m_subcpu; - required_memory_region m_rom_m6809; - required_device m_screen; - required_device m_gdc; - required_device m_palette; - required_shared_ptr m_video_ram; - required_device m_nvram; - required_device_array m_via; - required_device m_adlc; - required_device m_acia; - required_device m_ieee; - required_device m_tms9914; - required_device m_speaker; - required_device m_cassette; - required_device m_irqs; - - bool m_rom_mirror; -}; - - -void hhtiger_state::machine_start() -{ - save_item(NAME(m_rom_mirror)); -} - - -void hhtiger_state::machine_reset() -{ - m_rom_mirror = true; -} - - -static const gfx_layout hhtiger_charlayout = -{ - 8, 8, /* 8 x 8 characters */ - 128, /* 128 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 /* every char takes 8 bytes */ -}; - -static GFXDECODE_START(gfx_hhtiger) - GFXDECODE_ENTRY("rom_m6809", 0x2000, hhtiger_charlayout, 0, 1) -GFXDECODE_END - - -UPD7220_DISPLAY_PIXELS_MEMBER(hhtiger_state::display_pixels) -{ - /* 96KB video RAM (32KB green + 32KB red + 32KB blue) */ - uint16_t const green = m_video_ram[(0x00000 + (address & 0x3fff))]; - uint16_t const red = m_video_ram[(0x04000 + (address & 0x3fff))]; - uint16_t const blue = m_video_ram[(0x08000 + (address & 0x3fff))]; - - for (int xi = 0; xi<16; xi++) - { - int const r = BIT(red, xi) ? 255 : 0; - int const g = BIT(green, xi) ? 255 : 0; - int const b = BIT(blue, xi) ? 255 : 0; - - if (bitmap.cliprect().contains(x + xi, y)) - bitmap.pix(y, x + xi) = rgb_t(r, g, b); - } -} - -UPD7220_DRAW_TEXT_LINE_MEMBER(hhtiger_state::draw_text) -{ - rgb_t const *const palette = m_palette->palette()->entry_list_raw(); - - for (int x = 0; x < pitch; x++) - { - uint8_t tile = m_video_ram[(((addr + x) * 2) & 0x1ffff) >> 1] & 0xff; - uint8_t attr = m_video_ram[(((addr + x) * 2) & 0x1ffff) >> 1] >> 8; - - for (int yi = 0; yi < lr; yi++) - { - uint8_t tile_data = m_rom_m6809->base()[0x1000 | ((tile * 8 + yi) & 0x7ff)]; - - if (cursor_on && cursor_addr == addr + x) //TODO - tile_data ^= 0xff; - - for (int xi = 0; xi < 8; xi++) - { - int pen = (tile_data >> xi) & 1 ? (attr & 0x07) : 0; - - int const res_x = x * 8 + xi; - int const res_y = y + yi; - - if (yi >= 8) - pen = 0; - - if (!m_screen->visible_area().contains(res_x, res_y)) - bitmap.pix(res_y, res_x) = palette[pen]; - } - } - } -} - - -uint8_t hhtiger_state::disable_rom_r() -{ - if (!machine().side_effects_disabled()) - m_rom_mirror = false; - - return 0xff; -} - -uint8_t hhtiger_state::read(offs_t offset) -{ - uint8_t data; - - if (m_rom_mirror) - { - data = m_rom_z80->base()[offset & 0x0fff]; - } - else - { - switch (offset & 0xf800) - { - case 0xf800: - data = m_rom_z80->base()[offset & 0x0fff]; - break; - default: - data = m_ram->pointer()[offset]; - break; - } - } - - return data; -} - -void hhtiger_state::write(offs_t offset, uint8_t data) -{ - m_ram->pointer()[offset] = data; -} - - -WRITE_LINE_MEMBER(hhtiger_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 -} - -uint8_t hhtiger_state::memory_read_byte(offs_t offset) -{ - address_space& prog_space = m_maincpu->space(AS_PROGRAM); - return prog_space.read_byte(offset); -} - -void hhtiger_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 hhtiger_state::io_read_byte(offs_t offset) -{ - address_space& io_space = m_maincpu->space(AS_IO); - return io_space.read_byte(offset); -} - -void hhtiger_state::io_write_byte(offs_t offset, uint8_t data) -{ - address_space& io_space = m_maincpu->space(AS_IO); - io_space.write_byte(offset, data); -} - - -//------------------------------------------------- -// ADDRESS_MAP( z80_mem ) -//------------------------------------------------- - -void hhtiger_state::z80_mem(address_map &map) -{ - map(0x0000, 0xffff).rw(FUNC(hhtiger_state::read), FUNC(hhtiger_state::write)); -} - -void hhtiger_state::z80_io(address_map &map) -{ - map.global_mask(0xff); - map(0x00, 0x03).rw(m_dma, FUNC(z80dma_device::read), FUNC(z80dma_device::write)); - map(0x04, 0x07).rw(m_pio, FUNC(z80pio_device::read), FUNC(z80pio_device::write)); - map(0x10, 0x17).rw(m_tms9914, FUNC(tms9914_device::read), FUNC(tms9914_device::write)); // ?? - map(0x1e, 0x1e).r(FUNC(hhtiger_state::disable_rom_r)); -} - - -//------------------------------------------------- -// ADDRESS_MAP( m6809_mem ) -//------------------------------------------------- - -void hhtiger_state::m6809_mem(address_map &map) -{ - map(0x0000, 0x07ff).ram(); - map(0xb800, 0xb9ff).ram().share("nvram"); - map(0xbfa0, 0xbfa3).rw(m_gdc, FUNC(upd7220_device::read), FUNC(upd7220_device::write)); - map(0xbfb0, 0xbfb3).rw(m_adlc, FUNC(mc6854_device::read), FUNC(mc6854_device::write)); // ?? - map(0xbfc0, 0xbfcf).m(m_via[1], FUNC(via6522_device::map)); - map(0xbfd0, 0xbfd3).rw(m_acia, FUNC(mos6551_device::read), FUNC(mos6551_device::write)); // ?? - map(0xbfe0, 0xbfef).m(m_via[0], FUNC(via6522_device::map)); - map(0xc000, 0xffff).rom().region("rom_m6809", 0); -} - - -//------------------------------------------------- -// ADDRESS_MAP( upd7220_map ) -//------------------------------------------------- - -void hhtiger_state::upd7220_map(address_map &map) -{ - map.global_mask(0x17fff); - map(0x00000, 0x17fff).ram().share("video_ram"); -} - - -static const z80_daisy_config daisy_chain_intf[] = -{ - { "dma" }, - { "pio" }, - { nullptr } -}; - - -static INPUT_PORTS_START(hhtiger) -INPUT_PORTS_END - - -uint8_t hhtiger_state::pio_pa_r() -{ - uint8_t data = 0xff; - - LOG("pio_pa_r %02X\n", data); - return data; -} - -void hhtiger_state::pio_pa_w(uint8_t data) -{ - LOG("pio_pa_w %02X\n", data); - m_via[0]->write_pa(data); -} - -void hhtiger_state::pio_pb_w(uint8_t data) -{ - LOG("pio_pb_w %02X\n", data); - m_via[0]->write_pb(data); -} - -WRITE_LINE_MEMBER(hhtiger_state::ardy_w) -{ - LOG("ardy_w %d\n", state); - m_via[0]->write_ca1(state); -} - -WRITE_LINE_MEMBER(hhtiger_state::brdy_w) -{ - LOG("brdy_w %d\n", state); - m_via[0]->write_cb1(state); -} - - -uint8_t hhtiger_state::via_0_in_a() -{ - uint8_t data = 0xff; - - LOG("via0_in_a %02X\n", data); - data = m_pio->port_a_read(); - return data; -} - -void hhtiger_state::via_0_out_a(uint8_t data) -{ - LOG("via0_out_a %02X\n", data); - m_pio->port_a_write(data); -} - -void hhtiger_state::via_0_out_b(uint8_t data) -{ - LOG("via0_out_b %02X\n", data); -} - -WRITE_LINE_MEMBER(hhtiger_state::via_0_out_ca2) -{ - LOG("via0_out_ca2 %d\n", state); - m_pio->strobe_a(state); -} - -WRITE_LINE_MEMBER(hhtiger_state::via_0_out_cb2) -{ - LOG("via0_out_cb2 %d\n", state); -} - - -void hhtiger_state::via_1_out_a(uint8_t data) -{ - LOG("via1_out_a %02X\n", data); -} - -void hhtiger_state::via_1_out_b(uint8_t data) -{ - LOG("via1_out_b %02X\n", data); -} - -WRITE_LINE_MEMBER(hhtiger_state::via_1_out_ca2) -{ - LOG("via1_out_ca2 %d\n", state); -} - -WRITE_LINE_MEMBER(hhtiger_state::via_1_out_cb2) -{ - LOG("via1_out_cb2 %d\n", state); -} - - -static void hhtiger_floppies(device_slot_interface &device) -{ - device.option_add("525dd", FLOPPY_525_DD); -} - - -void hhtiger_state::hhtiger(machine_config &config) -{ - /* main cpu z80a */ - Z80(config, m_maincpu, 16_MHz_XTAL / 4); - m_maincpu->set_addrmap(AS_PROGRAM, &hhtiger_state::z80_mem); - m_maincpu->set_addrmap(AS_IO, &hhtiger_state::z80_io); - m_maincpu->set_daisy_config(daisy_chain_intf); - - 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(hhtiger_state::busreq_w)); - m_dma->in_mreq_callback().set(FUNC(hhtiger_state::memory_read_byte)); - m_dma->out_mreq_callback().set(FUNC(hhtiger_state::memory_write_byte)); - m_dma->in_iorq_callback().set(FUNC(hhtiger_state::io_read_byte)); - m_dma->out_iorq_callback().set(FUNC(hhtiger_state::io_write_byte)); - - Z80PIO(config, m_pio, 16_MHz_XTAL / 4); - m_pio->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); - m_pio->in_pa_callback().set(FUNC(hhtiger_state::pio_pa_r)); - m_pio->out_pa_callback().set(FUNC(hhtiger_state::pio_pa_w)); - m_pio->out_ardy_callback().set(FUNC(hhtiger_state::ardy_w)); - m_pio->out_pb_callback().set(FUNC(hhtiger_state::pio_pb_w)); - m_pio->out_brdy_callback().set(FUNC(hhtiger_state::brdy_w)); - - RAM(config, m_ram).set_default_size("64K"); - - /* unknown fdc - floppy drives are housed with monitor so maybe fdc is external */ - FLOPPY_CONNECTOR(config, "0", hhtiger_floppies, "525dd", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "1", hhtiger_floppies, "525dd", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "2", hhtiger_floppies, nullptr, floppy_image_device::default_mfm_floppy_formats).enable_sound(true); - - /* unknown sound hardware - maybe connected to square-wave timer output from via */ - SPEAKER(config, "mono").front_center(); - SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.50); - - /* io cpu 6809 */ - MC6809(config, m_subcpu, 16_MHz_XTAL / 4); - m_subcpu->set_addrmap(AS_PROGRAM, &hhtiger_state::m6809_mem); - - INPUT_MERGER_ANY_HIGH(config, m_irqs); - m_irqs->output_handler().set_inputline(m_maincpu, M6809_IRQ_LINE); - - NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); - - SCREEN(config, m_screen, SCREEN_TYPE_RASTER); - m_screen->set_video_attributes(VIDEO_UPDATE_BEFORE_VBLANK); - m_screen->set_raw(16_MHz_XTAL, 520, 0, 320, 308, 0, 240); - m_screen->set_screen_update("upd7220", FUNC(upd7220_device::screen_update)); - - GFXDECODE(config, "gfxdecode", m_palette, gfx_hhtiger); - PALETTE(config, m_palette, palette_device::RGB_3BIT); - - UPD7220(config, m_gdc, 16_MHz_XTAL / 16); - m_gdc->set_addrmap(0, &hhtiger_state::upd7220_map); - m_gdc->set_display_pixels(FUNC(hhtiger_state::display_pixels)); - m_gdc->set_draw_text(FUNC(hhtiger_state::draw_text)); - m_gdc->set_screen(m_screen); - - MOS6522(config, m_via[0], 16_MHz_XTAL / 16); - m_via[0]->readpa_handler().set(FUNC(hhtiger_state::via_0_in_a)); - m_via[0]->writepa_handler().set(FUNC(hhtiger_state::via_0_out_a)); - m_via[0]->writepb_handler().set(FUNC(hhtiger_state::via_0_out_b)); - m_via[0]->ca2_handler().set(FUNC(hhtiger_state::via_0_out_ca2)); - m_via[0]->cb2_handler().set(FUNC(hhtiger_state::via_0_out_cb2)); - m_via[0]->irq_handler().set(m_irqs, FUNC(input_merger_device::in_w<0>)); - - MOS6522(config, m_via[1], 16_MHz_XTAL / 16); - m_via[1]->irq_handler().set(m_irqs, FUNC(input_merger_device::in_w<1>)); - m_via[1]->writepa_handler().set(FUNC(hhtiger_state::via_1_out_a)); - m_via[1]->writepb_handler().set(FUNC(hhtiger_state::via_1_out_b)); - m_via[1]->ca2_handler().set(FUNC(hhtiger_state::via_1_out_ca2)); - m_via[1]->cb2_handler().set(FUNC(hhtiger_state::via_1_out_cb2)); - - centronics_device ¢ronics(CENTRONICS(config, "centronics", centronics_devices, "printer")); - centronics.ack_handler().set(m_via[1], FUNC(via6522_device::write_ca1)); - output_latch_device &latch(OUTPUT_LATCH(config, "cent_data_out")); - centronics.set_output_latch(latch); - - MC6854(config, m_adlc); - m_adlc->out_irq_cb().set("irqs", FUNC(input_merger_device::in_w<2>)); - - CASSETTE(config, m_cassette); - m_cassette->set_default_state(CASSETTE_STOPPED); - m_cassette->add_route(ALL_OUTPUTS, "mono", 0.05); - - MOS6551(config, m_acia, 0); - m_acia->set_xtal(1.8432_MHz_XTAL); - m_acia->irq_handler().set("irqs", FUNC(input_merger_device::in_w<3>)); - 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->dtr_handler().set("rs232", FUNC(rs232_port_device::write_dtr)); - - rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, nullptr)); - rs232.rxd_handler().set(m_acia, FUNC(mos6551_device::write_rxd)); - rs232.dcd_handler().set(m_acia, FUNC(mos6551_device::write_dcd)); - rs232.dsr_handler().set(m_acia, FUNC(mos6551_device::write_dsr)); - rs232.cts_handler().set(m_acia, FUNC(mos6551_device::write_cts)); - - TMS9914(config, m_tms9914, 16_MHz_XTAL / 4); - m_tms9914->int_write_cb().set("irqs", FUNC(input_merger_device::in_w<4>)); - m_tms9914->dio_read_cb().set(IEEE488_TAG, FUNC(ieee488_device::dio_r)); - m_tms9914->dio_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_dio_w)); - m_tms9914->eoi_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_eoi_w)); - m_tms9914->dav_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_dav_w)); - m_tms9914->nrfd_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_nrfd_w)); - m_tms9914->ndac_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_ndac_w)); - m_tms9914->ifc_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_ifc_w)); - m_tms9914->srq_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_srq_w)); - m_tms9914->atn_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_atn_w)); - m_tms9914->ren_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_ren_w)); - - IEEE488(config, m_ieee); - m_ieee->eoi_callback().set(m_tms9914, FUNC(tms9914_device::eoi_w)); - m_ieee->dav_callback().set(m_tms9914, FUNC(tms9914_device::dav_w)); - m_ieee->nrfd_callback().set(m_tms9914, FUNC(tms9914_device::nrfd_w)); - m_ieee->ndac_callback().set(m_tms9914, FUNC(tms9914_device::ndac_w)); - m_ieee->ifc_callback().set(m_tms9914, FUNC(tms9914_device::ifc_w)); - m_ieee->srq_callback().set(m_tms9914, FUNC(tms9914_device::srq_w)); - m_ieee->atn_callback().set(m_tms9914, FUNC(tms9914_device::atn_w)); - m_ieee->ren_callback().set(m_tms9914, FUNC(tms9914_device::ren_w)); - IEEE488_SLOT(config, "ieee_dev", 0, cbm_ieee488_devices, nullptr); -} - - -ROM_START(hhtiger) - ROM_REGION(0x1000, "rom_z80", 0) - ROM_DEFAULT_BIOS("rel13") - ROM_SYSTEM_BIOS(0, "rel12", "Rel1.2") - ROMX_LOAD("rel1.2-0ea0.ic79", 0x0000, 0x1000, CRC(2f81e48c) SHA1(a4a1d7fde9f92abd6d8f8a1c24e35d713a5cbcb2), ROM_BIOS(0)) - ROM_SYSTEM_BIOS(1, "rel13", "Rel1.3") - ROMX_LOAD("rel1.3-0ea0.ic79", 0x0000, 0x1000, CRC(2f81e48c) SHA1(a4a1d7fde9f92abd6d8f8a1c24e35d713a5cbcb2), ROM_BIOS(1)) - /* Rel1.4 also known to exist */ - ROM_REGION(0x4000, "rom_m6809", 0) - ROMX_LOAD("rel1.2-cfd3.ic16", 0x0000, 0x2000, CRC(1ae4d2e0) SHA1(c379c5f1be24835ae4b4bd7bed35800faa3a9af6), ROM_BIOS(0)) - ROMX_LOAD("rel1.2-8fd2.ic15", 0x2000, 0x2000, CRC(0ef23968) SHA1(d46ce3b965ce51d0c90a10121661199b51e33d8b), ROM_BIOS(0)) - ROMX_LOAD("rel1.3-789a.ic16", 0x0000, 0x2000, CRC(7fa6fd33) SHA1(0b2768c170ca7077ef5164bfa13d9bf033528115), ROM_BIOS(1)) - ROMX_LOAD("rel1.3-77c1.ic15", 0x2000, 0x2000, CRC(dd2f15d5) SHA1(139a2b97cb8c27a50e3bfa3f42a9572203e453e0), ROM_BIOS(1)) -ROM_END - - -/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ -COMP( 1983, hhtiger, 0, 0, hhtiger, hhtiger, hhtiger_state, empty_init, "H/H Microcomputers", "H/H Tiger", MACHINE_IS_SKELETON ) - diff --git a/src/mame/tangerin/microtan.cpp b/src/mame/tangerin/microtan.cpp deleted file mode 100644 index f631a519921..00000000000 --- a/src/mame/tangerin/microtan.cpp +++ /dev/null @@ -1,484 +0,0 @@ -// license:GPL-2.0+ -// copyright-holders:Juergen Buchmueller,Nigel Barnes -/****************************************************************************** - * Microtan 65 - * - * system driver - * - * Juergen Buchmueller , Jul 2000 - * - * Thanks go to Geoff Macdonald - * for his site http://www.geoff.org.uk/microtan/index.htm - * and to Fabrice Frances - * for his site http://oric.free.fr/microtan.html - * - * Microtan65 memory map - * - * range short description - * 0000-01ff SYSRAM system ram - * 0000-003f variables - * 0040-00ff basic - * 0100-01ff stack - * 0200-03ff VIDEORAM display - * 0400-afff RAM main memory - * bc00-bc01 AY8912-0 sound chip #0 - * bc02-bc03 AY8912-1 sound chip #1 - * bc04 SPACEINV space invasion sound (?) - * bfc0-bfcf VIA6522-0 VIA 6522 #0 - * bfd0-bfd3 SIO serial i/o - * bfe0-bfef VIA6522-1 VIA 6522 #1 - * bff0 GFX_KBD R: chunky graphics on W: reset KBD interrupt - * bff1 NMI W: start delayed NMI - * bff2 HEX W: hex. keypad column - * bff3 KBD_GFX R: ASCII KBD / hex. keypad row W: chunky graphics off - * c000-e7ff BASIC BASIC Interpreter ROM - * f000-f7ff XBUG XBUG ROM - * f800-ffff TANBUG TANBUG ROM - * - * Tanbug commands: - * B Set breakpoint - * C copy (move) memory block - * G Go - * L Hex dump - * M Modify memory - * N Exit single-step mode - * O Hex calculator - * P Step once - * R Register examine/modify - * S Enter single-step mode - * BAS Start BASIC - * WAR Re-enter BASIC (warm start) - * - * The keyboard is essentially an ordinary ASCII keyboard, with 71 keys, 8 - * TTL chips and an undumped 2716 eprom labelled MON V1. We currently use a - * generic keyboard because of the lack of a schematic. Unemulated keys are - * 'SHIFT LOCK' and 'REPT'. Since all commands must be uppercase, capslock - * is defaulted to on. - * - *****************************************************************************/ - -#include "emu.h" -#include "microtan.h" -#include "emupal.h" -#include "screen.h" -#include "softlist_dev.h" - - -void microtan_state::mt65_map(address_map &map) -{ - map(0x0000, 0xffff).rw(m_tanbus, FUNC(tanbus_device::read), FUNC(tanbus_device::write)); - map(0x0000, 0x01ff).ram(); - map(0x0200, 0x03ff).ram().w(FUNC(microtan_state::videoram_w)).share(m_videoram); - map(0xbff0, 0xbfff).rw(FUNC(microtan_state::bffx_r), FUNC(microtan_state::bffx_w)); - map(0xf800, 0xffff).rom(); -} - -void microtan_state::spinv_map(address_map &map) -{ - map.unmap_value_high(); - map(0x0000, 0x01ff).ram(); - map(0x0200, 0x03ff).ram().w(FUNC(microtan_state::videoram_w)).share(m_videoram); - map(0xbc04, 0xbc04).rw(FUNC(microtan_state::sound_r), FUNC(microtan_state::sound_w)); - map(0xbff0, 0xbfff).rw(FUNC(microtan_state::bffx_r), FUNC(microtan_state::bffx_w)); - map(0xe800, 0xefff).rom().mirror(0x1000); -} - -void mt6809_state::mt6809_map(address_map &map) -{ - map(0x0000, 0xffff).rw(m_tanbus, FUNC(tanbus_device::read), FUNC(tanbus_device::write)); - map(0xdc00, 0xdfff).ram(); - map(0xdfd8, 0xdfd8).r(FUNC(mt6809_state::keyboard_r)); - map(0xf800, 0xffff).rom(); -} - - -INPUT_CHANGED_MEMBER(microtan_state::trigger_reset) -{ - m_maincpu->set_input_line(INPUT_LINE_RESET, newval ? ASSERT_LINE : CLEAR_LINE); - - if (newval) - { - machine().schedule_soft_reset(); - } -} - -static INPUT_PORTS_START( microtan ) - PORT_START("CONFIG") - PORT_CONFNAME(0x03, 0x00, "Input") - PORT_CONFSETTING(0x00, "ASCII Keyboard") - PORT_CONFSETTING(0x01, "Hex Keypad") - - PORT_START("KBD0") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("ESC") PORT_CODE(KEYCODE_ESC) PORT_CHAR(27) - 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(39) - - PORT_START("KBD1") - 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("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR('~') - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(": *") PORT_CODE(KEYCODE_MINUS) PORT_CHAR(':') PORT_CHAR('*') - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("- =") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('-') PORT_CHAR('=') - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("NEW PAGE") PORT_CODE(KEYCODE_TILDE) PORT_CHAR(12) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("RUB OUT") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(UTF8_UP) PORT_CODE(KEYCODE_TAB) PORT_CHAR('^') PORT_CHAR('_') - - PORT_START("KBD2") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_CHAR('q') - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_CHAR('w') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_CHAR('e') - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_CHAR('r') - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_CHAR('t') - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_CHAR('y') - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_CHAR('u') - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_CHAR('i') - - PORT_START("KBD3") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_CHAR('o') - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CHAR('p') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("[ {") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("] }") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR(']') PORT_CHAR('}') - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("BREAK") PORT_CODE(KEYCODE_DEL) PORT_CHAR(3) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("ALFA LOCK") PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE - - PORT_START("KBD4") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_CHAR('a') - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_CHAR('s') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CHAR('d') - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_CHAR('f') - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_CHAR('g') - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_CHAR('h') - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_CHAR('j') - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_CHAR('k') - - PORT_START("KBD5") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_CHAR('l') - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("; +") PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('+') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("@") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('@') PORT_CHAR('`') - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("\\ |") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('\\') PORT_CHAR('|') - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("SHIFT (L)") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_CHAR('z') - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CHAR('x') - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_CHAR('c') - - PORT_START("KBD6") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_CHAR('v') - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_CHAR('b') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_CHAR('n') - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_CHAR('m') - 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_STOP) PORT_CHAR('.') PORT_CHAR('>') - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("/ ?") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("SHIFT (R)") PORT_CODE(KEYCODE_RSHIFT) - - PORT_START("KBD7") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("LINE FEED") PORT_CHAR(10) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(32) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("- (KP)") PORT_CODE(KEYCODE_MINUS_PAD) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(", (KP)") PORT_CODE(KEYCODE_PLUS_PAD) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("ENTER (KP)") PORT_CODE(KEYCODE_ENTER_PAD) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(". (KP)") PORT_CODE(KEYCODE_DEL_PAD) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("0 (KP)") PORT_CODE(KEYCODE_0_PAD) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("1 (KP)") PORT_CODE(KEYCODE_1_PAD) - - PORT_START("KBD8") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("2 (KP)") PORT_CODE(KEYCODE_2_PAD) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("3 (KP)") PORT_CODE(KEYCODE_3_PAD) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("4 (KP)") PORT_CODE(KEYCODE_4_PAD) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("5 (KP)") PORT_CODE(KEYCODE_5_PAD) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("6 (KP)") PORT_CODE(KEYCODE_6_PAD) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("7 (KP)") PORT_CODE(KEYCODE_7_PAD) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("8 (KP)") PORT_CODE(KEYCODE_8_PAD) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("9 (KP)") PORT_CODE(KEYCODE_9_PAD) - - PORT_START("KPAD0") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("0") PORT_CODE(KEYCODE_0_PAD) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("4") PORT_CODE(KEYCODE_4_PAD) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("8 P") PORT_CODE(KEYCODE_8_PAD) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("C M") PORT_CODE(KEYCODE_C) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT) - PORT_BIT(0xe0, IP_ACTIVE_LOW, IPT_UNUSED) - - PORT_START("KPAD1") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("1") PORT_CODE(KEYCODE_1_PAD) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("5 O") PORT_CODE(KEYCODE_5_PAD) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("9 ESC") PORT_CODE(KEYCODE_9_PAD) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("D G") PORT_CODE(KEYCODE_D) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("LF DEL") PORT_CODE(KEYCODE_DEL_PAD) - PORT_BIT(0xe0, IP_ACTIVE_LOW, IPT_UNUSED) - - PORT_START("KPAD2") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("2") PORT_CODE(KEYCODE_2_PAD) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("6 C") PORT_CODE(KEYCODE_6_PAD) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("A") PORT_CODE(KEYCODE_A) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("E S") PORT_CODE(KEYCODE_E) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("CR SP") PORT_CODE(KEYCODE_ENTER_PAD) - PORT_BIT(0xe0, IP_ACTIVE_LOW, IPT_UNUSED) - - PORT_START("KPAD3") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("3 '") PORT_CODE(KEYCODE_3_PAD) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("7 R") PORT_CODE(KEYCODE_7_PAD) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("B L") PORT_CODE(KEYCODE_B) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("F N") PORT_CODE(KEYCODE_F) - PORT_BIT(0xf0, IP_ACTIVE_LOW, IPT_UNUSED) - - PORT_START("BRK") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("RESET") PORT_CODE(KEYCODE_F12) PORT_CHAR(UCHAR_MAMEKEY(F12)) PORT_CHANGED_MEMBER(DEVICE_SELF, microtan_state, trigger_reset, 0) -INPUT_PORTS_END - -static INPUT_PORTS_START( spinveti ) - PORT_START("CONFIG") - PORT_CONFNAME(0x03, 0x02, "Input") - PORT_CONFSETTING(0x02, "ETI Keypad") - PORT_CONFNAME(0x60, 0x20, "Difficulty") - PORT_CONFSETTING(0x00, "Easy") - PORT_CONFSETTING(0x20, "Normal") - PORT_CONFSETTING(0x40, "Hard") - PORT_CONFSETTING(0x60, "Hardest") - - PORT_START("KEYPAD") - PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Play") PORT_CODE(KEYCODE_ENTER) - PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Right") PORT_CODE(KEYCODE_RIGHT) - PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Left") PORT_CODE(KEYCODE_LEFT) - PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Fire") PORT_CODE(KEYCODE_LCONTROL) - PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Hold") PORT_CODE(KEYCODE_H) - - PORT_START("BRK") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Reset") PORT_CODE(KEYCODE_R) PORT_CHANGED_MEMBER(DEVICE_SELF, microtan_state, trigger_reset, 0) -INPUT_PORTS_END - -static const gfx_layout char_layout = -{ - 8, 16, /* 8 x 16 graphics */ - 256, /* 256 codes */ - 1, /* 1 bit per pixel */ - { 0 }, /* no bitplanes */ - { 0, 1, 2, 3, 4, 5, 6, 7 }, - { 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 /* code takes 8 times 16 bits */ -}; - -static GFXDECODE_START( gfx_microtan ) - GFXDECODE_ENTRY( "gfx1", 0, char_layout, 0, 1 ) - GFXDECODE_ENTRY( "gfx2", 0, char_layout, 0, 1 ) -GFXDECODE_END - - -void microtan_state::mt65(machine_config &config) -{ - /* Microtan 65 CPU board */ - M6502(config, m_maincpu, 6_MHz_XTAL / 8); - m_maincpu->set_addrmap(AS_PROGRAM, µtan_state::mt65_map); - - TIMER(config, "kbd_timer").configure_periodic(FUNC(microtan_state::kbd_scan), attotime::from_hz(45)); - - INPUT_MERGER_ANY_HIGH(config, m_irq_line).output_handler().set_inputline(m_maincpu, M6502_IRQ_LINE); - - /* video hardware - include overscan */ - screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_raw(6_MHz_XTAL, 384, 0, 32*8, 312, 0, 16*16); - screen.set_screen_update(FUNC(microtan_state::screen_update)); - screen.set_palette("palette"); - - GFXDECODE(config, m_gfxdecode, "palette", gfx_microtan); - - PALETTE(config, "palette", palette_device::MONOCHROME); - - /* Microtan Motherboard */ - TANBUS(config, m_tanbus, 6_MHz_XTAL); - m_tanbus->out_irq_callback().set(m_irq_line, FUNC(input_merger_device::in_w)); - m_tanbus->out_so_callback().set_inputline(m_maincpu, M6502_SET_OVERFLOW); - m_tanbus->out_nmi_callback().set_inputline(m_maincpu, M6502_NMI_LINE); - m_tanbus->out_pgm_callback().set(FUNC(microtan_state::pgm_chargen_w)); - - TANBUS_SLOT(config, "tanbus:tanex", -1, tanex_devices, "tanex"); - TANBUS_SLOT(config, "tanbus:0", 0, tanbus_devices, "tanram"); - TANBUS_SLOT(config, "tanbus:1", 1, tanbus_devices, nullptr); - TANBUS_SLOT(config, "tanbus:2", 2, tanbus_devices, "bullsnd"); - TANBUS_SLOT(config, "tanbus:3", 3, tanbus_devices, nullptr); - TANBUS_SLOT(config, "tanbus:4", 4, tanbus_devices, nullptr); - TANBUS_SLOT(config, "tanbus:5", 5, tanbus_devices, nullptr); - TANBUS_SLOT(config, "tanbus:6", 6, tanbus_devices, nullptr); - TANBUS_SLOT(config, "tanbus:7", 7, tanbus_devices, nullptr); - TANBUS_SLOT(config, "tanbus:exp", 8, tanbus_devices, nullptr); - - /* snapshot/quickload */ - snapshot_image_device &snapshot(SNAPSHOT(config, "snapshot", "dmp,m65")); - snapshot.set_load_callback(FUNC(microtan_state::snapshot_cb)); - snapshot.set_interface("mt65_snap"); - QUICKLOAD(config, "quickload", "hex").set_load_callback(FUNC(microtan_state::quickload_cb)); - - /* software lists */ - SOFTWARE_LIST(config, "rom_list").set_original("mt65_rom"); - SOFTWARE_LIST(config, "cass_list").set_original("mt65_cass"); - //SOFTWARE_LIST(config, "flop_list").set_original("mt65_flop").set_filter("6502"); - SOFTWARE_LIST(config, "snap_list").set_original("mt65_snap"); -} - -void microtan_state::micron(machine_config &config) -{ - mt65(config); - - /* Microtan Mini-Motherboard connects MT65 CPU card and TANEX, no extra slots */ - config.device_remove("tanbus:0"); - config.device_remove("tanbus:1"); - config.device_remove("tanbus:2"); - config.device_remove("tanbus:3"); - config.device_remove("tanbus:4"); - config.device_remove("tanbus:5"); - config.device_remove("tanbus:6"); - config.device_remove("tanbus:7"); - config.device_remove("tanbus:exp"); -} - -void microtan_state::spinveti(machine_config &config) -{ - /* basic machine hardware */ - M6502(config, m_maincpu, 6_MHz_XTAL / 8); - m_maincpu->set_addrmap(AS_PROGRAM, µtan_state::spinv_map); - - INPUT_MERGER_ANY_HIGH(config, m_irq_line).output_handler().set_inputline(m_maincpu, M6502_IRQ_LINE); - - /* video hardware - include overscan */ - screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_raw(6_MHz_XTAL, 384, 0, 32*8, 312, 0, 16*16); - screen.set_screen_update(FUNC(microtan_state::screen_update)); - screen.set_palette("palette"); - - GFXDECODE(config, m_gfxdecode, "palette", gfx_microtan); - - PALETTE(config, "palette", palette_device::MONOCHROME); - - /* TODO: Sound hardware */ -} - - -static DEVICE_INPUT_DEFAULTS_START(ra32k_def_ram0000) - /* 32K RAM configured 0x0000-0x7fff */ - DEVICE_INPUT_DEFAULTS("SW1", 0xff, 0xff) // all blocks enabled - DEVICE_INPUT_DEFAULTS("SW2", 0xff, 0xff) // all blocks enabled - DEVICE_INPUT_DEFAULTS("SW3", 0x0f, 0x0f) // start address $0000 - DEVICE_INPUT_DEFAULTS("LNK1", 0x03, 0x01) -DEVICE_INPUT_DEFAULTS_END - -static DEVICE_INPUT_DEFAULTS_START(ra32k_def_ram8000) - /* 32K RAM configured 0x8000-0xffff */ - DEVICE_INPUT_DEFAULTS("SW1", 0xff, 0x7f) // disable block $F800 - DEVICE_INPUT_DEFAULTS("SW2", 0xff, 0xff) // all blocks enabled - DEVICE_INPUT_DEFAULTS("SW3", 0x0f, 0x0d) // start address $8000 - DEVICE_INPUT_DEFAULTS("LNK1", 0x03, 0x00) -DEVICE_INPUT_DEFAULTS_END - -static DEVICE_INPUT_DEFAULTS_START(ra32k_def_rom2000) - /* 8K EPROM configured 0x2000-0x3fff */ - DEVICE_INPUT_DEFAULTS("SW1", 0xff, 0xff) // all blocks enabled - DEVICE_INPUT_DEFAULTS("SW2", 0xff, 0xff) // all blocks enabled - DEVICE_INPUT_DEFAULTS("SW3", 0x0f, 0x04) // start address $2000 - DEVICE_INPUT_DEFAULTS("LNK1", 0x03, 0x02) -DEVICE_INPUT_DEFAULTS_END - -void mt6809_state::mt6809(machine_config &config) -{ - /* Ralph Allen 6809 CPU Board */ - MC6809(config, m_maincpu, 6_MHz_XTAL / 4); // TODO: verify divider - m_maincpu->set_addrmap(AS_PROGRAM, &mt6809_state::mt6809_map); - - TIMER(config, "kbd_timer").configure_periodic(FUNC(microtan_state::kbd_scan), attotime::from_hz(45)); - - INPUT_MERGER_ANY_HIGH(config, m_irq_line).output_handler().set_inputline(m_maincpu, M6809_IRQ_LINE); - - /* Microtan Motherboard */ - TANBUS(config, m_tanbus, 6_MHz_XTAL); - m_tanbus->out_irq_callback().set(m_irq_line, FUNC(input_merger_device::in_w)); - m_tanbus->out_nmi_callback().set_inputline(m_maincpu, M6809_FIRQ_LINE); - - TANBUS_SLOT(config, "tanbus:tanex", -1, tanex_devices, nullptr); - TANBUS_SLOT(config, "tanbus:0", 0, tanbus6809_devices, "ra32k").set_option_device_input_defaults("ra32k", DEVICE_INPUT_DEFAULTS_NAME(ra32k_def_ram0000)); - TANBUS_SLOT(config, "tanbus:1", 1, tanbus6809_devices, "ra32k").set_option_device_input_defaults("ra32k", DEVICE_INPUT_DEFAULTS_NAME(ra32k_def_ram8000)); - TANBUS_SLOT(config, "tanbus:2", 2, tanbus6809_devices, "ravdu"); - TANBUS_SLOT(config, "tanbus:3", 3, tanbus6809_devices, "radisc"); - TANBUS_SLOT(config, "tanbus:4", 4, tanbus6809_devices, nullptr); - TANBUS_SLOT(config, "tanbus:5", 5, tanbus6809_devices, nullptr); - TANBUS_SLOT(config, "tanbus:6", 6, tanbus6809_devices, nullptr); - TANBUS_SLOT(config, "tanbus:7", 7, tanbus6809_devices, "ra32k").set_option_device_input_defaults("ra32k", DEVICE_INPUT_DEFAULTS_NAME(ra32k_def_rom2000)); - TANBUS_SLOT(config, "tanbus:exp", 8, tanbus6809_devices, nullptr); - - /* software lists */ - //SOFTWARE_LIST(config, "flop_list").set_original("mt65_flop").set_filter("6809"); -} - - -ROM_START( mt65 ) - ROM_REGION(0x10000, "maincpu", 0) - ROM_DEFAULT_BIOS("tanbug23") - /* Microtan 65 (MT0016 Iss 1) */ - ROM_SYSTEM_BIOS(0, "tanbug23", "TANBUG V2.3") - ROMX_LOAD("tanbug23.k3", 0xf800, 0x0800, CRC(7f29845d) SHA1(de277e942eefa11a9a6defe3d7d03071d5100b68), ROM_BIOS(0)) - ROM_SYSTEM_BIOS(1, "tanbug23p", "TANBUG V2.3 (patched)") - ROMX_LOAD("tanbug_2.rom", 0xf800, 0x0400, CRC(7e215313) SHA1(c8fb3d33ce2beaf624dc75ec57d34c216b086274), ROM_BIOS(1)) - ROMX_LOAD("tanbug.rom", 0xfc00, 0x0400, CRC(c8221d9e) SHA1(c7fe4c174523aaaab30be7a8c9baf2bc08b33968), ROM_BIOS(1)) - ROM_SYSTEM_BIOS(2, "tanbug31", "TANBUG V3.1 (TANDOS)") - ROMX_LOAD("tanbug31.k3", 0xf800, 0x0800, CRC(5943e427) SHA1(55fe645363cd5f2015a537be6f7a00de33d1bea5), ROM_BIOS(2)) - ROM_SYSTEM_BIOS(3, "tanbug3b", "TANBUG V.3B (MPVDU)") - ROMX_LOAD("tanbug3b.k3", 0xf800, 0x0800, CRC(5b49f861) SHA1(b37cddf97b6324ab0647479b5b013a9b3d47ddda), ROM_BIOS(3)) - ROM_SYSTEM_BIOS(4, "tugbug11", "TUGBUG V1.1 (VID8082)") - ROMX_LOAD("tugbug11.k3", 0xf800, 0x0800, CRC(23b02439) SHA1(9e56fbd6c07b1dc5c10e7b574a5ea26405781a3d), ROM_BIOS(4)) - - ROM_REGION(0x1000, "gfx1", 0) - ROM_LOAD("charset.rom", 0x0000, 0x0800, CRC(3b3c5360) SHA1(a3a2f74149107f8b8f35b15069c71f3aa843d12f)) - ROM_RELOAD(0x0800, 0x0800) - - ROM_REGION(0x1000, "gfx2", ROMREGION_ERASEFF) - // initialized in init_gfx2 -ROM_END - -ROM_START( micron ) - ROM_REGION(0x10000, "maincpu", 0) - ROM_DEFAULT_BIOS("tanbug1") - /* MT65 (Iss 0) */ - ROM_SYSTEM_BIOS(0, "tanbug1", "TANBUG V1") - ROMX_LOAD("tanbug1.g2", 0xf800, 0x0400, CRC(6f45aaca) SHA1(c1a020d86830ee475ee75c847e98f7a02d467659), ROM_BIOS(0) | ROM_NIBBLE | ROM_SHIFT_NIBBLE_LO) - ROM_RELOAD(0xfc00, 0x0400) - ROMX_LOAD("tanbug1.h2", 0xf800, 0x0400, CRC(1ccd6b8f) SHA1(49784749599255458ba5513d8c2fc58c4df39515), ROM_BIOS(0) | ROM_NIBBLE | ROM_SHIFT_NIBBLE_HI) - ROM_RELOAD(0xfc00, 0x0400) - - ROM_REGION(0x1000, "gfx1", 0) - ROM_LOAD("charset.rom", 0x0000, 0x0800, CRC(3b3c5360) SHA1(a3a2f74149107f8b8f35b15069c71f3aa843d12f)) - ROM_RELOAD(0x0800, 0x0800) - - ROM_REGION(0x1000, "gfx2", ROMREGION_ERASEFF) - // initialized in init_gfx2 -ROM_END - -ROM_START( spinveti ) - ROM_REGION(0x10000, "maincpu", 0) - ROM_LOAD("spaceinv.ic20", 0xe800, 0x0800, CRC(3e235077) SHA1(ae7d2788125d01a3c5d57ab0d992bd708abd6ade)) - - ROM_REGION(0x1000, "gfx1", 0) - ROM_LOAD("charset.rom", 0x0000, 0x0800, CRC(3b3c5360) SHA1(a3a2f74149107f8b8f35b15069c71f3aa843d12f)) - ROM_RELOAD(0x0800, 0x0800) - - ROM_REGION(0x1000, "gfx2", ROMREGION_ERASEFF) - // initialized in init_gfx2 -ROM_END - -ROM_START( mt6809 ) - /* 6809 CPU Card (Ralph Allen Engineering) */ - ROM_REGION(0x10000, "maincpu", 0) - ROM_SYSTEM_BIOS(0, "ralbug14", "RALBUG V1.4") - ROMX_LOAD("ralbug14.rom", 0xf800, 0x0800, CRC(8bbc87d8) SHA1(3d53a6ffd4a8d7c8edf4f2e23946011ed29146ce), ROM_BIOS(0)) -ROM_END - - -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1979, mt65, 0, 0, mt65, microtan, microtan_state, init_microtan, "Tangerine", "Microtan 65", MACHINE_NO_SOUND_HW ) -COMP( 1980, micron, mt65, 0, micron, microtan, microtan_state, init_microtan, "Tangerine", "Micron", MACHINE_NO_SOUND_HW ) -COMP( 1980, spinveti, 0, 0, spinveti, spinveti, microtan_state, init_gfx2, "Tangerine/ETI", "Space Invasion (ETI)", MACHINE_NO_SOUND ) -COMP( 1984, mt6809, mt65, 0, mt6809, microtan, mt6809_state, empty_init, "Tangerine", "Microtan 6809 System", MACHINE_NO_SOUND_HW | MACHINE_NOT_WORKING ) diff --git a/src/mame/tangerin/microtan.h b/src/mame/tangerin/microtan.h deleted file mode 100644 index 90c1ebd2928..00000000000 --- a/src/mame/tangerin/microtan.h +++ /dev/null @@ -1,136 +0,0 @@ -// license:GPL-2.0+ -// copyright-holders:Juergen Buchmueller -/****************************************************************************** - * Microtan 65 - * - * variables and function prototypes - * - * Juergen Buchmueller , Jul 2000 - * - * Thanks go to Geoff Macdonald - * for his site http://www.geoff.org.uk/microtan/index.htm - * and to Fabrice Frances - * for his site http://oric.free.fr/microtan.html - * - ******************************************************************************/ - -#ifndef MAME_INCLUDES_MICROTAN_H -#define MAME_INCLUDES_MICROTAN_H - -#pragma once - -#include "cpu/m6502/m6502.h" -#include "cpu/m6809/m6809.h" -#include "machine/input_merger.h" -#include "machine/timer.h" -#include "bus/tanbus/tanbus.h" -#include "imagedev/snapquik.h" -#include "tilemap.h" - -class microtan_state : public driver_device -{ -public: - microtan_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_maincpu(*this, "maincpu") - , m_irq_line(*this, "irq_line") - , m_config(*this, "CONFIG") - , m_io_keyboard(*this, "KBD%u", 0) - , m_io_keypad(*this, "KPAD%u", 0) - , m_keypad(*this, "KEYPAD") - , m_tanbus(*this, "tanbus") - , m_videoram(*this, "videoram") - , m_gfxdecode(*this, "gfxdecode") - , m_gfx1(*this, "gfx1") - , m_led(*this, "led1") - { } - - void mt65(machine_config &config); - void micron(machine_config &config); - void spinveti(machine_config &config); - - void init_gfx2(); - void init_microtan(); - - TIMER_DEVICE_CALLBACK_MEMBER(kbd_scan); - uint8_t bffx_r(offs_t offset); - void bffx_w(offs_t offset, uint8_t data); - DECLARE_INPUT_CHANGED_MEMBER(trigger_reset); - -protected: - enum { IRQ_KBD, IRQ_TANBUS }; - - virtual void machine_start() override; - virtual void machine_reset() override; - virtual void video_start() override; - - required_device m_maincpu; - required_device m_irq_line; - required_ioport m_config; - optional_ioport_array<9> m_io_keyboard; - optional_ioport_array<4> m_io_keypad; - optional_ioport m_keypad; - optional_device m_tanbus; - - uint8_t m_keypad_column = 0; - uint8_t m_keyboard_ascii = 0; - emu_timer *m_pulse_nmi_timer = nullptr; - uint8_t m_keyrows[10]{}; - int m_lastrow = 0; - int m_mask = 0; - int m_key = 0; - int m_repeat = 0; - int m_repeater = 0; - - virtual void store_key(int key); - -private: - optional_shared_ptr m_videoram; - optional_device m_gfxdecode; - optional_memory_region m_gfx1; - output_finder<> m_led; - - uint8_t m_chunky_graphics = 0; - std::unique_ptr m_chunky_buffer; - tilemap_t *m_bg_tilemap = nullptr; - - uint8_t sound_r(); - void sound_w(uint8_t data); - void videoram_w(offs_t offset, uint8_t data); - TILE_GET_INFO_MEMBER(get_bg_tile_info); - void pgm_chargen_w(offs_t offset, uint8_t data); - uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - TIMER_CALLBACK_MEMBER(pulse_nmi); - - image_verify_result verify_snapshot(uint8_t *data, int size); - image_init_result parse_intel_hex(uint8_t *snapshot_buff, char *src); - image_init_result parse_zillion_hex(uint8_t *snapshot_buff, char *src); - void set_cpu_regs(const uint8_t *snapshot_buff, int base); - void snapshot_copy(uint8_t *snapshot_buff, int snapshot_size); - DECLARE_SNAPSHOT_LOAD_MEMBER(snapshot_cb); - DECLARE_QUICKLOAD_LOAD_MEMBER(quickload_cb); - - void mt65_map(address_map &map); - void spinv_map(address_map &map); -}; - - -class mt6809_state : public microtan_state -{ -public: - using microtan_state::microtan_state; - - void mt6809(machine_config &config); - -protected: - virtual void video_start() override; - - virtual void store_key(int key) override; - -private: - uint8_t keyboard_r(); - - void mt6809_map(address_map &map); -}; - -#endif // MAME_INCLUDES_MICROTAN_H diff --git a/src/mame/tangerin/microtan_m.cpp b/src/mame/tangerin/microtan_m.cpp deleted file mode 100644 index dca952e483a..00000000000 --- a/src/mame/tangerin/microtan_m.cpp +++ /dev/null @@ -1,712 +0,0 @@ -// license:GPL-2.0+ -// copyright-holders:Juergen Buchmueller -/****************************************************************************** - * Microtan 65 - * - * machine driver - * - * Juergen Buchmueller , Jul 2000 - * - * Thanks go to Geoff Macdonald - * for his site http://www.geoff.org.uk/microtan/index.htm - * and to Fabrice Frances - * for his site http://oric.free.fr/microtan.html - * - *****************************************************************************/ - -#include "emu.h" -#include "microtan.h" - -//#define VERBOSE 1 -#include "logmacro.h" - - -static const char keyboard[8][9][8] = { - { /* normal */ - { 27,'1','2','3','4','5','6','7'}, - {'8','9','0',':','-', 12,127,'^'}, - {'q','w','e','r','t','y','u','i'}, - {'o','p','[',']', 13, 3, 0, 0}, - {'a','s','d','f','g','h','j','k'}, - {'l',';','@', 92, 0,'z','x','c'}, - {'v','b','n','m',',','.','/', 0}, - { 10,' ','-',',', 13,'.','0','1'}, - {'2','3','4','5','6','7','8','9'}, - }, - { /* Shift */ - { 27,'!','"','#','$','%','&', 39}, - {'(',')','~','*','=', 12,127,'_'}, - {'Q','W','E','R','T','Y','U','I'}, - {'O','P','{','}', 13, 3, 0, 0}, - {'A','S','D','F','G','H','J','K'}, - {'L','+','`','|', 0,'Z','X','C'}, - {'V','B','N','M','<','>','?', 0}, - { 10,' ','-',',', 13,'.','0','1'}, - {'2','3','4','5','6','7','8','9'}, - }, - { /* Control */ - { 27,'1','2','3','4','5','6','7'}, - {'8','9','0',':','-','`',127, 30}, - { 17, 23, 5, 18, 20, 25, 21, 9}, - { 15, 16, 27, 29, 13, 3, 0, 0}, - { 1, 19, 4, 6, 7, 8, 10, 11}, - { 12,';','@', 28, 0, 26, 24, 3}, - { 22, 2, 14, 13,',','.','/', 0}, - { 10,' ','-',',', 13,'.','0','1'}, - {'2','3','4','5','6','7','8','9'}, - }, - { /* Shift+Control */ - { 27,'!','"','#','$','%','&', 39}, - {'(',')','~','*','=', 12,127, 31}, - { 17, 23, 5, 18, 20, 25, 21, 9}, - { 15, 16, 27, 29, 13,127, 0, 0}, - { 1, 19, 4, 6, 7, 8, 10, 11}, - { 12,'+','`', 28, 0, 26, 24, 3}, - { 22, 2, 14, 13,',','.','/', 0}, - { 10,' ','-',',', 13,'.','0','1'}, - {'2','3','4','5','6','7','8','9'}, - }, - { /* CapsLock */ - { 27,'1','2','3','4','5','6','7'}, - {'8','9','0',':','-', 12,127,'^'}, - {'Q','W','E','R','T','Y','U','I'}, - {'O','P','[',']', 13, 3, 0, 0}, - {'A','S','D','F','G','H','J','K'}, - {'L',';','@', 92, 0,'Z','X','C'}, - {'V','B','N','M',',','.','/', 0}, - { 10,' ','-',',', 13,'.','0','1'}, - {'2','3','4','5','6','7','8','9'}, - }, - { /* Shift+CapsLock */ - { 27,'!','"','#','$','%','&', 39}, - {'(',')','~','*','=', 12,127,'_'}, - {'q','w','e','r','t','y','u','i'}, - {'o','p','{','}', 13, 3, 0, 0}, - {'a','s','d','f','g','h','j','k'}, - {'l','+','`','|', 0,'z','x','c'}, - {'v','b','n','m','<','>','?', 0}, - { 10,' ','-',',', 13,'.','0','1'}, - {'2','3','4','5','6','7','8','9'}, - }, - { /* Control+CapsLock */ - { 27,'1','2','3','4','5','6','7'}, - {'8','9','0',':','-', 12,127, 9}, - { 17, 23, 5, 18, 20, 25, 21, 9}, - { 15, 16, 27, 29, 13,127, 0, 0}, - { 1, 19, 4, 6, 7, 8, 10, 11}, - { 12,';', 39, 28, 0, 26, 24, 3}, - { 22, 2, 14, 13,',','.','/', 0}, - { 10,' ','-',',', 13,'.','0','1'}, - {'2','3','4','5','6','7','8','9'}, - }, - { /* Shift+Control+CapsLock */ - { 27,'!','"','#','$','%','&', 39}, - {'(',')','~','*','=', 12,127, 9}, - { 17, 23, 5, 18, 20, 25, 21, 9}, - { 15, 16, 27, 29, 13,127, 0, 0}, - { 1, 19, 4, 6, 7, 8, 10, 11}, - { 12,':','"', 28, 0, 26, 24, 3}, - { 22, 2, 14, 13,',','.','/', 0}, - { 10,' ','-',',', 13,'.','0','1'}, - {'2','3','4','5','6','7','8','9'}, - }, -}; - - -uint8_t microtan_state::sound_r() -{ - int data = 0xff; - LOG("sound_r: -> %02x\n", data); - return data; -} - -void microtan_state::sound_w(uint8_t data) -{ - LOG("sound_w: <- %02x\n", data); -} - - -uint8_t microtan_state::bffx_r(offs_t offset) -{ - int data = 0xff; - switch( offset & 3 ) - { - case 0: /* BFF0: read enables chunky graphics */ - m_chunky_graphics = 1; - LOG("bff0_r: -> %02x (chunky graphics on)\n", data); - break; - case 1: /* BFF1: read undefined (?) */ - LOG("bff1_r: -> %02x\n", data); - break; - case 2: /* BFF2: read undefined (?) */ - LOG("bff2_r: -> %02x\n", data); - break; - case 3: /* BFF3: read keyboard/keypad */ - switch (m_config->read() & 3) - { - case 0: /* ASCII Keyboard */ - data = m_keyboard_ascii; - break; - case 1: /* Hex Keypad */ - data = 0x00; - for (u8 i = 0; i < 4; i++) - if (BIT(m_keypad_column, i)) - data |= m_io_keypad[i]->read(); - - break; - case 2: /* ETI Keypad */ - data = (m_keypad->read() & 0x1f) | (m_config->read() & 0x60); - break; - } - LOG("bff3_r: -> %02x (keyboard ASCII)\n", data); - break; - } - return data; -} - - -/* This callback is called one clock cycle after BFF2 is written (delayed nmi) */ -TIMER_CALLBACK_MEMBER(microtan_state::pulse_nmi) -{ - m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero); -} - -void microtan_state::bffx_w(offs_t offset, uint8_t data) -{ - switch( offset & 3 ) - { - case 0: /* BFF0: write reset keyboard interrupt flag */ - /* This removes bit 7 from the ASCII value of the last key pressed. */ - LOG("bff0_w: %d <- %02x (keyboard IRQ clear )\n", offset, data); - m_keyboard_ascii &= ~0x80; - m_irq_line->in_w(0); - break; - case 1: /* BFF1: write delayed NMI */ - LOG("bff1_w: %d <- %02x (delayed NMI)\n", offset, data); - m_pulse_nmi_timer->adjust(m_maincpu->cycles_to_attotime(8)); - break; - case 2: /* BFF2: write keypad */ - LOG("bff2_w: %d <- %02x (keypad column)\n", offset, data); // 1, 2, 4, 7, f - m_keypad_column = data & 0x0f; - break; - case 3: /* BFF3: write disable chunky graphics */ - LOG("bff3_w: %d <- %02x (chunky graphics off)\n", offset, data); - m_chunky_graphics = 0; - break; - } -} - -uint8_t mt6809_state::keyboard_r() -{ - uint8_t data = m_keyboard_ascii; - - m_keyboard_ascii = 0x00; - - return data; -} - -void mt6809_state::store_key(int key) -{ - m_keyboard_ascii = key | 0x80; -} - -void microtan_state::store_key(int key) -{ - m_keyboard_ascii = key | 0x80; - m_irq_line->in_w(1); -} - -TIMER_DEVICE_CALLBACK_MEMBER(microtan_state::kbd_scan) -{ - /* ASCII Keyboard only */ - if (m_config->read() & 3) - return; - - int mod, row, col, chg, newvar; - - if( m_repeat ) - { - if( !--m_repeat ) - m_repeater = 4; - } - else if( m_repeater ) - m_repeat = m_repeater; - - row = 9; - newvar = m_io_keyboard[8]->read(); - chg = m_keyrows[--row] ^ newvar; - - while ( !chg && row > 0) - { - newvar = m_io_keyboard[row - 1]->read(); - chg = m_keyrows[--row] ^ newvar; - } - if (!chg) - --row; - - if (row >= 0) - { - m_repeater = 0x00; - m_mask = 0x00; - m_key = 0x00; - m_lastrow = row; - /* CapsLock LED */ - if( row == 3 && chg == 0x80 ) - m_led = BIT(~m_keyrows[3], 7); - - if (newvar & chg) /* key(s) pressed ? */ - { - mod = 0; - - /* Shift modifier */ - if ( (m_keyrows[5] & 0x10) || (m_keyrows[6] & 0x80) ) - mod |= 1; - - /* Control modifier */ - if (m_keyrows[3] & 0x40) - mod |= 2; - - /* CapsLock modifier */ - if (m_keyrows[3] & 0x80) - mod |= 4; - - /* find newvar key */ - m_mask = 0x01; - for (col = 0; col < 8; col ++) - { - if (chg & m_mask) - { - newvar &= m_mask; - m_key = keyboard[mod][row][col]; - break; - } - m_mask <<= 1; - } - if( m_key ) /* normal key */ - { - m_repeater = 30; - store_key(m_key); - } - else - if( (row == 0) && (chg == 0x04) ) /* Ctrl-@ (NUL) */ - store_key(0); - m_keyrows[row] |= newvar; - } - else - m_keyrows[row] = newvar; - - m_repeat = m_repeater; - } - else - if ( m_key && (m_keyrows[m_lastrow] & m_mask) && m_repeat == 0 ) - store_key(m_key); -} - - -void microtan_state::pgm_chargen_w(offs_t offset, uint8_t data) -{ - switch (offset & 0x200) - { - case 0x000: - /* update char &80-&1F */ - m_gfx1->base()[offset | 0x800] = data; - m_gfxdecode->gfx(0)->mark_dirty(0x80 | (offset >> 4)); - break; - case 0x200: - /* update char &E0-&FF */ - m_gfx1->base()[offset | 0xc00] = data; - m_gfxdecode->gfx(0)->mark_dirty(0xc0 | (offset >> 4)); - break; - } -} - -void microtan_state::init_gfx2() -{ - uint8_t *dst = memregion("gfx2")->base(); - - for (int i = 0; i < 256; i++) - { - switch (i & 3) - { - case 0: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0x00; break; - case 1: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0xf0; break; - case 2: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0x0f; break; - case 3: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0xff; break; - } - dst += 4; - switch (BIT(i, 2, 2)) - { - case 0: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0x00; break; - case 1: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0xf0; break; - case 2: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0x0f; break; - case 3: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0xff; break; - } - dst += 4; - switch (BIT(i, 4, 2)) - { - case 0: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0x00; break; - case 1: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0xf0; break; - case 2: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0x0f; break; - case 3: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0xff; break; - } - dst += 4; - switch (BIT(i, 6, 2)) - { - case 0: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0x00; break; - case 1: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0xf0; break; - case 2: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0x0f; break; - case 3: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0xff; break; - } - dst += 4; - } -} - -void microtan_state::init_microtan() -{ - init_gfx2(); - - m_pulse_nmi_timer = timer_alloc(FUNC(microtan_state::pulse_nmi), this); -} - -void microtan_state::machine_start() -{ - m_led.resolve(); - - save_item(NAME(m_keypad_column)); - save_item(NAME(m_keyboard_ascii)); - save_item(NAME(m_keyrows)); - save_item(NAME(m_lastrow)); - save_item(NAME(m_mask)); - save_item(NAME(m_key)); - save_item(NAME(m_repeat)); - save_item(NAME(m_repeater)); -} - -void microtan_state::machine_reset() -{ - for (int i = 1; i < 10; i++) - m_keyrows[i] = m_io_keyboard[i-1].read_safe(0); - - m_led = BIT(~m_keyrows[3], 7); -} - -image_verify_result microtan_state::verify_snapshot(uint8_t *data, int size) -{ - if (size == 8263) - { - logerror("snapshot_id: magic size %d found\n", size); - return image_verify_result::PASS; - } - else - { - if (4 + data[2] + 256 * data[3] + 1 + 16 + 16 + 16 + 1 + 1 + 16 + 16 + 64 + 7 == size) - { - logerror("snapshot_id: header RAM size + structures matches filesize %d\n", size); - return image_verify_result::PASS; - } - } - - return image_verify_result::FAIL; -} - -image_init_result microtan_state::parse_intel_hex(uint8_t *snapshot_buff, char *src) -{ - char line[128]; - int /*row = 0,*/ column = 0, last_addr = 0, last_size = 0; - - while (*src) - { - if (*src == '\r' || *src == '\n') - { - if (column) - { - unsigned int size, addr, null, b[32], cs, n; - - line[column] = '\0'; - /*row++;*/ - n = sscanf(line, ":%02x%04x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", - &size, &addr, &null, - &b[ 0], &b[ 1], &b[ 2], &b[ 3], &b[ 4], &b[ 5], &b[ 6], &b[ 7], - &b[ 8], &b[ 9], &b[10], &b[11], &b[12], &b[13], &b[14], &b[15], - &b[16], &b[17], &b[18], &b[19], &b[20], &b[21], &b[22], &b[23], - &b[24], &b[25], &b[26], &b[27], &b[28], &b[29], &b[30], &b[31], - &cs); - if (n == 0) - logerror("parse_intel_hex: malformed line [%s]\n", line); - else - if (n == 1) - logerror("parse_intel_hex: only size found [%s]\n", line); - else - if (n == 2) - logerror("parse_intel_hex: only size and addr found [%s]\n", line); - else - if (n == 3) - logerror("parse_intel_hex: only size, addr and null found [%s]\n", line); - else - if (null != 0) - logerror("parse_intel_hex: warning null byte is != 0 [%s]\n", line); - else - { - int i, sum; - - n -= 3; - - sum = size + (addr & 0xff) + ((addr >> 8) & 0xff); - if (n != 32 + 1) - cs = b[n-1]; - - last_addr = addr; - last_size = n-1; - logerror("parse_intel_hex: %04X", addr); - for (i = 0; i < n-1; i++) - { - sum += b[i]; - snapshot_buff[addr++] = b[i]; - } - logerror("-%04X checksum %02X+%02X = %02X\n", addr-1, cs, sum & 0xff, (cs + sum) & 0xff); - } - } - column = 0; - } - else - line[column++] = *src; - - src++; - } - /* register preset? */ - if (last_size == 7) - { - logerror("parse_intel_hex: registers (?) at %04X\n", last_addr); - memcpy(&snapshot_buff[8192+64], &snapshot_buff[last_addr], last_size); - } - return image_init_result::PASS; -} - -image_init_result microtan_state::parse_zillion_hex(uint8_t *snapshot_buff, char *src) -{ - char line[128]; - int parsing = 0, /*row = 0,*/ column = 0; - - while (*src) - { - if (parsing) - { - if (*src == '}') - parsing = 0; - else - { - if (*src == '\r' || *src == '\n') - { - if (column) - { - unsigned int addr, b[8], n; - - line[column] = '\0'; - /*row++;*/ - n = sscanf(line, "%x %x %x %x %x %x %x %x %x", &addr, &b[0], &b[1], &b[2], &b[3], &b[4], &b[5], &b[6], &b[7]); - if (n == 0) - logerror("parse_zillion_hex: malformed line [%s]\n", line); - else - if (n == 1) - logerror("parse_zillion_hex: only addr found [%s]\n", line); - else - { - logerror("parse_zillion_hex: %04X", addr); - for (int i = 0; i < n-1; i++) - snapshot_buff[addr++] = b[i]; - logerror("-%04X\n", addr-1); - } - } - column = 0; - } - else - line[column++] = *src; - } - } - else - { - if (*src == '\r' || *src == '\n') - { - if (column) - { - int addr; - - /*row++;*/ - line[column] = '\0'; - int n = sscanf(line, "G%x", (unsigned int *) &addr); - if (n == 1 && !snapshot_buff[8192+64+0] && !snapshot_buff[8192+64+1]) - { - logerror("microtan_hexfile_init: go addr %04X\n", addr); - snapshot_buff[8192+64+0] = addr & 0xff; - snapshot_buff[8192+64+1] = (addr >> 8) & 0xff; - } - } - column = 0; - } - else - line[column++] = *src; - - if (*src == '{') - { - parsing = 1; - column = 0; - } - } - src++; - } - return image_init_result::PASS; -} - -void microtan_state::set_cpu_regs(const uint8_t *snapshot_buff, int base) -{ - logerror("snapshot_copy: PC:%02X%02X P:%02X A:%02X X:%02X Y:%02X SP:1%02X\n", - snapshot_buff[base+1], snapshot_buff[base+0], snapshot_buff[base+2], snapshot_buff[base+3], - snapshot_buff[base+4], snapshot_buff[base+5], snapshot_buff[base+6]); - m_maincpu->set_state_int(M6502_PC, snapshot_buff[base+0] + (snapshot_buff[base+1] << 8)); - m_maincpu->set_state_int(M6502_P, snapshot_buff[base+2]); - m_maincpu->set_state_int(M6502_A, snapshot_buff[base+3]); - m_maincpu->set_state_int(M6502_X, snapshot_buff[base+4]); - m_maincpu->set_state_int(M6502_Y, snapshot_buff[base+5]); - m_maincpu->set_state_int(M6502_S, snapshot_buff[base+6] + 0x100); -} - -void microtan_state::snapshot_copy(uint8_t *snapshot_buff, int snapshot_size) -{ - address_space &space = m_maincpu->space(AS_PROGRAM); - - /* check for .DMP file format */ - if (snapshot_size == 8263) - { - /********** DMP format - * Lower 8k of RAM (0000 to 1fff) - * 64 bytes of chunky graphics bits (first byte bit is for character at 0200, bit 1=0201, etc) - * 7 bytes of CPU registers (PCL, PCH, PSW, A, IX, IY, SP) - */ - - int base = 0; - /* 8K of RAM from 0000 to 1fff */ - for (int i = 0; i < 0x2000; i++) - space.write_byte(i, snapshot_buff[base + i]); - - base += 8192; - /* 64 bytes of chunky graphics info */ - for (int i = 0; i < 32*16; i++) - m_chunky_buffer[i] = (snapshot_buff[base+i/8] >> (i&7)) & 1; - - base += 64; - set_cpu_regs(snapshot_buff, base); - } - else - { - /********** M65 format ************************************ - * 2 bytes: File version - * 2 bytes: RAM size - * n bytes: RAM (0000 to RAM Size) - * 16 bytes: 1st 6522 (0xbfc0 to 0xbfcf) - * 16 bytes: 2nd 6522 (0xbfe0 to 0xbfef) - * 16 bytes: Microtan IO (0xbff0 to 0xbfff) - * 1 byte : Space Invasion sound (0xbc04) - * 1 byte : Chunky graphics state (0=off, 1=on) - * 16 bytes: 1st AY8910 registers - * 16 bytes: 2nd AY8910 registers - * 64 bytes: Chunky graphics bits (first byte bit 0 is for character at 0200, bit 1=0201, etc) - * 7 bytes: CPU registers (PCL, PCH, PSW, A, IX, IY, SP) - */ - int ramend = snapshot_buff[2] + 256 * snapshot_buff[3]; - if (2 + 2 + ramend + 1 + 16 + 16 + 16 + 1 + 1 + 16 + 16 + 64 + 7 != snapshot_size) - { - logerror("snapshot_copy: size %d doesn't match RAM size %d + structure size\n", snapshot_size, ramend+1); - return; - } - - int base = 4; - for (int i = 0; i < snapshot_buff[2] + 256 * snapshot_buff[3] + 1; i++) - space.write_byte(i, snapshot_buff[base + i]); - base += ramend + 1; - - /* first set of VIA6522 registers */ - for (int i = 0; i < 16; i++ ) - space.write_byte(0xbfc0 + i, snapshot_buff[base++]); - - /* second set of VIA6522 registers */ - for (int i = 0; i < 16; i++ ) - space.write_byte(0xbfe0 + i, snapshot_buff[base++]); - - /* microtan IO bff0-bfff */ - for (int i = 0; i < 16; i++ ) - { - if (i < 4) - bffx_w(i, snapshot_buff[base++]); - } - - sound_w(snapshot_buff[base++]); - m_chunky_graphics = snapshot_buff[base++]; - - /* first set of AY8910 registers */ - for (int i = 0; i < 16; i++ ) - { - space.write_byte(0xbc00, i); - space.write_byte(0xbc01, snapshot_buff[base++]); - } - - /* second set of AY8910 registers */ - for (int i = 0; i < 16; i++ ) - { - space.write_byte(0xbc02, i); - space.write_byte(0xbc03, snapshot_buff[base++]); - } - - for (int i = 0; i < 32*16; i++) - m_chunky_buffer[i] = (snapshot_buff[base+i/8] >> (i&7)) & 1; - - base += 64; - - set_cpu_regs(snapshot_buff, base); - } -} - -SNAPSHOT_LOAD_MEMBER(microtan_state::snapshot_cb) -{ - uint64_t snapshot_len = image.length(); - if (snapshot_len < 4 || snapshot_len >= 66000) - { - //image.seterror(image_error::INVALIDIMAGE); - return image_init_result::FAIL; - } - - auto snapshot_buff = std::make_unique(snapshot_len); - if (image.fread(snapshot_buff.get(), snapshot_len) != snapshot_len) - { - //image.seterror(image_error::UNSPECIFIED); - return image_init_result::FAIL; - } - - if (verify_snapshot(snapshot_buff.get(), snapshot_len) != image_verify_result::PASS) - { - //image.seterror(image_error::INVALIDIMAGE); - return image_init_result::FAIL; - } - - snapshot_copy(snapshot_buff.get(), snapshot_len); - return image_init_result::PASS; -} - -QUICKLOAD_LOAD_MEMBER(microtan_state::quickload_cb) -{ - int snapshot_size = 8263; /* magic size */ - std::vector snapshot_buff(snapshot_size, 0); - std::vector buff(image.length() + 1); - image_init_result rc; - - image.fread(&buff[0], image.length()); - - buff[image.length()] = '\0'; - - if (buff[0] == ':') - rc = parse_intel_hex(&snapshot_buff[0], &buff[0]); - else - rc = parse_zillion_hex(&snapshot_buff[0], &buff[0]); - if (rc == image_init_result::PASS) - snapshot_copy(&snapshot_buff[0], snapshot_size); - return rc; -} diff --git a/src/mame/tangerin/microtan_v.cpp b/src/mame/tangerin/microtan_v.cpp deleted file mode 100644 index d023f2ecffa..00000000000 --- a/src/mame/tangerin/microtan_v.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// license:GPL-2.0+ -// copyright-holders:Juergen Buchmueller -/*************************************************************************** - * Microtan 65 - * - * video hardware - * - * Juergen Buchmueller , Jul 2000 - * - * Thanks go to Geoff Macdonald - * for his site http://www.geoff.org.uk/microtan/index.htm - * and to Fabrice Frances - * for his site http://oric.free.fr/microtan.html - * - ***************************************************************************/ - -#include "emu.h" -#include "microtan.h" - - -void microtan_state::videoram_w(offs_t offset, uint8_t data) -{ - if ((m_videoram[offset] != data) || (m_chunky_buffer[offset] != m_chunky_graphics)) - { - m_videoram[offset] = data; - m_bg_tilemap->mark_tile_dirty(offset); - m_chunky_buffer[offset] = m_chunky_graphics; - } -} - -TILE_GET_INFO_MEMBER(microtan_state::get_bg_tile_info) -{ - int gfxn = m_chunky_buffer[tile_index]; - int code = m_videoram[tile_index]; - - tileinfo.set(gfxn, code, 0, 0); -} - -void microtan_state::video_start() -{ - /* randomize video memory contents */ - for (uint16_t addr = 0; addr < m_videoram.bytes(); addr++) - m_videoram[addr] = machine().rand() & 0xff; - - m_bg_tilemap = &machine().tilemap().create(* - m_gfxdecode, - tilemap_get_info_delegate(*this, FUNC(microtan_state::get_bg_tile_info)), - TILEMAP_SCAN_ROWS, 8, 16, 32, 16); - - m_chunky_buffer = std::make_unique(0x200); - memset(m_chunky_buffer.get(), 0, 0x200); - m_chunky_graphics = 0; - - save_pointer(NAME(m_chunky_buffer), 0x200); - save_item(NAME(m_chunky_graphics)); -} - -uint32_t microtan_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0); - return 0; -} - -void mt6809_state::video_start() -{ -} diff --git a/src/mame/tangerin/oric.cpp b/src/mame/tangerin/oric.cpp deleted file mode 100644 index cd8b16d9b35..00000000000 --- a/src/mame/tangerin/oric.cpp +++ /dev/null @@ -1,1005 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Olivier Galibert -/***************************************************************************************************** - - drivers/oric.cpp - - Systems supported by this driver: - - Oric 1, - Oric Atmos, - Oric Telestrat, - Pravetz 8D - - Pravetz is a Bulgarian copy of the Oric Atmos and uses - Apple 2 disc drives for storage. - - This driver originally by Paul Cook, rewritten by Kevin Thacker, - re-rewritten by Olivier Galibert. - - - -*****************************************************************************************************/ - -#include "emu.h" - -#include "bus/centronics/ctronics.h" -#include "bus/oricext/oricext.h" -#include "cpu/m6502/m6502.h" -#include "imagedev/cassette.h" -#include "imagedev/floppy.h" -#include "machine/6522via.h" -#include "machine/mos6551.h" -#include "machine/timer.h" -#include "machine/wd_fdc.h" -#include "sound/ay8910.h" - -#include "emupal.h" -#include "screen.h" -#include "speaker.h" - -#include "formats/oric_dsk.h" -#include "formats/oric_tap.h" - - -class oric_state : public driver_device -{ -public: - // Permanent attributes (kept from one line to the other) and line - // attributes (reset at start of line) - enum { - PATTR_50HZ = 0x02, - PATTR_HIRES = 0x04, - LATTR_ALT = 0x01, - LATTR_DSIZE = 0x02, - LATTR_BLINK = 0x04 - }; - - oric_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_maincpu(*this, "maincpu") - , m_palette(*this, "palette") - , m_psg(*this, "ay8912") - , m_centronics(*this, "centronics") - , m_cent_data_out(*this, "cent_data_out") - , m_cassette(*this, "cassette") - , m_via(*this, "via6522") - , m_ram(*this, "ram") - , m_rom(*this, "maincpu") - , m_bank_c000_r(*this, "bank_c000_r") - , m_bank_e000_r(*this, "bank_e000_r") - , m_bank_f800_r(*this, "bank_f800_r") - , m_bank_c000_w(*this, "bank_c000_w") - , m_bank_e000_w(*this, "bank_e000_w") - , m_bank_f800_w(*this, "bank_f800_w") - , m_config(*this, "CONFIG") - , m_kbd_row(*this, "ROW%u", 0U) - , m_tape_timer(nullptr) - { } - - DECLARE_INPUT_CHANGED_MEMBER(nmi_pressed); - void via_a_w(uint8_t data); - void via_b_w(uint8_t data); - DECLARE_WRITE_LINE_MEMBER(via_ca2_w); - DECLARE_WRITE_LINE_MEMBER(via_cb2_w); - DECLARE_WRITE_LINE_MEMBER(via_irq_w); - DECLARE_WRITE_LINE_MEMBER(ext_irq_w); - void psg_a_w(uint8_t data); - TIMER_CALLBACK_MEMBER(update_tape); - - virtual void machine_start() override; - virtual void machine_reset() override; - virtual void video_start() override; - uint32_t screen_update_oric(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - DECLARE_WRITE_LINE_MEMBER(vblank_w); - - void oric(machine_config &config, bool add_ext = true); - void prav8d(machine_config &config); - void oric_mem(address_map &map); -protected: - required_device m_maincpu; - required_device m_palette; - required_device m_psg; - required_device m_centronics; - required_device m_cent_data_out; - required_device m_cassette; - required_device m_via; - required_shared_ptr m_ram; - optional_memory_region m_rom; - required_memory_bank m_bank_c000_r; - optional_memory_bank m_bank_e000_r; - optional_memory_bank m_bank_f800_r; - required_memory_bank m_bank_c000_w; - optional_memory_bank m_bank_e000_w; - optional_memory_bank m_bank_f800_w; - required_ioport m_config; - required_ioport_array<8> m_kbd_row; - - emu_timer *m_tape_timer; - - int m_blink_counter; - uint8_t m_pattr; - uint8_t m_via_a, m_via_b, m_psg_a; - bool m_via_ca2, m_via_cb2, m_via_irq; - bool m_ext_irq; - - virtual void update_irq(); - void update_psg(); - void update_keyboard(); - void machine_start_common(); -}; - -class telestrat_state : public oric_state -{ -public: - telestrat_state(const machine_config &mconfig, device_type type, const char *tag) : - oric_state(mconfig, type, tag), - m_via2(*this, "via6522_2"), - m_fdc(*this, "fdc"), - m_telmatic(*this, "telmatic"), - m_teleass(*this, "teleass"), - m_hyperbas(*this, "hyperbas"), - m_telmon24(*this, "telmon24"), - m_joy1(*this, "JOY1"), - m_joy2(*this, "JOY2") - { } - - void via2_a_w(uint8_t data); - void via2_b_w(uint8_t data); - DECLARE_WRITE_LINE_MEMBER(via2_ca2_w); - DECLARE_WRITE_LINE_MEMBER(via2_cb2_w); - DECLARE_WRITE_LINE_MEMBER(via2_irq_w); - - DECLARE_WRITE_LINE_MEMBER(acia_irq_w); - - DECLARE_WRITE_LINE_MEMBER(fdc_irq_w); - DECLARE_WRITE_LINE_MEMBER(fdc_drq_w); - DECLARE_WRITE_LINE_MEMBER(fdc_hld_w); - - static void floppy_formats(format_registration &fr); - - virtual void machine_start() override; - virtual void machine_reset() override; - - void telstrat(machine_config &config); - void telestrat_mem(address_map &map); -protected: - enum { - P_IRQEN = 0x01, - P_DDS = 0x04, - P_DDEN = 0x08, - P_SS = 0x10, - P_DRIVE = 0x60 - }; - - required_device m_via2; - required_device m_fdc; - required_memory_region m_telmatic; - required_memory_region m_teleass; - required_memory_region m_hyperbas; - required_memory_region m_telmon24; - required_ioport m_joy1; - required_ioport m_joy2; - - floppy_image_device *m_floppies[4]; - uint8_t m_port_314; - uint8_t m_via2_a, m_via2_b; - bool m_via2_ca2, m_via2_cb2, m_via2_irq; - bool m_acia_irq; - bool m_fdc_irq, m_fdc_drq, m_fdc_hld; - - uint8_t m_junk_read[0x4000], m_junk_write[0x4000]; - - virtual void update_irq() override; - void remap(); - void port_314_w(u8 data); - u8 port_314_r(); - u8 port_318_r(); -}; - -/* Ram is 64K, with 16K hidden by the rom. The 300-3ff is also hidden by the i/o */ -void oric_state::oric_mem(address_map &map) -{ - map(0x0000, 0xffff).ram().share("ram"); - map(0x0300, 0x030f).m(m_via, FUNC(via6522_device::map)).mirror(0xf0); - map(0xc000, 0xdfff).bankr("bank_c000_r").bankw("bank_c000_w"); - map(0xe000, 0xf7ff).bankr("bank_e000_r").bankw("bank_e000_w"); - map(0xf800, 0xffff).bankr("bank_f800_r").bankw("bank_f800_w"); -} - -/* -The telestrat has the memory regions split into 16k blocks. -Memory region &c000-&ffff can be ram or rom. */ -void telestrat_state::telestrat_mem(address_map &map) -{ - map(0x0000, 0xffff).ram().share("ram"); - map(0x0300, 0x030f).m(m_via, FUNC(via6522_device::map)); - map(0x0310, 0x0313).rw(m_fdc, FUNC(fd1793_device::read), FUNC(fd1793_device::write)); - map(0x0314, 0x0314).rw(FUNC(telestrat_state::port_314_r), FUNC(telestrat_state::port_314_w)); - map(0x0318, 0x0318).r(FUNC(telestrat_state::port_318_r)); - map(0x031c, 0x031f).rw("acia", FUNC(mos6551_device::read), FUNC(mos6551_device::write)); - map(0x0320, 0x032f).m(m_via2, FUNC(via6522_device::map)); - map(0xc000, 0xffff).bankr("bank_c000_r").bankw("bank_c000_w"); -} - -uint32_t oric_state::screen_update_oric(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - bool blink_state = m_blink_counter & 0x20; - m_blink_counter = (m_blink_counter + 1) & 0x3f; - - uint8_t pattr = m_pattr; - - for(int y=0; y<224; y++) { - // Line attributes and current colors - uint8_t lattr = 0; - uint32_t fgcol = m_palette->pen_color(7); - uint32_t bgcol = m_palette->pen_color(0); - - uint32_t *p = &bitmap.pix(y); - - for(int x=0; x<40; x++) { - // Lookup the byte and, if needed, the pattern data - uint8_t ch, pat; - if((pattr & PATTR_HIRES) && y < 200) - ch = pat = m_ram[0xa000 + y*40 + x]; - - else { - ch = m_ram[0xbb80 + (y>>3)*40 + x]; - int off = (lattr & LATTR_DSIZE ? y >> 1 : y ) & 7; - const uint8_t *base; - if(pattr & PATTR_HIRES) - if(lattr & LATTR_ALT) - base = m_ram + 0x9c00; - else - base = m_ram + 0x9800; - else - if(lattr & LATTR_ALT) - base = m_ram + 0xb800; - else - base = m_ram + 0xb400; - pat = base[((ch & 0x7f) << 3) | off]; - } - - // Handle state-chaging attributes - if(!(ch & 0x60)) { - pat = 0x00; - switch(ch & 0x18) { - case 0x00: fgcol = m_palette->pen_color(ch & 7); break; - case 0x08: lattr = ch & 7; break; - case 0x10: bgcol = m_palette->pen_color(ch & 7); break; - case 0x18: pattr = ch & 7; break; - } - } - - // Pick up the colors for the pattern - uint32_t c_fgcol = fgcol; - uint32_t c_bgcol = bgcol; - - // inverse video - if(ch & 0x80) { - c_bgcol = c_bgcol ^ 0xffffff; - c_fgcol = c_fgcol ^ 0xffffff; - } - // blink - if((lattr & LATTR_BLINK) && blink_state) - c_fgcol = c_bgcol; - - // Draw the pattern - *p++ = pat & 0x20 ? c_fgcol : c_bgcol; - *p++ = pat & 0x10 ? c_fgcol : c_bgcol; - *p++ = pat & 0x08 ? c_fgcol : c_bgcol; - *p++ = pat & 0x04 ? c_fgcol : c_bgcol; - *p++ = pat & 0x02 ? c_fgcol : c_bgcol; - *p++ = pat & 0x01 ? c_fgcol : c_bgcol; - } - } - - m_pattr = pattr; - - return 0; -} - -void oric_state::update_keyboard() -{ - m_via->write_pb3((m_kbd_row[m_via_b & 7]->read() | m_psg_a) != 0xff); -} - -void oric_state::update_psg() -{ - if(m_via_ca2) - if(m_via_cb2) - m_psg->address_w(m_via_a); - else - m_via->write_pa(m_psg->data_r()); - else if(m_via_cb2) - m_psg->data_w(m_via_a); -} - -void oric_state::update_irq() -{ - m_maincpu->set_input_line(m6502_device::IRQ_LINE, m_via_irq || m_ext_irq ? ASSERT_LINE : CLEAR_LINE); -} - -INPUT_CHANGED_MEMBER(oric_state::nmi_pressed) -{ - m_maincpu->set_input_line(m6502_device::NMI_LINE, newval ? ASSERT_LINE : CLEAR_LINE); -} - -void oric_state::via_a_w(uint8_t data) -{ - m_via_a = data; - m_cent_data_out->write(m_via_a); - update_psg(); -} - -void oric_state::via_b_w(uint8_t data) -{ - m_via_b = data; - update_keyboard(); - m_centronics->write_strobe(data & 0x10 ? 1 : 0); - m_cassette->change_state(data & 0x40 ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, - CASSETTE_MOTOR_DISABLED); - m_cassette->output(data & 0x80 ? -1.0 : +1.0); -} - -WRITE_LINE_MEMBER(oric_state::via_ca2_w) -{ - m_via_ca2 = state; - update_psg(); -} - -WRITE_LINE_MEMBER(oric_state::via_cb2_w) -{ - m_via_cb2 = state; - update_psg(); -} - -WRITE_LINE_MEMBER(oric_state::via_irq_w) -{ - m_via_irq = state; - update_irq(); -} - -WRITE_LINE_MEMBER(oric_state::ext_irq_w) -{ - m_ext_irq = state; - update_irq(); -} - -void oric_state::psg_a_w(uint8_t data) -{ - m_psg_a = data; - update_keyboard(); -} - -TIMER_CALLBACK_MEMBER(oric_state::update_tape) -{ - if(!m_config->read()) - m_via->write_cb1(m_cassette->input() > 0.0038); -} - -WRITE_LINE_MEMBER(oric_state::vblank_w) -{ - if(m_config->read()) - m_via->write_cb1(state); -} - -void oric_state::video_start() -{ - m_blink_counter = 0; - m_pattr = 0; -} - -void oric_state::machine_start_common() -{ - m_via_a = 0xff; - m_via_b = 0xff; - m_psg_a = 0x00; - m_via_ca2 = false; - m_via_cb2 = false; - m_via_irq = false; - m_ext_irq = false; - - if (!m_tape_timer) - m_tape_timer = timer_alloc(FUNC(oric_state::update_tape), this); - - save_item(NAME(m_blink_counter)); - save_item(NAME(m_pattr)); - save_item(NAME(m_via_a)); - save_item(NAME(m_via_b)); - save_item(NAME(m_psg_a)); - save_item(NAME(m_via_ca2)); - save_item(NAME(m_via_cb2)); - save_item(NAME(m_via_irq)); - save_item(NAME(m_ext_irq)); -} - -void oric_state::machine_start() -{ - machine_start_common(); - m_bank_c000_r->set_base(m_rom->base()); - m_bank_e000_r->set_base(m_rom->base() + 0x2000); - m_bank_f800_r->set_base(m_rom->base() + 0x3800); -} - -void oric_state::machine_reset() -{ - m_tape_timer->adjust(attotime::from_hz(4800), 0, attotime::from_hz(4800)); -} - -void telestrat_state::machine_start() -{ - machine_start_common(); - for(u8 i=0; i<4; i++) - { - char name[32]; - sprintf(name, "fdc:%d", i); - m_floppies[i] = subdevice(name)->get_device(); - } - m_fdc_irq = m_fdc_drq = m_fdc_hld = false; - m_acia_irq = false; - - memset(m_junk_read, 0x00, sizeof(m_junk_read)); - memset(m_junk_write, 0x00, sizeof(m_junk_write)); - - save_item(NAME(m_port_314)); - save_item(NAME(m_via2_a)); - save_item(NAME(m_via2_b)); - save_item(NAME(m_via2_ca2)); - save_item(NAME(m_via2_cb2)); - save_item(NAME(m_via2_irq)); - save_item(NAME(m_acia_irq)); - save_item(NAME(m_fdc_irq)); - save_item(NAME(m_fdc_drq)); - save_item(NAME(m_fdc_hld)); -} - -void telestrat_state::machine_reset() -{ - m_tape_timer->adjust(attotime::from_hz(4800), 0, attotime::from_hz(4800)); - m_port_314 = 0x00; - m_via2_a = 0xff; - remap(); -} - -void telestrat_state::update_irq() -{ - m_maincpu->set_input_line(m6502_device::IRQ_LINE, - m_via_irq || - m_ext_irq || - (m_fdc_irq && (m_port_314 & P_IRQEN)) || - m_via2_irq || - m_acia_irq ? ASSERT_LINE : CLEAR_LINE); -} - -void telestrat_state::via2_a_w(uint8_t data) -{ - m_via2_a = data; - remap(); -} - -void telestrat_state::via2_b_w(uint8_t data) -{ - m_via2_b = data; - uint8_t port = 0xff; - if(!(m_via2_b & 0x40)) - port &= m_joy1->read(); - if(!(m_via2_b & 0x80)) - port &= m_joy2->read(); - - m_via2->write_pb(port); -} - -WRITE_LINE_MEMBER(telestrat_state::via2_ca2_w) -{ - m_via2_ca2 = state; -} - -WRITE_LINE_MEMBER(telestrat_state::via2_cb2_w) -{ - m_via2_cb2 = state; -} - -WRITE_LINE_MEMBER(telestrat_state::via2_irq_w) -{ - m_via2_irq = state; - update_irq(); -} - -void telestrat_state::port_314_w(u8 data) -{ - m_port_314 = data; - floppy_image_device *floppy = m_floppies[(m_port_314 >> 5) & 3]; - m_fdc->set_floppy(floppy); - m_fdc->dden_w(m_port_314 & P_DDEN); - if(floppy) { - floppy->ss_w(m_port_314 & P_SS ? 1 : 0); - floppy->mon_w(0); - } - update_irq(); -} - -u8 telestrat_state::port_314_r() -{ - return (m_fdc_irq && (m_port_314 & P_IRQEN)) ? 0x7f : 0xff; -} - -u8 telestrat_state::port_318_r() -{ - return m_fdc_drq ? 0x7f : 0xff; -} - - -WRITE_LINE_MEMBER(telestrat_state::acia_irq_w) -{ - m_acia_irq = state; - update_irq(); -} - -WRITE_LINE_MEMBER(telestrat_state::fdc_irq_w) -{ - m_fdc_irq = state; - update_irq(); -} - -WRITE_LINE_MEMBER(telestrat_state::fdc_drq_w) -{ - m_fdc_drq = state; -} - -WRITE_LINE_MEMBER(telestrat_state::fdc_hld_w) -{ - m_fdc_hld = state; -} - -void telestrat_state::remap() -{ - // Theorically, these are cartridges. There's no real point to - // making them configurable, when only 4 existed and there are 7 - // slots. - - switch(m_via2_a & 7) { - case 0: - m_bank_c000_r->set_base(m_ram+0xc000); - m_bank_c000_w->set_base(m_ram+0xc000); - break; - case 1: - case 2: - case 3: - m_bank_c000_r->set_base(m_junk_read); - m_bank_c000_w->set_base(m_junk_write); - break; - case 4: - m_bank_c000_r->set_base(m_telmatic->base()); - m_bank_c000_w->set_base(m_junk_write); - break; - case 5: - m_bank_c000_r->set_base(m_teleass->base()); - m_bank_c000_w->set_base(m_junk_write); - break; - case 6: - m_bank_c000_r->set_base(m_hyperbas->base()); - m_bank_c000_w->set_base(m_junk_write); - break; - case 7: - m_bank_c000_r->set_base(m_telmon24->base()); - m_bank_c000_w->set_base(m_junk_write); - break; - } -} - - - -static INPUT_PORTS_START(oric) - PORT_START("ROW0") - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') PORT_CHAR(24) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') PORT_CHAR(22) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') PORT_CHAR(14) - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') - - PORT_START("ROW1") - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') PORT_CHAR(4) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') PORT_CHAR(17) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_TAB) PORT_CHAR(27) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') PORT_CHAR(6) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') PORT_CHAR(18) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') PORT_CHAR(20) - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') PORT_CHAR(10) - - PORT_START("ROW2") - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') PORT_CHAR(3) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') PORT_CHAR(26) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_SHIFT_2) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') PORT_CHAR(2) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') - - PORT_START("ROW3") - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR(0xA3) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') PORT_CHAR(11) - - PORT_START("ROW4") - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') - - PORT_START("ROW5") - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') PORT_CHAR(29) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Del") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') PORT_CHAR(16) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') PORT_CHAR(15) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') PORT_CHAR(9) - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') PORT_CHAR(21) - - PORT_START("ROW6") - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') PORT_CHAR(23) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') PORT_CHAR(19) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') PORT_CHAR(1) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') PORT_CHAR(5) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') PORT_CHAR(7) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') PORT_CHAR(8) - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') PORT_CHAR(25) - - PORT_START("ROW7") - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RSHIFT) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') PORT_CHAR(12) - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') - - PORT_START("NMI") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("NMI") PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_CHANGED_MEMBER(DEVICE_SELF, oric_state, nmi_pressed, 0) - - /* vsync cable hardware. This is a simple cable connected to the video output - to the monitor/television. The sync signal is connected to the cassette input - allowing interrupts to be generated from the vsync signal. */ - PORT_START("CONFIG") - PORT_CONFNAME(0x01, 0x00, "Tape input") - PORT_CONFSETTING( 0x00, "Tape") - PORT_CONFSETTING( 0x01, "VSync cable") -INPUT_PORTS_END - -static INPUT_PORTS_START(orica) - PORT_INCLUDE( oric ) - - PORT_MODIFY("ROW5") - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Funct") PORT_CODE(KEYCODE_LALT) PORT_CHAR(UCHAR_MAMEKEY(LALT)) -INPUT_PORTS_END - -static INPUT_PORTS_START(prav8d) - PORT_START("ROW0") - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X \xd0\xac") PORT_CODE(KEYCODE_X) PORT_CHAR('X') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V \xd0\x96") PORT_CODE(KEYCODE_V) PORT_CHAR('V') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N \xd0\x9d") PORT_CODE(KEYCODE_N) PORT_CHAR('N') - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'') - - PORT_START("ROW1") - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D \xd0\x94") PORT_CODE(KEYCODE_D) PORT_CHAR('D') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q \xd0\xaf") PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Esc") PORT_CODE(KEYCODE_ESC) PORT_CHAR(27) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F \xd0\xa4") PORT_CODE(KEYCODE_F) PORT_CHAR('F') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R \xd0\xa0") PORT_CODE(KEYCODE_R) PORT_CHAR('R') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T \xd0\xa2") PORT_CODE(KEYCODE_T) PORT_CHAR('T') - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J \xd0\x99") PORT_CODE(KEYCODE_J) PORT_CHAR('J') - - PORT_START("ROW2") - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C \xd0\xa6") PORT_CODE(KEYCODE_C) PORT_CHAR('C') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z \xd0\x97") PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("MK") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_SHIFT_2) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B \xd0\x91") PORT_CODE(KEYCODE_B) PORT_CHAR('B') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M \xd0\x9c") PORT_CODE(KEYCODE_M) PORT_CHAR('M') - - PORT_START("ROW3") - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("] \xd0\xa9") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(']') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(';') PORT_CHAR('+') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C/L") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) // this one is 5th line, 1st key from right - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR(':') PORT_CHAR('*') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("[ \xd0\xa8") PORT_CODE(KEYCODE_COLON) PORT_CHAR('[') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K \xd0\x9a") PORT_CODE(KEYCODE_K) PORT_CHAR('K') - - PORT_START("ROW4") - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_RIGHT) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_DOWN) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_LEFT) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_UP) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') - - PORT_START("ROW5") - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("@ \xd0\xae") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('@') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("\\ \xd0\xad") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('\\') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Del") PORT_CODE(KEYCODE_DEL) PORT_CHAR(8) // this one is 5th line, 1st key from left - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P \xd0\x9f") PORT_CODE(KEYCODE_P) PORT_CHAR('P') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O \xd0\x9e") PORT_CODE(KEYCODE_O) PORT_CHAR('O') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I \xd0\x98") PORT_CODE(KEYCODE_I) PORT_CHAR('I') - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U \xd0\xa3") PORT_CODE(KEYCODE_U) PORT_CHAR('U') - - PORT_START("ROW6") - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W \xd0\x92") PORT_CODE(KEYCODE_W) PORT_CHAR('W') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S \xd0\xa1") PORT_CODE(KEYCODE_S) PORT_CHAR('S') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A \xd0\x90") PORT_CODE(KEYCODE_A) PORT_CHAR('A') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E \xd0\x95") PORT_CODE(KEYCODE_E) PORT_CHAR('E') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G \xd0\x93") PORT_CODE(KEYCODE_G) PORT_CHAR('G') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H \xd0\xa5") PORT_CODE(KEYCODE_H) PORT_CHAR('H') - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y \xd0\xaa") PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') - - PORT_START("ROW7") - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('-') PORT_CHAR('=') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("^ \xd0\xa7") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('^') // this one would be on 2nd line, 3rd key from 'P' - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RSHIFT) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L \xd0\x9b") PORT_CODE(KEYCODE_L) PORT_CHAR('L') - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') - - PORT_START("NMI") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("NMI") PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_CHANGED_MEMBER(DEVICE_SELF, oric_state, nmi_pressed, 0) - - /* vsync cable hardware. This is a simple cable connected to the video output - to the monitor/television. The sync signal is connected to the cassette input - allowing interrupts to be generated from the vsync signal. */ - PORT_START("CONFIG") - PORT_CONFNAME(0x01, 0x00, "Tape input") - PORT_CONFSETTING( 0x00, "Tape") - PORT_CONFSETTING( 0x01, "VSync cable") -INPUT_PORTS_END - -static INPUT_PORTS_START(telstrat) - PORT_INCLUDE( orica ) - -// The telestrat does not have the NMI button - PORT_MODIFY("NMI") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED) - - PORT_START("JOY1") /* left joystick port */ - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_8WAY PORT_PLAYER(1) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_8WAY PORT_PLAYER(1) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(1) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) PORT_8WAY PORT_PLAYER(1) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_8WAY PORT_PLAYER(1) - - PORT_START("JOY2") /* right joystick port */ - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_8WAY PORT_PLAYER(2) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_8WAY PORT_PLAYER(2) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(2) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) PORT_8WAY PORT_PLAYER(2) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_8WAY PORT_PLAYER(2) -INPUT_PORTS_END - - -void oric_state::oric(machine_config &config, bool add_ext) // this variable not used -{ - /* basic machine hardware */ - M6502(config, m_maincpu, 12_MHz_XTAL / 12); - m_maincpu->set_addrmap(AS_PROGRAM, &oric_state::oric_mem); - - config.set_maximum_quantum(attotime::from_hz(60)); - - /* video hardware */ - screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_raw(12_MHz_XTAL / 2, 64*6, 0, 40*6, 312, 0, 28*8); // 260 lines in 60 Hz mode - screen.set_screen_update(FUNC(oric_state::screen_update_oric)); - screen.screen_vblank().set(FUNC(oric_state::vblank_w)); - - PALETTE(config, m_palette, palette_device::RGB_3BIT); - - /* sound hardware */ - SPEAKER(config, "mono").front_center(); - - AY8912(config, m_psg, 12_MHz_XTAL / 12); - m_psg->set_flags(AY8910_DISCRETE_OUTPUT); - m_psg->set_resistors_load(4700, 4700, 4700); - m_psg->port_a_write_callback().set(FUNC(oric_state::psg_a_w)); - m_psg->add_route(ALL_OUTPUTS, "mono", 0.25); - - /* printer */ - CENTRONICS(config, m_centronics, centronics_devices, "printer"); - m_centronics->ack_handler().set(m_via, FUNC(via6522_device::write_ca1)); - - OUTPUT_LATCH(config, m_cent_data_out); - m_centronics->set_output_latch(*m_cent_data_out); - - /* cassette */ - CASSETTE(config, m_cassette, 0); - m_cassette->set_formats(oric_cassette_formats); - m_cassette->set_default_state(CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED); - m_cassette->add_route(ALL_OUTPUTS, "mono", 0.05); - - /* via */ - MOS6522(config, m_via, 12_MHz_XTAL / 12); - m_via->writepa_handler().set(FUNC(oric_state::via_a_w)); - m_via->writepb_handler().set(FUNC(oric_state::via_b_w)); - m_via->ca2_handler().set(FUNC(oric_state::via_ca2_w)); - m_via->cb2_handler().set(FUNC(oric_state::via_cb2_w)); - m_via->irq_handler().set(FUNC(oric_state::via_irq_w)); - - /* extension port */ - ORICEXT_CONNECTOR(config, "ext", oricext_intf, nullptr, "maincpu").irq_callback().set(FUNC(oric_state::ext_irq_w)); -} - -void oric_state::prav8d(machine_config &config) -{ - oric(config, true); -} - -void telestrat_state::floppy_formats(format_registration &fr) -{ - fr.add_mfm_containers(); - fr.add(FLOPPY_ORIC_DSK_FORMAT); -} - -static void telestrat_floppies(device_slot_interface &device) -{ - device.option_add("3dsdd", FLOPPY_3_DSDD); -} - -void telestrat_state::telstrat(machine_config &config) -{ - oric(config, false); - m_maincpu->set_addrmap(AS_PROGRAM, &telestrat_state::telestrat_mem); - - /* acia */ - mos6551_device &acia(MOS6551(config, "acia", 0)); - acia.set_xtal(1.8432_MHz_XTAL); - acia.irq_handler().set(FUNC(telestrat_state::acia_irq_w)); - - /* via */ - MOS6522(config, m_via2, 12_MHz_XTAL / 12); - m_via2->writepa_handler().set(FUNC(telestrat_state::via2_a_w)); - m_via2->writepb_handler().set(FUNC(telestrat_state::via2_b_w)); - m_via2->ca2_handler().set(FUNC(telestrat_state::via2_ca2_w)); - m_via2->cb2_handler().set(FUNC(telestrat_state::via2_cb2_w)); - m_via2->irq_handler().set(FUNC(telestrat_state::via2_irq_w)); - - /* microdisc */ - FD1793(config, m_fdc, 8_MHz_XTAL / 8); - m_fdc->intrq_wr_callback().set(FUNC(telestrat_state::fdc_irq_w)); - m_fdc->drq_wr_callback().set(FUNC(telestrat_state::fdc_drq_w)); - m_fdc->hld_wr_callback().set(FUNC(telestrat_state::fdc_hld_w)); - m_fdc->set_force_ready(true); - - FLOPPY_CONNECTOR(config, "fdc:0", telestrat_floppies, "3dsdd", telestrat_state::floppy_formats); - FLOPPY_CONNECTOR(config, "fdc:1", telestrat_floppies, nullptr, telestrat_state::floppy_formats); - FLOPPY_CONNECTOR(config, "fdc:2", telestrat_floppies, nullptr, telestrat_state::floppy_formats); - FLOPPY_CONNECTOR(config, "fdc:3", telestrat_floppies, nullptr, telestrat_state::floppy_formats); -} - - -ROM_START(oric1) - ROM_REGION(0x4000, "maincpu", 0) - ROM_SYSTEM_BIOS( 0, "ver10", "Basic 1.0") - ROMX_LOAD ("basic10.rom", 0, 0x04000, CRC(f18710b4) SHA1(333116e6884d85aaa4dfc7578a91cceeea66d016), ROM_BIOS(0)) - ROM_SYSTEM_BIOS( 1, "ver10uk", "Basic 1.0 UK") - ROMX_LOAD( "basic10uk.rom", 0, 0x04000, CRC(d6006a01) SHA1(84759cc8faae53070f1c8ce8408982a0edcb0796), ROM_BIOS(1)) -ROM_END - -ROM_START(orica) - ROM_REGION(0x4000, "maincpu", 0) - ROM_SYSTEM_BIOS( 0, "ver11", "Basic 1.1") - ROMX_LOAD ("basic11b.rom", 0, 0x04000, CRC(c3a92bef) SHA1(9451a1a09d8f75944dbd6f91193fc360f1de80ac), ROM_BIOS(0) ) - ROM_SYSTEM_BIOS( 1, "ver12", "Basic 1.2 (Pascal Leclerc)") // 1987/1999 - various enhancements and bugfixes - ROMX_LOAD ("basic12.rom", 0, 0x04000, CRC(dc4f22dc) SHA1(845e1a893de3dc0f856fdf2f69c3b73770b4094f), ROM_BIOS(1) ) - ROM_SYSTEM_BIOS( 2, "ver121", "Basic 1.21 (Pascal Leclerc)") // 07.1999 - DRAW enhancement - ROMX_LOAD ("basic121.rom", 0, 0x04000, CRC(0a2860b1) SHA1(b727d5c3bbc8cb1d510f224eb1e0d90d609e8506), ROM_BIOS(2) ) - ROM_SYSTEM_BIOS( 3, "ver122", "Basic 1.22 (Pascal Leclerc)") // 08.2001 - added EUR symbol - ROMX_LOAD ("basic122.rom", 0, 0x04000, CRC(5ef2a861) SHA1(9ab6dc47b6e9dc65a4137ce0f0f12fc2b6ca8442), ROM_BIOS(3) ) - ROM_SYSTEM_BIOS( 4, "ver11de", "Basic 1.1 DE") - ROMX_LOAD( "bas11_de.rom", 0, 0x04000, CRC(65233b2d) SHA1(b01cabb1a21980a6785a2fe37a8f8572c892123f), ROM_BIOS(4)) - ROM_SYSTEM_BIOS( 5, "ver11es", "Basic 1.1 ES") - ROMX_LOAD( "bas11_es.rom", 0, 0x04000, CRC(47bf26c7) SHA1(4fdbadd68db9ab8ad1cd56b4e5cbe51a9c3f11ae), ROM_BIOS(5)) - ROM_SYSTEM_BIOS( 6, "ver11fr", "Basic 1.1 FR") - ROMX_LOAD( "bas11_fr.rom", 0, 0x04000, CRC(603b1fbf) SHA1(2a4583df3b59ca454d67d5631f242c96ec4cf99a), ROM_BIOS(6)) - ROM_SYSTEM_BIOS( 7, "ver11se", "Basic 1.1 SE") - ROMX_LOAD( "bas11_se.rom", 0, 0x04000, CRC(a71523ac) SHA1(ce53acf84baec6ab5cbac9f9cefa71b3efeb2ead), ROM_BIOS(7)) - ROM_SYSTEM_BIOS( 8, "ver11uk", "Basic 1.1 UK") - ROMX_LOAD( "bas11_uk.rom", 0, 0x04000, CRC(303370d1) SHA1(589ff66fac8e06d65af3369491faa67a71f1322a), ROM_BIOS(8)) - ROM_SYSTEM_BIOS( 9, "ver12es", "Basic 1.2 ES") - ROMX_LOAD( "bas12es_le.rom", 0, 0x04000, CRC(70de4aeb) SHA1(b327418aa7d8a5a03c135e3d8acdd511df625893), ROM_BIOS(9)) - ROM_SYSTEM_BIOS( 10, "ver12fr", "Basic 1.2 FR") - ROMX_LOAD( "bas12fr_le.rom", 0, 0x04000, CRC(47a437fc) SHA1(70271bc3ed5c3bf4d339d6f5de3de8c3c50ff573), ROM_BIOS(10)) - ROM_SYSTEM_BIOS( 11, "ver12ge", "Basic 1.2 GE") - ROMX_LOAD( "bas12ge_le.rom", 0, 0x04000, CRC(f5f0dd52) SHA1(75359302452ee7b19537698f124aaefd333688d0), ROM_BIOS(11)) - ROM_SYSTEM_BIOS( 12, "ver12sw", "Basic 1.2 SW") - ROMX_LOAD( "bas12sw_le.rom", 0, 0x04000, CRC(100abe68) SHA1(6211d5969c4d7a6acb86ed19c5e51a33a3bef431), ROM_BIOS(12)) - ROM_SYSTEM_BIOS( 13, "ver12uk", "Basic 1.2 UK") - ROMX_LOAD( "bas12uk_le.rom", 0, 0x04000, CRC(00fce8a6) SHA1(d40558bdf61b8aba6260293c9424fd463be7fad8), ROM_BIOS(13)) - ROM_SYSTEM_BIOS( 14, "ver121es", "Basic 1.211 ES") - ROMX_LOAD( "bas121es_le.rom", 0, 0x04000, CRC(87ec679b) SHA1(5de6a5f5121f69069c9b93d678046e814b5b64e9), ROM_BIOS(14)) - ROM_SYSTEM_BIOS( 15, "ver121fr", "Basic 1.211 FR") - ROMX_LOAD( "bas121fr_le.rom", 0, 0x04000, CRC(e683dec2) SHA1(20df7ebc0f13aa835f286d50137f1a7ff7430c29), ROM_BIOS(15)) - ROM_SYSTEM_BIOS( 16, "ver121ge", "Basic 1.211 GE") - ROMX_LOAD( "bas121ge_le.rom", 0, 0x04000, CRC(94fe32bf) SHA1(1024776d20030d602e432e50014502524658643a), ROM_BIOS(16)) - ROM_SYSTEM_BIOS( 17, "ver121sw", "Basic 1.211 SW") - ROMX_LOAD( "bas121sw_le.rom", 0, 0x04000, CRC(e6ad11c7) SHA1(309c94a9861fcb770636dcde1801a5c68ca819b4), ROM_BIOS(17)) - ROM_SYSTEM_BIOS( 18, "ver121uk", "Basic 1.211 UK") - ROMX_LOAD( "bas121uk_le.rom", 0, 0x04000, CRC(75aa1aa9) SHA1(ca99e244d9cbef625344c2054023504a4f9dcfe4), ROM_BIOS(18)) - ROM_SYSTEM_BIOS( 19, "ver122es", "Basic 1.22 ES") - ROMX_LOAD( "bas122es_le.rom", 0, 0x04000, CRC(9144f9e0) SHA1(acf2094078af057e74a31d90d7010be51b9033fa), ROM_BIOS(19)) - ROM_SYSTEM_BIOS( 20, "ver122fr", "Basic 1.22 FR") - ROMX_LOAD( "bas122fr_le.rom", 0, 0x04000, CRC(370cfda4) SHA1(fad9a0661256e59bcc2915578647573e4128e1bb), ROM_BIOS(20)) - ROM_SYSTEM_BIOS( 21, "ver122ge", "Basic 1.22 GE") - ROMX_LOAD( "bas122ge_le.rom", 0, 0x04000, CRC(9a42bd62) SHA1(8a9c80f314daf4e5e64fa202e583b8a65796db8b), ROM_BIOS(21)) - ROM_SYSTEM_BIOS( 22, "ver122sw", "Basic 1.22 SW") - ROMX_LOAD( "bas122sw_le.rom", 0, 0x04000, CRC(e7fd57a4) SHA1(c75cbf7cfafaa02712dc7ca2f972220aef86fb8d), ROM_BIOS(22)) - ROM_SYSTEM_BIOS( 23, "ver122uk", "Basic 1.22 UK") - ROMX_LOAD( "bas122uk_le.rom", 0, 0x04000, CRC(9865bcd7) SHA1(2a92e2d119463e682bf10647e3880e26656d65b5), ROM_BIOS(23)) -ROM_END - -ROM_START(telstrat) - ROM_REGION(0x4000, "telmatic", 0) - ROM_LOAD ("telmatic.rom", 0, 0x2000, CRC(94358dc6) SHA1(35f92a0477a88f5cf564971125047ffcfa02ec10) ) - ROM_RELOAD (0x2000, 0x2000) - - ROM_REGION(0x4000, "teleass", 0) - ROM_LOAD ("teleass.rom", 0, 0x4000, CRC(68b0fde6) SHA1(9e9af51dae3199cccf49ab3f0d47e2b9be4ba97d) ) - - ROM_REGION(0x4000, "hyperbas", 0) - ROM_LOAD ("hyperbas.rom", 0, 0x4000, CRC(1d96ab50) SHA1(f5f70a0eb59f8cd6c261e179ae78ef906f68ed63) ) - - ROM_REGION(0x4000, "telmon24", 0) - ROM_LOAD ("telmon24.rom", 0, 0x4000, CRC(aa727c5d) SHA1(86fc8dc0932f983efa199e31ae05a4424772f959) ) -ROM_END - -ROM_START(prav8d) - ROM_REGION(0x4000, "maincpu", 0) /* 0x10000 + 0x04000 + 0x00100 + 0x00200 */ - ROM_LOAD( "pravetzt.rom", 0, 0x4000, CRC(58079502) SHA1(7afc276cb118adff72e4f16698f94bf3b2c64146) ) -// ROM_LOAD_OPTIONAL( "8ddoslo.rom", 0x014000, 0x0100, CRC(0c82f636) SHA1(b29d151a0dfa3c7cd50439b51d0a8f95559bc2b6) ) -// ROM_LOAD_OPTIONAL( "8ddoshi.rom", 0x014100, 0x0200, CRC(66309641) SHA1(9c2e82b3c4d385ade6215fcb89f8b92e6fd2bf4b) ) -ROM_END - -ROM_START(prav8dd) - ROM_REGION(0x4000, "maincpu", 0) /* 0x10000 + 0x04000 + 0x00100 + 0x00200 */ - ROM_SYSTEM_BIOS( 0, "default", "Disk ROM, 1989") - ROMX_LOAD( "8d.rom", 0, 0x4000, CRC(b48973ef) SHA1(fd47c977fc215a3b577596a7483df53e8a1e9c83), ROM_BIOS(0) ) - ROM_SYSTEM_BIOS( 1, "radosoft", "RadoSoft Disk ROM, 1992") - ROMX_LOAD( "pravetzd.rom", 0, 0x4000, CRC(f8d23821) SHA1(f87ad3c5832773b6e0614905552a80c98dc8e2a5), ROM_BIOS(1) ) -// ROM_LOAD_OPTIONAL( "8ddoslo.rom", 0x014000, 0x0100, CRC(0c82f636) SHA1(b29d151a0dfa3c7cd50439b51d0a8f95559bc2b6) ) -// ROM_LOAD_OPTIONAL( "8ddoshi.rom", 0x014100, 0x0200, CRC(66309641) SHA1(9c2e82b3c4d385ade6215fcb89f8b92e6fd2bf4b) ) -ROM_END - - -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1983, oric1, 0, 0, oric, oric, oric_state, empty_init, "Tangerine", "Oric 1" , MACHINE_SUPPORTS_SAVE ) -COMP( 1984, orica, oric1, 0, oric, orica, oric_state, empty_init, "Tangerine", "Oric Atmos" , MACHINE_SUPPORTS_SAVE ) -COMP( 1985, prav8d, oric1, 0, prav8d, prav8d, oric_state, empty_init, "Pravetz", "Pravetz 8D", MACHINE_SUPPORTS_SAVE ) -COMP( 1989, prav8dd, oric1, 0, prav8d, prav8d, oric_state, empty_init, "Pravetz", "Pravetz 8D (Disk ROM)", MACHINE_UNOFFICIAL | MACHINE_SUPPORTS_SAVE ) -COMP( 1986, telstrat, oric1, 0, telstrat, telstrat, telestrat_state, empty_init, "Tangerine", "Oric Telestrat", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/tangerine/alphatan.cpp b/src/mame/tangerine/alphatan.cpp new file mode 100644 index 00000000000..0bf5eb7ed1f --- /dev/null +++ b/src/mame/tangerine/alphatan.cpp @@ -0,0 +1,231 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Tantel AlphaTantel + + + Hardware: + --------- + CPU: R6504 + + RAM: M6810 + M5101 - battery backed + 2114 x 2 - video RAM + + Video: SAA5020 VTC + SAA5050 VCG + SAA5070 VIOP + TEA1002 + + TODO: + - implement SAA5070 (datasheet required) + - keyboard matrix (probably via SAA5070) + - cassette interface (via SAA5070) + - program mode switch + +**********************************************************************/ + +#include "emu.h" +#include "cpu/m6502/m6504.h" +#include "machine/nvram.h" +#include "machine/output_latch.h" +#include "video/tea1002.h" +#include "video/saa5050.h" +#include "bus/centronics/ctronics.h" +#include "imagedev/cassette.h" + +#include "emupal.h" +#include "screen.h" + + +class alphatan_state : public driver_device +{ +public: + alphatan_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_videoram(*this, "videoram") + , m_nvram(*this, "nvram") + , m_screen(*this, "screen") + , m_tea1002(*this, "encoder") + , m_palette(*this, "palette") + , m_trom(*this, "saa5050") + , m_centronics(*this, "centronics") + , m_cent_data_out(*this, "cent_data_out") + , m_cassette(*this, "cassette") + , m_config(*this, "CONFIG") + { } + + void alphatan(machine_config &config); + + uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + +protected: + virtual void machine_start() override; + +private: + required_device m_maincpu; + required_shared_ptr m_videoram; + required_device m_nvram; + required_device m_screen; + required_device m_tea1002; + required_device m_palette; + required_device m_trom; + required_device m_centronics; + required_device m_cent_data_out; + required_device m_cassette; + required_ioport m_config; + + void alphatan_map(address_map &map); + + uint8_t saa5070_r(offs_t offset); + void saa5070_w(offs_t offset, uint8_t data); + void write400(offs_t offset, uint8_t data); + void write600(offs_t offset, uint8_t data); + + void palette_init(palette_device &palette) const; +}; + +void alphatan_state::alphatan_map(address_map &map) +{ + map.unmap_value_high(); + map(0x0000, 0x007f).ram().mirror(0x0180); // MCM6810 + map(0x0200, 0x027f).ram().share("nvram"); // MCM5101 + map(0x0300, 0x0300).rw(FUNC(alphatan_state::saa5070_r), FUNC(alphatan_state::saa5070_w)); // write 0x20, 0x14, 0x0c, 0x18, 0x40, 0x90, 0x1f, 0xd4, 0x0f + map(0x0400, 0x0400).w(FUNC(alphatan_state::write400)); // write 0x03, 0x06, 0x08, 0x00, 0x04, 0x07, 0x01, 0x05 + map(0x0500, 0x0500).w(m_cent_data_out, FUNC(output_latch_device::write)); + map(0x0600, 0x0600).w(FUNC(alphatan_state::write600)); // unknown, writes only 0x01, 0x02, or 0x03 + map(0x0700, 0x0700).portr("CONFIG"); + map(0x0800, 0x0fff).ram().share("videoram"); // 2x2114 + map(0x1000, 0x1fff).rom().region("maincpu", 0); +} + + +static INPUT_PORTS_START( alphatan ) + PORT_START("CONFIG") + PORT_CONFNAME(0x10, 0x10, "Banner") + PORT_CONFSETTING(0x00, "Granada") + PORT_CONFSETTING(0x10, "Tantel") +INPUT_PORTS_END + + +uint8_t alphatan_state::saa5070_r(offs_t offset) +{ + uint8_t data = 0x00; + + //logerror("saa5070_r: %02x\n", data); + + return data; +} + +void alphatan_state::saa5070_w(offs_t offset, uint8_t data) +{ + //logerror("saa5070_w: %02x\n", data); +} + +void alphatan_state::write400(offs_t offset, uint8_t data) +{ + //logerror("write400: %02x\n", data); +} + +void alphatan_state::write600(offs_t offset, uint8_t data) +{ + //logerror("write600: %02x\n", data); +} + + +void alphatan_state::palette_init(palette_device &palette) const +{ + for (int i = 0; i < 8; i++) + palette.set_indirect_color(i, m_tea1002->color(i)); +} + +uint32_t alphatan_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + const rgb_t *palette = m_palette->palette()->entry_list_raw(); + + m_trom->dew_w(1); + m_trom->dew_w(0); + + for (int y = 0; y < 24 * 20; y++) + { + int sy = y / 20; + int x = 0; + + m_trom->lose_w(1); + m_trom->lose_w(0); + + int ssy = m_trom->tlc_r() ? sy : sy - 1; + offs_t video_ram_addr = ssy * 64; + + for (int sx = 0; sx < 40; sx++) + { + uint8_t code = m_videoram[video_ram_addr++]; + + m_trom->write(code & 0x7f); + + m_trom->f1_w(1); + m_trom->f1_w(0); + + for (int bit = 0; bit < 12; bit++) + { + m_trom->tr6_w(1); + m_trom->tr6_w(0); + + int color = m_trom->get_rgb(); + + if (BIT(code, 7)) color ^= 0x07; + + bitmap.pix(y, x++) = palette[color]; + } + } + } + + return 0; +} + + +void alphatan_state::machine_start() +{ +} + + +void alphatan_state::alphatan(machine_config &config) +{ + M6504(config, m_maincpu, 8.86_MHz_XTAL / 2); + m_maincpu->set_addrmap(AS_PROGRAM, &alphatan_state::alphatan_map); + + NVRAM(config, m_nvram, nvram_device::DEFAULT_ALL_0); + + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + //m_screen->set_raw(6_MHz_XTAL, 768, 0, 480, 625, 0, 480); + m_screen->set_refresh_hz(50); + m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500)); + m_screen->set_size(768, 480); + m_screen->set_visarea(0, 480-1, 0, 480-1); + m_screen->set_screen_update(FUNC(alphatan_state::screen_update)); + + TEA1002(config, m_tea1002, 8.86_MHz_XTAL); + PALETTE(config, m_palette, FUNC(alphatan_state::palette_init), 8, 8); + + SAA5050(config, m_trom, 6_MHz_XTAL); + + CENTRONICS(config, m_centronics, centronics_devices, "printer"); + + OUTPUT_LATCH(config, m_cent_data_out); + m_centronics->set_output_latch(*m_cent_data_out); + + CASSETTE(config, m_cassette); + m_cassette->set_default_state(CASSETTE_STOPPED); +} + + +ROM_START(alphatan) + ROM_REGION(0x1000, "maincpu", 0) + ROM_LOAD("tantel2732.bin", 0x0000, 0x1000, CRC(875c1ce9) SHA1(76e874cbc5d1341b09f57424181f24bdb31da210)) +ROM_END + + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1981, alphatan, 0, 0, alphatan, alphatan, alphatan_state, empty_init, "Tantel", "AlphaTantel", MACHINE_NO_SOUND_HW | MACHINE_NOT_WORKING ) diff --git a/src/mame/tangerine/hhtiger.cpp b/src/mame/tangerine/hhtiger.cpp new file mode 100644 index 00000000000..739887f9377 --- /dev/null +++ b/src/mame/tangerine/hhtiger.cpp @@ -0,0 +1,599 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + http://www.computinghistory.org.uk/det/52264/HH-Tiger/ + + SPECIFICATION + Processors: Z80A (4MHz) plus 6809 I/O processor (2MHz) plus 7220 + graphics processor. + RAM: 64K with Z80, 2K with 6809, 96K with 7220, plus 0.5K CMOS + RAM with battery back-up. 62K available to CP/M. + ROM: 2K with Z80, 16K with 6809. + Text screen: 80 x 24 or teletext-type 40 x 24, 8 colours. + Graphic screen: 512 x 512 pixels, 8 colours. + Keyboard: 88 keys in unit with CPU, numeric/cursor pad. 10 function + keys. + Storage: 2 x 1 MB (unformatted) floppies + Interfaces: RS232, Centronics parallel, IEEE488, networking, light pen, + cassette, disk expansion (5.25" or 8"), optional UHF or + additional video monitor +Operating system: CP/M + + TODO: + - nothing is known so emulation is very incomplete. + +**********************************************************************/ + + +#include "emu.h" +#include "cpu/z80/z80.h" +#include "machine/z80dma.h" +#include "machine/z80pio.h" +#include "machine/z80daisy.h" +#include "machine/ram.h" +#include "emupal.h" +#include "screen.h" +#include "speaker.h" + +#include "cpu/m6809/m6809.h" +#include "machine/input_merger.h" +#include "machine/nvram.h" +#include "machine/6522via.h" +#include "machine/mc6854.h" +#include "machine/mos6551.h" +#include "machine/tms9914.h" +#include "sound/spkrdev.h" +#include "video/upd7220.h" +#include "imagedev/cassette.h" +#include "imagedev/floppy.h" +#include "bus/ieee488/ieee488.h" +#include "bus/rs232/rs232.h" +#include "bus/centronics/ctronics.h" + +// Debugging +#define VERBOSE 1 +#include "logmacro.h" + + +class hhtiger_state : public driver_device +{ +public: + hhtiger_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "z80") + , m_rom_z80(*this, "rom_z80") + , m_ram(*this, RAM_TAG) + , m_dma(*this, "dma") + , m_pio(*this, "pio") + , m_subcpu(*this, "m6809") + , m_rom_m6809(*this, "rom_m6809") + , m_screen(*this, "screen") + , m_gdc(*this, "upd7220") + , m_palette(*this, "palette") + , m_video_ram(*this, "video_ram") + , m_nvram(*this, "nvram") + , m_via(*this, "via%u", 0) + , m_adlc(*this, "adlc") + , m_acia(*this, "acia") + , m_ieee(*this, IEEE488_TAG) + , m_tms9914(*this, "hpib") + , m_speaker(*this, "speaker") + , m_cassette(*this, "cassette") + , m_irqs(*this, "irqs") + , m_rom_mirror(true) + { } + + void hhtiger(machine_config &config); + +private: + virtual void machine_reset() override; + virtual void machine_start() override; + + uint8_t disable_rom_r(); + uint8_t read(offs_t offset); + void write(offs_t offset, uint8_t data); + 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); + + UPD7220_DISPLAY_PIXELS_MEMBER(display_pixels); + UPD7220_DRAW_TEXT_LINE_MEMBER(draw_text); + + /* handlers for logging only, can be removed when more is known */ + uint8_t pio_pa_r(); + void pio_pa_w(uint8_t data); + void pio_pb_w(uint8_t data); + DECLARE_WRITE_LINE_MEMBER(ardy_w); + DECLARE_WRITE_LINE_MEMBER(brdy_w); + + uint8_t via_0_in_a(); + void via_0_out_a(uint8_t data); + void via_0_out_b(uint8_t data); + DECLARE_WRITE_LINE_MEMBER(via_0_out_ca2); + DECLARE_WRITE_LINE_MEMBER(via_0_out_cb2); + + void via_1_out_a(uint8_t data); + void via_1_out_b(uint8_t data); + DECLARE_WRITE_LINE_MEMBER(via_1_out_ca2); + DECLARE_WRITE_LINE_MEMBER(via_1_out_cb2); + + void z80_mem(address_map &map); + void z80_io(address_map &map); + void m6809_mem(address_map &map); + void upd7220_map(address_map &map); + + required_device m_maincpu; + required_memory_region m_rom_z80; + required_device m_ram; + required_device m_dma; + required_device m_pio; + + required_device m_subcpu; + required_memory_region m_rom_m6809; + required_device m_screen; + required_device m_gdc; + required_device m_palette; + required_shared_ptr m_video_ram; + required_device m_nvram; + required_device_array m_via; + required_device m_adlc; + required_device m_acia; + required_device m_ieee; + required_device m_tms9914; + required_device m_speaker; + required_device m_cassette; + required_device m_irqs; + + bool m_rom_mirror; +}; + + +void hhtiger_state::machine_start() +{ + save_item(NAME(m_rom_mirror)); +} + + +void hhtiger_state::machine_reset() +{ + m_rom_mirror = true; +} + + +static const gfx_layout hhtiger_charlayout = +{ + 8, 8, /* 8 x 8 characters */ + 128, /* 128 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 /* every char takes 8 bytes */ +}; + +static GFXDECODE_START(gfx_hhtiger) + GFXDECODE_ENTRY("rom_m6809", 0x2000, hhtiger_charlayout, 0, 1) +GFXDECODE_END + + +UPD7220_DISPLAY_PIXELS_MEMBER(hhtiger_state::display_pixels) +{ + /* 96KB video RAM (32KB green + 32KB red + 32KB blue) */ + uint16_t const green = m_video_ram[(0x00000 + (address & 0x3fff))]; + uint16_t const red = m_video_ram[(0x04000 + (address & 0x3fff))]; + uint16_t const blue = m_video_ram[(0x08000 + (address & 0x3fff))]; + + for (int xi = 0; xi<16; xi++) + { + int const r = BIT(red, xi) ? 255 : 0; + int const g = BIT(green, xi) ? 255 : 0; + int const b = BIT(blue, xi) ? 255 : 0; + + if (bitmap.cliprect().contains(x + xi, y)) + bitmap.pix(y, x + xi) = rgb_t(r, g, b); + } +} + +UPD7220_DRAW_TEXT_LINE_MEMBER(hhtiger_state::draw_text) +{ + rgb_t const *const palette = m_palette->palette()->entry_list_raw(); + + for (int x = 0; x < pitch; x++) + { + uint8_t tile = m_video_ram[(((addr + x) * 2) & 0x1ffff) >> 1] & 0xff; + uint8_t attr = m_video_ram[(((addr + x) * 2) & 0x1ffff) >> 1] >> 8; + + for (int yi = 0; yi < lr; yi++) + { + uint8_t tile_data = m_rom_m6809->base()[0x1000 | ((tile * 8 + yi) & 0x7ff)]; + + if (cursor_on && cursor_addr == addr + x) //TODO + tile_data ^= 0xff; + + for (int xi = 0; xi < 8; xi++) + { + int pen = (tile_data >> xi) & 1 ? (attr & 0x07) : 0; + + int const res_x = x * 8 + xi; + int const res_y = y + yi; + + if (yi >= 8) + pen = 0; + + if (!m_screen->visible_area().contains(res_x, res_y)) + bitmap.pix(res_y, res_x) = palette[pen]; + } + } + } +} + + +uint8_t hhtiger_state::disable_rom_r() +{ + if (!machine().side_effects_disabled()) + m_rom_mirror = false; + + return 0xff; +} + +uint8_t hhtiger_state::read(offs_t offset) +{ + uint8_t data; + + if (m_rom_mirror) + { + data = m_rom_z80->base()[offset & 0x0fff]; + } + else + { + switch (offset & 0xf800) + { + case 0xf800: + data = m_rom_z80->base()[offset & 0x0fff]; + break; + default: + data = m_ram->pointer()[offset]; + break; + } + } + + return data; +} + +void hhtiger_state::write(offs_t offset, uint8_t data) +{ + m_ram->pointer()[offset] = data; +} + + +WRITE_LINE_MEMBER(hhtiger_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 +} + +uint8_t hhtiger_state::memory_read_byte(offs_t offset) +{ + address_space& prog_space = m_maincpu->space(AS_PROGRAM); + return prog_space.read_byte(offset); +} + +void hhtiger_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 hhtiger_state::io_read_byte(offs_t offset) +{ + address_space& io_space = m_maincpu->space(AS_IO); + return io_space.read_byte(offset); +} + +void hhtiger_state::io_write_byte(offs_t offset, uint8_t data) +{ + address_space& io_space = m_maincpu->space(AS_IO); + io_space.write_byte(offset, data); +} + + +//------------------------------------------------- +// ADDRESS_MAP( z80_mem ) +//------------------------------------------------- + +void hhtiger_state::z80_mem(address_map &map) +{ + map(0x0000, 0xffff).rw(FUNC(hhtiger_state::read), FUNC(hhtiger_state::write)); +} + +void hhtiger_state::z80_io(address_map &map) +{ + map.global_mask(0xff); + map(0x00, 0x03).rw(m_dma, FUNC(z80dma_device::read), FUNC(z80dma_device::write)); + map(0x04, 0x07).rw(m_pio, FUNC(z80pio_device::read), FUNC(z80pio_device::write)); + map(0x10, 0x17).rw(m_tms9914, FUNC(tms9914_device::read), FUNC(tms9914_device::write)); // ?? + map(0x1e, 0x1e).r(FUNC(hhtiger_state::disable_rom_r)); +} + + +//------------------------------------------------- +// ADDRESS_MAP( m6809_mem ) +//------------------------------------------------- + +void hhtiger_state::m6809_mem(address_map &map) +{ + map(0x0000, 0x07ff).ram(); + map(0xb800, 0xb9ff).ram().share("nvram"); + map(0xbfa0, 0xbfa3).rw(m_gdc, FUNC(upd7220_device::read), FUNC(upd7220_device::write)); + map(0xbfb0, 0xbfb3).rw(m_adlc, FUNC(mc6854_device::read), FUNC(mc6854_device::write)); // ?? + map(0xbfc0, 0xbfcf).m(m_via[1], FUNC(via6522_device::map)); + map(0xbfd0, 0xbfd3).rw(m_acia, FUNC(mos6551_device::read), FUNC(mos6551_device::write)); // ?? + map(0xbfe0, 0xbfef).m(m_via[0], FUNC(via6522_device::map)); + map(0xc000, 0xffff).rom().region("rom_m6809", 0); +} + + +//------------------------------------------------- +// ADDRESS_MAP( upd7220_map ) +//------------------------------------------------- + +void hhtiger_state::upd7220_map(address_map &map) +{ + map.global_mask(0x17fff); + map(0x00000, 0x17fff).ram().share("video_ram"); +} + + +static const z80_daisy_config daisy_chain_intf[] = +{ + { "dma" }, + { "pio" }, + { nullptr } +}; + + +static INPUT_PORTS_START(hhtiger) +INPUT_PORTS_END + + +uint8_t hhtiger_state::pio_pa_r() +{ + uint8_t data = 0xff; + + LOG("pio_pa_r %02X\n", data); + return data; +} + +void hhtiger_state::pio_pa_w(uint8_t data) +{ + LOG("pio_pa_w %02X\n", data); + m_via[0]->write_pa(data); +} + +void hhtiger_state::pio_pb_w(uint8_t data) +{ + LOG("pio_pb_w %02X\n", data); + m_via[0]->write_pb(data); +} + +WRITE_LINE_MEMBER(hhtiger_state::ardy_w) +{ + LOG("ardy_w %d\n", state); + m_via[0]->write_ca1(state); +} + +WRITE_LINE_MEMBER(hhtiger_state::brdy_w) +{ + LOG("brdy_w %d\n", state); + m_via[0]->write_cb1(state); +} + + +uint8_t hhtiger_state::via_0_in_a() +{ + uint8_t data = 0xff; + + LOG("via0_in_a %02X\n", data); + data = m_pio->port_a_read(); + return data; +} + +void hhtiger_state::via_0_out_a(uint8_t data) +{ + LOG("via0_out_a %02X\n", data); + m_pio->port_a_write(data); +} + +void hhtiger_state::via_0_out_b(uint8_t data) +{ + LOG("via0_out_b %02X\n", data); +} + +WRITE_LINE_MEMBER(hhtiger_state::via_0_out_ca2) +{ + LOG("via0_out_ca2 %d\n", state); + m_pio->strobe_a(state); +} + +WRITE_LINE_MEMBER(hhtiger_state::via_0_out_cb2) +{ + LOG("via0_out_cb2 %d\n", state); +} + + +void hhtiger_state::via_1_out_a(uint8_t data) +{ + LOG("via1_out_a %02X\n", data); +} + +void hhtiger_state::via_1_out_b(uint8_t data) +{ + LOG("via1_out_b %02X\n", data); +} + +WRITE_LINE_MEMBER(hhtiger_state::via_1_out_ca2) +{ + LOG("via1_out_ca2 %d\n", state); +} + +WRITE_LINE_MEMBER(hhtiger_state::via_1_out_cb2) +{ + LOG("via1_out_cb2 %d\n", state); +} + + +static void hhtiger_floppies(device_slot_interface &device) +{ + device.option_add("525dd", FLOPPY_525_DD); +} + + +void hhtiger_state::hhtiger(machine_config &config) +{ + /* main cpu z80a */ + Z80(config, m_maincpu, 16_MHz_XTAL / 4); + m_maincpu->set_addrmap(AS_PROGRAM, &hhtiger_state::z80_mem); + m_maincpu->set_addrmap(AS_IO, &hhtiger_state::z80_io); + m_maincpu->set_daisy_config(daisy_chain_intf); + + 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(hhtiger_state::busreq_w)); + m_dma->in_mreq_callback().set(FUNC(hhtiger_state::memory_read_byte)); + m_dma->out_mreq_callback().set(FUNC(hhtiger_state::memory_write_byte)); + m_dma->in_iorq_callback().set(FUNC(hhtiger_state::io_read_byte)); + m_dma->out_iorq_callback().set(FUNC(hhtiger_state::io_write_byte)); + + Z80PIO(config, m_pio, 16_MHz_XTAL / 4); + m_pio->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); + m_pio->in_pa_callback().set(FUNC(hhtiger_state::pio_pa_r)); + m_pio->out_pa_callback().set(FUNC(hhtiger_state::pio_pa_w)); + m_pio->out_ardy_callback().set(FUNC(hhtiger_state::ardy_w)); + m_pio->out_pb_callback().set(FUNC(hhtiger_state::pio_pb_w)); + m_pio->out_brdy_callback().set(FUNC(hhtiger_state::brdy_w)); + + RAM(config, m_ram).set_default_size("64K"); + + /* unknown fdc - floppy drives are housed with monitor so maybe fdc is external */ + FLOPPY_CONNECTOR(config, "0", hhtiger_floppies, "525dd", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, "1", hhtiger_floppies, "525dd", floppy_image_device::default_mfm_floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, "2", hhtiger_floppies, nullptr, floppy_image_device::default_mfm_floppy_formats).enable_sound(true); + + /* unknown sound hardware - maybe connected to square-wave timer output from via */ + SPEAKER(config, "mono").front_center(); + SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.50); + + /* io cpu 6809 */ + MC6809(config, m_subcpu, 16_MHz_XTAL / 4); + m_subcpu->set_addrmap(AS_PROGRAM, &hhtiger_state::m6809_mem); + + INPUT_MERGER_ANY_HIGH(config, m_irqs); + m_irqs->output_handler().set_inputline(m_maincpu, M6809_IRQ_LINE); + + NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); + + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_video_attributes(VIDEO_UPDATE_BEFORE_VBLANK); + m_screen->set_raw(16_MHz_XTAL, 520, 0, 320, 308, 0, 240); + m_screen->set_screen_update("upd7220", FUNC(upd7220_device::screen_update)); + + GFXDECODE(config, "gfxdecode", m_palette, gfx_hhtiger); + PALETTE(config, m_palette, palette_device::RGB_3BIT); + + UPD7220(config, m_gdc, 16_MHz_XTAL / 16); + m_gdc->set_addrmap(0, &hhtiger_state::upd7220_map); + m_gdc->set_display_pixels(FUNC(hhtiger_state::display_pixels)); + m_gdc->set_draw_text(FUNC(hhtiger_state::draw_text)); + m_gdc->set_screen(m_screen); + + MOS6522(config, m_via[0], 16_MHz_XTAL / 16); + m_via[0]->readpa_handler().set(FUNC(hhtiger_state::via_0_in_a)); + m_via[0]->writepa_handler().set(FUNC(hhtiger_state::via_0_out_a)); + m_via[0]->writepb_handler().set(FUNC(hhtiger_state::via_0_out_b)); + m_via[0]->ca2_handler().set(FUNC(hhtiger_state::via_0_out_ca2)); + m_via[0]->cb2_handler().set(FUNC(hhtiger_state::via_0_out_cb2)); + m_via[0]->irq_handler().set(m_irqs, FUNC(input_merger_device::in_w<0>)); + + MOS6522(config, m_via[1], 16_MHz_XTAL / 16); + m_via[1]->irq_handler().set(m_irqs, FUNC(input_merger_device::in_w<1>)); + m_via[1]->writepa_handler().set(FUNC(hhtiger_state::via_1_out_a)); + m_via[1]->writepb_handler().set(FUNC(hhtiger_state::via_1_out_b)); + m_via[1]->ca2_handler().set(FUNC(hhtiger_state::via_1_out_ca2)); + m_via[1]->cb2_handler().set(FUNC(hhtiger_state::via_1_out_cb2)); + + centronics_device ¢ronics(CENTRONICS(config, "centronics", centronics_devices, "printer")); + centronics.ack_handler().set(m_via[1], FUNC(via6522_device::write_ca1)); + output_latch_device &latch(OUTPUT_LATCH(config, "cent_data_out")); + centronics.set_output_latch(latch); + + MC6854(config, m_adlc); + m_adlc->out_irq_cb().set("irqs", FUNC(input_merger_device::in_w<2>)); + + CASSETTE(config, m_cassette); + m_cassette->set_default_state(CASSETTE_STOPPED); + m_cassette->add_route(ALL_OUTPUTS, "mono", 0.05); + + MOS6551(config, m_acia, 0); + m_acia->set_xtal(1.8432_MHz_XTAL); + m_acia->irq_handler().set("irqs", FUNC(input_merger_device::in_w<3>)); + 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->dtr_handler().set("rs232", FUNC(rs232_port_device::write_dtr)); + + rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, nullptr)); + rs232.rxd_handler().set(m_acia, FUNC(mos6551_device::write_rxd)); + rs232.dcd_handler().set(m_acia, FUNC(mos6551_device::write_dcd)); + rs232.dsr_handler().set(m_acia, FUNC(mos6551_device::write_dsr)); + rs232.cts_handler().set(m_acia, FUNC(mos6551_device::write_cts)); + + TMS9914(config, m_tms9914, 16_MHz_XTAL / 4); + m_tms9914->int_write_cb().set("irqs", FUNC(input_merger_device::in_w<4>)); + m_tms9914->dio_read_cb().set(IEEE488_TAG, FUNC(ieee488_device::dio_r)); + m_tms9914->dio_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_dio_w)); + m_tms9914->eoi_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_eoi_w)); + m_tms9914->dav_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_dav_w)); + m_tms9914->nrfd_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_nrfd_w)); + m_tms9914->ndac_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_ndac_w)); + m_tms9914->ifc_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_ifc_w)); + m_tms9914->srq_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_srq_w)); + m_tms9914->atn_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_atn_w)); + m_tms9914->ren_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_ren_w)); + + IEEE488(config, m_ieee); + m_ieee->eoi_callback().set(m_tms9914, FUNC(tms9914_device::eoi_w)); + m_ieee->dav_callback().set(m_tms9914, FUNC(tms9914_device::dav_w)); + m_ieee->nrfd_callback().set(m_tms9914, FUNC(tms9914_device::nrfd_w)); + m_ieee->ndac_callback().set(m_tms9914, FUNC(tms9914_device::ndac_w)); + m_ieee->ifc_callback().set(m_tms9914, FUNC(tms9914_device::ifc_w)); + m_ieee->srq_callback().set(m_tms9914, FUNC(tms9914_device::srq_w)); + m_ieee->atn_callback().set(m_tms9914, FUNC(tms9914_device::atn_w)); + m_ieee->ren_callback().set(m_tms9914, FUNC(tms9914_device::ren_w)); + IEEE488_SLOT(config, "ieee_dev", 0, cbm_ieee488_devices, nullptr); +} + + +ROM_START(hhtiger) + ROM_REGION(0x1000, "rom_z80", 0) + ROM_DEFAULT_BIOS("rel13") + ROM_SYSTEM_BIOS(0, "rel12", "Rel1.2") + ROMX_LOAD("rel1.2-0ea0.ic79", 0x0000, 0x1000, CRC(2f81e48c) SHA1(a4a1d7fde9f92abd6d8f8a1c24e35d713a5cbcb2), ROM_BIOS(0)) + ROM_SYSTEM_BIOS(1, "rel13", "Rel1.3") + ROMX_LOAD("rel1.3-0ea0.ic79", 0x0000, 0x1000, CRC(2f81e48c) SHA1(a4a1d7fde9f92abd6d8f8a1c24e35d713a5cbcb2), ROM_BIOS(1)) + /* Rel1.4 also known to exist */ + ROM_REGION(0x4000, "rom_m6809", 0) + ROMX_LOAD("rel1.2-cfd3.ic16", 0x0000, 0x2000, CRC(1ae4d2e0) SHA1(c379c5f1be24835ae4b4bd7bed35800faa3a9af6), ROM_BIOS(0)) + ROMX_LOAD("rel1.2-8fd2.ic15", 0x2000, 0x2000, CRC(0ef23968) SHA1(d46ce3b965ce51d0c90a10121661199b51e33d8b), ROM_BIOS(0)) + ROMX_LOAD("rel1.3-789a.ic16", 0x0000, 0x2000, CRC(7fa6fd33) SHA1(0b2768c170ca7077ef5164bfa13d9bf033528115), ROM_BIOS(1)) + ROMX_LOAD("rel1.3-77c1.ic15", 0x2000, 0x2000, CRC(dd2f15d5) SHA1(139a2b97cb8c27a50e3bfa3f42a9572203e453e0), ROM_BIOS(1)) +ROM_END + + +/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ +COMP( 1983, hhtiger, 0, 0, hhtiger, hhtiger, hhtiger_state, empty_init, "H/H Microcomputers", "H/H Tiger", MACHINE_IS_SKELETON ) + diff --git a/src/mame/tangerine/microtan.cpp b/src/mame/tangerine/microtan.cpp new file mode 100644 index 00000000000..f631a519921 --- /dev/null +++ b/src/mame/tangerine/microtan.cpp @@ -0,0 +1,484 @@ +// license:GPL-2.0+ +// copyright-holders:Juergen Buchmueller,Nigel Barnes +/****************************************************************************** + * Microtan 65 + * + * system driver + * + * Juergen Buchmueller , Jul 2000 + * + * Thanks go to Geoff Macdonald + * for his site http://www.geoff.org.uk/microtan/index.htm + * and to Fabrice Frances + * for his site http://oric.free.fr/microtan.html + * + * Microtan65 memory map + * + * range short description + * 0000-01ff SYSRAM system ram + * 0000-003f variables + * 0040-00ff basic + * 0100-01ff stack + * 0200-03ff VIDEORAM display + * 0400-afff RAM main memory + * bc00-bc01 AY8912-0 sound chip #0 + * bc02-bc03 AY8912-1 sound chip #1 + * bc04 SPACEINV space invasion sound (?) + * bfc0-bfcf VIA6522-0 VIA 6522 #0 + * bfd0-bfd3 SIO serial i/o + * bfe0-bfef VIA6522-1 VIA 6522 #1 + * bff0 GFX_KBD R: chunky graphics on W: reset KBD interrupt + * bff1 NMI W: start delayed NMI + * bff2 HEX W: hex. keypad column + * bff3 KBD_GFX R: ASCII KBD / hex. keypad row W: chunky graphics off + * c000-e7ff BASIC BASIC Interpreter ROM + * f000-f7ff XBUG XBUG ROM + * f800-ffff TANBUG TANBUG ROM + * + * Tanbug commands: + * B Set breakpoint + * C copy (move) memory block + * G Go + * L Hex dump + * M Modify memory + * N Exit single-step mode + * O Hex calculator + * P Step once + * R Register examine/modify + * S Enter single-step mode + * BAS Start BASIC + * WAR Re-enter BASIC (warm start) + * + * The keyboard is essentially an ordinary ASCII keyboard, with 71 keys, 8 + * TTL chips and an undumped 2716 eprom labelled MON V1. We currently use a + * generic keyboard because of the lack of a schematic. Unemulated keys are + * 'SHIFT LOCK' and 'REPT'. Since all commands must be uppercase, capslock + * is defaulted to on. + * + *****************************************************************************/ + +#include "emu.h" +#include "microtan.h" +#include "emupal.h" +#include "screen.h" +#include "softlist_dev.h" + + +void microtan_state::mt65_map(address_map &map) +{ + map(0x0000, 0xffff).rw(m_tanbus, FUNC(tanbus_device::read), FUNC(tanbus_device::write)); + map(0x0000, 0x01ff).ram(); + map(0x0200, 0x03ff).ram().w(FUNC(microtan_state::videoram_w)).share(m_videoram); + map(0xbff0, 0xbfff).rw(FUNC(microtan_state::bffx_r), FUNC(microtan_state::bffx_w)); + map(0xf800, 0xffff).rom(); +} + +void microtan_state::spinv_map(address_map &map) +{ + map.unmap_value_high(); + map(0x0000, 0x01ff).ram(); + map(0x0200, 0x03ff).ram().w(FUNC(microtan_state::videoram_w)).share(m_videoram); + map(0xbc04, 0xbc04).rw(FUNC(microtan_state::sound_r), FUNC(microtan_state::sound_w)); + map(0xbff0, 0xbfff).rw(FUNC(microtan_state::bffx_r), FUNC(microtan_state::bffx_w)); + map(0xe800, 0xefff).rom().mirror(0x1000); +} + +void mt6809_state::mt6809_map(address_map &map) +{ + map(0x0000, 0xffff).rw(m_tanbus, FUNC(tanbus_device::read), FUNC(tanbus_device::write)); + map(0xdc00, 0xdfff).ram(); + map(0xdfd8, 0xdfd8).r(FUNC(mt6809_state::keyboard_r)); + map(0xf800, 0xffff).rom(); +} + + +INPUT_CHANGED_MEMBER(microtan_state::trigger_reset) +{ + m_maincpu->set_input_line(INPUT_LINE_RESET, newval ? ASSERT_LINE : CLEAR_LINE); + + if (newval) + { + machine().schedule_soft_reset(); + } +} + +static INPUT_PORTS_START( microtan ) + PORT_START("CONFIG") + PORT_CONFNAME(0x03, 0x00, "Input") + PORT_CONFSETTING(0x00, "ASCII Keyboard") + PORT_CONFSETTING(0x01, "Hex Keypad") + + PORT_START("KBD0") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("ESC") PORT_CODE(KEYCODE_ESC) PORT_CHAR(27) + 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(39) + + PORT_START("KBD1") + 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("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR('~') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(": *") PORT_CODE(KEYCODE_MINUS) PORT_CHAR(':') PORT_CHAR('*') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("- =") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('-') PORT_CHAR('=') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("NEW PAGE") PORT_CODE(KEYCODE_TILDE) PORT_CHAR(12) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("RUB OUT") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(UTF8_UP) PORT_CODE(KEYCODE_TAB) PORT_CHAR('^') PORT_CHAR('_') + + PORT_START("KBD2") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_CHAR('q') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_CHAR('w') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_CHAR('e') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_CHAR('r') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_CHAR('t') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_CHAR('y') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_CHAR('u') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_CHAR('i') + + PORT_START("KBD3") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_CHAR('o') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CHAR('p') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("[ {") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("] }") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR(']') PORT_CHAR('}') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("BREAK") PORT_CODE(KEYCODE_DEL) PORT_CHAR(3) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("ALFA LOCK") PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE + + PORT_START("KBD4") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_CHAR('a') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_CHAR('s') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CHAR('d') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_CHAR('f') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_CHAR('g') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_CHAR('h') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_CHAR('j') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_CHAR('k') + + PORT_START("KBD5") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_CHAR('l') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("; +") PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('+') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("@") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('@') PORT_CHAR('`') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("\\ |") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('\\') PORT_CHAR('|') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("SHIFT (L)") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_CHAR('z') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CHAR('x') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_CHAR('c') + + PORT_START("KBD6") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_CHAR('v') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_CHAR('b') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_CHAR('n') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_CHAR('m') + 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_STOP) PORT_CHAR('.') PORT_CHAR('>') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("/ ?") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("SHIFT (R)") PORT_CODE(KEYCODE_RSHIFT) + + PORT_START("KBD7") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("LINE FEED") PORT_CHAR(10) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(32) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("- (KP)") PORT_CODE(KEYCODE_MINUS_PAD) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(", (KP)") PORT_CODE(KEYCODE_PLUS_PAD) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("ENTER (KP)") PORT_CODE(KEYCODE_ENTER_PAD) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME(". (KP)") PORT_CODE(KEYCODE_DEL_PAD) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("0 (KP)") PORT_CODE(KEYCODE_0_PAD) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("1 (KP)") PORT_CODE(KEYCODE_1_PAD) + + PORT_START("KBD8") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("2 (KP)") PORT_CODE(KEYCODE_2_PAD) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("3 (KP)") PORT_CODE(KEYCODE_3_PAD) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("4 (KP)") PORT_CODE(KEYCODE_4_PAD) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("5 (KP)") PORT_CODE(KEYCODE_5_PAD) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("6 (KP)") PORT_CODE(KEYCODE_6_PAD) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("7 (KP)") PORT_CODE(KEYCODE_7_PAD) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("8 (KP)") PORT_CODE(KEYCODE_8_PAD) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("9 (KP)") PORT_CODE(KEYCODE_9_PAD) + + PORT_START("KPAD0") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("0") PORT_CODE(KEYCODE_0_PAD) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("4") PORT_CODE(KEYCODE_4_PAD) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("8 P") PORT_CODE(KEYCODE_8_PAD) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("C M") PORT_CODE(KEYCODE_C) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT) + PORT_BIT(0xe0, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("KPAD1") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("1") PORT_CODE(KEYCODE_1_PAD) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("5 O") PORT_CODE(KEYCODE_5_PAD) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("9 ESC") PORT_CODE(KEYCODE_9_PAD) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("D G") PORT_CODE(KEYCODE_D) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("LF DEL") PORT_CODE(KEYCODE_DEL_PAD) + PORT_BIT(0xe0, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("KPAD2") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("2") PORT_CODE(KEYCODE_2_PAD) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("6 C") PORT_CODE(KEYCODE_6_PAD) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("A") PORT_CODE(KEYCODE_A) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("E S") PORT_CODE(KEYCODE_E) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("CR SP") PORT_CODE(KEYCODE_ENTER_PAD) + PORT_BIT(0xe0, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("KPAD3") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("3 '") PORT_CODE(KEYCODE_3_PAD) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("7 R") PORT_CODE(KEYCODE_7_PAD) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("B L") PORT_CODE(KEYCODE_B) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("F N") PORT_CODE(KEYCODE_F) + PORT_BIT(0xf0, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("BRK") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("RESET") PORT_CODE(KEYCODE_F12) PORT_CHAR(UCHAR_MAMEKEY(F12)) PORT_CHANGED_MEMBER(DEVICE_SELF, microtan_state, trigger_reset, 0) +INPUT_PORTS_END + +static INPUT_PORTS_START( spinveti ) + PORT_START("CONFIG") + PORT_CONFNAME(0x03, 0x02, "Input") + PORT_CONFSETTING(0x02, "ETI Keypad") + PORT_CONFNAME(0x60, 0x20, "Difficulty") + PORT_CONFSETTING(0x00, "Easy") + PORT_CONFSETTING(0x20, "Normal") + PORT_CONFSETTING(0x40, "Hard") + PORT_CONFSETTING(0x60, "Hardest") + + PORT_START("KEYPAD") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Play") PORT_CODE(KEYCODE_ENTER) + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Right") PORT_CODE(KEYCODE_RIGHT) + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Left") PORT_CODE(KEYCODE_LEFT) + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Fire") PORT_CODE(KEYCODE_LCONTROL) + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Hold") PORT_CODE(KEYCODE_H) + + PORT_START("BRK") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Reset") PORT_CODE(KEYCODE_R) PORT_CHANGED_MEMBER(DEVICE_SELF, microtan_state, trigger_reset, 0) +INPUT_PORTS_END + +static const gfx_layout char_layout = +{ + 8, 16, /* 8 x 16 graphics */ + 256, /* 256 codes */ + 1, /* 1 bit per pixel */ + { 0 }, /* no bitplanes */ + { 0, 1, 2, 3, 4, 5, 6, 7 }, + { 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 /* code takes 8 times 16 bits */ +}; + +static GFXDECODE_START( gfx_microtan ) + GFXDECODE_ENTRY( "gfx1", 0, char_layout, 0, 1 ) + GFXDECODE_ENTRY( "gfx2", 0, char_layout, 0, 1 ) +GFXDECODE_END + + +void microtan_state::mt65(machine_config &config) +{ + /* Microtan 65 CPU board */ + M6502(config, m_maincpu, 6_MHz_XTAL / 8); + m_maincpu->set_addrmap(AS_PROGRAM, µtan_state::mt65_map); + + TIMER(config, "kbd_timer").configure_periodic(FUNC(microtan_state::kbd_scan), attotime::from_hz(45)); + + INPUT_MERGER_ANY_HIGH(config, m_irq_line).output_handler().set_inputline(m_maincpu, M6502_IRQ_LINE); + + /* video hardware - include overscan */ + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); + screen.set_raw(6_MHz_XTAL, 384, 0, 32*8, 312, 0, 16*16); + screen.set_screen_update(FUNC(microtan_state::screen_update)); + screen.set_palette("palette"); + + GFXDECODE(config, m_gfxdecode, "palette", gfx_microtan); + + PALETTE(config, "palette", palette_device::MONOCHROME); + + /* Microtan Motherboard */ + TANBUS(config, m_tanbus, 6_MHz_XTAL); + m_tanbus->out_irq_callback().set(m_irq_line, FUNC(input_merger_device::in_w)); + m_tanbus->out_so_callback().set_inputline(m_maincpu, M6502_SET_OVERFLOW); + m_tanbus->out_nmi_callback().set_inputline(m_maincpu, M6502_NMI_LINE); + m_tanbus->out_pgm_callback().set(FUNC(microtan_state::pgm_chargen_w)); + + TANBUS_SLOT(config, "tanbus:tanex", -1, tanex_devices, "tanex"); + TANBUS_SLOT(config, "tanbus:0", 0, tanbus_devices, "tanram"); + TANBUS_SLOT(config, "tanbus:1", 1, tanbus_devices, nullptr); + TANBUS_SLOT(config, "tanbus:2", 2, tanbus_devices, "bullsnd"); + TANBUS_SLOT(config, "tanbus:3", 3, tanbus_devices, nullptr); + TANBUS_SLOT(config, "tanbus:4", 4, tanbus_devices, nullptr); + TANBUS_SLOT(config, "tanbus:5", 5, tanbus_devices, nullptr); + TANBUS_SLOT(config, "tanbus:6", 6, tanbus_devices, nullptr); + TANBUS_SLOT(config, "tanbus:7", 7, tanbus_devices, nullptr); + TANBUS_SLOT(config, "tanbus:exp", 8, tanbus_devices, nullptr); + + /* snapshot/quickload */ + snapshot_image_device &snapshot(SNAPSHOT(config, "snapshot", "dmp,m65")); + snapshot.set_load_callback(FUNC(microtan_state::snapshot_cb)); + snapshot.set_interface("mt65_snap"); + QUICKLOAD(config, "quickload", "hex").set_load_callback(FUNC(microtan_state::quickload_cb)); + + /* software lists */ + SOFTWARE_LIST(config, "rom_list").set_original("mt65_rom"); + SOFTWARE_LIST(config, "cass_list").set_original("mt65_cass"); + //SOFTWARE_LIST(config, "flop_list").set_original("mt65_flop").set_filter("6502"); + SOFTWARE_LIST(config, "snap_list").set_original("mt65_snap"); +} + +void microtan_state::micron(machine_config &config) +{ + mt65(config); + + /* Microtan Mini-Motherboard connects MT65 CPU card and TANEX, no extra slots */ + config.device_remove("tanbus:0"); + config.device_remove("tanbus:1"); + config.device_remove("tanbus:2"); + config.device_remove("tanbus:3"); + config.device_remove("tanbus:4"); + config.device_remove("tanbus:5"); + config.device_remove("tanbus:6"); + config.device_remove("tanbus:7"); + config.device_remove("tanbus:exp"); +} + +void microtan_state::spinveti(machine_config &config) +{ + /* basic machine hardware */ + M6502(config, m_maincpu, 6_MHz_XTAL / 8); + m_maincpu->set_addrmap(AS_PROGRAM, µtan_state::spinv_map); + + INPUT_MERGER_ANY_HIGH(config, m_irq_line).output_handler().set_inputline(m_maincpu, M6502_IRQ_LINE); + + /* video hardware - include overscan */ + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); + screen.set_raw(6_MHz_XTAL, 384, 0, 32*8, 312, 0, 16*16); + screen.set_screen_update(FUNC(microtan_state::screen_update)); + screen.set_palette("palette"); + + GFXDECODE(config, m_gfxdecode, "palette", gfx_microtan); + + PALETTE(config, "palette", palette_device::MONOCHROME); + + /* TODO: Sound hardware */ +} + + +static DEVICE_INPUT_DEFAULTS_START(ra32k_def_ram0000) + /* 32K RAM configured 0x0000-0x7fff */ + DEVICE_INPUT_DEFAULTS("SW1", 0xff, 0xff) // all blocks enabled + DEVICE_INPUT_DEFAULTS("SW2", 0xff, 0xff) // all blocks enabled + DEVICE_INPUT_DEFAULTS("SW3", 0x0f, 0x0f) // start address $0000 + DEVICE_INPUT_DEFAULTS("LNK1", 0x03, 0x01) +DEVICE_INPUT_DEFAULTS_END + +static DEVICE_INPUT_DEFAULTS_START(ra32k_def_ram8000) + /* 32K RAM configured 0x8000-0xffff */ + DEVICE_INPUT_DEFAULTS("SW1", 0xff, 0x7f) // disable block $F800 + DEVICE_INPUT_DEFAULTS("SW2", 0xff, 0xff) // all blocks enabled + DEVICE_INPUT_DEFAULTS("SW3", 0x0f, 0x0d) // start address $8000 + DEVICE_INPUT_DEFAULTS("LNK1", 0x03, 0x00) +DEVICE_INPUT_DEFAULTS_END + +static DEVICE_INPUT_DEFAULTS_START(ra32k_def_rom2000) + /* 8K EPROM configured 0x2000-0x3fff */ + DEVICE_INPUT_DEFAULTS("SW1", 0xff, 0xff) // all blocks enabled + DEVICE_INPUT_DEFAULTS("SW2", 0xff, 0xff) // all blocks enabled + DEVICE_INPUT_DEFAULTS("SW3", 0x0f, 0x04) // start address $2000 + DEVICE_INPUT_DEFAULTS("LNK1", 0x03, 0x02) +DEVICE_INPUT_DEFAULTS_END + +void mt6809_state::mt6809(machine_config &config) +{ + /* Ralph Allen 6809 CPU Board */ + MC6809(config, m_maincpu, 6_MHz_XTAL / 4); // TODO: verify divider + m_maincpu->set_addrmap(AS_PROGRAM, &mt6809_state::mt6809_map); + + TIMER(config, "kbd_timer").configure_periodic(FUNC(microtan_state::kbd_scan), attotime::from_hz(45)); + + INPUT_MERGER_ANY_HIGH(config, m_irq_line).output_handler().set_inputline(m_maincpu, M6809_IRQ_LINE); + + /* Microtan Motherboard */ + TANBUS(config, m_tanbus, 6_MHz_XTAL); + m_tanbus->out_irq_callback().set(m_irq_line, FUNC(input_merger_device::in_w)); + m_tanbus->out_nmi_callback().set_inputline(m_maincpu, M6809_FIRQ_LINE); + + TANBUS_SLOT(config, "tanbus:tanex", -1, tanex_devices, nullptr); + TANBUS_SLOT(config, "tanbus:0", 0, tanbus6809_devices, "ra32k").set_option_device_input_defaults("ra32k", DEVICE_INPUT_DEFAULTS_NAME(ra32k_def_ram0000)); + TANBUS_SLOT(config, "tanbus:1", 1, tanbus6809_devices, "ra32k").set_option_device_input_defaults("ra32k", DEVICE_INPUT_DEFAULTS_NAME(ra32k_def_ram8000)); + TANBUS_SLOT(config, "tanbus:2", 2, tanbus6809_devices, "ravdu"); + TANBUS_SLOT(config, "tanbus:3", 3, tanbus6809_devices, "radisc"); + TANBUS_SLOT(config, "tanbus:4", 4, tanbus6809_devices, nullptr); + TANBUS_SLOT(config, "tanbus:5", 5, tanbus6809_devices, nullptr); + TANBUS_SLOT(config, "tanbus:6", 6, tanbus6809_devices, nullptr); + TANBUS_SLOT(config, "tanbus:7", 7, tanbus6809_devices, "ra32k").set_option_device_input_defaults("ra32k", DEVICE_INPUT_DEFAULTS_NAME(ra32k_def_rom2000)); + TANBUS_SLOT(config, "tanbus:exp", 8, tanbus6809_devices, nullptr); + + /* software lists */ + //SOFTWARE_LIST(config, "flop_list").set_original("mt65_flop").set_filter("6809"); +} + + +ROM_START( mt65 ) + ROM_REGION(0x10000, "maincpu", 0) + ROM_DEFAULT_BIOS("tanbug23") + /* Microtan 65 (MT0016 Iss 1) */ + ROM_SYSTEM_BIOS(0, "tanbug23", "TANBUG V2.3") + ROMX_LOAD("tanbug23.k3", 0xf800, 0x0800, CRC(7f29845d) SHA1(de277e942eefa11a9a6defe3d7d03071d5100b68), ROM_BIOS(0)) + ROM_SYSTEM_BIOS(1, "tanbug23p", "TANBUG V2.3 (patched)") + ROMX_LOAD("tanbug_2.rom", 0xf800, 0x0400, CRC(7e215313) SHA1(c8fb3d33ce2beaf624dc75ec57d34c216b086274), ROM_BIOS(1)) + ROMX_LOAD("tanbug.rom", 0xfc00, 0x0400, CRC(c8221d9e) SHA1(c7fe4c174523aaaab30be7a8c9baf2bc08b33968), ROM_BIOS(1)) + ROM_SYSTEM_BIOS(2, "tanbug31", "TANBUG V3.1 (TANDOS)") + ROMX_LOAD("tanbug31.k3", 0xf800, 0x0800, CRC(5943e427) SHA1(55fe645363cd5f2015a537be6f7a00de33d1bea5), ROM_BIOS(2)) + ROM_SYSTEM_BIOS(3, "tanbug3b", "TANBUG V.3B (MPVDU)") + ROMX_LOAD("tanbug3b.k3", 0xf800, 0x0800, CRC(5b49f861) SHA1(b37cddf97b6324ab0647479b5b013a9b3d47ddda), ROM_BIOS(3)) + ROM_SYSTEM_BIOS(4, "tugbug11", "TUGBUG V1.1 (VID8082)") + ROMX_LOAD("tugbug11.k3", 0xf800, 0x0800, CRC(23b02439) SHA1(9e56fbd6c07b1dc5c10e7b574a5ea26405781a3d), ROM_BIOS(4)) + + ROM_REGION(0x1000, "gfx1", 0) + ROM_LOAD("charset.rom", 0x0000, 0x0800, CRC(3b3c5360) SHA1(a3a2f74149107f8b8f35b15069c71f3aa843d12f)) + ROM_RELOAD(0x0800, 0x0800) + + ROM_REGION(0x1000, "gfx2", ROMREGION_ERASEFF) + // initialized in init_gfx2 +ROM_END + +ROM_START( micron ) + ROM_REGION(0x10000, "maincpu", 0) + ROM_DEFAULT_BIOS("tanbug1") + /* MT65 (Iss 0) */ + ROM_SYSTEM_BIOS(0, "tanbug1", "TANBUG V1") + ROMX_LOAD("tanbug1.g2", 0xf800, 0x0400, CRC(6f45aaca) SHA1(c1a020d86830ee475ee75c847e98f7a02d467659), ROM_BIOS(0) | ROM_NIBBLE | ROM_SHIFT_NIBBLE_LO) + ROM_RELOAD(0xfc00, 0x0400) + ROMX_LOAD("tanbug1.h2", 0xf800, 0x0400, CRC(1ccd6b8f) SHA1(49784749599255458ba5513d8c2fc58c4df39515), ROM_BIOS(0) | ROM_NIBBLE | ROM_SHIFT_NIBBLE_HI) + ROM_RELOAD(0xfc00, 0x0400) + + ROM_REGION(0x1000, "gfx1", 0) + ROM_LOAD("charset.rom", 0x0000, 0x0800, CRC(3b3c5360) SHA1(a3a2f74149107f8b8f35b15069c71f3aa843d12f)) + ROM_RELOAD(0x0800, 0x0800) + + ROM_REGION(0x1000, "gfx2", ROMREGION_ERASEFF) + // initialized in init_gfx2 +ROM_END + +ROM_START( spinveti ) + ROM_REGION(0x10000, "maincpu", 0) + ROM_LOAD("spaceinv.ic20", 0xe800, 0x0800, CRC(3e235077) SHA1(ae7d2788125d01a3c5d57ab0d992bd708abd6ade)) + + ROM_REGION(0x1000, "gfx1", 0) + ROM_LOAD("charset.rom", 0x0000, 0x0800, CRC(3b3c5360) SHA1(a3a2f74149107f8b8f35b15069c71f3aa843d12f)) + ROM_RELOAD(0x0800, 0x0800) + + ROM_REGION(0x1000, "gfx2", ROMREGION_ERASEFF) + // initialized in init_gfx2 +ROM_END + +ROM_START( mt6809 ) + /* 6809 CPU Card (Ralph Allen Engineering) */ + ROM_REGION(0x10000, "maincpu", 0) + ROM_SYSTEM_BIOS(0, "ralbug14", "RALBUG V1.4") + ROMX_LOAD("ralbug14.rom", 0xf800, 0x0800, CRC(8bbc87d8) SHA1(3d53a6ffd4a8d7c8edf4f2e23946011ed29146ce), ROM_BIOS(0)) +ROM_END + + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1979, mt65, 0, 0, mt65, microtan, microtan_state, init_microtan, "Tangerine", "Microtan 65", MACHINE_NO_SOUND_HW ) +COMP( 1980, micron, mt65, 0, micron, microtan, microtan_state, init_microtan, "Tangerine", "Micron", MACHINE_NO_SOUND_HW ) +COMP( 1980, spinveti, 0, 0, spinveti, spinveti, microtan_state, init_gfx2, "Tangerine/ETI", "Space Invasion (ETI)", MACHINE_NO_SOUND ) +COMP( 1984, mt6809, mt65, 0, mt6809, microtan, mt6809_state, empty_init, "Tangerine", "Microtan 6809 System", MACHINE_NO_SOUND_HW | MACHINE_NOT_WORKING ) diff --git a/src/mame/tangerine/microtan.h b/src/mame/tangerine/microtan.h new file mode 100644 index 00000000000..90c1ebd2928 --- /dev/null +++ b/src/mame/tangerine/microtan.h @@ -0,0 +1,136 @@ +// license:GPL-2.0+ +// copyright-holders:Juergen Buchmueller +/****************************************************************************** + * Microtan 65 + * + * variables and function prototypes + * + * Juergen Buchmueller , Jul 2000 + * + * Thanks go to Geoff Macdonald + * for his site http://www.geoff.org.uk/microtan/index.htm + * and to Fabrice Frances + * for his site http://oric.free.fr/microtan.html + * + ******************************************************************************/ + +#ifndef MAME_INCLUDES_MICROTAN_H +#define MAME_INCLUDES_MICROTAN_H + +#pragma once + +#include "cpu/m6502/m6502.h" +#include "cpu/m6809/m6809.h" +#include "machine/input_merger.h" +#include "machine/timer.h" +#include "bus/tanbus/tanbus.h" +#include "imagedev/snapquik.h" +#include "tilemap.h" + +class microtan_state : public driver_device +{ +public: + microtan_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_irq_line(*this, "irq_line") + , m_config(*this, "CONFIG") + , m_io_keyboard(*this, "KBD%u", 0) + , m_io_keypad(*this, "KPAD%u", 0) + , m_keypad(*this, "KEYPAD") + , m_tanbus(*this, "tanbus") + , m_videoram(*this, "videoram") + , m_gfxdecode(*this, "gfxdecode") + , m_gfx1(*this, "gfx1") + , m_led(*this, "led1") + { } + + void mt65(machine_config &config); + void micron(machine_config &config); + void spinveti(machine_config &config); + + void init_gfx2(); + void init_microtan(); + + TIMER_DEVICE_CALLBACK_MEMBER(kbd_scan); + uint8_t bffx_r(offs_t offset); + void bffx_w(offs_t offset, uint8_t data); + DECLARE_INPUT_CHANGED_MEMBER(trigger_reset); + +protected: + enum { IRQ_KBD, IRQ_TANBUS }; + + virtual void machine_start() override; + virtual void machine_reset() override; + virtual void video_start() override; + + required_device m_maincpu; + required_device m_irq_line; + required_ioport m_config; + optional_ioport_array<9> m_io_keyboard; + optional_ioport_array<4> m_io_keypad; + optional_ioport m_keypad; + optional_device m_tanbus; + + uint8_t m_keypad_column = 0; + uint8_t m_keyboard_ascii = 0; + emu_timer *m_pulse_nmi_timer = nullptr; + uint8_t m_keyrows[10]{}; + int m_lastrow = 0; + int m_mask = 0; + int m_key = 0; + int m_repeat = 0; + int m_repeater = 0; + + virtual void store_key(int key); + +private: + optional_shared_ptr m_videoram; + optional_device m_gfxdecode; + optional_memory_region m_gfx1; + output_finder<> m_led; + + uint8_t m_chunky_graphics = 0; + std::unique_ptr m_chunky_buffer; + tilemap_t *m_bg_tilemap = nullptr; + + uint8_t sound_r(); + void sound_w(uint8_t data); + void videoram_w(offs_t offset, uint8_t data); + TILE_GET_INFO_MEMBER(get_bg_tile_info); + void pgm_chargen_w(offs_t offset, uint8_t data); + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + TIMER_CALLBACK_MEMBER(pulse_nmi); + + image_verify_result verify_snapshot(uint8_t *data, int size); + image_init_result parse_intel_hex(uint8_t *snapshot_buff, char *src); + image_init_result parse_zillion_hex(uint8_t *snapshot_buff, char *src); + void set_cpu_regs(const uint8_t *snapshot_buff, int base); + void snapshot_copy(uint8_t *snapshot_buff, int snapshot_size); + DECLARE_SNAPSHOT_LOAD_MEMBER(snapshot_cb); + DECLARE_QUICKLOAD_LOAD_MEMBER(quickload_cb); + + void mt65_map(address_map &map); + void spinv_map(address_map &map); +}; + + +class mt6809_state : public microtan_state +{ +public: + using microtan_state::microtan_state; + + void mt6809(machine_config &config); + +protected: + virtual void video_start() override; + + virtual void store_key(int key) override; + +private: + uint8_t keyboard_r(); + + void mt6809_map(address_map &map); +}; + +#endif // MAME_INCLUDES_MICROTAN_H diff --git a/src/mame/tangerine/microtan_m.cpp b/src/mame/tangerine/microtan_m.cpp new file mode 100644 index 00000000000..dca952e483a --- /dev/null +++ b/src/mame/tangerine/microtan_m.cpp @@ -0,0 +1,712 @@ +// license:GPL-2.0+ +// copyright-holders:Juergen Buchmueller +/****************************************************************************** + * Microtan 65 + * + * machine driver + * + * Juergen Buchmueller , Jul 2000 + * + * Thanks go to Geoff Macdonald + * for his site http://www.geoff.org.uk/microtan/index.htm + * and to Fabrice Frances + * for his site http://oric.free.fr/microtan.html + * + *****************************************************************************/ + +#include "emu.h" +#include "microtan.h" + +//#define VERBOSE 1 +#include "logmacro.h" + + +static const char keyboard[8][9][8] = { + { /* normal */ + { 27,'1','2','3','4','5','6','7'}, + {'8','9','0',':','-', 12,127,'^'}, + {'q','w','e','r','t','y','u','i'}, + {'o','p','[',']', 13, 3, 0, 0}, + {'a','s','d','f','g','h','j','k'}, + {'l',';','@', 92, 0,'z','x','c'}, + {'v','b','n','m',',','.','/', 0}, + { 10,' ','-',',', 13,'.','0','1'}, + {'2','3','4','5','6','7','8','9'}, + }, + { /* Shift */ + { 27,'!','"','#','$','%','&', 39}, + {'(',')','~','*','=', 12,127,'_'}, + {'Q','W','E','R','T','Y','U','I'}, + {'O','P','{','}', 13, 3, 0, 0}, + {'A','S','D','F','G','H','J','K'}, + {'L','+','`','|', 0,'Z','X','C'}, + {'V','B','N','M','<','>','?', 0}, + { 10,' ','-',',', 13,'.','0','1'}, + {'2','3','4','5','6','7','8','9'}, + }, + { /* Control */ + { 27,'1','2','3','4','5','6','7'}, + {'8','9','0',':','-','`',127, 30}, + { 17, 23, 5, 18, 20, 25, 21, 9}, + { 15, 16, 27, 29, 13, 3, 0, 0}, + { 1, 19, 4, 6, 7, 8, 10, 11}, + { 12,';','@', 28, 0, 26, 24, 3}, + { 22, 2, 14, 13,',','.','/', 0}, + { 10,' ','-',',', 13,'.','0','1'}, + {'2','3','4','5','6','7','8','9'}, + }, + { /* Shift+Control */ + { 27,'!','"','#','$','%','&', 39}, + {'(',')','~','*','=', 12,127, 31}, + { 17, 23, 5, 18, 20, 25, 21, 9}, + { 15, 16, 27, 29, 13,127, 0, 0}, + { 1, 19, 4, 6, 7, 8, 10, 11}, + { 12,'+','`', 28, 0, 26, 24, 3}, + { 22, 2, 14, 13,',','.','/', 0}, + { 10,' ','-',',', 13,'.','0','1'}, + {'2','3','4','5','6','7','8','9'}, + }, + { /* CapsLock */ + { 27,'1','2','3','4','5','6','7'}, + {'8','9','0',':','-', 12,127,'^'}, + {'Q','W','E','R','T','Y','U','I'}, + {'O','P','[',']', 13, 3, 0, 0}, + {'A','S','D','F','G','H','J','K'}, + {'L',';','@', 92, 0,'Z','X','C'}, + {'V','B','N','M',',','.','/', 0}, + { 10,' ','-',',', 13,'.','0','1'}, + {'2','3','4','5','6','7','8','9'}, + }, + { /* Shift+CapsLock */ + { 27,'!','"','#','$','%','&', 39}, + {'(',')','~','*','=', 12,127,'_'}, + {'q','w','e','r','t','y','u','i'}, + {'o','p','{','}', 13, 3, 0, 0}, + {'a','s','d','f','g','h','j','k'}, + {'l','+','`','|', 0,'z','x','c'}, + {'v','b','n','m','<','>','?', 0}, + { 10,' ','-',',', 13,'.','0','1'}, + {'2','3','4','5','6','7','8','9'}, + }, + { /* Control+CapsLock */ + { 27,'1','2','3','4','5','6','7'}, + {'8','9','0',':','-', 12,127, 9}, + { 17, 23, 5, 18, 20, 25, 21, 9}, + { 15, 16, 27, 29, 13,127, 0, 0}, + { 1, 19, 4, 6, 7, 8, 10, 11}, + { 12,';', 39, 28, 0, 26, 24, 3}, + { 22, 2, 14, 13,',','.','/', 0}, + { 10,' ','-',',', 13,'.','0','1'}, + {'2','3','4','5','6','7','8','9'}, + }, + { /* Shift+Control+CapsLock */ + { 27,'!','"','#','$','%','&', 39}, + {'(',')','~','*','=', 12,127, 9}, + { 17, 23, 5, 18, 20, 25, 21, 9}, + { 15, 16, 27, 29, 13,127, 0, 0}, + { 1, 19, 4, 6, 7, 8, 10, 11}, + { 12,':','"', 28, 0, 26, 24, 3}, + { 22, 2, 14, 13,',','.','/', 0}, + { 10,' ','-',',', 13,'.','0','1'}, + {'2','3','4','5','6','7','8','9'}, + }, +}; + + +uint8_t microtan_state::sound_r() +{ + int data = 0xff; + LOG("sound_r: -> %02x\n", data); + return data; +} + +void microtan_state::sound_w(uint8_t data) +{ + LOG("sound_w: <- %02x\n", data); +} + + +uint8_t microtan_state::bffx_r(offs_t offset) +{ + int data = 0xff; + switch( offset & 3 ) + { + case 0: /* BFF0: read enables chunky graphics */ + m_chunky_graphics = 1; + LOG("bff0_r: -> %02x (chunky graphics on)\n", data); + break; + case 1: /* BFF1: read undefined (?) */ + LOG("bff1_r: -> %02x\n", data); + break; + case 2: /* BFF2: read undefined (?) */ + LOG("bff2_r: -> %02x\n", data); + break; + case 3: /* BFF3: read keyboard/keypad */ + switch (m_config->read() & 3) + { + case 0: /* ASCII Keyboard */ + data = m_keyboard_ascii; + break; + case 1: /* Hex Keypad */ + data = 0x00; + for (u8 i = 0; i < 4; i++) + if (BIT(m_keypad_column, i)) + data |= m_io_keypad[i]->read(); + + break; + case 2: /* ETI Keypad */ + data = (m_keypad->read() & 0x1f) | (m_config->read() & 0x60); + break; + } + LOG("bff3_r: -> %02x (keyboard ASCII)\n", data); + break; + } + return data; +} + + +/* This callback is called one clock cycle after BFF2 is written (delayed nmi) */ +TIMER_CALLBACK_MEMBER(microtan_state::pulse_nmi) +{ + m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero); +} + +void microtan_state::bffx_w(offs_t offset, uint8_t data) +{ + switch( offset & 3 ) + { + case 0: /* BFF0: write reset keyboard interrupt flag */ + /* This removes bit 7 from the ASCII value of the last key pressed. */ + LOG("bff0_w: %d <- %02x (keyboard IRQ clear )\n", offset, data); + m_keyboard_ascii &= ~0x80; + m_irq_line->in_w(0); + break; + case 1: /* BFF1: write delayed NMI */ + LOG("bff1_w: %d <- %02x (delayed NMI)\n", offset, data); + m_pulse_nmi_timer->adjust(m_maincpu->cycles_to_attotime(8)); + break; + case 2: /* BFF2: write keypad */ + LOG("bff2_w: %d <- %02x (keypad column)\n", offset, data); // 1, 2, 4, 7, f + m_keypad_column = data & 0x0f; + break; + case 3: /* BFF3: write disable chunky graphics */ + LOG("bff3_w: %d <- %02x (chunky graphics off)\n", offset, data); + m_chunky_graphics = 0; + break; + } +} + +uint8_t mt6809_state::keyboard_r() +{ + uint8_t data = m_keyboard_ascii; + + m_keyboard_ascii = 0x00; + + return data; +} + +void mt6809_state::store_key(int key) +{ + m_keyboard_ascii = key | 0x80; +} + +void microtan_state::store_key(int key) +{ + m_keyboard_ascii = key | 0x80; + m_irq_line->in_w(1); +} + +TIMER_DEVICE_CALLBACK_MEMBER(microtan_state::kbd_scan) +{ + /* ASCII Keyboard only */ + if (m_config->read() & 3) + return; + + int mod, row, col, chg, newvar; + + if( m_repeat ) + { + if( !--m_repeat ) + m_repeater = 4; + } + else if( m_repeater ) + m_repeat = m_repeater; + + row = 9; + newvar = m_io_keyboard[8]->read(); + chg = m_keyrows[--row] ^ newvar; + + while ( !chg && row > 0) + { + newvar = m_io_keyboard[row - 1]->read(); + chg = m_keyrows[--row] ^ newvar; + } + if (!chg) + --row; + + if (row >= 0) + { + m_repeater = 0x00; + m_mask = 0x00; + m_key = 0x00; + m_lastrow = row; + /* CapsLock LED */ + if( row == 3 && chg == 0x80 ) + m_led = BIT(~m_keyrows[3], 7); + + if (newvar & chg) /* key(s) pressed ? */ + { + mod = 0; + + /* Shift modifier */ + if ( (m_keyrows[5] & 0x10) || (m_keyrows[6] & 0x80) ) + mod |= 1; + + /* Control modifier */ + if (m_keyrows[3] & 0x40) + mod |= 2; + + /* CapsLock modifier */ + if (m_keyrows[3] & 0x80) + mod |= 4; + + /* find newvar key */ + m_mask = 0x01; + for (col = 0; col < 8; col ++) + { + if (chg & m_mask) + { + newvar &= m_mask; + m_key = keyboard[mod][row][col]; + break; + } + m_mask <<= 1; + } + if( m_key ) /* normal key */ + { + m_repeater = 30; + store_key(m_key); + } + else + if( (row == 0) && (chg == 0x04) ) /* Ctrl-@ (NUL) */ + store_key(0); + m_keyrows[row] |= newvar; + } + else + m_keyrows[row] = newvar; + + m_repeat = m_repeater; + } + else + if ( m_key && (m_keyrows[m_lastrow] & m_mask) && m_repeat == 0 ) + store_key(m_key); +} + + +void microtan_state::pgm_chargen_w(offs_t offset, uint8_t data) +{ + switch (offset & 0x200) + { + case 0x000: + /* update char &80-&1F */ + m_gfx1->base()[offset | 0x800] = data; + m_gfxdecode->gfx(0)->mark_dirty(0x80 | (offset >> 4)); + break; + case 0x200: + /* update char &E0-&FF */ + m_gfx1->base()[offset | 0xc00] = data; + m_gfxdecode->gfx(0)->mark_dirty(0xc0 | (offset >> 4)); + break; + } +} + +void microtan_state::init_gfx2() +{ + uint8_t *dst = memregion("gfx2")->base(); + + for (int i = 0; i < 256; i++) + { + switch (i & 3) + { + case 0: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0x00; break; + case 1: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0xf0; break; + case 2: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0x0f; break; + case 3: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0xff; break; + } + dst += 4; + switch (BIT(i, 2, 2)) + { + case 0: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0x00; break; + case 1: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0xf0; break; + case 2: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0x0f; break; + case 3: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0xff; break; + } + dst += 4; + switch (BIT(i, 4, 2)) + { + case 0: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0x00; break; + case 1: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0xf0; break; + case 2: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0x0f; break; + case 3: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0xff; break; + } + dst += 4; + switch (BIT(i, 6, 2)) + { + case 0: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0x00; break; + case 1: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0xf0; break; + case 2: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0x0f; break; + case 3: dst[ 0] = dst[ 1] = dst[ 2] = dst[ 3] = 0xff; break; + } + dst += 4; + } +} + +void microtan_state::init_microtan() +{ + init_gfx2(); + + m_pulse_nmi_timer = timer_alloc(FUNC(microtan_state::pulse_nmi), this); +} + +void microtan_state::machine_start() +{ + m_led.resolve(); + + save_item(NAME(m_keypad_column)); + save_item(NAME(m_keyboard_ascii)); + save_item(NAME(m_keyrows)); + save_item(NAME(m_lastrow)); + save_item(NAME(m_mask)); + save_item(NAME(m_key)); + save_item(NAME(m_repeat)); + save_item(NAME(m_repeater)); +} + +void microtan_state::machine_reset() +{ + for (int i = 1; i < 10; i++) + m_keyrows[i] = m_io_keyboard[i-1].read_safe(0); + + m_led = BIT(~m_keyrows[3], 7); +} + +image_verify_result microtan_state::verify_snapshot(uint8_t *data, int size) +{ + if (size == 8263) + { + logerror("snapshot_id: magic size %d found\n", size); + return image_verify_result::PASS; + } + else + { + if (4 + data[2] + 256 * data[3] + 1 + 16 + 16 + 16 + 1 + 1 + 16 + 16 + 64 + 7 == size) + { + logerror("snapshot_id: header RAM size + structures matches filesize %d\n", size); + return image_verify_result::PASS; + } + } + + return image_verify_result::FAIL; +} + +image_init_result microtan_state::parse_intel_hex(uint8_t *snapshot_buff, char *src) +{ + char line[128]; + int /*row = 0,*/ column = 0, last_addr = 0, last_size = 0; + + while (*src) + { + if (*src == '\r' || *src == '\n') + { + if (column) + { + unsigned int size, addr, null, b[32], cs, n; + + line[column] = '\0'; + /*row++;*/ + n = sscanf(line, ":%02x%04x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + &size, &addr, &null, + &b[ 0], &b[ 1], &b[ 2], &b[ 3], &b[ 4], &b[ 5], &b[ 6], &b[ 7], + &b[ 8], &b[ 9], &b[10], &b[11], &b[12], &b[13], &b[14], &b[15], + &b[16], &b[17], &b[18], &b[19], &b[20], &b[21], &b[22], &b[23], + &b[24], &b[25], &b[26], &b[27], &b[28], &b[29], &b[30], &b[31], + &cs); + if (n == 0) + logerror("parse_intel_hex: malformed line [%s]\n", line); + else + if (n == 1) + logerror("parse_intel_hex: only size found [%s]\n", line); + else + if (n == 2) + logerror("parse_intel_hex: only size and addr found [%s]\n", line); + else + if (n == 3) + logerror("parse_intel_hex: only size, addr and null found [%s]\n", line); + else + if (null != 0) + logerror("parse_intel_hex: warning null byte is != 0 [%s]\n", line); + else + { + int i, sum; + + n -= 3; + + sum = size + (addr & 0xff) + ((addr >> 8) & 0xff); + if (n != 32 + 1) + cs = b[n-1]; + + last_addr = addr; + last_size = n-1; + logerror("parse_intel_hex: %04X", addr); + for (i = 0; i < n-1; i++) + { + sum += b[i]; + snapshot_buff[addr++] = b[i]; + } + logerror("-%04X checksum %02X+%02X = %02X\n", addr-1, cs, sum & 0xff, (cs + sum) & 0xff); + } + } + column = 0; + } + else + line[column++] = *src; + + src++; + } + /* register preset? */ + if (last_size == 7) + { + logerror("parse_intel_hex: registers (?) at %04X\n", last_addr); + memcpy(&snapshot_buff[8192+64], &snapshot_buff[last_addr], last_size); + } + return image_init_result::PASS; +} + +image_init_result microtan_state::parse_zillion_hex(uint8_t *snapshot_buff, char *src) +{ + char line[128]; + int parsing = 0, /*row = 0,*/ column = 0; + + while (*src) + { + if (parsing) + { + if (*src == '}') + parsing = 0; + else + { + if (*src == '\r' || *src == '\n') + { + if (column) + { + unsigned int addr, b[8], n; + + line[column] = '\0'; + /*row++;*/ + n = sscanf(line, "%x %x %x %x %x %x %x %x %x", &addr, &b[0], &b[1], &b[2], &b[3], &b[4], &b[5], &b[6], &b[7]); + if (n == 0) + logerror("parse_zillion_hex: malformed line [%s]\n", line); + else + if (n == 1) + logerror("parse_zillion_hex: only addr found [%s]\n", line); + else + { + logerror("parse_zillion_hex: %04X", addr); + for (int i = 0; i < n-1; i++) + snapshot_buff[addr++] = b[i]; + logerror("-%04X\n", addr-1); + } + } + column = 0; + } + else + line[column++] = *src; + } + } + else + { + if (*src == '\r' || *src == '\n') + { + if (column) + { + int addr; + + /*row++;*/ + line[column] = '\0'; + int n = sscanf(line, "G%x", (unsigned int *) &addr); + if (n == 1 && !snapshot_buff[8192+64+0] && !snapshot_buff[8192+64+1]) + { + logerror("microtan_hexfile_init: go addr %04X\n", addr); + snapshot_buff[8192+64+0] = addr & 0xff; + snapshot_buff[8192+64+1] = (addr >> 8) & 0xff; + } + } + column = 0; + } + else + line[column++] = *src; + + if (*src == '{') + { + parsing = 1; + column = 0; + } + } + src++; + } + return image_init_result::PASS; +} + +void microtan_state::set_cpu_regs(const uint8_t *snapshot_buff, int base) +{ + logerror("snapshot_copy: PC:%02X%02X P:%02X A:%02X X:%02X Y:%02X SP:1%02X\n", + snapshot_buff[base+1], snapshot_buff[base+0], snapshot_buff[base+2], snapshot_buff[base+3], + snapshot_buff[base+4], snapshot_buff[base+5], snapshot_buff[base+6]); + m_maincpu->set_state_int(M6502_PC, snapshot_buff[base+0] + (snapshot_buff[base+1] << 8)); + m_maincpu->set_state_int(M6502_P, snapshot_buff[base+2]); + m_maincpu->set_state_int(M6502_A, snapshot_buff[base+3]); + m_maincpu->set_state_int(M6502_X, snapshot_buff[base+4]); + m_maincpu->set_state_int(M6502_Y, snapshot_buff[base+5]); + m_maincpu->set_state_int(M6502_S, snapshot_buff[base+6] + 0x100); +} + +void microtan_state::snapshot_copy(uint8_t *snapshot_buff, int snapshot_size) +{ + address_space &space = m_maincpu->space(AS_PROGRAM); + + /* check for .DMP file format */ + if (snapshot_size == 8263) + { + /********** DMP format + * Lower 8k of RAM (0000 to 1fff) + * 64 bytes of chunky graphics bits (first byte bit is for character at 0200, bit 1=0201, etc) + * 7 bytes of CPU registers (PCL, PCH, PSW, A, IX, IY, SP) + */ + + int base = 0; + /* 8K of RAM from 0000 to 1fff */ + for (int i = 0; i < 0x2000; i++) + space.write_byte(i, snapshot_buff[base + i]); + + base += 8192; + /* 64 bytes of chunky graphics info */ + for (int i = 0; i < 32*16; i++) + m_chunky_buffer[i] = (snapshot_buff[base+i/8] >> (i&7)) & 1; + + base += 64; + set_cpu_regs(snapshot_buff, base); + } + else + { + /********** M65 format ************************************ + * 2 bytes: File version + * 2 bytes: RAM size + * n bytes: RAM (0000 to RAM Size) + * 16 bytes: 1st 6522 (0xbfc0 to 0xbfcf) + * 16 bytes: 2nd 6522 (0xbfe0 to 0xbfef) + * 16 bytes: Microtan IO (0xbff0 to 0xbfff) + * 1 byte : Space Invasion sound (0xbc04) + * 1 byte : Chunky graphics state (0=off, 1=on) + * 16 bytes: 1st AY8910 registers + * 16 bytes: 2nd AY8910 registers + * 64 bytes: Chunky graphics bits (first byte bit 0 is for character at 0200, bit 1=0201, etc) + * 7 bytes: CPU registers (PCL, PCH, PSW, A, IX, IY, SP) + */ + int ramend = snapshot_buff[2] + 256 * snapshot_buff[3]; + if (2 + 2 + ramend + 1 + 16 + 16 + 16 + 1 + 1 + 16 + 16 + 64 + 7 != snapshot_size) + { + logerror("snapshot_copy: size %d doesn't match RAM size %d + structure size\n", snapshot_size, ramend+1); + return; + } + + int base = 4; + for (int i = 0; i < snapshot_buff[2] + 256 * snapshot_buff[3] + 1; i++) + space.write_byte(i, snapshot_buff[base + i]); + base += ramend + 1; + + /* first set of VIA6522 registers */ + for (int i = 0; i < 16; i++ ) + space.write_byte(0xbfc0 + i, snapshot_buff[base++]); + + /* second set of VIA6522 registers */ + for (int i = 0; i < 16; i++ ) + space.write_byte(0xbfe0 + i, snapshot_buff[base++]); + + /* microtan IO bff0-bfff */ + for (int i = 0; i < 16; i++ ) + { + if (i < 4) + bffx_w(i, snapshot_buff[base++]); + } + + sound_w(snapshot_buff[base++]); + m_chunky_graphics = snapshot_buff[base++]; + + /* first set of AY8910 registers */ + for (int i = 0; i < 16; i++ ) + { + space.write_byte(0xbc00, i); + space.write_byte(0xbc01, snapshot_buff[base++]); + } + + /* second set of AY8910 registers */ + for (int i = 0; i < 16; i++ ) + { + space.write_byte(0xbc02, i); + space.write_byte(0xbc03, snapshot_buff[base++]); + } + + for (int i = 0; i < 32*16; i++) + m_chunky_buffer[i] = (snapshot_buff[base+i/8] >> (i&7)) & 1; + + base += 64; + + set_cpu_regs(snapshot_buff, base); + } +} + +SNAPSHOT_LOAD_MEMBER(microtan_state::snapshot_cb) +{ + uint64_t snapshot_len = image.length(); + if (snapshot_len < 4 || snapshot_len >= 66000) + { + //image.seterror(image_error::INVALIDIMAGE); + return image_init_result::FAIL; + } + + auto snapshot_buff = std::make_unique(snapshot_len); + if (image.fread(snapshot_buff.get(), snapshot_len) != snapshot_len) + { + //image.seterror(image_error::UNSPECIFIED); + return image_init_result::FAIL; + } + + if (verify_snapshot(snapshot_buff.get(), snapshot_len) != image_verify_result::PASS) + { + //image.seterror(image_error::INVALIDIMAGE); + return image_init_result::FAIL; + } + + snapshot_copy(snapshot_buff.get(), snapshot_len); + return image_init_result::PASS; +} + +QUICKLOAD_LOAD_MEMBER(microtan_state::quickload_cb) +{ + int snapshot_size = 8263; /* magic size */ + std::vector snapshot_buff(snapshot_size, 0); + std::vector buff(image.length() + 1); + image_init_result rc; + + image.fread(&buff[0], image.length()); + + buff[image.length()] = '\0'; + + if (buff[0] == ':') + rc = parse_intel_hex(&snapshot_buff[0], &buff[0]); + else + rc = parse_zillion_hex(&snapshot_buff[0], &buff[0]); + if (rc == image_init_result::PASS) + snapshot_copy(&snapshot_buff[0], snapshot_size); + return rc; +} diff --git a/src/mame/tangerine/microtan_v.cpp b/src/mame/tangerine/microtan_v.cpp new file mode 100644 index 00000000000..d023f2ecffa --- /dev/null +++ b/src/mame/tangerine/microtan_v.cpp @@ -0,0 +1,66 @@ +// license:GPL-2.0+ +// copyright-holders:Juergen Buchmueller +/*************************************************************************** + * Microtan 65 + * + * video hardware + * + * Juergen Buchmueller , Jul 2000 + * + * Thanks go to Geoff Macdonald + * for his site http://www.geoff.org.uk/microtan/index.htm + * and to Fabrice Frances + * for his site http://oric.free.fr/microtan.html + * + ***************************************************************************/ + +#include "emu.h" +#include "microtan.h" + + +void microtan_state::videoram_w(offs_t offset, uint8_t data) +{ + if ((m_videoram[offset] != data) || (m_chunky_buffer[offset] != m_chunky_graphics)) + { + m_videoram[offset] = data; + m_bg_tilemap->mark_tile_dirty(offset); + m_chunky_buffer[offset] = m_chunky_graphics; + } +} + +TILE_GET_INFO_MEMBER(microtan_state::get_bg_tile_info) +{ + int gfxn = m_chunky_buffer[tile_index]; + int code = m_videoram[tile_index]; + + tileinfo.set(gfxn, code, 0, 0); +} + +void microtan_state::video_start() +{ + /* randomize video memory contents */ + for (uint16_t addr = 0; addr < m_videoram.bytes(); addr++) + m_videoram[addr] = machine().rand() & 0xff; + + m_bg_tilemap = &machine().tilemap().create(* + m_gfxdecode, + tilemap_get_info_delegate(*this, FUNC(microtan_state::get_bg_tile_info)), + TILEMAP_SCAN_ROWS, 8, 16, 32, 16); + + m_chunky_buffer = std::make_unique(0x200); + memset(m_chunky_buffer.get(), 0, 0x200); + m_chunky_graphics = 0; + + save_pointer(NAME(m_chunky_buffer), 0x200); + save_item(NAME(m_chunky_graphics)); +} + +uint32_t microtan_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0); + return 0; +} + +void mt6809_state::video_start() +{ +} diff --git a/src/mame/tangerine/oric.cpp b/src/mame/tangerine/oric.cpp new file mode 100644 index 00000000000..cd8b16d9b35 --- /dev/null +++ b/src/mame/tangerine/oric.cpp @@ -0,0 +1,1005 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/***************************************************************************************************** + + drivers/oric.cpp + + Systems supported by this driver: + + Oric 1, + Oric Atmos, + Oric Telestrat, + Pravetz 8D + + Pravetz is a Bulgarian copy of the Oric Atmos and uses + Apple 2 disc drives for storage. + + This driver originally by Paul Cook, rewritten by Kevin Thacker, + re-rewritten by Olivier Galibert. + + + +*****************************************************************************************************/ + +#include "emu.h" + +#include "bus/centronics/ctronics.h" +#include "bus/oricext/oricext.h" +#include "cpu/m6502/m6502.h" +#include "imagedev/cassette.h" +#include "imagedev/floppy.h" +#include "machine/6522via.h" +#include "machine/mos6551.h" +#include "machine/timer.h" +#include "machine/wd_fdc.h" +#include "sound/ay8910.h" + +#include "emupal.h" +#include "screen.h" +#include "speaker.h" + +#include "formats/oric_dsk.h" +#include "formats/oric_tap.h" + + +class oric_state : public driver_device +{ +public: + // Permanent attributes (kept from one line to the other) and line + // attributes (reset at start of line) + enum { + PATTR_50HZ = 0x02, + PATTR_HIRES = 0x04, + LATTR_ALT = 0x01, + LATTR_DSIZE = 0x02, + LATTR_BLINK = 0x04 + }; + + oric_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_palette(*this, "palette") + , m_psg(*this, "ay8912") + , m_centronics(*this, "centronics") + , m_cent_data_out(*this, "cent_data_out") + , m_cassette(*this, "cassette") + , m_via(*this, "via6522") + , m_ram(*this, "ram") + , m_rom(*this, "maincpu") + , m_bank_c000_r(*this, "bank_c000_r") + , m_bank_e000_r(*this, "bank_e000_r") + , m_bank_f800_r(*this, "bank_f800_r") + , m_bank_c000_w(*this, "bank_c000_w") + , m_bank_e000_w(*this, "bank_e000_w") + , m_bank_f800_w(*this, "bank_f800_w") + , m_config(*this, "CONFIG") + , m_kbd_row(*this, "ROW%u", 0U) + , m_tape_timer(nullptr) + { } + + DECLARE_INPUT_CHANGED_MEMBER(nmi_pressed); + void via_a_w(uint8_t data); + void via_b_w(uint8_t data); + DECLARE_WRITE_LINE_MEMBER(via_ca2_w); + DECLARE_WRITE_LINE_MEMBER(via_cb2_w); + DECLARE_WRITE_LINE_MEMBER(via_irq_w); + DECLARE_WRITE_LINE_MEMBER(ext_irq_w); + void psg_a_w(uint8_t data); + TIMER_CALLBACK_MEMBER(update_tape); + + virtual void machine_start() override; + virtual void machine_reset() override; + virtual void video_start() override; + uint32_t screen_update_oric(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + DECLARE_WRITE_LINE_MEMBER(vblank_w); + + void oric(machine_config &config, bool add_ext = true); + void prav8d(machine_config &config); + void oric_mem(address_map &map); +protected: + required_device m_maincpu; + required_device m_palette; + required_device m_psg; + required_device m_centronics; + required_device m_cent_data_out; + required_device m_cassette; + required_device m_via; + required_shared_ptr m_ram; + optional_memory_region m_rom; + required_memory_bank m_bank_c000_r; + optional_memory_bank m_bank_e000_r; + optional_memory_bank m_bank_f800_r; + required_memory_bank m_bank_c000_w; + optional_memory_bank m_bank_e000_w; + optional_memory_bank m_bank_f800_w; + required_ioport m_config; + required_ioport_array<8> m_kbd_row; + + emu_timer *m_tape_timer; + + int m_blink_counter; + uint8_t m_pattr; + uint8_t m_via_a, m_via_b, m_psg_a; + bool m_via_ca2, m_via_cb2, m_via_irq; + bool m_ext_irq; + + virtual void update_irq(); + void update_psg(); + void update_keyboard(); + void machine_start_common(); +}; + +class telestrat_state : public oric_state +{ +public: + telestrat_state(const machine_config &mconfig, device_type type, const char *tag) : + oric_state(mconfig, type, tag), + m_via2(*this, "via6522_2"), + m_fdc(*this, "fdc"), + m_telmatic(*this, "telmatic"), + m_teleass(*this, "teleass"), + m_hyperbas(*this, "hyperbas"), + m_telmon24(*this, "telmon24"), + m_joy1(*this, "JOY1"), + m_joy2(*this, "JOY2") + { } + + void via2_a_w(uint8_t data); + void via2_b_w(uint8_t data); + DECLARE_WRITE_LINE_MEMBER(via2_ca2_w); + DECLARE_WRITE_LINE_MEMBER(via2_cb2_w); + DECLARE_WRITE_LINE_MEMBER(via2_irq_w); + + DECLARE_WRITE_LINE_MEMBER(acia_irq_w); + + DECLARE_WRITE_LINE_MEMBER(fdc_irq_w); + DECLARE_WRITE_LINE_MEMBER(fdc_drq_w); + DECLARE_WRITE_LINE_MEMBER(fdc_hld_w); + + static void floppy_formats(format_registration &fr); + + virtual void machine_start() override; + virtual void machine_reset() override; + + void telstrat(machine_config &config); + void telestrat_mem(address_map &map); +protected: + enum { + P_IRQEN = 0x01, + P_DDS = 0x04, + P_DDEN = 0x08, + P_SS = 0x10, + P_DRIVE = 0x60 + }; + + required_device m_via2; + required_device m_fdc; + required_memory_region m_telmatic; + required_memory_region m_teleass; + required_memory_region m_hyperbas; + required_memory_region m_telmon24; + required_ioport m_joy1; + required_ioport m_joy2; + + floppy_image_device *m_floppies[4]; + uint8_t m_port_314; + uint8_t m_via2_a, m_via2_b; + bool m_via2_ca2, m_via2_cb2, m_via2_irq; + bool m_acia_irq; + bool m_fdc_irq, m_fdc_drq, m_fdc_hld; + + uint8_t m_junk_read[0x4000], m_junk_write[0x4000]; + + virtual void update_irq() override; + void remap(); + void port_314_w(u8 data); + u8 port_314_r(); + u8 port_318_r(); +}; + +/* Ram is 64K, with 16K hidden by the rom. The 300-3ff is also hidden by the i/o */ +void oric_state::oric_mem(address_map &map) +{ + map(0x0000, 0xffff).ram().share("ram"); + map(0x0300, 0x030f).m(m_via, FUNC(via6522_device::map)).mirror(0xf0); + map(0xc000, 0xdfff).bankr("bank_c000_r").bankw("bank_c000_w"); + map(0xe000, 0xf7ff).bankr("bank_e000_r").bankw("bank_e000_w"); + map(0xf800, 0xffff).bankr("bank_f800_r").bankw("bank_f800_w"); +} + +/* +The telestrat has the memory regions split into 16k blocks. +Memory region &c000-&ffff can be ram or rom. */ +void telestrat_state::telestrat_mem(address_map &map) +{ + map(0x0000, 0xffff).ram().share("ram"); + map(0x0300, 0x030f).m(m_via, FUNC(via6522_device::map)); + map(0x0310, 0x0313).rw(m_fdc, FUNC(fd1793_device::read), FUNC(fd1793_device::write)); + map(0x0314, 0x0314).rw(FUNC(telestrat_state::port_314_r), FUNC(telestrat_state::port_314_w)); + map(0x0318, 0x0318).r(FUNC(telestrat_state::port_318_r)); + map(0x031c, 0x031f).rw("acia", FUNC(mos6551_device::read), FUNC(mos6551_device::write)); + map(0x0320, 0x032f).m(m_via2, FUNC(via6522_device::map)); + map(0xc000, 0xffff).bankr("bank_c000_r").bankw("bank_c000_w"); +} + +uint32_t oric_state::screen_update_oric(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + bool blink_state = m_blink_counter & 0x20; + m_blink_counter = (m_blink_counter + 1) & 0x3f; + + uint8_t pattr = m_pattr; + + for(int y=0; y<224; y++) { + // Line attributes and current colors + uint8_t lattr = 0; + uint32_t fgcol = m_palette->pen_color(7); + uint32_t bgcol = m_palette->pen_color(0); + + uint32_t *p = &bitmap.pix(y); + + for(int x=0; x<40; x++) { + // Lookup the byte and, if needed, the pattern data + uint8_t ch, pat; + if((pattr & PATTR_HIRES) && y < 200) + ch = pat = m_ram[0xa000 + y*40 + x]; + + else { + ch = m_ram[0xbb80 + (y>>3)*40 + x]; + int off = (lattr & LATTR_DSIZE ? y >> 1 : y ) & 7; + const uint8_t *base; + if(pattr & PATTR_HIRES) + if(lattr & LATTR_ALT) + base = m_ram + 0x9c00; + else + base = m_ram + 0x9800; + else + if(lattr & LATTR_ALT) + base = m_ram + 0xb800; + else + base = m_ram + 0xb400; + pat = base[((ch & 0x7f) << 3) | off]; + } + + // Handle state-chaging attributes + if(!(ch & 0x60)) { + pat = 0x00; + switch(ch & 0x18) { + case 0x00: fgcol = m_palette->pen_color(ch & 7); break; + case 0x08: lattr = ch & 7; break; + case 0x10: bgcol = m_palette->pen_color(ch & 7); break; + case 0x18: pattr = ch & 7; break; + } + } + + // Pick up the colors for the pattern + uint32_t c_fgcol = fgcol; + uint32_t c_bgcol = bgcol; + + // inverse video + if(ch & 0x80) { + c_bgcol = c_bgcol ^ 0xffffff; + c_fgcol = c_fgcol ^ 0xffffff; + } + // blink + if((lattr & LATTR_BLINK) && blink_state) + c_fgcol = c_bgcol; + + // Draw the pattern + *p++ = pat & 0x20 ? c_fgcol : c_bgcol; + *p++ = pat & 0x10 ? c_fgcol : c_bgcol; + *p++ = pat & 0x08 ? c_fgcol : c_bgcol; + *p++ = pat & 0x04 ? c_fgcol : c_bgcol; + *p++ = pat & 0x02 ? c_fgcol : c_bgcol; + *p++ = pat & 0x01 ? c_fgcol : c_bgcol; + } + } + + m_pattr = pattr; + + return 0; +} + +void oric_state::update_keyboard() +{ + m_via->write_pb3((m_kbd_row[m_via_b & 7]->read() | m_psg_a) != 0xff); +} + +void oric_state::update_psg() +{ + if(m_via_ca2) + if(m_via_cb2) + m_psg->address_w(m_via_a); + else + m_via->write_pa(m_psg->data_r()); + else if(m_via_cb2) + m_psg->data_w(m_via_a); +} + +void oric_state::update_irq() +{ + m_maincpu->set_input_line(m6502_device::IRQ_LINE, m_via_irq || m_ext_irq ? ASSERT_LINE : CLEAR_LINE); +} + +INPUT_CHANGED_MEMBER(oric_state::nmi_pressed) +{ + m_maincpu->set_input_line(m6502_device::NMI_LINE, newval ? ASSERT_LINE : CLEAR_LINE); +} + +void oric_state::via_a_w(uint8_t data) +{ + m_via_a = data; + m_cent_data_out->write(m_via_a); + update_psg(); +} + +void oric_state::via_b_w(uint8_t data) +{ + m_via_b = data; + update_keyboard(); + m_centronics->write_strobe(data & 0x10 ? 1 : 0); + m_cassette->change_state(data & 0x40 ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, + CASSETTE_MOTOR_DISABLED); + m_cassette->output(data & 0x80 ? -1.0 : +1.0); +} + +WRITE_LINE_MEMBER(oric_state::via_ca2_w) +{ + m_via_ca2 = state; + update_psg(); +} + +WRITE_LINE_MEMBER(oric_state::via_cb2_w) +{ + m_via_cb2 = state; + update_psg(); +} + +WRITE_LINE_MEMBER(oric_state::via_irq_w) +{ + m_via_irq = state; + update_irq(); +} + +WRITE_LINE_MEMBER(oric_state::ext_irq_w) +{ + m_ext_irq = state; + update_irq(); +} + +void oric_state::psg_a_w(uint8_t data) +{ + m_psg_a = data; + update_keyboard(); +} + +TIMER_CALLBACK_MEMBER(oric_state::update_tape) +{ + if(!m_config->read()) + m_via->write_cb1(m_cassette->input() > 0.0038); +} + +WRITE_LINE_MEMBER(oric_state::vblank_w) +{ + if(m_config->read()) + m_via->write_cb1(state); +} + +void oric_state::video_start() +{ + m_blink_counter = 0; + m_pattr = 0; +} + +void oric_state::machine_start_common() +{ + m_via_a = 0xff; + m_via_b = 0xff; + m_psg_a = 0x00; + m_via_ca2 = false; + m_via_cb2 = false; + m_via_irq = false; + m_ext_irq = false; + + if (!m_tape_timer) + m_tape_timer = timer_alloc(FUNC(oric_state::update_tape), this); + + save_item(NAME(m_blink_counter)); + save_item(NAME(m_pattr)); + save_item(NAME(m_via_a)); + save_item(NAME(m_via_b)); + save_item(NAME(m_psg_a)); + save_item(NAME(m_via_ca2)); + save_item(NAME(m_via_cb2)); + save_item(NAME(m_via_irq)); + save_item(NAME(m_ext_irq)); +} + +void oric_state::machine_start() +{ + machine_start_common(); + m_bank_c000_r->set_base(m_rom->base()); + m_bank_e000_r->set_base(m_rom->base() + 0x2000); + m_bank_f800_r->set_base(m_rom->base() + 0x3800); +} + +void oric_state::machine_reset() +{ + m_tape_timer->adjust(attotime::from_hz(4800), 0, attotime::from_hz(4800)); +} + +void telestrat_state::machine_start() +{ + machine_start_common(); + for(u8 i=0; i<4; i++) + { + char name[32]; + sprintf(name, "fdc:%d", i); + m_floppies[i] = subdevice(name)->get_device(); + } + m_fdc_irq = m_fdc_drq = m_fdc_hld = false; + m_acia_irq = false; + + memset(m_junk_read, 0x00, sizeof(m_junk_read)); + memset(m_junk_write, 0x00, sizeof(m_junk_write)); + + save_item(NAME(m_port_314)); + save_item(NAME(m_via2_a)); + save_item(NAME(m_via2_b)); + save_item(NAME(m_via2_ca2)); + save_item(NAME(m_via2_cb2)); + save_item(NAME(m_via2_irq)); + save_item(NAME(m_acia_irq)); + save_item(NAME(m_fdc_irq)); + save_item(NAME(m_fdc_drq)); + save_item(NAME(m_fdc_hld)); +} + +void telestrat_state::machine_reset() +{ + m_tape_timer->adjust(attotime::from_hz(4800), 0, attotime::from_hz(4800)); + m_port_314 = 0x00; + m_via2_a = 0xff; + remap(); +} + +void telestrat_state::update_irq() +{ + m_maincpu->set_input_line(m6502_device::IRQ_LINE, + m_via_irq || + m_ext_irq || + (m_fdc_irq && (m_port_314 & P_IRQEN)) || + m_via2_irq || + m_acia_irq ? ASSERT_LINE : CLEAR_LINE); +} + +void telestrat_state::via2_a_w(uint8_t data) +{ + m_via2_a = data; + remap(); +} + +void telestrat_state::via2_b_w(uint8_t data) +{ + m_via2_b = data; + uint8_t port = 0xff; + if(!(m_via2_b & 0x40)) + port &= m_joy1->read(); + if(!(m_via2_b & 0x80)) + port &= m_joy2->read(); + + m_via2->write_pb(port); +} + +WRITE_LINE_MEMBER(telestrat_state::via2_ca2_w) +{ + m_via2_ca2 = state; +} + +WRITE_LINE_MEMBER(telestrat_state::via2_cb2_w) +{ + m_via2_cb2 = state; +} + +WRITE_LINE_MEMBER(telestrat_state::via2_irq_w) +{ + m_via2_irq = state; + update_irq(); +} + +void telestrat_state::port_314_w(u8 data) +{ + m_port_314 = data; + floppy_image_device *floppy = m_floppies[(m_port_314 >> 5) & 3]; + m_fdc->set_floppy(floppy); + m_fdc->dden_w(m_port_314 & P_DDEN); + if(floppy) { + floppy->ss_w(m_port_314 & P_SS ? 1 : 0); + floppy->mon_w(0); + } + update_irq(); +} + +u8 telestrat_state::port_314_r() +{ + return (m_fdc_irq && (m_port_314 & P_IRQEN)) ? 0x7f : 0xff; +} + +u8 telestrat_state::port_318_r() +{ + return m_fdc_drq ? 0x7f : 0xff; +} + + +WRITE_LINE_MEMBER(telestrat_state::acia_irq_w) +{ + m_acia_irq = state; + update_irq(); +} + +WRITE_LINE_MEMBER(telestrat_state::fdc_irq_w) +{ + m_fdc_irq = state; + update_irq(); +} + +WRITE_LINE_MEMBER(telestrat_state::fdc_drq_w) +{ + m_fdc_drq = state; +} + +WRITE_LINE_MEMBER(telestrat_state::fdc_hld_w) +{ + m_fdc_hld = state; +} + +void telestrat_state::remap() +{ + // Theorically, these are cartridges. There's no real point to + // making them configurable, when only 4 existed and there are 7 + // slots. + + switch(m_via2_a & 7) { + case 0: + m_bank_c000_r->set_base(m_ram+0xc000); + m_bank_c000_w->set_base(m_ram+0xc000); + break; + case 1: + case 2: + case 3: + m_bank_c000_r->set_base(m_junk_read); + m_bank_c000_w->set_base(m_junk_write); + break; + case 4: + m_bank_c000_r->set_base(m_telmatic->base()); + m_bank_c000_w->set_base(m_junk_write); + break; + case 5: + m_bank_c000_r->set_base(m_teleass->base()); + m_bank_c000_w->set_base(m_junk_write); + break; + case 6: + m_bank_c000_r->set_base(m_hyperbas->base()); + m_bank_c000_w->set_base(m_junk_write); + break; + case 7: + m_bank_c000_r->set_base(m_telmon24->base()); + m_bank_c000_w->set_base(m_junk_write); + break; + } +} + + + +static INPUT_PORTS_START(oric) + PORT_START("ROW0") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') PORT_CHAR(24) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') PORT_CHAR(22) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') PORT_CHAR(14) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') + + PORT_START("ROW1") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') PORT_CHAR(4) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') PORT_CHAR(17) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_TAB) PORT_CHAR(27) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') PORT_CHAR(6) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') PORT_CHAR(18) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') PORT_CHAR(20) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') PORT_CHAR(10) + + PORT_START("ROW2") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') PORT_CHAR(3) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') PORT_CHAR(26) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_SHIFT_2) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') PORT_CHAR(2) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') + + PORT_START("ROW3") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR(0xA3) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') PORT_CHAR(11) + + PORT_START("ROW4") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + + PORT_START("ROW5") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') PORT_CHAR(29) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Del") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') PORT_CHAR(16) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') PORT_CHAR(15) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') PORT_CHAR(9) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') PORT_CHAR(21) + + PORT_START("ROW6") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') PORT_CHAR(23) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') PORT_CHAR(19) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') PORT_CHAR(1) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') PORT_CHAR(5) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') PORT_CHAR(7) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') PORT_CHAR(8) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') PORT_CHAR(25) + + PORT_START("ROW7") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RSHIFT) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') PORT_CHAR(12) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') + + PORT_START("NMI") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("NMI") PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_CHANGED_MEMBER(DEVICE_SELF, oric_state, nmi_pressed, 0) + + /* vsync cable hardware. This is a simple cable connected to the video output + to the monitor/television. The sync signal is connected to the cassette input + allowing interrupts to be generated from the vsync signal. */ + PORT_START("CONFIG") + PORT_CONFNAME(0x01, 0x00, "Tape input") + PORT_CONFSETTING( 0x00, "Tape") + PORT_CONFSETTING( 0x01, "VSync cable") +INPUT_PORTS_END + +static INPUT_PORTS_START(orica) + PORT_INCLUDE( oric ) + + PORT_MODIFY("ROW5") + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Funct") PORT_CODE(KEYCODE_LALT) PORT_CHAR(UCHAR_MAMEKEY(LALT)) +INPUT_PORTS_END + +static INPUT_PORTS_START(prav8d) + PORT_START("ROW0") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X \xd0\xac") PORT_CODE(KEYCODE_X) PORT_CHAR('X') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V \xd0\x96") PORT_CODE(KEYCODE_V) PORT_CHAR('V') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N \xd0\x9d") PORT_CODE(KEYCODE_N) PORT_CHAR('N') + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'') + + PORT_START("ROW1") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D \xd0\x94") PORT_CODE(KEYCODE_D) PORT_CHAR('D') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q \xd0\xaf") PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Esc") PORT_CODE(KEYCODE_ESC) PORT_CHAR(27) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F \xd0\xa4") PORT_CODE(KEYCODE_F) PORT_CHAR('F') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R \xd0\xa0") PORT_CODE(KEYCODE_R) PORT_CHAR('R') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T \xd0\xa2") PORT_CODE(KEYCODE_T) PORT_CHAR('T') + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J \xd0\x99") PORT_CODE(KEYCODE_J) PORT_CHAR('J') + + PORT_START("ROW2") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C \xd0\xa6") PORT_CODE(KEYCODE_C) PORT_CHAR('C') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z \xd0\x97") PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("MK") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_SHIFT_2) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B \xd0\x91") PORT_CODE(KEYCODE_B) PORT_CHAR('B') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M \xd0\x9c") PORT_CODE(KEYCODE_M) PORT_CHAR('M') + + PORT_START("ROW3") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("] \xd0\xa9") PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(']') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(';') PORT_CHAR('+') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C/L") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) // this one is 5th line, 1st key from right + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR(':') PORT_CHAR('*') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("[ \xd0\xa8") PORT_CODE(KEYCODE_COLON) PORT_CHAR('[') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K \xd0\x9a") PORT_CODE(KEYCODE_K) PORT_CHAR('K') + + PORT_START("ROW4") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_RIGHT) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_DOWN) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_LEFT) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_UP) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + + PORT_START("ROW5") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("@ \xd0\xae") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('@') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("\\ \xd0\xad") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('\\') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Del") PORT_CODE(KEYCODE_DEL) PORT_CHAR(8) // this one is 5th line, 1st key from left + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P \xd0\x9f") PORT_CODE(KEYCODE_P) PORT_CHAR('P') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O \xd0\x9e") PORT_CODE(KEYCODE_O) PORT_CHAR('O') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I \xd0\x98") PORT_CODE(KEYCODE_I) PORT_CHAR('I') + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U \xd0\xa3") PORT_CODE(KEYCODE_U) PORT_CHAR('U') + + PORT_START("ROW6") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W \xd0\x92") PORT_CODE(KEYCODE_W) PORT_CHAR('W') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S \xd0\xa1") PORT_CODE(KEYCODE_S) PORT_CHAR('S') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A \xd0\x90") PORT_CODE(KEYCODE_A) PORT_CHAR('A') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E \xd0\x95") PORT_CODE(KEYCODE_E) PORT_CHAR('E') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G \xd0\x93") PORT_CODE(KEYCODE_G) PORT_CHAR('G') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H \xd0\xa5") PORT_CODE(KEYCODE_H) PORT_CHAR('H') + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y \xd0\xaa") PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') + + PORT_START("ROW7") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('-') PORT_CHAR('=') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("^ \xd0\xa7") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('^') // this one would be on 2nd line, 3rd key from 'P' + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RSHIFT) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L \xd0\x9b") PORT_CODE(KEYCODE_L) PORT_CHAR('L') + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') + + PORT_START("NMI") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("NMI") PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_CHANGED_MEMBER(DEVICE_SELF, oric_state, nmi_pressed, 0) + + /* vsync cable hardware. This is a simple cable connected to the video output + to the monitor/television. The sync signal is connected to the cassette input + allowing interrupts to be generated from the vsync signal. */ + PORT_START("CONFIG") + PORT_CONFNAME(0x01, 0x00, "Tape input") + PORT_CONFSETTING( 0x00, "Tape") + PORT_CONFSETTING( 0x01, "VSync cable") +INPUT_PORTS_END + +static INPUT_PORTS_START(telstrat) + PORT_INCLUDE( orica ) + +// The telestrat does not have the NMI button + PORT_MODIFY("NMI") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED) + + PORT_START("JOY1") /* left joystick port */ + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_8WAY PORT_PLAYER(1) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_8WAY PORT_PLAYER(1) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(1) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) PORT_8WAY PORT_PLAYER(1) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_8WAY PORT_PLAYER(1) + + PORT_START("JOY2") /* right joystick port */ + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_8WAY PORT_PLAYER(2) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_8WAY PORT_PLAYER(2) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(2) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) PORT_8WAY PORT_PLAYER(2) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_8WAY PORT_PLAYER(2) +INPUT_PORTS_END + + +void oric_state::oric(machine_config &config, bool add_ext) // this variable not used +{ + /* basic machine hardware */ + M6502(config, m_maincpu, 12_MHz_XTAL / 12); + m_maincpu->set_addrmap(AS_PROGRAM, &oric_state::oric_mem); + + config.set_maximum_quantum(attotime::from_hz(60)); + + /* video hardware */ + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); + screen.set_raw(12_MHz_XTAL / 2, 64*6, 0, 40*6, 312, 0, 28*8); // 260 lines in 60 Hz mode + screen.set_screen_update(FUNC(oric_state::screen_update_oric)); + screen.screen_vblank().set(FUNC(oric_state::vblank_w)); + + PALETTE(config, m_palette, palette_device::RGB_3BIT); + + /* sound hardware */ + SPEAKER(config, "mono").front_center(); + + AY8912(config, m_psg, 12_MHz_XTAL / 12); + m_psg->set_flags(AY8910_DISCRETE_OUTPUT); + m_psg->set_resistors_load(4700, 4700, 4700); + m_psg->port_a_write_callback().set(FUNC(oric_state::psg_a_w)); + m_psg->add_route(ALL_OUTPUTS, "mono", 0.25); + + /* printer */ + CENTRONICS(config, m_centronics, centronics_devices, "printer"); + m_centronics->ack_handler().set(m_via, FUNC(via6522_device::write_ca1)); + + OUTPUT_LATCH(config, m_cent_data_out); + m_centronics->set_output_latch(*m_cent_data_out); + + /* cassette */ + CASSETTE(config, m_cassette, 0); + m_cassette->set_formats(oric_cassette_formats); + m_cassette->set_default_state(CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED); + m_cassette->add_route(ALL_OUTPUTS, "mono", 0.05); + + /* via */ + MOS6522(config, m_via, 12_MHz_XTAL / 12); + m_via->writepa_handler().set(FUNC(oric_state::via_a_w)); + m_via->writepb_handler().set(FUNC(oric_state::via_b_w)); + m_via->ca2_handler().set(FUNC(oric_state::via_ca2_w)); + m_via->cb2_handler().set(FUNC(oric_state::via_cb2_w)); + m_via->irq_handler().set(FUNC(oric_state::via_irq_w)); + + /* extension port */ + ORICEXT_CONNECTOR(config, "ext", oricext_intf, nullptr, "maincpu").irq_callback().set(FUNC(oric_state::ext_irq_w)); +} + +void oric_state::prav8d(machine_config &config) +{ + oric(config, true); +} + +void telestrat_state::floppy_formats(format_registration &fr) +{ + fr.add_mfm_containers(); + fr.add(FLOPPY_ORIC_DSK_FORMAT); +} + +static void telestrat_floppies(device_slot_interface &device) +{ + device.option_add("3dsdd", FLOPPY_3_DSDD); +} + +void telestrat_state::telstrat(machine_config &config) +{ + oric(config, false); + m_maincpu->set_addrmap(AS_PROGRAM, &telestrat_state::telestrat_mem); + + /* acia */ + mos6551_device &acia(MOS6551(config, "acia", 0)); + acia.set_xtal(1.8432_MHz_XTAL); + acia.irq_handler().set(FUNC(telestrat_state::acia_irq_w)); + + /* via */ + MOS6522(config, m_via2, 12_MHz_XTAL / 12); + m_via2->writepa_handler().set(FUNC(telestrat_state::via2_a_w)); + m_via2->writepb_handler().set(FUNC(telestrat_state::via2_b_w)); + m_via2->ca2_handler().set(FUNC(telestrat_state::via2_ca2_w)); + m_via2->cb2_handler().set(FUNC(telestrat_state::via2_cb2_w)); + m_via2->irq_handler().set(FUNC(telestrat_state::via2_irq_w)); + + /* microdisc */ + FD1793(config, m_fdc, 8_MHz_XTAL / 8); + m_fdc->intrq_wr_callback().set(FUNC(telestrat_state::fdc_irq_w)); + m_fdc->drq_wr_callback().set(FUNC(telestrat_state::fdc_drq_w)); + m_fdc->hld_wr_callback().set(FUNC(telestrat_state::fdc_hld_w)); + m_fdc->set_force_ready(true); + + FLOPPY_CONNECTOR(config, "fdc:0", telestrat_floppies, "3dsdd", telestrat_state::floppy_formats); + FLOPPY_CONNECTOR(config, "fdc:1", telestrat_floppies, nullptr, telestrat_state::floppy_formats); + FLOPPY_CONNECTOR(config, "fdc:2", telestrat_floppies, nullptr, telestrat_state::floppy_formats); + FLOPPY_CONNECTOR(config, "fdc:3", telestrat_floppies, nullptr, telestrat_state::floppy_formats); +} + + +ROM_START(oric1) + ROM_REGION(0x4000, "maincpu", 0) + ROM_SYSTEM_BIOS( 0, "ver10", "Basic 1.0") + ROMX_LOAD ("basic10.rom", 0, 0x04000, CRC(f18710b4) SHA1(333116e6884d85aaa4dfc7578a91cceeea66d016), ROM_BIOS(0)) + ROM_SYSTEM_BIOS( 1, "ver10uk", "Basic 1.0 UK") + ROMX_LOAD( "basic10uk.rom", 0, 0x04000, CRC(d6006a01) SHA1(84759cc8faae53070f1c8ce8408982a0edcb0796), ROM_BIOS(1)) +ROM_END + +ROM_START(orica) + ROM_REGION(0x4000, "maincpu", 0) + ROM_SYSTEM_BIOS( 0, "ver11", "Basic 1.1") + ROMX_LOAD ("basic11b.rom", 0, 0x04000, CRC(c3a92bef) SHA1(9451a1a09d8f75944dbd6f91193fc360f1de80ac), ROM_BIOS(0) ) + ROM_SYSTEM_BIOS( 1, "ver12", "Basic 1.2 (Pascal Leclerc)") // 1987/1999 - various enhancements and bugfixes + ROMX_LOAD ("basic12.rom", 0, 0x04000, CRC(dc4f22dc) SHA1(845e1a893de3dc0f856fdf2f69c3b73770b4094f), ROM_BIOS(1) ) + ROM_SYSTEM_BIOS( 2, "ver121", "Basic 1.21 (Pascal Leclerc)") // 07.1999 - DRAW enhancement + ROMX_LOAD ("basic121.rom", 0, 0x04000, CRC(0a2860b1) SHA1(b727d5c3bbc8cb1d510f224eb1e0d90d609e8506), ROM_BIOS(2) ) + ROM_SYSTEM_BIOS( 3, "ver122", "Basic 1.22 (Pascal Leclerc)") // 08.2001 - added EUR symbol + ROMX_LOAD ("basic122.rom", 0, 0x04000, CRC(5ef2a861) SHA1(9ab6dc47b6e9dc65a4137ce0f0f12fc2b6ca8442), ROM_BIOS(3) ) + ROM_SYSTEM_BIOS( 4, "ver11de", "Basic 1.1 DE") + ROMX_LOAD( "bas11_de.rom", 0, 0x04000, CRC(65233b2d) SHA1(b01cabb1a21980a6785a2fe37a8f8572c892123f), ROM_BIOS(4)) + ROM_SYSTEM_BIOS( 5, "ver11es", "Basic 1.1 ES") + ROMX_LOAD( "bas11_es.rom", 0, 0x04000, CRC(47bf26c7) SHA1(4fdbadd68db9ab8ad1cd56b4e5cbe51a9c3f11ae), ROM_BIOS(5)) + ROM_SYSTEM_BIOS( 6, "ver11fr", "Basic 1.1 FR") + ROMX_LOAD( "bas11_fr.rom", 0, 0x04000, CRC(603b1fbf) SHA1(2a4583df3b59ca454d67d5631f242c96ec4cf99a), ROM_BIOS(6)) + ROM_SYSTEM_BIOS( 7, "ver11se", "Basic 1.1 SE") + ROMX_LOAD( "bas11_se.rom", 0, 0x04000, CRC(a71523ac) SHA1(ce53acf84baec6ab5cbac9f9cefa71b3efeb2ead), ROM_BIOS(7)) + ROM_SYSTEM_BIOS( 8, "ver11uk", "Basic 1.1 UK") + ROMX_LOAD( "bas11_uk.rom", 0, 0x04000, CRC(303370d1) SHA1(589ff66fac8e06d65af3369491faa67a71f1322a), ROM_BIOS(8)) + ROM_SYSTEM_BIOS( 9, "ver12es", "Basic 1.2 ES") + ROMX_LOAD( "bas12es_le.rom", 0, 0x04000, CRC(70de4aeb) SHA1(b327418aa7d8a5a03c135e3d8acdd511df625893), ROM_BIOS(9)) + ROM_SYSTEM_BIOS( 10, "ver12fr", "Basic 1.2 FR") + ROMX_LOAD( "bas12fr_le.rom", 0, 0x04000, CRC(47a437fc) SHA1(70271bc3ed5c3bf4d339d6f5de3de8c3c50ff573), ROM_BIOS(10)) + ROM_SYSTEM_BIOS( 11, "ver12ge", "Basic 1.2 GE") + ROMX_LOAD( "bas12ge_le.rom", 0, 0x04000, CRC(f5f0dd52) SHA1(75359302452ee7b19537698f124aaefd333688d0), ROM_BIOS(11)) + ROM_SYSTEM_BIOS( 12, "ver12sw", "Basic 1.2 SW") + ROMX_LOAD( "bas12sw_le.rom", 0, 0x04000, CRC(100abe68) SHA1(6211d5969c4d7a6acb86ed19c5e51a33a3bef431), ROM_BIOS(12)) + ROM_SYSTEM_BIOS( 13, "ver12uk", "Basic 1.2 UK") + ROMX_LOAD( "bas12uk_le.rom", 0, 0x04000, CRC(00fce8a6) SHA1(d40558bdf61b8aba6260293c9424fd463be7fad8), ROM_BIOS(13)) + ROM_SYSTEM_BIOS( 14, "ver121es", "Basic 1.211 ES") + ROMX_LOAD( "bas121es_le.rom", 0, 0x04000, CRC(87ec679b) SHA1(5de6a5f5121f69069c9b93d678046e814b5b64e9), ROM_BIOS(14)) + ROM_SYSTEM_BIOS( 15, "ver121fr", "Basic 1.211 FR") + ROMX_LOAD( "bas121fr_le.rom", 0, 0x04000, CRC(e683dec2) SHA1(20df7ebc0f13aa835f286d50137f1a7ff7430c29), ROM_BIOS(15)) + ROM_SYSTEM_BIOS( 16, "ver121ge", "Basic 1.211 GE") + ROMX_LOAD( "bas121ge_le.rom", 0, 0x04000, CRC(94fe32bf) SHA1(1024776d20030d602e432e50014502524658643a), ROM_BIOS(16)) + ROM_SYSTEM_BIOS( 17, "ver121sw", "Basic 1.211 SW") + ROMX_LOAD( "bas121sw_le.rom", 0, 0x04000, CRC(e6ad11c7) SHA1(309c94a9861fcb770636dcde1801a5c68ca819b4), ROM_BIOS(17)) + ROM_SYSTEM_BIOS( 18, "ver121uk", "Basic 1.211 UK") + ROMX_LOAD( "bas121uk_le.rom", 0, 0x04000, CRC(75aa1aa9) SHA1(ca99e244d9cbef625344c2054023504a4f9dcfe4), ROM_BIOS(18)) + ROM_SYSTEM_BIOS( 19, "ver122es", "Basic 1.22 ES") + ROMX_LOAD( "bas122es_le.rom", 0, 0x04000, CRC(9144f9e0) SHA1(acf2094078af057e74a31d90d7010be51b9033fa), ROM_BIOS(19)) + ROM_SYSTEM_BIOS( 20, "ver122fr", "Basic 1.22 FR") + ROMX_LOAD( "bas122fr_le.rom", 0, 0x04000, CRC(370cfda4) SHA1(fad9a0661256e59bcc2915578647573e4128e1bb), ROM_BIOS(20)) + ROM_SYSTEM_BIOS( 21, "ver122ge", "Basic 1.22 GE") + ROMX_LOAD( "bas122ge_le.rom", 0, 0x04000, CRC(9a42bd62) SHA1(8a9c80f314daf4e5e64fa202e583b8a65796db8b), ROM_BIOS(21)) + ROM_SYSTEM_BIOS( 22, "ver122sw", "Basic 1.22 SW") + ROMX_LOAD( "bas122sw_le.rom", 0, 0x04000, CRC(e7fd57a4) SHA1(c75cbf7cfafaa02712dc7ca2f972220aef86fb8d), ROM_BIOS(22)) + ROM_SYSTEM_BIOS( 23, "ver122uk", "Basic 1.22 UK") + ROMX_LOAD( "bas122uk_le.rom", 0, 0x04000, CRC(9865bcd7) SHA1(2a92e2d119463e682bf10647e3880e26656d65b5), ROM_BIOS(23)) +ROM_END + +ROM_START(telstrat) + ROM_REGION(0x4000, "telmatic", 0) + ROM_LOAD ("telmatic.rom", 0, 0x2000, CRC(94358dc6) SHA1(35f92a0477a88f5cf564971125047ffcfa02ec10) ) + ROM_RELOAD (0x2000, 0x2000) + + ROM_REGION(0x4000, "teleass", 0) + ROM_LOAD ("teleass.rom", 0, 0x4000, CRC(68b0fde6) SHA1(9e9af51dae3199cccf49ab3f0d47e2b9be4ba97d) ) + + ROM_REGION(0x4000, "hyperbas", 0) + ROM_LOAD ("hyperbas.rom", 0, 0x4000, CRC(1d96ab50) SHA1(f5f70a0eb59f8cd6c261e179ae78ef906f68ed63) ) + + ROM_REGION(0x4000, "telmon24", 0) + ROM_LOAD ("telmon24.rom", 0, 0x4000, CRC(aa727c5d) SHA1(86fc8dc0932f983efa199e31ae05a4424772f959) ) +ROM_END + +ROM_START(prav8d) + ROM_REGION(0x4000, "maincpu", 0) /* 0x10000 + 0x04000 + 0x00100 + 0x00200 */ + ROM_LOAD( "pravetzt.rom", 0, 0x4000, CRC(58079502) SHA1(7afc276cb118adff72e4f16698f94bf3b2c64146) ) +// ROM_LOAD_OPTIONAL( "8ddoslo.rom", 0x014000, 0x0100, CRC(0c82f636) SHA1(b29d151a0dfa3c7cd50439b51d0a8f95559bc2b6) ) +// ROM_LOAD_OPTIONAL( "8ddoshi.rom", 0x014100, 0x0200, CRC(66309641) SHA1(9c2e82b3c4d385ade6215fcb89f8b92e6fd2bf4b) ) +ROM_END + +ROM_START(prav8dd) + ROM_REGION(0x4000, "maincpu", 0) /* 0x10000 + 0x04000 + 0x00100 + 0x00200 */ + ROM_SYSTEM_BIOS( 0, "default", "Disk ROM, 1989") + ROMX_LOAD( "8d.rom", 0, 0x4000, CRC(b48973ef) SHA1(fd47c977fc215a3b577596a7483df53e8a1e9c83), ROM_BIOS(0) ) + ROM_SYSTEM_BIOS( 1, "radosoft", "RadoSoft Disk ROM, 1992") + ROMX_LOAD( "pravetzd.rom", 0, 0x4000, CRC(f8d23821) SHA1(f87ad3c5832773b6e0614905552a80c98dc8e2a5), ROM_BIOS(1) ) +// ROM_LOAD_OPTIONAL( "8ddoslo.rom", 0x014000, 0x0100, CRC(0c82f636) SHA1(b29d151a0dfa3c7cd50439b51d0a8f95559bc2b6) ) +// ROM_LOAD_OPTIONAL( "8ddoshi.rom", 0x014100, 0x0200, CRC(66309641) SHA1(9c2e82b3c4d385ade6215fcb89f8b92e6fd2bf4b) ) +ROM_END + + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1983, oric1, 0, 0, oric, oric, oric_state, empty_init, "Tangerine", "Oric 1" , MACHINE_SUPPORTS_SAVE ) +COMP( 1984, orica, oric1, 0, oric, orica, oric_state, empty_init, "Tangerine", "Oric Atmos" , MACHINE_SUPPORTS_SAVE ) +COMP( 1985, prav8d, oric1, 0, prav8d, prav8d, oric_state, empty_init, "Pravetz", "Pravetz 8D", MACHINE_SUPPORTS_SAVE ) +COMP( 1989, prav8dd, oric1, 0, prav8d, prav8d, oric_state, empty_init, "Pravetz", "Pravetz 8D (Disk ROM)", MACHINE_UNOFFICIAL | MACHINE_SUPPORTS_SAVE ) +COMP( 1986, telstrat, oric1, 0, telstrat, telstrat, telestrat_state, empty_init, "Tangerine", "Oric Telestrat", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/tektroni/tek405x.cpp b/src/mame/tektroni/tek405x.cpp deleted file mode 100644 index b03d1c76233..00000000000 --- a/src/mame/tektroni/tek405x.cpp +++ /dev/null @@ -1,1193 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Curt Coder -/*************************************************************************** - - Tektronix 4051/4052A - - Skeleton driver. - - http://www.electronixandmore.com/articles/teksystem.html - -****************************************************************************/ - -/* - - TODO: - - - bank switch - - keyboard - - video (persistent vector display) - - joystick - - magnetic tape storage (3M 300) - - communications backpack - - 4051E01 ROM expander - -*/ - - -#include "emu.h" -#include "tek405x.h" -#include "screen.h" -#include "softlist_dev.h" -#include "speaker.h" - - -//************************************************************************** -// MACROS / CONSTANTS -//************************************************************************** - -enum { - LBS_RBC = 0, // ROM Bank Control - LBS_BSOFL, // Bank Switch Overflow (Select Overflow ROMs) - LBS_BSCOM, // Bank Switch Communication (Select Communication ROMs) - LBS_INVALID, - LBS_BS_L, // Bank Switch Left (Select Left ROM Pack) - LBS_BS_R, // Bank Switch Right (Select Right ROM Pack) - LBS_BSX_L, // Bank Switch Expander (Select Left ROM Expander Unit) - LBS_BSX_R // Bank Switch Expander (Select Right ROM Expander Unit) -}; - - -//************************************************************************** -// INTERRUPTS -//************************************************************************** - -void tek4051_state::update_irq() -{ - int state = m_kb_pia_irqa | m_kb_pia_irqb | m_x_pia_irqa | m_x_pia_irqb | m_gpib_pia_irqa | m_gpib_pia_irqb | m_com_pia_irqa | m_com_pia_irqb | m_acia_irq; - - m_maincpu->set_input_line(INPUT_LINE_IRQ0, state); -} - -void tek4051_state::update_nmi() -{ - int state = m_y_pia_irqa | m_y_pia_irqb | m_tape_pia_irqa | m_tape_pia_irqb; - - m_maincpu->set_input_line(INPUT_LINE_NMI, state); -} - - -//************************************************************************** -// KEYBOARD -//************************************************************************** - -void tek4051_state::scan_keyboard() -{ -} - -TIMER_DEVICE_CALLBACK_MEMBER(tek4051_state::keyboard_tick) -{ - scan_keyboard(); -} - - -//************************************************************************** -// MEMORY BANKING -//************************************************************************** - -void tek4051_state::bankswitch(uint8_t data) -{ - address_space &program = m_maincpu->space(AS_PROGRAM); - - //int d = data & 0x07; - int lbs = (data >> 3) & 0x07; - - switch (lbs) - { - case LBS_RBC: - program.install_rom(0x8800, 0xa7ff, m_rom->base() + 0x800); - break; - - case LBS_BSOFL: - program.install_rom(0x8800, 0xa7ff, m_bsofl_rom->base()); - break; - - case LBS_BSCOM: - program.install_rom(0x8800, 0xa7ff, m_bscom_rom->base()); - break; - - default: - program.unmap_readwrite(0x8800, 0xa7ff); - } -} - -void tek4051_state::lbs_w(uint8_t data) -{ - /* - - bit description - - 0 ROM Expander Slot Address - 1 ROM Expander Slot Address - 2 ROM Expander Slot Address - 3 Bank Switch - 4 Bank Switch - 5 Bank Switch - 6 - 7 - - */ - - logerror("LBS %02x\n", data); - - bankswitch(data); -} - - -//************************************************************************** -// ADDRESS MAPS -//************************************************************************** - -void tek4051_state::tek4051_mem(address_map &map) -{ - map(0x0000, 0x1fff).ram(); - map(0x2000, 0x7fff).ram(); // optional RAM - map(0x8000, 0x877f).rom().region(MC6800_TAG, 0); - map(0x878c, 0x878f).rw(MC6820_Y_TAG, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); - map(0x8794, 0x8797).rw(MC6820_X_TAG, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); - map(0x8798, 0x879b).rw(MC6820_TAPE_TAG, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); - map(0x87a8, 0x87ab).rw(MC6820_KB_TAG, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); - map(0x87b0, 0x87b3).rw(m_gpib_pia, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); - map(0x87c0, 0x87c0).mirror(0x03).w(FUNC(tek4051_state::lbs_w)); -// map(0x87c0, 0x87c3).rw(MC6820_COM_TAG, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); -// map(0x87c4, 0x87c5).mirror(0x02).rw(MC6850_TAG, FUNC(acia6850_device::read), FUNC(acia6850_device::write)); -// map(0x87c8, 0x87cb) XPC2 -// map(0x87cc, 0x87cf) XPC3 -// map(0x87d0, 0x87d3) XPC4 - map(0x8800, 0xa7ff).rom().region(MC6800_TAG, 0x800); - map(0xa800, 0xffff).rom().region(MC6800_TAG, 0x2800); -} - -void tek4052_state::tek4052_mem(address_map &map) -{ -} - - -//************************************************************************** -// INPUT PORTS -//************************************************************************** - -static INPUT_PORTS_START( tek4051 ) - PORT_START("Y0") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) - - PORT_START("Y1") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) - - PORT_START("Y2") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) - - PORT_START("Y3") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) - - PORT_START("Y4") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) - - PORT_START("Y5") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) - - PORT_START("Y6") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) - - PORT_START("Y7") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) - - PORT_START("Y8") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) - - PORT_START("Y9") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) - - PORT_START("Y10") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) - - PORT_START("Y11") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) - - PORT_START("Y12") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) - - PORT_START("Y13") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) - - PORT_START("Y14") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) - - PORT_START("Y15") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) - - PORT_START("SPECIAL") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Left SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Right SHIFT") PORT_CODE(KEYCODE_RSHIFT) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("TTY LOCK") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) -INPUT_PORTS_END - - -//************************************************************************** -// VIDEO -//************************************************************************** - -void tek4051_state::video_start() -{ -} - - -void tek4052_state::video_start() -{ -} - - -//************************************************************************** -// DEVICE CONFIGURATION -//************************************************************************** - -uint8_t tek4051_state::x_pia_pa_r() -{ - /* - - bit description - - PA0 - PA1 - PA2 DRBUSY-0 - PA3 VPULSE-1 - PA4 - PA5 - PA6 - PA7 - - */ - - return 0; -} - -void tek4051_state::x_pia_pa_w(uint8_t data) -{ - /* - - bit description - - PA0 X D/A - PA1 X D/A - PA2 - PA3 - PA4 ERASE-0 - PA5 COPY-0 - PA6 VECTOR-0 - PA7 VEN-1 - - */ -} - -void tek4051_state::x_pia_pb_w(uint8_t data) -{ - /* - - bit description - - PB0 X D/A - PB1 X D/A - PB2 X D/A - PB3 X D/A - PB4 X D/A - PB5 X D/A - PB6 X D/A - PB7 X D/A - - */ -} - -WRITE_LINE_MEMBER( tek4051_state::adot_w ) -{ -} - -WRITE_LINE_MEMBER( tek4051_state::bufclk_w ) -{ -} - -WRITE_LINE_MEMBER( tek4051_state::x_pia_irqa_w ) -{ - m_x_pia_irqa = state; - update_irq(); -} - -WRITE_LINE_MEMBER( tek4051_state::x_pia_irqb_w ) -{ - m_x_pia_irqb = state; - update_irq(); -} - -uint8_t tek4051_state::sa_r() -{ - /* - - bit description - - PA0 SA0 - PA1 SA1 - PA2 SA2 - PA3 SA3 - PA4 SA4 - PA5 SA5 - PA6 SA6 - PA7 SA7 - - */ - - return 0; -} - -void tek4051_state::y_pia_pa_w(uint8_t data) -{ - /* - - bit description - - PA0 Y D/A - PA1 Y D/A - PA2 Y CHAR D/A - PA3 Y CHAR D/A - PA4 Y CHAR D/A - PA5 X CHAR D/A - PA6 X CHAR D/A - PA7 X CHAR D/A - - */ -} - -void tek4051_state::sb_w(uint8_t data) -{ - /* - - bit description - - PB0 SB0 - PB1 SB1 - PB2 SB2 - PB3 SB3 - PB4 SB4 - PB5 SB5 - PB6 SB6 - PB7 SB7 - - */ -} - -WRITE_LINE_MEMBER( tek4051_state::sot_w ) -{ -} - -WRITE_LINE_MEMBER( tek4051_state::y_pia_irqa_w ) -{ - m_y_pia_irqa = state; - update_nmi(); -} - -WRITE_LINE_MEMBER( tek4051_state::y_pia_irqb_w ) -{ - m_y_pia_irqb = state; - update_nmi(); -} - - -uint8_t tek4051_state::kb_pia_pa_r() -{ - /* - - bit description - - PA0 KC0-1 - PA1 KC1-1 - PA2 KC2-1 - PA3 KC3-1 - PA4 KC4-1 - PA5 KC5-1 - PA6 KC6-1 - PA7 TTY-0 - - */ - - uint8_t data = 0; - uint8_t special = m_special->read(); - - // keyboard column - data = m_kc; - - // TTY lock - data |= BIT(special, 3) << 7; - - return data; -} - -uint8_t tek4051_state::kb_pia_pb_r() -{ - /* - - bit description - - PB0 SHIFT-0 - PB1 CTRL-0 - PB2 - PB3 LOAD-0 - PB4 - PB5 - PB6 - PB7 - - */ - - uint8_t data = 0; - uint8_t special = m_special->read(); - - // shift - data |= (BIT(special, 0) & BIT(special, 1)); - - // ctrl - data |= BIT(special, 2) << 1; - - return data; -} - -void tek4051_state::kb_pia_pb_w(uint8_t data) -{ - /* - - bit description - - PB0 - PB1 - PB2 - PB3 - PB4 EOI-1 - PB5 BREAK-1 - PB6 I/O-1 - PB7 BUSY-1/REN-0/SPEAKER - - */ - - // lamps - m_lamps[0] = BIT(~data, 5); - m_lamps[1] = BIT(~data, 6); - m_lamps[2] = BIT(~data, 7); - - // end or identify - m_gpib->host_eoi_w(!BIT(data, 4)); - - // speaker - m_speaker->level_w(!BIT(data, 7)); - - // remote enable - m_gpib->host_ren_w(!BIT(data, 7)); -} - -WRITE_LINE_MEMBER( tek4051_state::kb_halt_w ) -{ -} - -WRITE_LINE_MEMBER( tek4051_state::kb_pia_irqa_w ) -{ - m_kb_pia_irqa = state; - update_irq(); -} - -WRITE_LINE_MEMBER( tek4051_state::kb_pia_irqb_w ) -{ - m_kb_pia_irqb = state; - update_irq(); -} - - -uint8_t tek4051_state::tape_pia_pa_r() -{ - /* - - bit description - - PA0 DELAY OUT-1 - PA1 - PA2 TUTS-1 - PA3 SAFE-1 - PA4 SAFE-1 - PA5 JOYSTICK - PA6 FILFND-1 - PA7 JOYSTICK - - */ - - return 0; -} - -void tek4051_state::tape_pia_pa_w(uint8_t data) -{ - /* - - bit description - - PA0 - PA1 LDCLK-1 - PA2 - PA3 - PA4 - PA5 XERR-1 - PA6 - PA7 YERR-1 - - */ -} - -void tek4051_state::tape_pia_pb_w(uint8_t data) -{ - /* - - bit description - - PB0 WR-0 - PB1 FAST-1 - PB2 REV-1 - PB3 DRTAPE-0 - PB4 GICG-1 - PB5 FICG-1 - PB6 WENABLE-1 - PB7 FSENABLE-0 - - */ -} - -WRITE_LINE_MEMBER( tek4051_state::tape_pia_irqa_w ) -{ - m_tape_pia_irqa = state; - update_nmi(); -} - -WRITE_LINE_MEMBER( tek4051_state::tape_pia_irqb_w ) -{ - m_tape_pia_irqb = state; - update_nmi(); -} - -void tek4051_state::dio_w(uint8_t data) -{ - /* - - bit description - - PA0 DIO1-1 - PA1 DIO2-1 - PA2 DIO3-1 - PA3 DIO4-1 - PA4 DIO5-1 - PA5 DIO6-1 - PA6 DIO7-1 - PA7 DIO8-1 - - */ - - if (m_talk) - { - m_gpib->host_dio_w(data); - } -} - -uint8_t tek4051_state::gpib_pia_pb_r() -{ - /* - - bit description - - PB0 - PB1 - PB2 - PB3 - PB4 NRFD - PB5 SRQ-1 - PB6 DAV-1 - PB7 NDAC - - */ - - uint8_t data = 0; - - // service request - data |= m_gpib->srq_r() << 5; - - // data valid - data |= m_gpib->dav_r() << 6; - - if (!m_talk) - { - // not ready for data - data |= m_gpib->nrfd_r() << 4; - - // not data acknowledged - data |= m_gpib->ndac_r() << 7; - } - - return data; -} - -void tek4051_state::gpib_pia_pb_w(uint8_t data) -{ - /* - - bit description - - PB0 EOI-1 - PB1 IFC-1 - PB2 - PB3 ATN-0 - PB4 NRFD - PB5 - PB6 - PB7 NDAC - - */ - - // end or identify - m_gpib->host_eoi_w(!BIT(data, 0)); - - // interface clear - m_gpib->host_ifc_w(!BIT(data, 1)); - - // attention - m_gpib->host_atn_w(BIT(data, 3)); - - if (m_talk) - { - // not ready for data - m_gpib->host_nrfd_w(!BIT(data, 4)); - - // not data acknowledged - m_gpib->host_ndac_w(!BIT(data, 7)); - } -} - -WRITE_LINE_MEMBER( tek4051_state::talk_w ) -{ - m_talk = state; - - if (!m_talk) - { - m_gpib->host_dio_w(0xff); - m_gpib->host_nrfd_w(1); - m_gpib->host_ndac_w(1); - } -} - -WRITE_LINE_MEMBER( tek4051_state::gpib_pia_irqa_w ) -{ - m_gpib_pia_irqa = state; - update_irq(); -} - -WRITE_LINE_MEMBER( tek4051_state::gpib_pia_irqb_w ) -{ - m_gpib_pia_irqb = state; - update_irq(); -} - -void tek4051_state::com_pia_pa_w(uint8_t data) -{ - /* - - bit description - - PA0 - PA1 - PA2 - PA3 Bank Switch Register - PA4 Bank Switch Register - PA5 Bank Switch Register - PA6 - PA7 - - */ - - bankswitch(data); -} - -uint8_t tek4051_state::com_pia_pb_r() -{ - /* - - bit description - - PB0 SRX - PB1 DTR - PB2 RTS - PB3 - PB4 - PB5 - PB6 - PB7 - - */ - - uint8_t data = 0; - - // data terminal ready - - // request to send - - return data; -} - -void tek4051_state::com_pia_pb_w(uint8_t data) -{ - /* - - bit description - - PB0 - PB1 - PB2 - PB3 CTS - PB4 STXA-C - PB5 Baud Rate Select - PB6 Baud Rate Select - PB7 Baud Rate Select - - */ - - // clear to send - - // baud rate select - int osc = BIT(data, 7) ? 28160 : 38400; - int div = 1; - - switch ((data >> 5) & 0x03) - { - case 2: div = 4; break; - case 3: div = 2; break; - } - - m_acia_clock->set_unscaled_clock(osc); - m_acia_clock->set_clock_scale((double) 1 / div); -} - -WRITE_LINE_MEMBER( tek4051_state::com_pia_irqa_w ) -{ - m_com_pia_irqa = state; - update_irq(); -} - -WRITE_LINE_MEMBER( tek4051_state::com_pia_irqb_w ) -{ - m_com_pia_irqb = state; - update_irq(); -} - -WRITE_LINE_MEMBER( tek4051_state::acia_irq_w ) -{ - m_acia_irq = state; - update_irq(); -} - -WRITE_LINE_MEMBER( tek4051_state::write_acia_clock ) -{ - m_acia->write_txc(state); - m_acia->write_rxc(state); -} - - -//************************************************************************** -// MACHINE INITIALIZATION -//************************************************************************** - -void tek4051_state::machine_start() -{ - m_lamps.resolve(); - - address_space &program = m_maincpu->space(AS_PROGRAM); - - // configure RAM - switch (m_ram->size()) - { - case 8*1024: - program.unmap_readwrite(0x2000, 0x7fff); - break; - - case 16*1024: - program.unmap_readwrite(0x4000, 0x7fff); - break; - - case 24*1024: - program.unmap_readwrite(0x6000, 0x7fff); - break; - } - - m_x_pia_irqa = 0; - m_x_pia_irqb = 0; - m_y_pia_irqa = 0; - m_y_pia_irqb = 0; - m_tape_pia_irqa = 0; - m_tape_pia_irqb = 0; - m_kb_pia_irqa = 0; - m_kb_pia_irqb = 0; - m_gpib_pia_irqa = 0; - m_gpib_pia_irqb = 0; - m_com_pia_irqa = 0; - m_com_pia_irqb = 0; - m_acia_irq = 0; - - // register for state saving -} - -void tek4052_state::machine_start() -{ -} - - -//************************************************************************** -// MACHINE CONFIGURATION -//************************************************************************** - -void tek4051_state::tek4051(machine_config &config) -{ - // basic machine hardware - M6800(config, m_maincpu, XTAL(12'500'000)/15); - m_maincpu->set_addrmap(AS_PROGRAM, &tek4051_state::tek4051_mem); - - // video hardware - VECTOR(config, "vector", 0); - screen_device &screen(SCREEN(config, SCREEN_TAG, SCREEN_TYPE_VECTOR)); - screen.set_color(rgb_t::green()); - screen.set_refresh_hz(50); - screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); // not accurate - screen.set_size(1024, 780); - screen.set_visarea(0, 1024-1, 0, 780-1); - screen.set_screen_update("vector", FUNC(vector_device::screen_update)); - - PALETTE(config, "palette", palette_device::MONOCHROME); - - // sound hardware - SPEAKER(config, "mono").front_center(); - SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25); - - // devices - TIMER(config, "keyboard").configure_periodic(FUNC(tek4051_state::keyboard_tick), attotime::from_hz(XTAL(12'500'000)/15/4)); - - pia6821_device &piax(PIA6821(config, MC6820_X_TAG, 0)); - piax.readpa_handler().set(FUNC(tek4051_state::x_pia_pa_r)); - // CB1 viewcause - piax.writepa_handler().set(FUNC(tek4051_state::x_pia_pa_w)); - piax.writepb_handler().set(FUNC(tek4051_state::x_pia_pb_w)); - piax.ca2_handler().set(FUNC(tek4051_state::adot_w)); - piax.cb2_handler().set(FUNC(tek4051_state::bufclk_w)); - piax.irqa_handler().set(FUNC(tek4051_state::x_pia_irqa_w)); - piax.irqb_handler().set(FUNC(tek4051_state::x_pia_irqb_w)); - - pia6821_device &piay(PIA6821(config, MC6820_Y_TAG, 0)); - piay.readpa_handler().set(FUNC(tek4051_state::sa_r)); - // CA1 rdbyte - // CB1 mdata - // CB2 fmark - piay.writepa_handler().set(FUNC(tek4051_state::y_pia_pa_w)); - piay.writepb_handler().set(FUNC(tek4051_state::sb_w)); - piay.ca2_handler().set(FUNC(tek4051_state::sot_w)); - piay.irqa_handler().set(FUNC(tek4051_state::y_pia_irqa_w)); - piay.irqb_handler().set(FUNC(tek4051_state::y_pia_irqb_w)); - - pia6821_device &piakbd(PIA6821(config, MC6820_KB_TAG, 0)); - piakbd.readpa_handler().set(FUNC(tek4051_state::kb_pia_pa_r)); - piakbd.readpb_handler().set(FUNC(tek4051_state::kb_pia_pb_r)); - // CA1 key - piakbd.writepb_handler().set(FUNC(tek4051_state::kb_pia_pb_w)); - piakbd.ca2_handler().set(FUNC(tek4051_state::kb_halt_w)); - piakbd.irqa_handler().set(FUNC(tek4051_state::kb_pia_irqa_w)); - piakbd.irqb_handler().set(FUNC(tek4051_state::kb_pia_irqb_w)); - - pia6821_device &piatape(PIA6821(config, MC6820_TAPE_TAG, 0)); - piatape.readpa_handler().set(FUNC(tek4051_state::tape_pia_pa_r)); - // CA1 rmark - // CB1 lohole - // CA2 filfnd - // CB2 uphole - piatape.writepa_handler().set(FUNC(tek4051_state::tape_pia_pa_w)); - piatape.writepb_handler().set(FUNC(tek4051_state::tape_pia_pb_w)); - piatape.irqa_handler().set(FUNC(tek4051_state::tape_pia_irqa_w)); - piatape.irqb_handler().set(FUNC(tek4051_state::tape_pia_irqb_w)); - - PIA6821(config, m_gpib_pia, 0); - m_gpib_pia->readpa_handler().set(IEEE488_TAG, FUNC(ieee488_device::dio_r)); - m_gpib_pia->readpb_handler().set(FUNC(tek4051_state::gpib_pia_pb_r)); - m_gpib_pia->writepa_handler().set(FUNC(tek4051_state::dio_w)); - m_gpib_pia->writepb_handler().set(FUNC(tek4051_state::gpib_pia_pb_w)); - m_gpib_pia->cb2_handler().set(FUNC(tek4051_state::talk_w)); - m_gpib_pia->irqa_handler().set(FUNC(tek4051_state::gpib_pia_irqa_w)); - m_gpib_pia->irqb_handler().set(FUNC(tek4051_state::gpib_pia_irqb_w)); - - PIA6821(config, m_com_pia, 0); - m_com_pia->readpb_handler().set(FUNC(tek4051_state::com_pia_pb_r)); - //CA1 - SRX (RS-232 pin 12) - m_com_pia->writepa_handler().set(FUNC(tek4051_state::com_pia_pa_w)); - m_com_pia->writepb_handler().set(FUNC(tek4051_state::com_pia_pb_w)); - m_com_pia->irqa_handler().set(FUNC(tek4051_state::com_pia_irqa_w)); - m_com_pia->irqb_handler().set(FUNC(tek4051_state::com_pia_irqb_w)); - - ACIA6850(config, m_acia, 0); - m_acia->irq_handler().set(FUNC(tek4051_state::acia_irq_w)); - - CLOCK(config, m_acia_clock, 38400); - m_acia_clock->signal_handler().set(FUNC(tek4051_state::write_acia_clock)); - - IEEE488(config, m_gpib); - m_gpib->eoi_callback().set(MC6820_GPIB_TAG, FUNC(pia6821_device::ca1_w)); - m_gpib->srq_callback().set(MC6820_GPIB_TAG, FUNC(pia6821_device::cb1_w)); - - // internal ram - RAM(config, RAM_TAG).set_default_size("8K").set_extra_options("16K,24K,32K"); - - // cartridge - GENERIC_CARTSLOT(config, "cartslot1", generic_plain_slot, "tek4050_cart"); - GENERIC_CARTSLOT(config, "cartslot2", generic_plain_slot, "tek4050_cart"); -} - -void tek4052_state::tek4052(machine_config &config) -{ - // basic machine hardware - m6800_cpu_device &cpu(M6800(config, AM2901A_TAG, 1000000)); // should be 4x AM2901A + AM2911 - cpu.set_addrmap(AS_PROGRAM, &tek4052_state::tek4052_mem); - - // video hardware - VECTOR(config, "vector", 0); - screen_device &screen(SCREEN(config, SCREEN_TAG, SCREEN_TYPE_VECTOR)); - screen.set_color(rgb_t::green()); - screen.set_refresh_hz(50); - screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); // not accurate - screen.set_size(1024, 780); - screen.set_visarea(0, 1024-1, 0, 780-1); - screen.set_screen_update("vector", FUNC(vector_device::screen_update)); - - PALETTE(config, "palette", palette_device::MONOCHROME); - - // sound hardware - SPEAKER(config, "mono").front_center(); - SPEAKER_SOUND(config, "speaker").add_route(ALL_OUTPUTS, "mono", 0.25); - - // internal ram - RAM(config, RAM_TAG).set_default_size("32K").set_extra_options("64K"); - - // cartridge - GENERIC_CARTSLOT(config, "cartslot1", generic_plain_slot, "tek4050_cart"); - GENERIC_CARTSLOT(config, "cartslot2", generic_plain_slot, "tek4050_cart"); - - // software lists - SOFTWARE_LIST(config, "cart_list").set_original("tek4052_cart"); -} - -/* -void tek4054_state::tek4054(machine_config &config) -{ - // screen size: 4096, 3125 -} -*/ - - - -//************************************************************************** -// ROMS -//************************************************************************** - -ROM_START( tek4051 ) - ROM_REGION( 0x8000, MC6800_TAG, 0 ) - ROM_LOAD( "156-0659-xx.u585", 0x0000, 0x0800, CRC(0017ba54) SHA1(533bfacb2e698c1df88a00acce6df6a8c536239d) ) // -01 or -02 ? - ROM_LOAD( "156-0660-01.u581", 0x0800, 0x0800, CRC(c4e302e8) SHA1(a0438cbc70ddc1bab000e30c0f835f0948aae969) ) - ROM_LOAD( "156-0661-01.u487", 0x1000, 0x0800, CRC(edb097c8) SHA1(a07b777b6b20de496089730db8097b65b9a8ef31) ) - ROM_LOAD( "156-0662-01.u485", 0x1800, 0x0800, CRC(0a3af548) SHA1(01bcffa7d55b2585348ea96852b4319c6454d19a) ) - ROM_LOAD( "156-0663-01.u481", 0x2000, 0x0800, CRC(f220d24c) SHA1(fb5dc8a617f4b4d5c094c0cbabb9af158c19c2c2) ) - ROM_LOAD( "156-0664-xx.u385", 0x2800, 0x0800, CRC(aa1ae67d) SHA1(8816654c1b0ad0230bf5027f68c2ec1d315ad188) ) // -01 or -02 ? - ROM_LOAD( "156-0665-xx.u381", 0x3000, 0x0800, CRC(90497138) SHA1(2d6bbe169a434581a49fffcab0d2ca18107b67da) ) // -01 or -02 ? - ROM_LOAD( "156-0666-01.u285", 0x3800, 0x0800, CRC(c35ce405) SHA1(10cae122d000fe2886228a178a1a4e4d3ec2c3f5) ) - ROM_LOAD( "156-0667-xx.u595", 0x4000, 0x0800, CRC(e1723a06) SHA1(dde3e64eb6acc77d8e7234235a99ec338cc74717) ) // -01 or -02 ? - ROM_LOAD( "156-0668-xx.u591", 0x4800, 0x0800, CRC(d8b80d7a) SHA1(6c1f00fa2f9ff6ebd84268c2100637ddbdb3bae6) ) // -01 or -02 ? - ROM_LOAD( "156-0669-01.u497", 0x5000, 0x0800, CRC(f760ed39) SHA1(2b30d20d880002ce3950ee7abe40f4e1539208cc) ) - ROM_LOAD( "156-0670-01.u495", 0x5800, 0x0800, CRC(d40a303d) SHA1(111b399f6178e2fe50b1368536f290d4df9883fc) ) - ROM_LOAD( "156-0671-xx.u491", 0x6000, 0x0800, CRC(32060b64) SHA1(af254dc068686fcd7584128258724fd5415ea458) ) // -01 or -02 ? - ROM_LOAD( "156-0672-xx.u395", 0x6800, 0x0800, CRC(93ad68d1) SHA1(8242058bfc89d11cd9ae82d967410714875eface) ) // -01 or -02 ? - ROM_LOAD( "156-0673-xx.u391", 0x7000, 0x0800, CRC(ee1f5d4c) SHA1(a6fb8347a0dfa94268f091fb7ca091c8bfabeabd) ) // -01 or -02 or -03 ? - ROM_LOAD( "156-0674-xx.u295", 0x7800, 0x0800, CRC(50582341) SHA1(1a028176e5d5ca83012e2f75e9daad88cd7d8fc3) ) // -01 or -02 ? - - ROM_REGION( 0x2000, "020_0147_00", 0 ) // Firmware Backpack (020-0147-00) - ROM_LOAD( "156-0747-xx.u101", 0x0000, 0x0800, CRC(9e1facc1) SHA1(7e7a118c3e8c49630f630ee02c3de843dd95d7e1) ) // -00 or -01 ? - ROM_LOAD( "156-0748-xx.u201", 0x0800, 0x0800, CRC(be42bfbf) SHA1(23575b411bd9dcb7d7116628820096e3064ff93b) ) // -00 or -01 ? - - ROM_REGION( 0x2000, "021_0188_00", 0 ) // Communications Backpack (021-0188-00) - ROM_LOAD( "156-0712-00.u101", 0x0000, 0x0800, NO_DUMP ) - ROM_LOAD( "156-0712-01.u101", 0x0000, 0x0800, NO_DUMP ) - ROM_LOAD( "156-0713-00.u111", 0x0800, 0x0800, NO_DUMP ) - ROM_LOAD( "156-0713-01.u111", 0x0800, 0x0800, NO_DUMP ) - ROM_LOAD( "156-0714-00.u121", 0x1000, 0x0800, NO_DUMP ) - ROM_LOAD( "156-0714-01.u121", 0x1000, 0x0800, NO_DUMP ) - ROM_LOAD( "156-0715-01.u131", 0x1800, 0x0800, NO_DUMP ) -/* - ROM_REGION( 0x2000, "4051r01", 0 ) // 4051R01 Matrix Functions - ROM_LOAD( "4051r01", 0x0000, 0x1000, NO_DUMP ) - - ROM_REGION( 0x2000, "4051r05", 0 ) // 4051R05 Binary Program Loader - ROM_LOAD( "156-0856-00.u1", 0x0000, 0x0800, NO_DUMP ) - ROM_LOAD( "156-0857-00.u11", 0x0800, 0x0800, NO_DUMP ) - - ROM_REGION( 0x2000, "4051r06", 0 ) // 4051R06 Editor - ROM_LOAD( "4051r06", 0x0000, 0x1000, NO_DUMP ) -*/ -ROM_END - -ROM_START( tek4052a ) - ROM_REGION( 0x3800, AM2901A_TAG, 0 ) // ALU 670-7705-00 microcode - ROM_LOAD( "160-1689-00.u340", 0x0000, 0x0800, CRC(97ff62d4) SHA1(e25b495fd1b3f8a5bfef5c8f20efacde8366e89c) ) - ROM_LOAD( "160-1688-00.u335", 0x0800, 0x0800, CRC(19033422) SHA1(0f6ea45be5123701940331c4278bcdc5db4f4147) ) - ROM_LOAD( "160-1687-00.u330", 0x1000, 0x0800, CRC(3b2e37dd) SHA1(294b626d0022fbf9bec50680b6b932f21a3cb049) ) - ROM_LOAD( "160-1686-00.u320", 0x1800, 0x0800, CRC(7916cd64) SHA1(d6b3ed783e488667ca203ec605aa27d78261c61b) ) - ROM_LOAD( "160-1695-00.u315", 0x2000, 0x0800, CRC(cdac76a7) SHA1(2a47f34ae63fb7fe96e7c6fc92ca4f629b0e31ec) ) - ROM_LOAD( "160-1694-00.u305", 0x2800, 0x0800, CRC(c33ae212) SHA1(25ed4cc3600391fbc93bb46c92d3f64ca2aca58e) ) - ROM_LOAD( "160-1693-00.u300", 0x3000, 0x0800, CRC(651b7af2) SHA1(7255c682cf74f2e77661d77c8406b36a567eea46) ) - - ROM_REGION( 0x14000, "672_0799_08", 0 ) // Memory Access Sequencer 672-0799-08 - ROM_LOAD16_BYTE( "160-1698-00.u810", 0x00000, 0x2000, CRC(fd0b8bc3) SHA1(ea9caa151295024267a467ba636ad41aa0c517d3) ) - ROM_LOAD16_BYTE( "160-1682-00.u893", 0x00001, 0x2000, CRC(d54104ef) SHA1(b796c320c8f96f6e4b845718bfb62ccb5903f2db) ) - ROM_LOAD16_BYTE( "160-1699-00.u820", 0x04000, 0x2000, CRC(59cc6c2e) SHA1(b6d85cdfaaef360af2a4fc44eae55e512bb08b21) ) - ROM_LOAD16_BYTE( "160-1684-00.u870", 0x04001, 0x2000, CRC(b24cdbaf) SHA1(476032624110bc5c7a7f30d10458e8baffb2f2ff) ) - ROM_LOAD16_BYTE( "160-1700-00.u825", 0x08000, 0x2000, CRC(59f4a4e2) SHA1(81b5f74ec14bb13735382abc123bb9b09dfb7a63) ) - ROM_LOAD16_BYTE( "160-1683-00.u880", 0x08001, 0x2000, CRC(f6bb15d1) SHA1(eca06211876c12236cfeae0417131e8f04728d51) ) - ROM_LOAD16_BYTE( "160-1701-00.u835", 0x0c000, 0x2000, CRC(195988b9) SHA1(995a77963e869f1a461addf58db9ecbf2b9222ba) ) - ROM_LOAD16_BYTE( "160-1691-00.u885", 0x0c001, 0x2000, CRC(0670bf9e) SHA1(a8c39bd7f3f61436296c6bc5f734354371ae8123) ) - ROM_LOAD16_BYTE( "160-1702-00.u845", 0x10000, 0x2000, CRC(013344b1) SHA1(4a79654427e15d0fcedd9519914f6448938ecffd) ) - ROM_LOAD16_BYTE( "160-1685-00.u863", 0x10001, 0x2000, CRC(53ddc8f9) SHA1(431d6f329dedebb54232c623a924d5ecddc5e44e) ) - - ROM_REGION( 0x2000, "020_0147_00", 0 ) // Firmware Backpack (020-0147-00) - ROM_LOAD( "156-0747-xx.u101", 0x0000, 0x0800, CRC(9e1facc1) SHA1(7e7a118c3e8c49630f630ee02c3de843dd95d7e1) ) // -00 or -01 ? - ROM_LOAD( "156-0748-xx.u201", 0x0800, 0x0800, CRC(be42bfbf) SHA1(23575b411bd9dcb7d7116628820096e3064ff93b) ) // -00 or -01 ? - - ROM_REGION( 0x2000, "021_0188_00", 0 ) // Communications Backpack (021-0188-00) - ROM_LOAD( "156-0712-00.u101", 0x0000, 0x0800, NO_DUMP ) - ROM_LOAD( "156-0712-01.u101", 0x0000, 0x0800, NO_DUMP ) - ROM_LOAD( "156-0713-00.u111", 0x0800, 0x0800, NO_DUMP ) - ROM_LOAD( "156-0713-01.u111", 0x0800, 0x0800, NO_DUMP ) - ROM_LOAD( "156-0714-00.u121", 0x1000, 0x0800, NO_DUMP ) - ROM_LOAD( "156-0714-01.u121", 0x1000, 0x0800, NO_DUMP ) - ROM_LOAD( "156-0715-01.u131", 0x1800, 0x0800, NO_DUMP ) -ROM_END - - - -//************************************************************************** -// SYSTEM DRIVERS -//************************************************************************** - -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1975, tek4051, 0, 0, tek4051, tek4051, tek4051_state, empty_init, "Tektronix", "Tektronix 4051", MACHINE_NOT_WORKING ) -COMP( 1978, tek4052a, tek4051, 0, tek4052, tek4051, tek4052_state, empty_init, "Tektronix", "Tektronix 4052A", MACHINE_NOT_WORKING ) -//COMP( 1979, tek4054, tek4051, 0, tek4054, tek4054, tek4052_state, empty_init, "Tektronix", "Tektronix 4054", MACHINE_NOT_WORKING ) diff --git a/src/mame/tektroni/tek405x.h b/src/mame/tektroni/tek405x.h deleted file mode 100644 index 93eed3bc563..00000000000 --- a/src/mame/tektroni/tek405x.h +++ /dev/null @@ -1,176 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Curt Coder -#ifndef MAME_INCLUDES_TEK405X_H -#define MAME_INCLUDES_TEK405X_H - -#pragma once - -#include "bus/generic/carts.h" -#include "bus/generic/slot.h" -#include "bus/ieee488/ieee488.h" - -#include "cpu/m6800/m6800.h" - -#include "machine/6821pia.h" -#include "machine/6850acia.h" -#include "machine/clock.h" -#include "machine/ram.h" -#include "machine/timer.h" - -#include "sound/spkrdev.h" - -#include "video/vector.h" - -#include "emupal.h" - - -#define MC6800_TAG "u61" -#define MC6820_Y_TAG "u561" -#define MC6820_X_TAG "u565" -#define MC6820_TAPE_TAG "u361" -#define MC6820_KB_TAG "u461" -#define MC6820_GPIB_TAG "u265" -#define MC6820_COM_TAG "u5" -#define MC6850_TAG "u25" -#define RS232_TAG "rs232" -#define SCREEN_TAG "screen" - -#define AM2901A_TAG "am2901a" - -class tek4051_state : public driver_device -{ -public: - tek4051_state(const machine_config &mconfig, device_type type, const char *tag) : - driver_device(mconfig, type, tag), - m_maincpu(*this, MC6800_TAG), - m_gpib_pia(*this, MC6820_GPIB_TAG), - m_com_pia(*this, MC6820_COM_TAG), - m_acia(*this, MC6850_TAG), - m_acia_clock(*this, "acia_clock"), - m_gpib(*this, IEEE488_TAG), - m_speaker(*this, "speaker"), - m_ram(*this, RAM_TAG), - m_rom(*this, MC6800_TAG), - m_bsofl_rom(*this, "020_0147_00"), - m_bscom_rom(*this, "021_0188_00"), - m_special(*this, "SPECIAL"), - m_lamps(*this, "lamp%u", 1U) - { } - - void tek4051(machine_config &config); - -private: - void bankswitch(uint8_t data); - void update_irq(); - void update_nmi(); - void scan_keyboard(); - - void lbs_w(uint8_t data); - - uint8_t x_pia_pa_r(); - void x_pia_pa_w(uint8_t data); - void x_pia_pb_w(uint8_t data); - DECLARE_WRITE_LINE_MEMBER( adot_w ); - DECLARE_WRITE_LINE_MEMBER( bufclk_w ); - DECLARE_WRITE_LINE_MEMBER( x_pia_irqa_w ); - DECLARE_WRITE_LINE_MEMBER( x_pia_irqb_w ); - - uint8_t sa_r(); - void y_pia_pa_w(uint8_t data); - void sb_w(uint8_t data); - DECLARE_WRITE_LINE_MEMBER( sot_w ); - DECLARE_WRITE_LINE_MEMBER( y_pia_irqa_w ); - DECLARE_WRITE_LINE_MEMBER( y_pia_irqb_w ); - - uint8_t kb_pia_pa_r(); - uint8_t kb_pia_pb_r(); - void kb_pia_pb_w(uint8_t data); - DECLARE_WRITE_LINE_MEMBER( kb_halt_w ); - DECLARE_WRITE_LINE_MEMBER( kb_pia_irqa_w ); - DECLARE_WRITE_LINE_MEMBER( kb_pia_irqb_w ); - - uint8_t tape_pia_pa_r(); - void tape_pia_pa_w(uint8_t data); - void tape_pia_pb_w(uint8_t data); - DECLARE_WRITE_LINE_MEMBER( tape_pia_irqa_w ); - DECLARE_WRITE_LINE_MEMBER( tape_pia_irqb_w ); - - void dio_w(uint8_t data); - uint8_t gpib_pia_pb_r(); - void gpib_pia_pb_w(uint8_t data); - DECLARE_WRITE_LINE_MEMBER( talk_w ); - DECLARE_WRITE_LINE_MEMBER( gpib_pia_irqa_w ); - DECLARE_WRITE_LINE_MEMBER( gpib_pia_irqb_w ); - - void com_pia_pa_w(uint8_t data); - uint8_t com_pia_pb_r(); - void com_pia_pb_w(uint8_t data); - DECLARE_WRITE_LINE_MEMBER( com_pia_irqa_w ); - DECLARE_WRITE_LINE_MEMBER( com_pia_irqb_w ); - DECLARE_WRITE_LINE_MEMBER( acia_irq_w ); - DECLARE_WRITE_LINE_MEMBER( write_acia_clock ); - - TIMER_DEVICE_CALLBACK_MEMBER(keyboard_tick); - void tek4051_mem(address_map &map); - - virtual void machine_start() override; - virtual void video_start() override; - - required_device m_maincpu; - required_device m_gpib_pia; - required_device m_com_pia; - required_device m_acia; - required_device m_acia_clock; - required_device m_gpib; - required_device m_speaker; - required_device m_ram; - required_memory_region m_rom; - required_memory_region m_bsofl_rom; - required_memory_region m_bscom_rom; - required_ioport m_special; - output_finder<3> m_lamps; - - // interrupts - int m_x_pia_irqa = 0; - int m_x_pia_irqb = 0; - int m_y_pia_irqa = 0; - int m_y_pia_irqb = 0; - int m_tape_pia_irqa = 0; - int m_tape_pia_irqb = 0; - int m_kb_pia_irqa = 0; - int m_kb_pia_irqb = 0; - int m_gpib_pia_irqa = 0; - int m_gpib_pia_irqb = 0; - int m_com_pia_irqa = 0; - int m_com_pia_irqb = 0; - int m_acia_irq = 0; - - // keyboard - int m_kc = 0; - - // GPIB - int m_talk = 0; -}; - -class tek4052_state : public driver_device -{ -public: - tek4052_state(const machine_config &mconfig, device_type type, const char *tag) : - driver_device(mconfig, type, tag), - m_maincpu(*this, AM2901A_TAG), - m_ram(*this, RAM_TAG) - { } - - void tek4052(machine_config &config); - -private: - void tek4052_mem(address_map &map); - - virtual void machine_start() override; - virtual void video_start() override; - - required_device m_maincpu; - required_device m_ram; -}; - -#endif // MAME_INCLUDES_TEK405X_H diff --git a/src/mame/tektroni/tek410x.cpp b/src/mame/tektroni/tek410x.cpp deleted file mode 100644 index 8329a9729b8..00000000000 --- a/src/mame/tektroni/tek410x.cpp +++ /dev/null @@ -1,378 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Curt Coder, AJR -/*************************************************************************** - - Tektronix 4107A/4109A - - Skeleton driver. - -****************************************************************************/ - -#include "emu.h" -#include "cpu/i86/i186.h" -#include "machine/i8255.h" -#include "machine/mc68681.h" -#include "tek410x_kbd.h" -#include "video/crt9007.h" -#include "emupal.h" -#include "screen.h" - - -class tek4107a_state : public driver_device -{ -public: - tek4107a_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_duart(*this, "duart%u", 0U) - , m_keyboard(*this, "keyboard") - , m_vpac(*this, "vpac") - , m_ppi_pc(0) - , m_kb_rdata(true) - , m_kb_tdata(true) - , m_kb_rclamp(false) - , m_graphics_control(0) - , m_alpha_control(0) - , m_x_position(0) - , m_y_position(0) - , m_x_cursor(0) - , m_y_cursor(0) - { } - - void tek4109a(machine_config &config); - void tek4107a(machine_config &config); - -protected: - virtual void machine_start() override; - virtual void video_start() override; - -private: - u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - - u8 vpac_r(offs_t offset); - - u16 nmi_enable_r(); - u16 nmi_disable_r(); - u16 system_reset_r(); - - void ppi_pc_w(u8 data); - DECLARE_WRITE_LINE_MEMBER(kb_rdata_w); - DECLARE_WRITE_LINE_MEMBER(kb_tdata_w); - DECLARE_WRITE_LINE_MEMBER(kb_rclamp_w); - - void xpos_w(u16 data); - void ypos_w(u16 data); - void xcur_w(u16 data); - void ycur_w(u16 data); - void tbwin_w(u16 data); - u16 gcntl_r(); - void gcntl_w(u16 data); - u16 acntl_r(); - void acntl_w(u16 data); - u16 test_r(); - u8 font_r(); - - void tek4107a_io(address_map &map); - void tek4107a_mem(address_map &map); - - required_device_array m_duart; - required_device m_keyboard; - required_device m_vpac; - - u8 m_ppi_pc; - bool m_kb_rdata; - bool m_kb_tdata; - bool m_kb_rclamp; - - u16 m_graphics_control; - u16 m_alpha_control; - u16 m_x_position; - u16 m_y_position; - u16 m_x_cursor; - u16 m_y_cursor; -}; - -u8 tek4107a_state::vpac_r(offs_t offset) -{ - return m_vpac->read(offset + 0x20); -} - -u16 tek4107a_state::nmi_enable_r() -{ - // TODO - return 0; -} - -u16 tek4107a_state::nmi_disable_r() -{ - // TODO - return 0; -} - -u16 tek4107a_state::system_reset_r() -{ - // TODO - return 0; -} - -void tek4107a_state::ppi_pc_w(u8 data) -{ - if (!m_kb_rclamp && BIT(m_ppi_pc, 2) != BIT(data, 2)) - m_keyboard->kdo_w(!BIT(data, 2) || m_kb_tdata); - - m_ppi_pc = data; -} - -WRITE_LINE_MEMBER(tek4107a_state::kb_rdata_w) -{ - m_kb_rdata = state; - if (!m_kb_rclamp) - m_duart[0]->rx_a_w(state); -} - -WRITE_LINE_MEMBER(tek4107a_state::kb_rclamp_w) -{ - if (m_kb_rclamp != !state) - { - m_kb_rclamp = !state; - - // Clamp RXDA to 1 and KBRDATA to 0 when DUART asserts RxRDYA - if (m_kb_tdata || !BIT(m_ppi_pc, 2)) - m_keyboard->kdo_w(state); - m_duart[0]->rx_a_w(state ? m_kb_rdata : 1); - } -} - -WRITE_LINE_MEMBER(tek4107a_state::kb_tdata_w) -{ - if (m_kb_tdata != state) - { - m_kb_tdata = state; - - m_duart[0]->ip4_w(!state); - if (BIT(m_ppi_pc, 2) && m_kb_rdata && !m_kb_rclamp) - m_keyboard->kdo_w(state); - } -} - -void tek4107a_state::xpos_w(u16 data) -{ - m_x_position = data & 0x03ff; -} - -void tek4107a_state::ypos_w(u16 data) -{ - m_y_position = data & 0x01ff; -} - -void tek4107a_state::xcur_w(u16 data) -{ - m_x_cursor = data & 0x03ff; -} - -void tek4107a_state::ycur_w(u16 data) -{ - m_y_cursor = data & 0x01ff; -} - -void tek4107a_state::tbwin_w(u16 data) -{ - // TODO -} - -u16 tek4107a_state::gcntl_r() -{ - return m_graphics_control; -} - -void tek4107a_state::gcntl_w(u16 data) -{ - m_graphics_control = data; -} - -u16 tek4107a_state::acntl_r() -{ - return m_alpha_control; -} - -void tek4107a_state::acntl_w(u16 data) -{ - m_alpha_control = data; -} - -u16 tek4107a_state::test_r() -{ - // TODO - return 0; -} - -u8 tek4107a_state::font_r() -{ - // TODO - return 0; -} - - -/* Memory Maps */ - -void tek4107a_state::tek4107a_mem(address_map &map) -{ - map(0x00000, 0x3ffff).ram(); - map(0x40000, 0x7ffff).ram().share("gfxram"); - map(0x80000, 0xbffff).rom().region("firmware", 0); - map(0xf0000, 0xfffff).rom().region("firmware", 0x30000); -} - -void tek4107a_state::tek4107a_io(address_map &map) -{ - map(0x0000, 0x001f).rw(m_duart[0], FUNC(scn2681_device::read), FUNC(scn2681_device::write)).umask16(0x00ff); - map(0x0000, 0x001f).rw(m_duart[1], FUNC(scn2681_device::read), FUNC(scn2681_device::write)).umask16(0xff00); - map(0x0080, 0x00bf).r(FUNC(tek4107a_state::vpac_r)).w(m_vpac, FUNC(crt9007_device::write)).umask16(0x00ff); - map(0x00c0, 0x00c1).w(FUNC(tek4107a_state::xpos_w)); - map(0x00c2, 0x00c3).w(FUNC(tek4107a_state::ypos_w)); - map(0x00c4, 0x00c5).w(FUNC(tek4107a_state::xcur_w)); - map(0x00c6, 0x00c7).w(FUNC(tek4107a_state::ycur_w)); - map(0x00c8, 0x00c9).r(FUNC(tek4107a_state::test_r)); - map(0x00ca, 0x00ca).r(FUNC(tek4107a_state::font_r)); - map(0x00ca, 0x00cb).w(FUNC(tek4107a_state::tbwin_w)); - map(0x00cc, 0x00cd).rw(FUNC(tek4107a_state::gcntl_r), FUNC(tek4107a_state::gcntl_w)); - map(0x00ce, 0x00cf).rw(FUNC(tek4107a_state::acntl_r), FUNC(tek4107a_state::acntl_w)); - map(0x0100, 0x0107).rw("ppi", FUNC(i8255_device::read), FUNC(i8255_device::write)).umask16(0xff00); - map(0x0200, 0x0201).r(FUNC(tek4107a_state::nmi_enable_r)); - map(0x0280, 0x0281).r(FUNC(tek4107a_state::system_reset_r)); - map(0x0300, 0x0301).r(FUNC(tek4107a_state::nmi_disable_r)); -} - -/* Input Ports */ - -static INPUT_PORTS_START( tek4107a ) -INPUT_PORTS_END - -/* Video */ - -void tek4107a_state::video_start() -{ - save_item(NAME(m_graphics_control)); - save_item(NAME(m_alpha_control)); - save_item(NAME(m_x_position)); - save_item(NAME(m_y_position)); - save_item(NAME(m_x_cursor)); - save_item(NAME(m_y_cursor)); -} - -u32 tek4107a_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - return 0; -} - -static const gfx_layout tek4107a_charlayout = -{ - 8, 15, - RGN_FRAC(1,1), - 1, - { 0 }, - { STEP8(0,1) }, - { 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 }, - 16*8 -}; - -static GFXDECODE_START( gfx_tek4107a ) - GFXDECODE_ENTRY( "chargen", 0x0000, tek4107a_charlayout, 0, 1 ) -GFXDECODE_END - -/* Machine Initialization */ - -void tek4107a_state::machine_start() -{ - save_item(NAME(m_ppi_pc)); - save_item(NAME(m_kb_rdata)); - save_item(NAME(m_kb_tdata)); - save_item(NAME(m_kb_rclamp)); -} - -/* Machine Driver */ - -void tek4107a_state::tek4107a(machine_config &config) -{ - /* basic machine hardware */ - i80186_cpu_device &maincpu(I80186(config, "maincpu", 14.7456_MHz_XTAL)); - maincpu.set_addrmap(AS_PROGRAM, &tek4107a_state::tek4107a_mem); - maincpu.set_addrmap(AS_IO, &tek4107a_state::tek4107a_io); - - SCN2681(config, m_duart[0], 14.7456_MHz_XTAL / 4); - m_duart[0]->irq_cb().set("maincpu", FUNC(i80186_cpu_device::int0_w)); - m_duart[0]->outport_cb().set_inputline("maincpu", INPUT_LINE_NMI).bit(5).invert(); // RxRDYB - m_duart[0]->outport_cb().append(FUNC(tek4107a_state::kb_rclamp_w)).bit(4); - m_duart[0]->outport_cb().append(m_keyboard, FUNC(tek410x_keyboard_device::reset_w)).bit(3); - m_duart[0]->a_tx_cb().set(m_keyboard, FUNC(tek410x_keyboard_device::kdi_w)); - - SCN2681(config, m_duart[1], 14.7456_MHz_XTAL / 4); - m_duart[1]->irq_cb().set("maincpu", FUNC(i80186_cpu_device::int2_w)); - - i8255_device &ppi(I8255(config, "ppi")); - ppi.in_pb_callback().set_constant(0x30); - ppi.out_pc_callback().set(FUNC(tek4107a_state::ppi_pc_w)); - - TEK410X_KEYBOARD(config, m_keyboard); - m_keyboard->tdata_callback().set(FUNC(tek4107a_state::kb_tdata_w)); - m_keyboard->rdata_callback().set(FUNC(tek4107a_state::kb_rdata_w)); - - /* video hardware */ - screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_raw(25.2_MHz_XTAL, 800, 0, 640, 525, 0, 480); - screen.set_screen_update(FUNC(tek4107a_state::screen_update)); - - CRT9007(config, m_vpac, 25.2_MHz_XTAL / 8); - m_vpac->set_screen("screen"); - m_vpac->set_character_width(8); - m_vpac->int_callback().set("maincpu", FUNC(i80186_cpu_device::int1_w)); - - PALETTE(config, "palette").set_entries(64); - GFXDECODE(config, "gfxdecode", "palette", gfx_tek4107a); -} - -void tek4107a_state::tek4109a(machine_config &config) -{ - tek4107a(config); - - /* video hardware */ - subdevice("palette")->set_entries(4096); -} - -/* ROMs */ - -ROM_START( tek4107a ) - ROM_REGION16_LE( 0x40000, "firmware", 0 ) - ROM_LOAD16_BYTE( "160-2379-03.u60", 0x00000, 0x8000, NO_DUMP ) - ROM_LOAD16_BYTE( "160-2380-03.u160", 0x00001, 0x8000, NO_DUMP ) - ROM_LOAD16_BYTE( "160-2377-03.u70", 0x10000, 0x8000, NO_DUMP ) - ROM_LOAD16_BYTE( "160-2378-03.u170", 0x10001, 0x8000, CRC(feac272f) SHA1(f2018dc9bb5bd6840b2843c709cbc24689054dc0) ) - ROM_LOAD16_BYTE( "160-2375-03.u80", 0x20000, 0x8000, NO_DUMP ) - ROM_LOAD16_BYTE( "160-2376-03.u180", 0x20001, 0x8000, CRC(35a44e75) SHA1(278c7f218105ad3473409b16a8d27a0b9f7a859e) ) - ROM_LOAD16_BYTE( "160-2373-03.u90", 0x30000, 0x8000, CRC(d5e89b15) SHA1(d6eb1a0a684348a8194238d641528fb96fb29087) ) - ROM_LOAD16_BYTE( "160-2374-03.u190", 0x30001, 0x8000, CRC(a3fef76e) SHA1(902845c4aa0cbc392b62c726ac746ca62567d91c) ) - - ROM_REGION( 0x1000, "chargen", 0 ) - ROM_LOAD( "160-2381 v1.0.u855", 0x0000, 0x1000, CRC(ac7ca279) SHA1(4c9de06d1c346f83eb8d0d09a0eb32c40bd8014c) ) -ROM_END - -ROM_START( tek4109a ) - // another set with 160-32xx-03 v10.5 labels exists - ROM_REGION16_LE( 0x40000, "firmware", 0 ) - ROM_LOAD16_BYTE( "160-3283-02 v8.2.u60", 0x00000, 0x8000, CRC(2a821db6) SHA1(b4d8b74bd9fe43885dcdc4efbdd1eebb96e32060) ) - ROM_LOAD16_BYTE( "160-3284-02 v8.2.u160", 0x00001, 0x8000, CRC(ee567b01) SHA1(67b1b0648cfaa28d57473bcc45358ff2bf986acf) ) - ROM_LOAD16_BYTE( "160-3281-02 v8.2.u70", 0x10000, 0x8000, CRC(e2713328) SHA1(b0bb3471539ef24d79b18d0e33bc148ed27d0ec4) ) - ROM_LOAD16_BYTE( "160-3282-02 v8.2.u170", 0x10001, 0x8000, CRC(c109a4f7) SHA1(762019105c1f82200a9c99ccfcfd8ee81d2ac4fe) ) - ROM_LOAD16_BYTE( "160-3279-02 v8.2.u80", 0x20000, 0x8000, CRC(00822078) SHA1(a82e61dafccbaea44e67efaa5940e52ec6d07d7d) ) - ROM_LOAD16_BYTE( "160-3280-02 v8.2.u180", 0x20001, 0x8000, CRC(eec9f70f) SHA1(7b65336219f5fa0d11f8be2b37040b564a53c52f) ) - ROM_LOAD16_BYTE( "160-3277-02 v8.2.u90", 0x30000, 0x8000, CRC(cf6ebc97) SHA1(298db473874c57bf4eec788818179748030a9ad8) ) - ROM_LOAD16_BYTE( "160-3278-02 v8.2.u190", 0x30001, 0x8000, CRC(d6124cd1) SHA1(f826aee5ec07cf5ac369697d93def0259ad225bb) ) - - ROM_REGION( 0x1000, "chargen", 0 ) - ROM_LOAD( "160-3087 v1.0.u855", 0x0000, 0x1000, CRC(97479528) SHA1(e9e15f1f64b3b6bd139accd51950bae71fdc2193) ) -ROM_END - -/* System Drivers */ - -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1983, tek4107a, 0, 0, tek4107a, tek4107a, tek4107a_state, empty_init, "Tektronix", "Tektronix 4107A", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) -COMP( 1983, tek4109a, tek4107a, 0, tek4109a, tek4107a, tek4107a_state, empty_init, "Tektronix", "Tektronix 4109A", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) diff --git a/src/mame/tektroni/tek410x_kbd.cpp b/src/mame/tektroni/tek410x_kbd.cpp deleted file mode 100644 index 4d0d1beea46..00000000000 --- a/src/mame/tektroni/tek410x_kbd.cpp +++ /dev/null @@ -1,385 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:AJR -/********************************************************************** - - This emulates the standard serial keyboard used with Tektronix's - 4105, 4106, 4107 and 4109 terminals, including the trademark - octagonal "joy disk". The 4404 keyboard is also compatible. - - The hardware was designed by the Keytronic Corporation, and uses - their 20-pin key strobe driver (22-0950-003) and input receiver - (22-0908-003) ASICs. - - The 8048/8748's DB pins are connected to drivers for up to 5 LEDs, - but only one of these LEDs (CR9, on the Caps Lock key) is actually - populated. - - A different but apparently backward-compatible keyboard was used - with the CX4107 and CX4109, based on a 8051 CPU with space for an - external program ROM and adding an onboard speaker as well as many - extra keys and an IBM 3279-style layout. - - Hexadecimal table of press codes (release codes are the same + 80): - - 00 Caps Lock - 01 Left Shift - 02 Right Shift - 03 Ctrl - 04 DEras/SEras - 05 Break - 06 Back Space - 07 Tab - 08 Line Feed - 09 Return - 0A Esc - 0B Space Bar - 0C " ' - 0D < , - 0E _ - - 0F > . - 10 ? / - 11 ) 0 - 12 ! 1 - 13 @ 2 - 14 # 3 - 15 $ 4 - 16 % 5 - 17 ^ 6 - 18 & 7 - 19 * 8 - 1A ( 9 - 1B : ; - 1C = - 1D A - 1E B - 1F C - 20 D - 21 E - 22 F - 23 G - 24 H - 25 I - 26 J - 27 K - 28 L - 29 M - 2A N - 2B O - 2C P - 2D Q - 2E R - 2F S - 30 T - 31 U - 32 V - 33 W - 34 X - 35 Y - 36 Z - 37 { [ - 38 ` \ - 39 } ] - 3A ~ | - 3B Rub Out - 3C Enter (keypad) - 3D , (keypad) - 3E - (keypad) - 3F . (keypad) - 40 0 (keypad) - 41 1 (keypad) - 42 2 (keypad) - 43 3 (keypad) - 44 4 (keypad) - 45 5 (keypad) - 46 6 (keypad) - 47 7 (keypad) - 48 8 (keypad) - 49 9 (keypad) - 4A F1 - 4B F2 - 4C F3 - 4D F4 - 4E F5 - 4F F6 - 50 F7 - 51 F8 - 52 GEras/Dialog - 53 Cancel/Setup - 54 DCopy/SCopy - 55 Menu - 56 Cursor Right (joystick) - 57 Cursor Up (joystick) - 58 Cursor Left (joystick) - 59 Cursor Down (joystick) - - Additional press codes for CX keyboard only: - - 5A Erase EOF - 5B Dup/PA1 - 5C Reset/Dev Cncl - 5D Field Mark/PA2/_ - 5E Attn Sys Req - 5F Cursr Sel/Clear - 60 < > - 61 Cursr Blink/Alt Cursr - 62 Ident - 63 Down Arrow - 64 Right Arrow/Right Double Arrow - 65 Left Arrow/Left Double Arrow - 66 Up Arrow - 67 Insert/Alpha - 68 Right Alt/Ctrl - - The baud rate is 4800, with 8 data bits and no parity. - -**********************************************************************/ - -#include "emu.h" -#include "tek410x_kbd.h" - -// device type definition -DEFINE_DEVICE_TYPE(TEK410X_KEYBOARD, tek410x_keyboard_device, "tek410x_kbd", "Tektronix 410X Standard Keyboard (119-1592-01)") - -tek410x_keyboard_device::tek410x_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : device_t(mconfig, TEK410X_KEYBOARD, tag, owner, clock) - , m_mcu(*this, "mcu") - , m_key_matrix(*this, "X%u", 0U) - , m_config(*this, "CONFIG") - , m_tdata_callback(*this) - , m_rdata_callback(*this) - , m_select(0) - , m_p2_out(0) - , m_kdi(true) - , m_kdo(false) -{ -} - -void tek410x_keyboard_device::device_resolve_objects() -{ - m_tdata_callback.resolve_safe(); - m_rdata_callback.resolve_safe(); -} - -void tek410x_keyboard_device::device_start() -{ - save_item(NAME(m_select)); - save_item(NAME(m_p2_out)); - save_item(NAME(m_kdi)); - save_item(NAME(m_kdo)); -} - -WRITE_LINE_MEMBER(tek410x_keyboard_device::kdi_w) -{ - m_kdi = state; - if (BIT(m_p2_out, 7)) - { - m_mcu->set_input_line(MCS48_INPUT_IRQ, state ? CLEAR_LINE : ASSERT_LINE); - m_tdata_callback(state); - } -} - -WRITE_LINE_MEMBER(tek410x_keyboard_device::kdo_w) -{ - m_kdo = state; - if (BIT(m_p2_out, 5)) - m_rdata_callback(state); -} - -WRITE_LINE_MEMBER(tek410x_keyboard_device::reset_w) -{ - m_mcu->set_input_line(INPUT_LINE_RESET, state ? CLEAR_LINE : ASSERT_LINE); - if (!state) - p2_w(0xff); -} - -u8 tek410x_keyboard_device::p1_r() -{ - if (m_select < 12) - return m_key_matrix[m_select]->read(); - else - return 0xff; -} - -u8 tek410x_keyboard_device::p2_r() -{ - return 0xb0 | (m_kdo ? (m_p2_out & 0x20) << 1 : 0) | m_config->read(); -} - -void tek410x_keyboard_device::p2_w(u8 data) -{ - if (!BIT(data, 4)) - m_select = m_mcu->p1_r() & 0x0f; - - if (m_kdi && BIT(data, 7) != BIT(m_p2_out, 7)) - { - m_tdata_callback(BIT(data, 7)); - m_mcu->set_input_line(MCS48_INPUT_IRQ, BIT(data, 7) ? CLEAR_LINE : ASSERT_LINE); - } - - if (m_kdo && BIT(data, 5) != BIT(m_p2_out, 5)) - m_rdata_callback(BIT(data, 5)); - - m_p2_out = data; -} - -void tek410x_keyboard_device::ext_map(address_map &map) -{ - map(0x00, 0xff).nopr(); -} - -static INPUT_PORTS_START(tek410x_keyboard) - PORT_START("X0") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) PORT_CODE(KEYCODE_ENTER_PAD) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(COMMA_PAD)) PORT_CODE(KEYCODE_PLUS_PAD) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) PORT_CODE(KEYCODE_3_PAD) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) PORT_CODE(KEYCODE_6_PAD) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) PORT_CODE(KEYCODE_MINUS_PAD) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) PORT_CODE(KEYCODE_9_PAD) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD)) PORT_CODE(KEYCODE_DEL_PAD) - - PORT_START("X1") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) PORT_CODE(KEYCODE_4_PAD) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) PORT_CODE(KEYCODE_2_PAD) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) PORT_CODE(KEYCODE_5_PAD) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) PORT_CODE(KEYCODE_7_PAD) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) PORT_CODE(KEYCODE_1_PAD) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) PORT_CODE(KEYCODE_8_PAD) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) PORT_CODE(KEYCODE_0_PAD) - - PORT_START("X2") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Break") //PORT_CODE(KEYCODE_XXX) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Line Feed") PORT_CHAR(0x0a) //PORT_CODE(KEYCODE_XXX) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Rub Out") PORT_CODE(KEYCODE_BACKSPACE) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(']') PORT_CHAR('}') PORT_CODE(KEYCODE_BACKSLASH) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) - - PORT_START("X3") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Right Shift") PORT_CODE(KEYCODE_RSHIFT) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('\\') PORT_CHAR('`') PORT_CODE(KEYCODE_OPENBRACE) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('\'') PORT_CHAR('"') PORT_CODE(KEYCODE_QUOTE) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Back Space") PORT_CHAR(0x08) PORT_CODE(KEYCODE_CLOSEBRACE) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('-') PORT_CHAR('_') PORT_CODE(KEYCODE_MINUS) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Return") PORT_CHAR(0x0d) PORT_CODE(KEYCODE_ENTER) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('=') PORT_CHAR('+') PORT_CODE(KEYCODE_EQUALS) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Space Bar") PORT_CHAR(' ') PORT_CODE(KEYCODE_SPACE) - - PORT_START("X4") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_CODE(KEYCODE_DOWN) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_CODE(KEYCODE_LEFT) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F7)) PORT_CODE(KEYCODE_F11) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_CODE(KEYCODE_F6) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F6)) PORT_CODE(KEYCODE_F10) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Setup Cancel") PORT_CODE(KEYCODE_F2) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_CODE(KEYCODE_F7) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("SCopy DCopy") PORT_CODE(KEYCODE_F3) - - PORT_START("X5") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PORT_CODE(KEYCODE_RIGHT) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(UP)) PORT_CODE(KEYCODE_UP) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F8)) PORT_CODE(KEYCODE_F12) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F1)) PORT_CODE(KEYCODE_F5) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F5)) PORT_CODE(KEYCODE_F9) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Dialog GEras") PORT_CODE(KEYCODE_F1) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F4)) PORT_CODE(KEYCODE_F8) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Menu") PORT_CODE(KEYCODE_F4) - - PORT_START("X6") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X") PORT_CHAR('x') PORT_CHAR('X') PORT_CODE(KEYCODE_X) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W") PORT_CHAR('w') PORT_CHAR('W') PORT_CODE(KEYCODE_W) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S") PORT_CHAR('s') PORT_CHAR('S') PORT_CODE(KEYCODE_S) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q") PORT_CHAR('q') PORT_CHAR('Q') PORT_CODE(KEYCODE_Q) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('2') PORT_CHAR('@') PORT_CODE(KEYCODE_2) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A") PORT_CHAR('a') PORT_CHAR('A') PORT_CODE(KEYCODE_A) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('1') PORT_CHAR('!') PORT_CODE(KEYCODE_1) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z") PORT_CHAR('z') PORT_CHAR('Z') PORT_CODE(KEYCODE_Z) - - PORT_START("X7") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Caps Lock") PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) PORT_CODE(KEYCODE_LCONTROL) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Esc") PORT_CHAR(0x1b) //PORT_CODE(KEYCODE_XXX) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Tab") PORT_CHAR(0x09) //PORT_CODE(KEYCODE_XXX) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('|') PORT_CHAR('~') PORT_CODE(KEYCODE_TAB) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("SEras DEras") //PORT_CODE(KEYCODE_XXX) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ctrl") PORT_CHAR(UCHAR_SHIFT_2) PORT_CODE(KEYCODE_CAPSLOCK) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('[') PORT_CHAR('{') PORT_CODE(KEYCODE_TILDE) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Left Shift") PORT_CHAR(UCHAR_SHIFT_1) PORT_CODE(KEYCODE_LSHIFT) - - PORT_START("X8") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CHAR('c') PORT_CHAR('C') PORT_CODE(KEYCODE_C) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CHAR('e') PORT_CHAR('E') PORT_CODE(KEYCODE_E) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CHAR('d') PORT_CHAR('D') PORT_CODE(KEYCODE_D) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R") PORT_CHAR('r') PORT_CHAR('R') PORT_CODE(KEYCODE_R) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('3') PORT_CHAR('#') PORT_CODE(KEYCODE_3) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F") PORT_CHAR('f') PORT_CHAR('F') PORT_CODE(KEYCODE_F) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('4') PORT_CHAR('$') PORT_CODE(KEYCODE_4) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V") PORT_CHAR('v') PORT_CHAR('V') PORT_CODE(KEYCODE_V) - - PORT_START("X9") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N") PORT_CHAR('n') PORT_CHAR('N') PORT_CODE(KEYCODE_N) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y") PORT_CHAR('y') PORT_CHAR('Y') PORT_CODE(KEYCODE_Y) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H") PORT_CHAR('h') PORT_CHAR('H') PORT_CODE(KEYCODE_H) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T") PORT_CHAR('t') PORT_CHAR('T') PORT_CODE(KEYCODE_T) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('6') PORT_CHAR('^') PORT_CODE(KEYCODE_6) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G") PORT_CHAR('g') PORT_CHAR('G') PORT_CODE(KEYCODE_G) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('5') PORT_CHAR('%') PORT_CODE(KEYCODE_5) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CHAR('b') PORT_CHAR('B') PORT_CODE(KEYCODE_B) - - PORT_START("X10") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M") PORT_CHAR('m') PORT_CHAR('M') PORT_CODE(KEYCODE_M) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U") PORT_CHAR('u') PORT_CHAR('U') PORT_CODE(KEYCODE_U) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J") PORT_CHAR('j') PORT_CHAR('J') PORT_CODE(KEYCODE_J) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I") PORT_CHAR('i') PORT_CHAR('I') PORT_CODE(KEYCODE_I) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('7') PORT_CHAR('&') PORT_CODE(KEYCODE_7) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K") PORT_CHAR('k') PORT_CHAR('K') PORT_CODE(KEYCODE_K) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('8') PORT_CHAR('*') PORT_CODE(KEYCODE_8) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(',') PORT_CHAR('>') PORT_CODE(KEYCODE_COMMA) - - PORT_START("X11") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('/') PORT_CHAR('?') PORT_CODE(KEYCODE_SLASH) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P") PORT_CHAR('p') PORT_CHAR('P') PORT_CODE(KEYCODE_P) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(';') PORT_CHAR(':') PORT_CODE(KEYCODE_COLON) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O") PORT_CHAR('o') PORT_CHAR('O') PORT_CODE(KEYCODE_O) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('0') PORT_CHAR('(') PORT_CODE(KEYCODE_0) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L") PORT_CHAR('l') PORT_CHAR('L') PORT_CODE(KEYCODE_L) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('9') PORT_CHAR(')') PORT_CODE(KEYCODE_9) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('.') PORT_CHAR('>') PORT_CODE(KEYCODE_STOP) - - PORT_START("CONFIG") - PORT_DIPNAME(0x0f, 0x00, "Keyboard Type") PORT_DIPLOCATION("E:1,2,3,4") - PORT_DIPSETTING(0x00, "North America") - PORT_DIPSETTING(0x08, "United Kingdom (4A)") - PORT_DIPSETTING(0x04, "French (4B)") - PORT_DIPSETTING(0x02, "Swedish (4C)") - PORT_DIPSETTING(0x06, "Danish/Norwegian (4F)") - PORT_DIPSETTING(0x07, "German (4G)") - PORT_DIPSETTING(0x0a, "Katakana (4K)") -INPUT_PORTS_END - -ioport_constructor tek410x_keyboard_device::device_input_ports() const -{ - return INPUT_PORTS_NAME(tek410x_keyboard); -} - -void tek410x_keyboard_device::device_add_mconfig(machine_config &config) -{ - I8748(config, m_mcu, 4.608_MHz_XTAL); - m_mcu->set_addrmap(AS_IO, &tek410x_keyboard_device::ext_map); - m_mcu->bus_out_cb().set_output("led0").bit(0); - m_mcu->p1_in_cb().set(FUNC(tek410x_keyboard_device::p1_r)); - m_mcu->p2_in_cb().set(FUNC(tek410x_keyboard_device::p2_r)); - m_mcu->p2_out_cb().set(FUNC(tek410x_keyboard_device::p2_w)); -} - -ROM_START(tek410x_kbd) - ROM_REGION(0x400, "mcu", 0) - ROM_LOAD("473_8748.bin", 0x000, 0x400, CRC(371553a8) SHA1(165ffc2c0775c1a3c2cc3ec86fb05adc8e8bb3eb)) -ROM_END - -const tiny_rom_entry *tek410x_keyboard_device::device_rom_region() const -{ - return ROM_NAME(tek410x_kbd); -} diff --git a/src/mame/tektroni/tek410x_kbd.h b/src/mame/tektroni/tek410x_kbd.h deleted file mode 100644 index 095f7648094..00000000000 --- a/src/mame/tektroni/tek410x_kbd.h +++ /dev/null @@ -1,69 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:AJR - -#ifndef MAME_MACHINE_TEK410X_KEYBOARD_H -#define MAME_MACHINE_TEK410X_KEYBOARD_H - -#pragma once - -#include "cpu/mcs48/mcs48.h" - - -//************************************************************************** -// TYPE DEFINITIONS -//************************************************************************** - -// ======================> tek410x_keyboard_device - -class tek410x_keyboard_device : public device_t -{ -public: - // device type constructor - tek410x_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); - - // callback configuration - auto tdata_callback() { return m_tdata_callback.bind(); } - auto rdata_callback() { return m_rdata_callback.bind(); } - - // line inputs - DECLARE_WRITE_LINE_MEMBER(kdi_w); - DECLARE_WRITE_LINE_MEMBER(kdo_w); - DECLARE_WRITE_LINE_MEMBER(reset_w); - -protected: - // device-level overrides - virtual void device_resolve_objects() override; - virtual void device_start() override; - virtual ioport_constructor device_input_ports() const override; - virtual void device_add_mconfig(machine_config &config) override; - virtual const tiny_rom_entry *device_rom_region() const override; - -private: - // MCU handlers - u8 p1_r(); - u8 p2_r(); - void p2_w(u8 data); - - // address maps - void ext_map(address_map &map); - - // object finders - required_device m_mcu; - required_ioport_array<12> m_key_matrix; - required_ioport m_config; - - // output callbacks - devcb_write_line m_tdata_callback; - devcb_write_line m_rdata_callback; - - // internal state - u8 m_select; - u8 m_p2_out; - bool m_kdi; - bool m_kdo; -}; - -// device type declaration -DECLARE_DEVICE_TYPE(TEK410X_KEYBOARD, tek410x_keyboard_device) - -#endif // MAME_MACHINE_TEK410X_KEYBOARD_H diff --git a/src/mame/tektroni/tek43xx.cpp b/src/mame/tektroni/tek43xx.cpp deleted file mode 100644 index 544a5113b3d..00000000000 --- a/src/mame/tektroni/tek43xx.cpp +++ /dev/null @@ -1,70 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:AJR -/************************************************************************************************************ - - Skeleton driver for Tektronix 4300 series MC68020-based graphics workstations. - -************************************************************************************************************/ - -#include "emu.h" -#include "cpu/m68000/m68000.h" -#include "screen.h" - - -namespace { - -class tek43xx_state : public driver_device -{ -public: - tek43xx_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) - , m_maincpu(*this, "maincpu") - { - } - - void tek4319(machine_config &config); - -private: - u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - - void mem_map(address_map &map); - - required_device m_maincpu; -}; - - -u32 tek43xx_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - return 0; -} - -void tek43xx_state::mem_map(address_map &map) -{ - map(0x00000000, 0x00000007).rom().region("program", 0); - map(0x00000008, 0x000fffff).ram(); - map(0x01cb0000, 0x01cb0003).nopr(); - map(0x10000000, 0x1001ffff).rom().region("program", 0); -} - -static INPUT_PORTS_START(tek4319) -INPUT_PORTS_END - -void tek43xx_state::tek4319(machine_config &config) -{ - M68020(config, m_maincpu, 20'000'000); - m_maincpu->set_addrmap(AS_PROGRAM, &tek43xx_state::mem_map); - - screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_raw(60 * 1600 * 1066, 1600, 0, 1280, 1066, 0, 1024); // not confirmed except for displayed resolution - screen.set_screen_update(FUNC(tek43xx_state::screen_update)); -} - -ROM_START(tek4319) - ROM_REGION32_BE(0x20000, "program", 0) - ROM_LOAD16_BYTE("160-5528-00.bin", 0x00000, 0x10000, CRC(a04ffe7f) SHA1(601c27c47138c38dc54b9cbabca8467170cc580b)) - ROM_LOAD16_BYTE("160-5528-01.bin", 0x00001, 0x10000, CRC(869ec49f) SHA1(145a20272b1f9eb42618d0b4aefe9ea79a27dcce)) -ROM_END - -} // anonymous namespace - -COMP(1988, tek4319, 0, 0, tek4319, tek4319, tek43xx_state, empty_init, "Tektronix", "4319 Graphics Workstation", MACHINE_IS_SKELETON) diff --git a/src/mame/tektroni/tek440x.cpp b/src/mame/tektroni/tek440x.cpp deleted file mode 100644 index be815541d56..00000000000 --- a/src/mame/tektroni/tek440x.cpp +++ /dev/null @@ -1,432 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:R. Belmont, AJR -/*************************************************************************** - - Tektronix 440x "AI Workstations" - - skeleton by R. Belmont - - Hardware overview: - * 68010 (4404) or 68020 (4405) with custom MMU - * Intelligent floppy subsystem with 6502 driving a uPD765 controller - * NS32081 FPU - * 6551 debug console AICA - * SN76496 PSG for sound - * MC146818 RTC - * MC68681 DUART / timer (3.6864 MHz clock) (serial channel A = keyboard, channel B = RS-232 port) - * AM9513 timer (source of timer IRQ) - * NCR5385 SCSI controller - - Video is a 640x480 1bpp window on a 1024x1024 VRAM area; smooth panning around that area - is possible as is flat-out changing the scanout address. - - IRQ levels: - 7 = Debug (NMI) - 6 = VBL - 5 = UART - 4 = Spare (exp slots) - 3 = SCSI - 2 = DMA - 1 = Timer - 0 = Unused - - MMU info: - Map control register (location unk): bit 15 = VM enable, bits 10-8 = process ID - - Map entries: - bit 15 = dirty - bit 14 = write enable - bit 13-11 = process ID - bits 10-0 = address bits 22-12 in the final address - -***************************************************************************/ - -#include "emu.h" -#include "bus/rs232/rs232.h" -#include "cpu/m68000/m68000.h" -#include "cpu/m6502/m6502.h" -#include "machine/am9513.h" -#include "machine/bankdev.h" -#include "machine/mos6551.h" // debug tty -#include "machine/mc146818.h" -#include "machine/mc68681.h" -#include "machine/ncr5385.h" -#include "tek410x_kbd.h" -#include "sound/sn76496.h" -#include "emupal.h" -#include "screen.h" -#include "speaker.h" - - -class tek440x_state : public driver_device -{ -public: - tek440x_state(const machine_config &mconfig, device_type type, const char *tag) : - driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_fdccpu(*this, "fdccpu"), - m_vm(*this, "vm"), - m_duart(*this, "duart"), - m_keyboard(*this, "keyboard"), - m_snsnd(*this, "snsnd"), - m_prom(*this, "maincpu"), - m_mainram(*this, "mainram"), - m_vram(*this, "vram"), - m_map(*this, "map", 0x1000, ENDIANNESS_BIG), - m_map_view(*this, "map"), - m_boot(false), - m_map_control(0), - m_kb_rdata(true), - m_kb_tdata(true), - m_kb_rclamp(false), - m_kb_loop(false) - { } - - void tek4404(machine_config &config); - -private: - virtual void machine_start() override; - virtual void machine_reset() override; - u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - - u16 memory_r(offs_t offset, u16 mem_mask); - void memory_w(offs_t offset, u16 data, u16 mem_mask); - u16 map_r(offs_t offset); - void map_w(offs_t offset, u16 data, u16 mem_mask); - u8 mapcntl_r(); - void mapcntl_w(u8 data); - void sound_w(u8 data); - void diag_w(u8 data); - - DECLARE_WRITE_LINE_MEMBER(kb_rdata_w); - DECLARE_WRITE_LINE_MEMBER(kb_tdata_w); - DECLARE_WRITE_LINE_MEMBER(kb_rclamp_w); - - void logical_map(address_map &map); - void physical_map(address_map &map); - void fdccpu_map(address_map &map); - - required_device m_maincpu; - required_device m_fdccpu; - required_device m_vm; - required_device m_duart; - required_device m_keyboard; - required_device m_snsnd; - required_region_ptr m_prom; - required_shared_ptr m_mainram; - required_shared_ptr m_vram; - memory_share_creator m_map; - memory_view m_map_view; - - bool m_boot; - u8 m_map_control; - bool m_kb_rdata; - bool m_kb_tdata; - bool m_kb_rclamp; - bool m_kb_loop; -}; - -/************************************* - * - * Machine start - * - *************************************/ - -void tek440x_state::machine_start() -{ - save_item(NAME(m_boot)); - save_item(NAME(m_map_control)); - save_item(NAME(m_kb_rdata)); - save_item(NAME(m_kb_tdata)); - save_item(NAME(m_kb_rclamp)); - save_item(NAME(m_kb_loop)); -} - - - -/************************************* - * - * Machine reset - * - *************************************/ - -void tek440x_state::machine_reset() -{ - m_boot = true; - diag_w(0); - m_keyboard->kdo_w(1); - mapcntl_w(0); -} - - - -/************************************* - * - * Video refresh - * - *************************************/ - -u32 tek440x_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - for (int y = 0; y < 480; y++) - { - u16 *const line = &bitmap.pix(y); - u16 const *video_ram = &m_vram[y * 64]; - - for (int x = 0; x < 640; x += 16) - { - u16 const word = *(video_ram++); - for (int b = 0; b < 16; b++) - { - line[x + b] = BIT(word, 15 - b); - } - } - } - - return 0; -} - - - -/************************************* - * - * CPU memory handlers - * - *************************************/ - -u16 tek440x_state::memory_r(offs_t offset, u16 mem_mask) -{ - if (m_boot) - return m_prom[offset & 0x3fff]; - - const offs_t offset0 = offset; - if (BIT(m_map_control, 4)) - offset = BIT(offset, 0, 11) | BIT(m_map[offset >> 11], 0, 11) << 11; - if (offset < 0x300000 && offset >= 0x100000 && !machine().side_effects_disabled()) - { - m_maincpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE); - m_maincpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE); - m_maincpu->set_buserror_details(offset0 << 1, 1, m_maincpu->get_fc()); - } - - return m_vm->read16(offset, mem_mask); -} - -void tek440x_state::memory_w(offs_t offset, u16 data, u16 mem_mask) -{ - const offs_t offset0 = offset; - if (BIT(m_map_control, 4)) - offset = BIT(offset, 0, 11) | BIT(m_map[offset >> 11], 0, 11) << 11; - if (offset < 0x300000 && offset >= 0x100000 && !machine().side_effects_disabled()) - { - m_maincpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE); - m_maincpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE); - m_maincpu->set_buserror_details(offset0 << 1, 0, m_maincpu->get_fc()); - } - - m_vm->write16(offset, data, mem_mask); -} - -u16 tek440x_state::map_r(offs_t offset) -{ - return m_map[offset >> 11]; -} - -void tek440x_state::map_w(offs_t offset, u16 data, u16 mem_mask) -{ - COMBINE_DATA(&m_map[offset >> 11]); -} - -u8 tek440x_state::mapcntl_r() -{ - return m_map_control; -} - -void tek440x_state::mapcntl_w(u8 data) -{ - if (BIT(data, 5)) - m_map_view.select(0); - else - m_map_view.disable(); - m_map_control = data & 0x1f; -} - -void tek440x_state::sound_w(u8 data) -{ - m_snsnd->write(data); - m_boot = false; -} - -void tek440x_state::diag_w(u8 data) -{ - if (!m_kb_rclamp && m_kb_loop != BIT(data, 7)) - m_keyboard->kdo_w(!BIT(data, 7) || m_kb_tdata); - - m_kb_loop = BIT(data, 7); -} - -WRITE_LINE_MEMBER(tek440x_state::kb_rdata_w) -{ - m_kb_rdata = state; - if (!m_kb_rclamp) - m_duart->rx_a_w(state); -} - -WRITE_LINE_MEMBER(tek440x_state::kb_rclamp_w) -{ - if (m_kb_rclamp != !state) - { - m_kb_rclamp = !state; - - // Clamp RXDA to 1 and KBRDATA to 0 when DUART asserts RxRDYA - if (m_kb_tdata || !m_kb_loop) - m_keyboard->kdo_w(state); - m_duart->rx_a_w(state ? m_kb_rdata : 1); - } -} - -WRITE_LINE_MEMBER(tek440x_state::kb_tdata_w) -{ - if (m_kb_tdata != state) - { - m_kb_tdata = state; - - m_duart->ip4_w(!state); - if (m_kb_loop && m_kb_rdata && !m_kb_rclamp) - m_keyboard->kdo_w(state); - } -} - -void tek440x_state::logical_map(address_map &map) -{ - map(0x000000, 0x7fffff).rw(FUNC(tek440x_state::memory_r), FUNC(tek440x_state::memory_w)); - map(0x800000, 0xffffff).view(m_map_view); - m_map_view[0](0x800000, 0xffffff).rw(FUNC(tek440x_state::map_r), FUNC(tek440x_state::map_w)); -} - -void tek440x_state::physical_map(address_map &map) -{ - map(0x000000, 0x1fffff).ram().share("mainram"); - map(0x600000, 0x61ffff).ram().share("vram"); - map(0x740000, 0x747fff).rom().mirror(0x8000).region("maincpu", 0); - map(0x760000, 0x760fff).ram().mirror(0xf000); // debug RAM - map(0x780000, 0x780000).rw(FUNC(tek440x_state::mapcntl_r), FUNC(tek440x_state::mapcntl_w)); - // 782000-783fff: video address registers - // 784000-785fff: video control registers - map(0x788000, 0x788000).w(FUNC(tek440x_state::sound_w)); - // 78a000-78bfff: NS32081 FPU - map(0x78c000, 0x78c007).rw("aica", FUNC(mos6551_device::read), FUNC(mos6551_device::write)).umask16(0xff00); - map(0x7b0000, 0x7b0000).w(FUNC(tek440x_state::diag_w)); - // 7b1000-7b2fff: diagnostic registers - // 7b2000-7b3fff: Centronics printer data - map(0x7b4000, 0x7b401f).rw(m_duart, FUNC(mc68681_device::read), FUNC(mc68681_device::write)).umask16(0xff00); - // 7b6000-7b7fff: Mouse - map(0x7b8000, 0x7b8003).mirror(0x100).rw("timer", FUNC(am9513_device::read16), FUNC(am9513_device::write16)); - // 7ba000-7bbfff: MC146818 RTC - // 7bc000-7bdfff: SCSI bus address registers - map(0x7be000, 0x7be01f).mirror(0x1fe0).rw("scsic", FUNC(ncr5385_device::read), FUNC(ncr5385_device::write)).umask16(0xff00).cswidth(16); -} - -void tek440x_state::fdccpu_map(address_map &map) -{ - map(0x0000, 0x1000).ram(); - map(0xf000, 0xffff).rom().region("fdccpu", 0); -} - -/************************************* - * - * Port definitions - * - *************************************/ - -static INPUT_PORTS_START( tek4404 ) -INPUT_PORTS_END - -/************************************* - * - * Machine driver - * - *************************************/ - -void tek440x_state::tek4404(machine_config &config) -{ - /* basic machine hardware */ - M68010(config, m_maincpu, 40_MHz_XTAL / 4); // MC68010L10 - m_maincpu->set_addrmap(AS_PROGRAM, &tek440x_state::logical_map); - - ADDRESS_MAP_BANK(config, m_vm); - m_vm->set_addrmap(0, &tek440x_state::physical_map); - m_vm->set_data_width(16); - m_vm->set_addr_width(23); - m_vm->set_endianness(ENDIANNESS_BIG); - - M6502(config, m_fdccpu, 16_MHz_XTAL / 8); - m_fdccpu->set_addrmap(AS_PROGRAM, &tek440x_state::fdccpu_map); - - /* video hardware */ - screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_video_attributes(VIDEO_UPDATE_BEFORE_VBLANK); - screen.set_raw(25.2_MHz_XTAL, 800, 0, 640, 525, 0, 480); // 31.5 kHz horizontal (guessed), 60 Hz vertical - screen.set_screen_update(FUNC(tek440x_state::screen_update)); - screen.set_palette("palette"); - PALETTE(config, "palette", palette_device::MONOCHROME); - - mos6551_device &aica(MOS6551(config, "aica", 40_MHz_XTAL / 4 / 10)); - aica.set_xtal(1.8432_MHz_XTAL); - aica.txd_handler().set("rs232", FUNC(rs232_port_device::write_txd)); - aica.irq_handler().set_inputline(m_maincpu, M68K_IRQ_7); - - MC68681(config, m_duart, 3.6864_MHz_XTAL); - m_duart->irq_cb().set_inputline(m_maincpu, M68K_IRQ_5); // auto-vectored - m_duart->outport_cb().set(FUNC(tek440x_state::kb_rclamp_w)).bit(4); - m_duart->outport_cb().append(m_keyboard, FUNC(tek410x_keyboard_device::reset_w)).bit(3); - m_duart->a_tx_cb().set(m_keyboard, FUNC(tek410x_keyboard_device::kdi_w)); - - TEK410X_KEYBOARD(config, m_keyboard); - m_keyboard->tdata_callback().set(FUNC(tek440x_state::kb_tdata_w)); - m_keyboard->rdata_callback().set(FUNC(tek440x_state::kb_rdata_w)); - - AM9513(config, "timer", 40_MHz_XTAL / 4 / 10); // from CPU E output - - //MC146818(config, "calendar", 32.768_MHz_XTAL); - - NCR5385(config, "scsic", 40_MHz_XTAL / 4).irq().set_inputline(m_maincpu, M68K_IRQ_3); - - rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, nullptr)); - rs232.rxd_handler().set("aica", FUNC(mos6551_device::write_rxd)); - rs232.dcd_handler().set("aica", FUNC(mos6551_device::write_dcd)); - rs232.dsr_handler().set("aica", FUNC(mos6551_device::write_dsr)); - rs232.cts_handler().set("aica", FUNC(mos6551_device::write_cts)); - - SPEAKER(config, "mono").front_center(); - - SN76496(config, m_snsnd, 25.2_MHz_XTAL / 8).add_route(ALL_OUTPUTS, "mono", 0.80); -} - - - -/************************************* - * - * ROM definition(s) - * - *************************************/ - -ROM_START( tek4404 ) - ROM_REGION( 0x8000, "maincpu", 0 ) - ROM_LOAD16_BYTE( "tek_u158.bin", 0x000000, 0x004000, CRC(9939e660) SHA1(66b4309e93e4ff20c1295dc2ec2a8d6389b2578c) ) - ROM_LOAD16_BYTE( "tek_u163.bin", 0x000001, 0x004000, CRC(a82dcbb1) SHA1(a7e4545e9ea57619faacc1556fa346b18f870084) ) - - ROM_REGION( 0x1000, "fdccpu", 0 ) - ROM_LOAD( "tek_u130.bin", 0x000000, 0x001000, CRC(2c11a3f1) SHA1(b29b3705692d50f15f7e8bbba12a24c69817d52e) ) - - ROM_REGION( 0x2000, "scsimfm", 0 ) - ROM_LOAD( "scsi_mfm.bin", 0x000000, 0x002000, CRC(b4293435) SHA1(5e2b96c19c4f5c63a5afa2de504d29fe64a4c908) ) -ROM_END - -/************************************* - * - * Game driver(s) - * - *************************************/ -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1984, tek4404, 0, 0, tek4404, tek4404, tek440x_state, empty_init, "Tektronix", "4404 Artificial Intelligence System", MACHINE_NOT_WORKING ) diff --git a/src/mame/tektroni/tekigw.cpp b/src/mame/tektroni/tekigw.cpp deleted file mode 100644 index 3000d55ccd3..00000000000 --- a/src/mame/tektroni/tekigw.cpp +++ /dev/null @@ -1,967 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Patrick Mackinlay - -/* - * Tektronix Intelligent Graphics Workstations (6110, 6120, 6130, 6205, 6210, 6212, 4132) - * - * Sources: - * - http://bitsavers.trailing-edge.com/pdf/tektronix/6130/6100_Series_Hardware_Descriptions.pdf - * - https://archive.org/details/tektronix_Tektronix_1985 - * - * TODO: - * - am9516 dma controller - * - slots and cards - * - gpib devices - * - graphics and keyboard - */ -/* - * WIP - * - novram chip select not asserted when trying to read ethernet mac address? - * - aborts to firmware monitor on second serial port after failing to boot - */ - -#include "emu.h" - -// cpus and memory -#include "cpu/ns32000/ns32000.h" -#include "machine/ram.h" - -// various hardware -//#include "machine/am9516a.h" -#include "machine/am9517a.h" -#include "machine/eepromser.h" -#include "machine/i82586.h" -#include "machine/mm58167.h" -//#include "machine/ncr5385.h" -#include "machine/ns32081.h" -#include "machine/ns32082.h" -#include "machine/ns32202.h" -#include "machine/tms9914.h" -#include "machine/wd_fdc.h" -#include "machine/wd1010.h" -#include "machine/z80scc.h" - -#include "machine/input_merger.h" - -// busses and connectors -#include "bus/ieee488/ieee488.h" -#include "machine/nscsi_bus.h" -#include "bus/nscsi/hd.h" -#include "bus/rs232/rs232.h" -#include "imagedev/floppy.h" -#include "imagedev/harddriv.h" - -// graphics -#include "cpu/mcs51/mcs51.h" -#include "video/mc6845.h" -#include "screen.h" - -#define VERBOSE 0 -#include "logmacro.h" - -namespace { - -class tekigw_state_base : public driver_device -{ -protected: - tekigw_state_base(machine_config const &mconfig, device_type type, char const *tag) - : driver_device(mconfig, type, tag) - , m_cpu(*this, "cpu") - , m_fpu(*this, "fpu") - , m_mmu(*this, "mmu") - , m_icu(*this, "icu") - , m_ram(*this, "ram") - , m_scc(*this, "scc") - , m_serial(*this, "port%u", 0U) - , m_rtc(*this, "rtc") - , m_nov(*this, "nov%u", 0U) - //, m_dma(*this, "dma") - , m_lan(*this, "lan") - , m_led(*this, "led") - { - } - - void common_config(machine_config &config); - void common_init(); - - // driver_device overrides - virtual void machine_start() override; - virtual void machine_reset() override; - - // address maps - template void cpu_map(address_map &map); - - // computer board control registers - u8 nov_r() { return m_nmr; } - u8 scr_r() { return m_scr; } - u8 ssr_r() { return m_ssr; } - void led_w(u8 data) { m_led = data; } - void nov_w(u8 data); - void scr_w(u8 data); - - // novram data out handler - void nov_do(int state); - - void buserror(s32 param); - - required_device m_cpu; - required_device m_fpu; - required_device m_mmu; - required_device m_icu; - required_device m_ram; - - required_device m_scc; - required_device_array m_serial; - required_device m_rtc; - optional_device_array m_nov; - //required_device m_dma; - required_device m_lan; - - output_finder<> m_led; - - emu_timer *m_buserror = nullptr; - -private: - u8 m_nmr = 0; // nonvolatile memory register - u16 m_per = 0; // parity error register - u8 m_scr = 0; // system control register - u8 m_ssr = 0; // system status register - - // ram parity state - memory_passthrough_handler m_parity_mph; - std::unique_ptr m_parity_flag; - unsigned m_parity_bad = 0; - bool m_parity_check = 0; -}; - -class tek6100_state : public tekigw_state_base -{ -public: - tek6100_state(machine_config const &mconfig, device_type type, char const *tag) - : tekigw_state_base(mconfig, type, tag) - , m_gpib(*this, "gpib") - , m_fdc(*this, "fdc") - , m_fdd(*this, "fdc:%u:525dd", 0U) - , m_hdc(*this, "hdc") - , m_hdd(*this, "hdc:0") - , m_dpu_cpu(*this, "dpu_cpu") - , m_dpu_cram(*this, "dpu_cram") - , m_dpu_vram(*this, "dpu_vram") - { - } - - void tek6130(machine_config &config); - void init() { tekigw_state_base::common_init(); } - -protected: - // driver_device overrides - virtual void machine_start() override; - virtual void machine_reset() override; - - // address maps - template void cpu_map(address_map &map); - void lan_map(address_map &map); - template void dpu_cpu_map(address_map &map); - -private: - // computer board control registers - void fcr_w(u8 data); - void gcr_w(u8 data); - void hcr_w(u8 data); - - // hard disk buffer handlers - template T buf_r(); - template void buf_w(T data); - - u32 screen_update(screen_device& screen, bitmap_rgb32& bitmap, rectangle const& cliprect) { return 0; } - - required_device m_gpib; - required_device m_fdc; - optional_device_array m_fdd; - required_device m_hdc; - required_device m_hdd; - - optional_device m_dpu_cpu; - optional_device m_dpu_cram; - optional_device m_dpu_vram; - - u8 m_hcr = 0; // hard disk control register - - // hard disk controller buffer - u16 m_hdc_ptr = 0; - std::unique_ptr m_hdc_buf; -}; - -class tek4132_state : public tekigw_state_base -{ -public: - tek4132_state(machine_config const &mconfig, device_type type, char const *tag) - : tekigw_state_base(mconfig, type, tag) - , m_scsibus(*this, "scsi") - //, m_scsi(*this, "scsi:7:ncr5385") - , m_sdma(*this, "sdma") - , m_sirq(*this, "sirq") - { - } - - void tek4132(machine_config &config); - void init() { tekigw_state_base::common_init(); } - -protected: - // driver_device overrides - //virtual void machine_start() override; - //virtual void machine_reset() override; - - // address maps - template void cpu_map(address_map &map); - void lan_map(address_map &map); - -private: - required_device m_scsibus; - //required_device m_scsi; - required_device m_sdma; - - required_device m_sirq; -}; - -void tekigw_state_base::machine_start() -{ - save_item(NAME(m_nmr)); - save_item(NAME(m_per)); - save_item(NAME(m_scr)); - save_item(NAME(m_ssr)); - - m_per = 0; - m_ssr = 0; - - m_parity_check = false; - - m_buserror = timer_alloc(FUNC(tek4132_state::buserror), this); -} - -void tekigw_state_base::machine_reset() -{ - nov_w(0); - scr_w(0); -} - -void tek6100_state::machine_start() -{ - tekigw_state_base::machine_start(); - - m_hdc_buf = std::make_unique(4096); - - save_item(NAME(m_hcr)); - - save_item(NAME(m_hdc_ptr)); - save_pointer(NAME(m_hdc_buf), 4096); -} - -void tek6100_state::machine_reset() -{ - tekigw_state_base::machine_reset(); - - hcr_w(0); - fcr_w(0); - - m_icu->ir_w<0>(1); // mmu present - m_icu->ir_w<3>(1); - m_icu->ir_w<4>(1); - m_icu->ir_w<5>(1); - m_icu->ir_w<6>(1); - m_icu->ir_w<7>(1); - m_icu->ir_w<8>(1); - m_icu->ir_w<9>(1); - m_icu->ir_w<14>(1); // fpu present -} - -void tekigw_state_base::common_init() -{ - m_led.resolve(); - - m_lan->space(0).install_ram(0, m_ram->mask(), m_ram->pointer()); -} - -enum fcr_mask : u8 -{ - FCR_DRIVE = 0x01, // drive select - FCR_SIDE = 0x02, // side select - FCR_DDEN = 0x04, // double density enable - FCR_FDEN = 0x08, // flexible disk enable -}; - -void tek6100_state::fcr_w(u8 data) -{ - floppy_image_device *fdd = nullptr; - if (data & FCR_FDEN) - fdd = m_fdd[data & FCR_DRIVE]; - - m_fdc->set_floppy(fdd); - if (fdd) - fdd->ss_w(bool(data & FCR_SIDE)); - - m_fdc->dden_w(bool(data & FCR_DDEN)); -} - -enum gcr_mask : u8 -{ - GCR_SYSCTL = 0x02, // gpib line driver enable -}; - -void tek6100_state::gcr_w(u8 data) -{ - // TODO: enable/disable line drivers -} - -enum scr_mask : u8 -{ - SCR_RAME = 0x01, // ram enable - SCR_NMIE = 0x04, // nmi enable - SCR_LLOP = 0x08, // lan loopback enable - SCR_BERRE = 0x10, // bus error enable - SCR_DMAE = 0x20, // dma enable - SCR_PARB = 0x40, // parity bad - SCR_PARE = 0x80, // parity enable -}; - -enum ssr_mask : u8 -{ - SSR_DMACH = 0x0f, // dma channel - SSR_BERR = 0x10, // bus error - SSR_PWRSW = 0x20, // power switch - SSR_PFAIL = 0x40, // power fail - SSR_PERR = 0x80, // parity error -}; - -enum per_mask : u16 -{ - PER_PARADR = 0x3fff, // parity address - PER_HIERR = 0x4000, - PER_LOERR = 0x8000, -}; - -void tekigw_state_base::scr_w(u8 data) -{ - if (!(m_scr & SCR_RAME) && (data & SCR_RAME)) - m_cpu->space(0).install_ram(0, m_ram->mask(), m_ram->pointer()); - - if ((m_scr ^ data) & SCR_LLOP) - m_lan->set_loopback(data & SCR_LLOP); - - if (m_scr & SCR_BERRE && !(data & SCR_BERRE)) - m_ssr &= ~(SSR_BERR | SSR_DMACH); - - // install parity handlers - if (!(m_scr & SCR_PARB) && (data & SCR_PARB) && !m_parity_check) - { - m_parity_flag = std::make_unique(m_ram->size() / 32); - m_parity_bad = 0; - m_parity_check = true; - - m_parity_mph = m_cpu->space(0).install_readwrite_tap( - 0, m_ram->mask(), - "parity", - [this] (offs_t offset, u16 &data, u16 mem_mask) - { - if (m_scr & SCR_PARE) - { - bool error = false; - - // check bad parity (lo) - if ((mem_mask & 0x00ff) && BIT(m_parity_flag[offset / 32], (offset & 31) + 0)) - { - m_ssr |= SSR_PERR; - m_per &= ~PER_PARADR; - m_per |= PER_LOERR | ((offset >> 9) & PER_PARADR); - - error = true; - } - - // check bad parity (hi) - if ((mem_mask & 0xff00) && BIT(m_parity_flag[offset / 32], (offset & 31) + 1)) - { - m_ssr |= SSR_PERR; - m_per &= ~PER_PARADR; - m_per |= PER_HIERR | ((offset >> 9) & PER_PARADR); - - error = true; - } - - if (error && (m_scr & SCR_NMIE)) - m_cpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE); - } - }, - [this] (offs_t offset, u16 &data, u16 mem_mask) - { - if (m_scr & SCR_PARB) - { - // mark bad parity (lo) - if ((mem_mask & 0x00ff) && !BIT(m_parity_flag[offset / 32], (offset & 31) + 0)) - { - m_parity_flag[offset / 32] |= 1U << ((offset & 31) + 0); - m_parity_bad++; - } - - // mark bad parity (hi) - if ((mem_mask & 0xff00) && !BIT(m_parity_flag[offset / 32], (offset & 31) + 1)) - { - m_parity_flag[offset / 32] |= 1U << ((offset & 31) + 1); - m_parity_bad++; - } - } - else - { - // clear bad parity (lo) - if ((mem_mask & 0x00ff) && BIT(m_parity_flag[offset / 32], (offset & 31) + 0)) - { - m_parity_flag[offset / 32] &= ~(1U << ((offset & 31) + 0)); - m_parity_bad--; - } - - // clear bad parity (hi) - if ((mem_mask & 0xff00) && BIT(m_parity_flag[offset / 32], (offset & 31) + 1)) - { - m_parity_flag[offset / 32] &= ~(1U << ((offset & 31) + 1)); - m_parity_bad--; - } - - // stop checking parity if all clear - if (!m_parity_bad) - { - m_parity_flag.reset(); - m_parity_mph.remove(); - m_parity_check = false; - } - } - }, - &m_parity_mph); - } - - // stop checking parity if all clear - if ((m_scr & SCR_PARB) && !(data & SCR_PARB) && m_parity_check && !m_parity_bad) - { - m_parity_flag.reset(); - m_parity_mph.remove(); - m_parity_check = false; - } - - if (data & SCR_PARE) - m_per = 0; - else - m_ssr &= ~SSR_PERR; - - m_scr = data; -} - -enum nov_mask : u8 -{ - NOV_NDAT = 0x01, // nonvolatile memory data - NOV_SK = 0x02, // serial clock - NOV_CS0 = 0x04, // chip select 0 - NOV_CS1 = 0x08, // chip select 1 - NOV_LED = 0x10, // power-on led - NOV_PON = 0x20, // system power enable - NOV_MSK = 0x3e, -}; - -void tekigw_state_base::nov_w(u8 data) -{ - bool const cs0 = data & NOV_CS0; - bool const cs1 = data & NOV_CS1; - - if (m_nov[0] && ((m_nmr ^ data) & NOV_CS0)) - m_nov[0]->cs_write(cs0); - if (m_nov[1] && ((m_nmr ^ data) & NOV_CS1)) - m_nov[1]->cs_write(cs1); - - if (m_nov[0] && cs0) - { - m_nov[0]->di_write(bool(data & NOV_NDAT)); - m_nov[0]->clk_write(bool(data & NOV_SK)); - } - - if (m_nov[1] && cs1) - { - m_nov[1]->di_write(bool(data & NOV_NDAT)); - m_nov[1]->clk_write(bool(data & NOV_SK)); - } - - m_nmr = (m_nmr & ~NOV_MSK) | (data & NOV_MSK); -} - -void tekigw_state_base::nov_do(int state) -{ - if (state) - m_nmr |= NOV_NDAT; - else - m_nmr &= ~NOV_NDAT; -} - -void tekigw_state_base::buserror(s32 param) -{ - if (m_scr & SCR_BERRE) - { - m_ssr |= SSR_BERR | (param & SSR_DMACH); - - if (m_scr & SCR_NMIE) - m_cpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE); - } -} - -enum hcr_mask : u8 -{ - HCR_HDSEL = 0x0f, // head select - HCR_DRSEL = 0x10, // drive select - HCR_MULT = 0x20, // multiple sector - HCR_BFRDY = 0x40, // buffer ready - HCR_BCCLR = 0x80, // buffer counter clear -}; - -void tek6100_state::hcr_w(u8 data) -{ - m_hdc->drdy_w(m_hdd->exists() && bool(data & HCR_DRSEL)); - m_hdc->brdy_w(bool(data & HCR_BFRDY)); - - if (!(data & HCR_BCCLR)) - m_hdc_ptr = 0; - - m_hdc->head_w(data & 7); - m_hdc->sc_w(bool(data & HCR_DRSEL)); - - m_hcr = data; -} - -template T tek6100_state::buf_r() -{ - T data = 0; - - for (unsigned i = 0; i < sizeof(T); i++) - data |= T(m_hdc_buf[m_hdc_ptr++ & 0xfff]) << (i * 8); - - return data; -} - -template void tek6100_state::buf_w(T data) -{ - for (unsigned i = 0; i < sizeof(T); i++) - m_hdc_buf[m_hdc_ptr++ & 0xfff] = u8(data >> (i * 8)); -} - -template void tekigw_state_base::cpu_map(address_map &map) -{ - map(0xfff004, 0xfff005).lw16([this](u16 data) { m_lan->ca(1); }, "lan_ca"); - map(0xfff006, 0xfff006).rw(FUNC(tekigw_state_base::nov_r), FUNC(tekigw_state_base::nov_w)); - map(0xfff008, 0xfff009).portr("config"); - map(0xfff008, 0xfff008).w(FUNC(tekigw_state_base::led_w)); - map(0xfff00a, 0xfff00b).lr16([this]() { return m_per; }, "per_r"); - map(0xfff00c, 0xfff00c).rw(FUNC(tekigw_state_base::scr_r), FUNC(tekigw_state_base::scr_w)); - map(0xfff00e, 0xfff00e).r(FUNC(tekigw_state_base::ssr_r)); - - map(0xfff800, 0xfff83f).rw(m_rtc, FUNC(mm58167_device::read), FUNC(mm58167_device::write)).umask16(0xff); - map(0xfffa00, 0xfffa07).rw(m_scc, FUNC(z80scc_device::ab_dc_r), FUNC(z80scc_device::ab_dc_w)).umask16(0xff); - //map(0xfffd00, 0xfffdff); // dma controller - map(0xfffe00, 0xfffeff).m(m_icu, FUNC(ns32202_device::map)).umask16(0xff); -} - -template void tek6100_state::cpu_map(address_map &map) -{ - tekigw_state_base::cpu_map(map); - - map(0x000000, 0x007fff).rom().region("kernel", 0); - - //map(0x300000, 0x7fffff); // external bus - map(0x800000, 0x807fff).rom().region("kernel", 0); - //map(0x820000, 0xfdffff); // external bus - map(0xfe0000, 0xfeffff).lr8( - [this](address_space &space) - { - // FIXME: Should be 20μs according to 6100 documentation; CPU is still - // too fast, and timing may differ on 4132. Also DMACH field should be - // 7 for CPU, but diagnostic expects F; maybe 4132 is different? - m_buserror->adjust(attotime::from_ticks(10, m_cpu->clock()), 0x7); - - return 0; // space.unmap(); - }, "buserror"); // expansion I/O - - map(0xff0000, 0xff7fff).rw(FUNC(tek6100_state::buf_r), FUNC(tek6100_state::buf_w)); - - map(0xfff000, 0xfff000).w(FUNC(tek6100_state::fcr_w)); - map(0xfff002, 0xfff002).w(FUNC(tek6100_state::gcr_w)); - - map(0xfff900, 0xfff90f).rw(m_gpib, FUNC(tms9914_device::read), FUNC(tms9914_device::write)).umask16(0xff); - map(0xfffb00, 0xfffb0f).rw(m_hdc, FUNC(wd1010_device::read), FUNC(wd1010_device::write)).umask16(0xff); - map(0xfffb10, 0xfffb10).w(FUNC(tek6100_state::hcr_w)); - map(0xfffc00, 0xfffc07).rw(m_fdc, FUNC(wd1770_device::read), FUNC(wd1770_device::write)).umask16(0xff); - map(0xffff00, 0xffffff).rom().region("kernel", 0x7f00); -} - -void tek6100_state::lan_map(address_map &map) -{ - map.global_mask(0x3fffff); - - map(0x3fff00, 0x3fffff).rom().region("kernel", 0x7f00); // 0xf00000-0xffffff -} - -template void tek6100_state::dpu_cpu_map(address_map &map) -{ - map(0x000000, 0x007fff).rom().region("dpu", 0); - - map(0x100000, 0x107fff).rom().region("dpu", 0); - - - map(0x20000e, 0x20000e).lr8([]() { return 0x20; }, "fpu_present"); - - //map(0x200026, 0x200026); - map(0x200028, 0x200028).lw8( - [this](u8 data) - { - if (!BIT(data, 7) && m_dpu_cpu) - { - m_dpu_cpu->space(0).install_ram(0, m_dpu_cram->mask(), m_dpu_cram->pointer()); - m_dpu_cpu->space(0).install_ram(0x400000, 0x400000 | m_dpu_vram->mask(), m_dpu_vram->pointer()); - } - }, "ram_enable"); - //map(0x20002a, 0x20002a); - //map(0x20002c, 0x20002c); - - //map(0x300000, 0x300000); // PUbram - pattern ram - map(0xc00000, 0xc0000f).ram(); // PUpixm1 (1/2 bit x 4 planes) -} - -enum csr_mask : u8 -{ - CSR_IDENT = 0x07, // scsi bus id (inverted) - CSR_RESET = 0x08, // scsi bus reset - CSR_FEOP = 0x10, // dma force eop - CSR_IENBL = 0x20, // scsi interrupt enable - CSR_DIPEND = 0x40, // dma interrupt pending - CSR_SIPEND = 0x80, // scsi interrupt pending -}; - -template void tek4132_state::cpu_map(address_map &map) -{ - map(0x000000, 0xffffff).lr8( - [this](address_space &space) - { - // FIXME: Should be 20μs according to 6100 documentation; CPU is still - // too fast, and timing may differ on 4132. Also DMACH field should be - // 7 for CPU, but diagnostic expects F; maybe 4132 is different? - m_buserror->adjust(attotime::from_ticks(50, m_cpu->clock()), 0xf); - - return space.unmap(); - }, "buserror"); - - tekigw_state_base::cpu_map(map); - - map(0x000000, 0x00ffff).rom().region("kernel", 0); - map(0x800000, 0x80ffff).rom().region("kernel", 0); - - //map(0xfff000, 0xfff000).w(FUNC(tek6100_state::fcr_w)); // rsaa_dmaaos serial dma address offset register - //map(0xfff002, 0xfff002).w(FUNC(tek6100_state::gcr_w)); // rsaa_auxlatch serial auxiliary control register - - map(0xfff900, 0xfff91f).rw(m_sdma, FUNC(am9517a_device::read), FUNC(am9517a_device::write)).umask16(0xff); - //map(0xfffa08, 0xfffa08); // rsaa_status - - //map(0xfffc00, 0xfffc1f); // signature - map(0xfffc20, 0xfffc3f).lw8( - [this](u8 data) - { - LOG("csr_w 0x%02x (%s)\n", data, machine().describe_context()); - - //m_scsi->set_own_id(~data & CSR_IDENT); - //m_sirq->in_w<1>(bool(data & CSR_IENBL)); - }, "csr_w"); - //map(0xfffc40, 0xfffc5f).m(m_scsi, FUNC(ncr5385_device::map)).umask16(0xff); - map(0xfffc60, 0xfffc61).ram(); // 9516 data - map(0xfffc62, 0xfffc63).ram(); // 9516 pointer - map(0xfffd00, 0xfffdff).ram(); // stub out 9516 - - map(0xffff00, 0xffffff).rom().region("kernel", 0xff00); -} - -void tek4132_state::lan_map(address_map &map) -{ - map.global_mask(0x3fffff); - - map(0x3fff00, 0x3fffff).rom().region("kernel", 0xff00); // 0xf00000-0xffffff -} - -void tekigw_state_base::common_config(machine_config &config) -{ - NS32016(config, m_cpu, 20_MHz_XTAL / 2); - - NS32081(config, m_fpu, 20_MHz_XTAL / 2); - m_cpu->set_fpu(m_fpu); - - NS32082(config, m_mmu, 20_MHz_XTAL / 2); - m_cpu->set_mmu(m_mmu); - - NS32202(config, m_icu, 20_MHz_XTAL / 1000); - m_icu->out_int().set_inputline(m_cpu, INPUT_LINE_IRQ0).invert(); - - RAM(config, m_ram); - m_ram->set_default_size("1M"); - - SCC8530N(config, m_scc, 16_MHz_XTAL / 4); - m_scc->out_int_callback().set(m_icu, FUNC(ns32202_device::ir_w<1>)).invert(); - m_scc->configure_channels(2'457'600, 0, 2'457'600, 0); - - RS232_PORT(config, m_serial[0], default_rs232_devices, "terminal"); - m_serial[0]->cts_handler().set(m_scc, FUNC(z80scc_device::ctsa_w)); - m_serial[0]->dcd_handler().set(m_scc, FUNC(z80scc_device::dcda_w)); - m_serial[0]->rxd_handler().set(m_scc, FUNC(z80scc_device::rxa_w)); - m_scc->out_dtra_callback().set(m_serial[0], FUNC(rs232_port_device::write_dtr)); - m_scc->out_rtsa_callback().set(m_serial[0], FUNC(rs232_port_device::write_rts)); - m_scc->out_txda_callback().set(m_serial[0], FUNC(rs232_port_device::write_txd)); - - RS232_PORT(config, m_serial[1], default_rs232_devices, nullptr); - m_serial[1]->cts_handler().set(m_scc, FUNC(z80scc_device::ctsb_w)); - m_serial[1]->dcd_handler().set(m_scc, FUNC(z80scc_device::dcdb_w)); - m_serial[1]->rxd_handler().set(m_scc, FUNC(z80scc_device::rxb_w)); - m_scc->out_dtrb_callback().set(m_serial[1], FUNC(rs232_port_device::write_dtr)); - m_scc->out_rtsb_callback().set(m_serial[1], FUNC(rs232_port_device::write_rts)); - m_scc->out_txdb_callback().set(m_serial[1], FUNC(rs232_port_device::write_txd)); - - MM58167(config, m_rtc, 32.768_kHz_XTAL); - - EEPROM_X24C44_16BIT(config, m_nov[0]); // X2443P - m_nov[0]->do_callback().set(FUNC(tekigw_state_base::nov_do)); - - I82586(config, m_lan, 16_MHz_XTAL / 2); - m_lan->out_irq_cb().set(m_icu, FUNC(ns32202_device::ir_w<11>)).invert(); -} - -void tek6100_state::tek6130(machine_config &config) -{ - tekigw_state_base::common_config(config); - - m_cpu->set_addrmap(0, &tek6100_state::cpu_map<0>); - m_cpu->set_addrmap(6, &tek6100_state::cpu_map<6>); - - m_lan->set_addrmap(0, &tek6100_state::lan_map); - - /* - * Interrupt sources - * 0 interval clock - * 1 serial - * 2 hard disk - * 3 display - * 4 backplane slot 1 - * 5 backplane slot 2 - * 6 backplane slot 3 - * 7 backplane slot 4 - * 8 backplane slot 5 - * 9 backplane slot 6 - * 10 gpib - * 11 local area network - * 12 power switch - * 13 flexible disk - * 14 network level - * 15 software clock - */ - - WD1770(config, m_fdc, 8_MHz_XTAL); // clock? - m_fdc->intrq_wr_callback().set(m_icu, FUNC(ns32202_device::ir_w<13>)); - //m_fdc->drq_wr_callback().set(m_dma, FUNC(::)); - FLOPPY_CONNECTOR(config, "fdc:0", "525dd", FLOPPY_525_DD, true, floppy_image_device::default_mfm_floppy_formats).enable_sound(true); - - WD1010(config, m_hdc, 20_MHz_XTAL / 4); - m_hdc->out_intrq_callback().set(m_icu, FUNC(ns32202_device::ir_w<2>)); - m_hdc->in_data_callback().set(FUNC(tek6100_state::buf_r)); - m_hdc->out_data_callback().set(FUNC(tek6100_state::buf_w)); - m_hdc->out_bcr_callback().set([this](int state) { if (state) m_hdc_ptr = 0; }); - - /* - * Supported hard drives (c,h,s,bps): - * - Micropolis 1302 (830,3,16,512) - * - Micropolis 1304 (830,6,16,512) - * - Maxtor XT-1105 (918,11,16,512) - */ - HARDDISK(config, m_hdd, 0); - - TMS9914(config, m_gpib, 20_MHz_XTAL / 4); - m_gpib->int_write_cb().set(m_icu, FUNC(ns32202_device::ir_w<10>)); - m_gpib->dio_read_cb().set(IEEE488_TAG, FUNC(ieee488_device::dio_r)); - m_gpib->dio_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_dio_w)); - m_gpib->eoi_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_eoi_w)); - m_gpib->dav_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_dav_w)); - m_gpib->nrfd_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_nrfd_w)); - m_gpib->ndac_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_ndac_w)); - m_gpib->ifc_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_ifc_w)); - m_gpib->srq_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_srq_w)); - m_gpib->atn_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_atn_w)); - m_gpib->ren_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_ren_w)); - - ieee488_device &ieee(IEEE488(config, IEEE488_TAG)); - ieee.eoi_callback().set(m_gpib, FUNC(tms9914_device::eoi_w)); - ieee.dav_callback().set(m_gpib, FUNC(tms9914_device::dav_w)); - ieee.nrfd_callback().set(m_gpib, FUNC(tms9914_device::nrfd_w)); - ieee.ndac_callback().set(m_gpib, FUNC(tms9914_device::ndac_w)); - ieee.ifc_callback().set(m_gpib, FUNC(tms9914_device::ifc_w)); - ieee.srq_callback().set(m_gpib, FUNC(tms9914_device::srq_w)); - ieee.atn_callback().set(m_gpib, FUNC(tms9914_device::atn_w)); - ieee.ren_callback().set(m_gpib, FUNC(tms9914_device::ren_w)); - - IEEE488_SLOT(config, "ieee_rem", 0, remote488_devices, nullptr); - - // TODO: graphics board disabled for now - if (false) - { - NS32016(config, m_dpu_cpu, 0); // 8'000'000); - m_dpu_cpu->set_addrmap(0, &tek6100_state::dpu_cpu_map<0>); - - ns32081_device &dpu_fpu(NS32081(config, "dpu_fpu", 8'000'000)); - m_dpu_cpu->set_fpu(dpu_fpu); - - ns32202_device &dpu_icu(NS32202(config, "dpu_icu", 20'000)); - dpu_icu.out_int().set_inputline(m_dpu_cpu, INPUT_LINE_IRQ0).invert(); - - i8744_device &dpu_mcu(I8744(config, "dpu_mcu", 0)); // 10'000'000)); // 8744H-10 - (void)dpu_mcu; - - mc6845_device &dpu_crtc(SY6845E(config, "dpu_crtc", 25.2_MHz_XTAL)); // SYP6845EA - dpu_crtc.set_screen("dpu_screen"); - - // 32 x HM50256-15 (256K x 1 DRAM) total 1MiB - RAM(config, m_dpu_cram); - m_dpu_cram->set_default_size("1MiB"); - - // 32 x IMS2620P-12 (16K x 4 DRAM) total 256KiB - RAM(config, m_dpu_vram); - m_dpu_vram->set_default_size("256KiB"); - - // 13-inch 640x480 60Hz 4-bit color - // 15-inch 640x480 60Hz monochrome - screen_device &dpu_screen(SCREEN(config, "dpu_screen", SCREEN_TYPE_RASTER)); - dpu_screen.set_raw(25200000, 800, 0, 640, 525, 0, 480); - dpu_screen.set_screen_update(FUNC(tek6100_state::screen_update)); - } -} - -static void scsi_devices(device_slot_interface &device) -{ - device.option_add("harddisk", NSCSI_HARDDISK); -} - -void tek4132_state::tek4132(machine_config &config) -{ - tekigw_state_base::common_config(config); - - m_cpu->set_addrmap(0, &tek4132_state::cpu_map<0>); - m_cpu->set_addrmap(6, &tek4132_state::cpu_map<6>); - - m_lan->set_addrmap(0, &tek4132_state::lan_map); - - m_scc->configure_channels(3'686'400, 0, 3'686'400, 0); - - /* - * Interrupt sources - * 0 interval clock - * 1 serial - * 2 display - * 3 serial dma - * 4 scsi controller - * 5 backplane slot 1 - * 6 backplane slot 2 - * 7 backplane slot 3 - * 8 backplane slot 4 - * 9 backplane slot 5 - * 10 backplane slot 6 - * 11 local area network - * 12 power switch interrupt - * 13 time of day clock - * 14 network level - * 15 software clock - */ - - m_rtc->irq().set(m_icu, FUNC(ns32202_device::ir_w<13>)); - - EEPROM_X24C44_16BIT(config, m_nov[1]); // X2443P - m_nov[1]->do_callback().set(FUNC(tek4132_state::nov_do)); - - AM9517A(config, m_sdma, 4'000'000); // clock? - m_sdma->dreq_active_low(); - - INPUT_MERGER_ALL_HIGH(config, m_sirq); - //m_sirq->output_handler().set(m_icu, FUNC(ns32202_device::ir_w<4>)); - - NSCSI_BUS(config, m_scsibus); - NSCSI_CONNECTOR(config, "scsi:0", scsi_devices, "harddisk"); - NSCSI_CONNECTOR(config, "scsi:1", scsi_devices, nullptr); - NSCSI_CONNECTOR(config, "scsi:2", scsi_devices, nullptr); - NSCSI_CONNECTOR(config, "scsi:3", scsi_devices, nullptr); - NSCSI_CONNECTOR(config, "scsi:4", scsi_devices, nullptr); - NSCSI_CONNECTOR(config, "scsi:5", scsi_devices, nullptr); - NSCSI_CONNECTOR(config, "scsi:6", scsi_devices, nullptr); -#if 1 - NSCSI_CONNECTOR(config, "scsi:7", scsi_devices, nullptr); -#else - NSCSI_CONNECTOR(config, "scsi:7").option_set("ncr5385", NCR5385).clock(10'000'000).machine_config( - [this](device_t *device) - { - ncr5385_device &adapter = downcast(*device); - - //adapter.irq().set(m_sirq, FUNC(input_merger_all_high_device::in_w<0>)); - adapter.irq().set(m_icu, FUNC(ns32202_device::ir_w<4>)); - //adapter.drq_handler_cb().set(m_mct_adr, FUNC(mct_adr_device::drq<0>)); - - //subdevice(":mct_adr")->dma_r_cb<0>().set(adapter, FUNC(ncr53c94_device::dma_r)); - //subdevice(":mct_adr")->dma_w_cb<0>().set(adapter, FUNC(ncr53c94_device::dma_w)); - }); -#endif -} - -static INPUT_PORTS_START(tekigw) - PORT_START("config") - PORT_DIPNAME(0x80, 0x00, "Mode") PORT_DIPLOCATION("SW:1") - PORT_DIPSETTING( 0x00, "Normal") - PORT_DIPSETTING( 0x80, "Service") - PORT_DIPNAME(0x60, 0x20, "Console") PORT_DIPLOCATION("SW:3,2") - PORT_DIPSETTING( 0x00, "Display") - PORT_DIPSETTING( 0x20, "9600 baud RS-232-C terminal (port 0)") - PORT_DIPSETTING( 0x40, "1200 baud RS-232-C modem/terminal (port 1)") - PORT_DIPSETTING( 0x60, "300 baud model/terminal (port 1)") - PORT_DIPNAME(0x10, 0x00, "Boot") PORT_DIPLOCATION("SW:4") - PORT_DIPSETTING( 0x00, "UTek") - PORT_DIPSETTING( 0x10, "File") - PORT_DIPNAME(0x0c, 0x00, "Boot Device") PORT_DIPLOCATION("SW:6,5") - PORT_DIPSETTING( 0x00, "Autoboot") - PORT_DIPSETTING( 0x04, "Hard disk") - PORT_DIPSETTING( 0x08, "Diskette drive") - PORT_DIPSETTING( 0x0c, "LAN port") - PORT_DIPNAME(0x03, 0x00, "Diagnostic") PORT_DIPLOCATION("SW:8,7") - PORT_DIPSETTING( 0x00, "0") - PORT_DIPSETTING( 0x01, "1") - PORT_DIPSETTING( 0x02, "2") - PORT_DIPSETTING( 0x03, "3") -INPUT_PORTS_END - -ROM_START(tek6130) - ROM_REGION16_LE(0x8000, "kernel", 0) - ROM_SYSTEM_BIOS(0, "5.107", "5.107 85/02/20 13:51:51") - ROMX_LOAD("160-2921-02.bin", 0x00000, 0x4000, CRC(44688258) SHA1(645ceaa6ea9ef76ba8b557dec0387fce73f669c0), ROM_BIOS(0) | ROM_SKIP(1)) - ROMX_LOAD("160-2922-02.bin", 0x00001, 0x4000, CRC(5d84dff3) SHA1(08e74f0157a5c002397b3c8644613dc0ae8355a0), ROM_BIOS(0) | ROM_SKIP(1)) - - ROM_SYSTEM_BIOS(1, "5.105", "5.105 85/02/16 11:03:32") - ROMX_LOAD("pwr_up__5.105__adb_lo.bin", 0x00000, 0x4000, CRC(429a6a4a) SHA1(5ec5a045ec14a1b546d75e9406f0ad21163298f6), ROM_BIOS(1) | ROM_SKIP(1)) - ROMX_LOAD("pwr_up__5.105__adb_hi.bin", 0x00001, 0x4000, CRC(1ad7a762) SHA1(98472c30f1148c43f43d2131ebc9644d8ebf376a), ROM_BIOS(1) | ROM_SKIP(1)) - - ROM_REGION16_LE(0x8000, "dpu", 0) - ROMX_LOAD("l__sdpu__1.73.bin", 0x00000, 0x4000, CRC(cd1be127) SHA1(9c16ab7e8b195e9ae660288b4b26566581a029e5), ROM_SKIP(1)) - ROMX_LOAD("h__sdpu__1.73.bin", 0x00001, 0x4000, CRC(1adf3130) SHA1(966f839de0b10aff3ffc6af64d94e4b19ece52c7), ROM_SKIP(1)) - - ROM_REGION(0x1000, "dpu_mcu", 0) - ROM_LOAD("2960-01.bin", 0x0, 0x1000, CRC(5974eaec) SHA1(362cdfb7be162636429d614807b9066ca8bbab28)) -ROM_END - -ROM_START(tek4132) - ROM_REGION16_LE(0x10000, "kernel", 0) - ROM_SYSTEM_BIOS(0, "1.7", "5.107 85/02/20 13:51:51") - ROMX_LOAD("160-4018-00__v1.7.u3130", 0x00000, 0x8000, CRC(cdf154ab) SHA1(381d012b0ec85db03d8cb164ef22f92e33d40b57), ROM_BIOS(0) | ROM_SKIP(1)) - ROMX_LOAD("160-4019-00__v1.7.u3140", 0x00001, 0x8000, CRC(5fe870b1) SHA1(369507763e37e947bbbfde080ba3d83bb6f3a7bf), ROM_BIOS(0) | ROM_SKIP(1)) -ROM_END -} // anonymous namespace - -/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ -COMP(1984, tek6130, 0, 0, tek6130, tekigw, tek6100_state, init, "Tektronix", "6130", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW) -COMP(1984, tek4132, 0, 0, tek4132, tekigw, tek4132_state, init, "Tektronix", "4132", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW) diff --git a/src/mame/tektroni/tekxp33x.cpp b/src/mame/tektroni/tekxp33x.cpp deleted file mode 100644 index ed2e4bb74f1..00000000000 --- a/src/mame/tektroni/tekxp33x.cpp +++ /dev/null @@ -1,132 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Justin Kerk -/*************************************************************************** - - Tektronix TekXpress XP33x series X terminals - - Skeleton driver. - -****************************************************************************/ - -/* - - TODO: - - - everything - - Technical info: - https://www.linux-mips.org/wiki/Tektronix_TekXPress_XP338 - https://web.archive.org/web/20061013084616/http://tekxp-linux.hopto.org/pmwiki/pmwiki.php/Hardware/XP33x - http://bio.gsi.de/DOCS/NCD/xp.html - - CPU: IDT 79R3052E (MIPS I R3000 embedded core. Big Endian. With MMU, without FPU.) - Graphic Chipset: Texas Instruments (34020AGBL-40) TI 34010 (TIGA) - Graphic RAMDAC: Brooktree BT458LPJ135 (Supported in XFree86) - RAM: 4MB onboard, upgradeable to 52MB, 3 slots for 5V FPM NoParity SIMMs - ROM: 256Kb, 2 x 27c1024 (64Kx16), with BootMonitor - Peripherals: - 1x Ethernet Port (AUI and UTP) -- AMD AM79C98 Chipset - 2x Serial Ports -- Philips SCC2692 Dual UART chipset - Keyboard and Mouse controller is a generic PC-Style i8742 with Phoenix BIOS. - 1x "ERGO" Port (Combined Monitor, Keyboard, Mouse) - 16K (2K*8) EEPROM is SEEQ NQ2816A-250, AT28C16 compatible. Contains Boot Monitor settings. The content is compressed. - Micron MT56C0816 - ??? Flash - -*/ - - -#include "emu.h" -#include "cpu/mips/mips1.h" -#include "cpu/tms34010/tms34010.h" -#include "emupal.h" -#include "screen.h" - - -#define SCREEN_TAG "screen" - -class tekxp330_state : public driver_device -{ -public: - tekxp330_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) { } - - void tekxp330(machine_config &config); - -private: - virtual void machine_start() override; - - virtual void video_start() override; - uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - void cpu_map(address_map &map); - void tms_map(address_map &map); -}; - -/* Memory Maps */ - -void tekxp330_state::cpu_map(address_map &map) -{ - map(0x00000000, 0x003fffff).ram(); - map(0x1fc00000, 0x1fdfffff).rom().region("maincpu", 0); -} - -void tekxp330_state::tms_map(address_map &map) -{ -} - -/* Input Ports */ - -static INPUT_PORTS_START( tekxp330 ) -INPUT_PORTS_END - -/* Video */ - -void tekxp330_state::video_start() -{ -} - -uint32_t tekxp330_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - return 0; -} - -/* Machine Initialization */ - -void tekxp330_state::machine_start() -{ -} - -/* Machine Driver */ - -void tekxp330_state::tekxp330(machine_config &config) -{ - /* basic machine hardware */ - r3052e_device &maincpu(R3052E(config, "maincpu", XTAL(20'000'000))); /* IDT 79R3052E, clock unknown */ - maincpu.set_endianness(ENDIANNESS_BIG); - maincpu.set_addrmap(AS_PROGRAM, &tekxp330_state::cpu_map); - - tms34010_device &tms(TMS34010(config, "tms", XTAL(40'000'000))); /* clock unknown */ - tms.set_addrmap(AS_PROGRAM, &tekxp330_state::tms_map); - - /* video hardware */ - screen_device &screen(SCREEN(config, SCREEN_TAG, SCREEN_TYPE_RASTER)); - screen.set_refresh_hz(60); - screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */ - screen.set_screen_update(FUNC(tekxp330_state::screen_update)); - screen.set_size(640, 480); - screen.set_visarea(0, 640-1, 0, 480-1); - - PALETTE(config, "palette").set_entries(64); -} - -/* ROMs */ - -ROM_START( tekxp330 ) - ROM_REGION( 0x200000, "maincpu", 0 ) - /* TekXpress XP300 Boot ROM V1.0 Thu Feb 6 14:50:16 PST 1992 */ - ROM_LOAD32_DWORD( "xp300.bin", 0x000000, 0x200000, CRC(9a324588) SHA1(a6e10275f8215f446be91128bab4c643693da653) ) -ROM_END - -/* System Drivers */ - -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1992, tekxp330, 0, 0, tekxp330, tekxp330, tekxp330_state, empty_init, "Tektronix", "TekXpress XP330", MACHINE_IS_SKELETON ) diff --git a/src/mame/tektronix/tek405x.cpp b/src/mame/tektronix/tek405x.cpp new file mode 100644 index 00000000000..b03d1c76233 --- /dev/null +++ b/src/mame/tektronix/tek405x.cpp @@ -0,0 +1,1193 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/*************************************************************************** + + Tektronix 4051/4052A + + Skeleton driver. + + http://www.electronixandmore.com/articles/teksystem.html + +****************************************************************************/ + +/* + + TODO: + + - bank switch + - keyboard + - video (persistent vector display) + - joystick + - magnetic tape storage (3M 300) + - communications backpack + - 4051E01 ROM expander + +*/ + + +#include "emu.h" +#include "tek405x.h" +#include "screen.h" +#include "softlist_dev.h" +#include "speaker.h" + + +//************************************************************************** +// MACROS / CONSTANTS +//************************************************************************** + +enum { + LBS_RBC = 0, // ROM Bank Control + LBS_BSOFL, // Bank Switch Overflow (Select Overflow ROMs) + LBS_BSCOM, // Bank Switch Communication (Select Communication ROMs) + LBS_INVALID, + LBS_BS_L, // Bank Switch Left (Select Left ROM Pack) + LBS_BS_R, // Bank Switch Right (Select Right ROM Pack) + LBS_BSX_L, // Bank Switch Expander (Select Left ROM Expander Unit) + LBS_BSX_R // Bank Switch Expander (Select Right ROM Expander Unit) +}; + + +//************************************************************************** +// INTERRUPTS +//************************************************************************** + +void tek4051_state::update_irq() +{ + int state = m_kb_pia_irqa | m_kb_pia_irqb | m_x_pia_irqa | m_x_pia_irqb | m_gpib_pia_irqa | m_gpib_pia_irqb | m_com_pia_irqa | m_com_pia_irqb | m_acia_irq; + + m_maincpu->set_input_line(INPUT_LINE_IRQ0, state); +} + +void tek4051_state::update_nmi() +{ + int state = m_y_pia_irqa | m_y_pia_irqb | m_tape_pia_irqa | m_tape_pia_irqb; + + m_maincpu->set_input_line(INPUT_LINE_NMI, state); +} + + +//************************************************************************** +// KEYBOARD +//************************************************************************** + +void tek4051_state::scan_keyboard() +{ +} + +TIMER_DEVICE_CALLBACK_MEMBER(tek4051_state::keyboard_tick) +{ + scan_keyboard(); +} + + +//************************************************************************** +// MEMORY BANKING +//************************************************************************** + +void tek4051_state::bankswitch(uint8_t data) +{ + address_space &program = m_maincpu->space(AS_PROGRAM); + + //int d = data & 0x07; + int lbs = (data >> 3) & 0x07; + + switch (lbs) + { + case LBS_RBC: + program.install_rom(0x8800, 0xa7ff, m_rom->base() + 0x800); + break; + + case LBS_BSOFL: + program.install_rom(0x8800, 0xa7ff, m_bsofl_rom->base()); + break; + + case LBS_BSCOM: + program.install_rom(0x8800, 0xa7ff, m_bscom_rom->base()); + break; + + default: + program.unmap_readwrite(0x8800, 0xa7ff); + } +} + +void tek4051_state::lbs_w(uint8_t data) +{ + /* + + bit description + + 0 ROM Expander Slot Address + 1 ROM Expander Slot Address + 2 ROM Expander Slot Address + 3 Bank Switch + 4 Bank Switch + 5 Bank Switch + 6 + 7 + + */ + + logerror("LBS %02x\n", data); + + bankswitch(data); +} + + +//************************************************************************** +// ADDRESS MAPS +//************************************************************************** + +void tek4051_state::tek4051_mem(address_map &map) +{ + map(0x0000, 0x1fff).ram(); + map(0x2000, 0x7fff).ram(); // optional RAM + map(0x8000, 0x877f).rom().region(MC6800_TAG, 0); + map(0x878c, 0x878f).rw(MC6820_Y_TAG, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); + map(0x8794, 0x8797).rw(MC6820_X_TAG, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); + map(0x8798, 0x879b).rw(MC6820_TAPE_TAG, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); + map(0x87a8, 0x87ab).rw(MC6820_KB_TAG, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); + map(0x87b0, 0x87b3).rw(m_gpib_pia, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); + map(0x87c0, 0x87c0).mirror(0x03).w(FUNC(tek4051_state::lbs_w)); +// map(0x87c0, 0x87c3).rw(MC6820_COM_TAG, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); +// map(0x87c4, 0x87c5).mirror(0x02).rw(MC6850_TAG, FUNC(acia6850_device::read), FUNC(acia6850_device::write)); +// map(0x87c8, 0x87cb) XPC2 +// map(0x87cc, 0x87cf) XPC3 +// map(0x87d0, 0x87d3) XPC4 + map(0x8800, 0xa7ff).rom().region(MC6800_TAG, 0x800); + map(0xa800, 0xffff).rom().region(MC6800_TAG, 0x2800); +} + +void tek4052_state::tek4052_mem(address_map &map) +{ +} + + +//************************************************************************** +// INPUT PORTS +//************************************************************************** + +static INPUT_PORTS_START( tek4051 ) + PORT_START("Y0") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) + + PORT_START("Y1") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) + + PORT_START("Y2") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) + + PORT_START("Y3") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) + + PORT_START("Y4") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) + + PORT_START("Y5") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) + + PORT_START("Y6") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) + + PORT_START("Y7") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) + + PORT_START("Y8") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) + + PORT_START("Y9") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) + + PORT_START("Y10") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) + + PORT_START("Y11") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) + + PORT_START("Y12") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) + + PORT_START("Y13") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) + + PORT_START("Y14") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) + + PORT_START("Y15") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) + + PORT_START("SPECIAL") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Left SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Right SHIFT") PORT_CODE(KEYCODE_RSHIFT) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("TTY LOCK") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) +INPUT_PORTS_END + + +//************************************************************************** +// VIDEO +//************************************************************************** + +void tek4051_state::video_start() +{ +} + + +void tek4052_state::video_start() +{ +} + + +//************************************************************************** +// DEVICE CONFIGURATION +//************************************************************************** + +uint8_t tek4051_state::x_pia_pa_r() +{ + /* + + bit description + + PA0 + PA1 + PA2 DRBUSY-0 + PA3 VPULSE-1 + PA4 + PA5 + PA6 + PA7 + + */ + + return 0; +} + +void tek4051_state::x_pia_pa_w(uint8_t data) +{ + /* + + bit description + + PA0 X D/A + PA1 X D/A + PA2 + PA3 + PA4 ERASE-0 + PA5 COPY-0 + PA6 VECTOR-0 + PA7 VEN-1 + + */ +} + +void tek4051_state::x_pia_pb_w(uint8_t data) +{ + /* + + bit description + + PB0 X D/A + PB1 X D/A + PB2 X D/A + PB3 X D/A + PB4 X D/A + PB5 X D/A + PB6 X D/A + PB7 X D/A + + */ +} + +WRITE_LINE_MEMBER( tek4051_state::adot_w ) +{ +} + +WRITE_LINE_MEMBER( tek4051_state::bufclk_w ) +{ +} + +WRITE_LINE_MEMBER( tek4051_state::x_pia_irqa_w ) +{ + m_x_pia_irqa = state; + update_irq(); +} + +WRITE_LINE_MEMBER( tek4051_state::x_pia_irqb_w ) +{ + m_x_pia_irqb = state; + update_irq(); +} + +uint8_t tek4051_state::sa_r() +{ + /* + + bit description + + PA0 SA0 + PA1 SA1 + PA2 SA2 + PA3 SA3 + PA4 SA4 + PA5 SA5 + PA6 SA6 + PA7 SA7 + + */ + + return 0; +} + +void tek4051_state::y_pia_pa_w(uint8_t data) +{ + /* + + bit description + + PA0 Y D/A + PA1 Y D/A + PA2 Y CHAR D/A + PA3 Y CHAR D/A + PA4 Y CHAR D/A + PA5 X CHAR D/A + PA6 X CHAR D/A + PA7 X CHAR D/A + + */ +} + +void tek4051_state::sb_w(uint8_t data) +{ + /* + + bit description + + PB0 SB0 + PB1 SB1 + PB2 SB2 + PB3 SB3 + PB4 SB4 + PB5 SB5 + PB6 SB6 + PB7 SB7 + + */ +} + +WRITE_LINE_MEMBER( tek4051_state::sot_w ) +{ +} + +WRITE_LINE_MEMBER( tek4051_state::y_pia_irqa_w ) +{ + m_y_pia_irqa = state; + update_nmi(); +} + +WRITE_LINE_MEMBER( tek4051_state::y_pia_irqb_w ) +{ + m_y_pia_irqb = state; + update_nmi(); +} + + +uint8_t tek4051_state::kb_pia_pa_r() +{ + /* + + bit description + + PA0 KC0-1 + PA1 KC1-1 + PA2 KC2-1 + PA3 KC3-1 + PA4 KC4-1 + PA5 KC5-1 + PA6 KC6-1 + PA7 TTY-0 + + */ + + uint8_t data = 0; + uint8_t special = m_special->read(); + + // keyboard column + data = m_kc; + + // TTY lock + data |= BIT(special, 3) << 7; + + return data; +} + +uint8_t tek4051_state::kb_pia_pb_r() +{ + /* + + bit description + + PB0 SHIFT-0 + PB1 CTRL-0 + PB2 + PB3 LOAD-0 + PB4 + PB5 + PB6 + PB7 + + */ + + uint8_t data = 0; + uint8_t special = m_special->read(); + + // shift + data |= (BIT(special, 0) & BIT(special, 1)); + + // ctrl + data |= BIT(special, 2) << 1; + + return data; +} + +void tek4051_state::kb_pia_pb_w(uint8_t data) +{ + /* + + bit description + + PB0 + PB1 + PB2 + PB3 + PB4 EOI-1 + PB5 BREAK-1 + PB6 I/O-1 + PB7 BUSY-1/REN-0/SPEAKER + + */ + + // lamps + m_lamps[0] = BIT(~data, 5); + m_lamps[1] = BIT(~data, 6); + m_lamps[2] = BIT(~data, 7); + + // end or identify + m_gpib->host_eoi_w(!BIT(data, 4)); + + // speaker + m_speaker->level_w(!BIT(data, 7)); + + // remote enable + m_gpib->host_ren_w(!BIT(data, 7)); +} + +WRITE_LINE_MEMBER( tek4051_state::kb_halt_w ) +{ +} + +WRITE_LINE_MEMBER( tek4051_state::kb_pia_irqa_w ) +{ + m_kb_pia_irqa = state; + update_irq(); +} + +WRITE_LINE_MEMBER( tek4051_state::kb_pia_irqb_w ) +{ + m_kb_pia_irqb = state; + update_irq(); +} + + +uint8_t tek4051_state::tape_pia_pa_r() +{ + /* + + bit description + + PA0 DELAY OUT-1 + PA1 + PA2 TUTS-1 + PA3 SAFE-1 + PA4 SAFE-1 + PA5 JOYSTICK + PA6 FILFND-1 + PA7 JOYSTICK + + */ + + return 0; +} + +void tek4051_state::tape_pia_pa_w(uint8_t data) +{ + /* + + bit description + + PA0 + PA1 LDCLK-1 + PA2 + PA3 + PA4 + PA5 XERR-1 + PA6 + PA7 YERR-1 + + */ +} + +void tek4051_state::tape_pia_pb_w(uint8_t data) +{ + /* + + bit description + + PB0 WR-0 + PB1 FAST-1 + PB2 REV-1 + PB3 DRTAPE-0 + PB4 GICG-1 + PB5 FICG-1 + PB6 WENABLE-1 + PB7 FSENABLE-0 + + */ +} + +WRITE_LINE_MEMBER( tek4051_state::tape_pia_irqa_w ) +{ + m_tape_pia_irqa = state; + update_nmi(); +} + +WRITE_LINE_MEMBER( tek4051_state::tape_pia_irqb_w ) +{ + m_tape_pia_irqb = state; + update_nmi(); +} + +void tek4051_state::dio_w(uint8_t data) +{ + /* + + bit description + + PA0 DIO1-1 + PA1 DIO2-1 + PA2 DIO3-1 + PA3 DIO4-1 + PA4 DIO5-1 + PA5 DIO6-1 + PA6 DIO7-1 + PA7 DIO8-1 + + */ + + if (m_talk) + { + m_gpib->host_dio_w(data); + } +} + +uint8_t tek4051_state::gpib_pia_pb_r() +{ + /* + + bit description + + PB0 + PB1 + PB2 + PB3 + PB4 NRFD + PB5 SRQ-1 + PB6 DAV-1 + PB7 NDAC + + */ + + uint8_t data = 0; + + // service request + data |= m_gpib->srq_r() << 5; + + // data valid + data |= m_gpib->dav_r() << 6; + + if (!m_talk) + { + // not ready for data + data |= m_gpib->nrfd_r() << 4; + + // not data acknowledged + data |= m_gpib->ndac_r() << 7; + } + + return data; +} + +void tek4051_state::gpib_pia_pb_w(uint8_t data) +{ + /* + + bit description + + PB0 EOI-1 + PB1 IFC-1 + PB2 + PB3 ATN-0 + PB4 NRFD + PB5 + PB6 + PB7 NDAC + + */ + + // end or identify + m_gpib->host_eoi_w(!BIT(data, 0)); + + // interface clear + m_gpib->host_ifc_w(!BIT(data, 1)); + + // attention + m_gpib->host_atn_w(BIT(data, 3)); + + if (m_talk) + { + // not ready for data + m_gpib->host_nrfd_w(!BIT(data, 4)); + + // not data acknowledged + m_gpib->host_ndac_w(!BIT(data, 7)); + } +} + +WRITE_LINE_MEMBER( tek4051_state::talk_w ) +{ + m_talk = state; + + if (!m_talk) + { + m_gpib->host_dio_w(0xff); + m_gpib->host_nrfd_w(1); + m_gpib->host_ndac_w(1); + } +} + +WRITE_LINE_MEMBER( tek4051_state::gpib_pia_irqa_w ) +{ + m_gpib_pia_irqa = state; + update_irq(); +} + +WRITE_LINE_MEMBER( tek4051_state::gpib_pia_irqb_w ) +{ + m_gpib_pia_irqb = state; + update_irq(); +} + +void tek4051_state::com_pia_pa_w(uint8_t data) +{ + /* + + bit description + + PA0 + PA1 + PA2 + PA3 Bank Switch Register + PA4 Bank Switch Register + PA5 Bank Switch Register + PA6 + PA7 + + */ + + bankswitch(data); +} + +uint8_t tek4051_state::com_pia_pb_r() +{ + /* + + bit description + + PB0 SRX + PB1 DTR + PB2 RTS + PB3 + PB4 + PB5 + PB6 + PB7 + + */ + + uint8_t data = 0; + + // data terminal ready + + // request to send + + return data; +} + +void tek4051_state::com_pia_pb_w(uint8_t data) +{ + /* + + bit description + + PB0 + PB1 + PB2 + PB3 CTS + PB4 STXA-C + PB5 Baud Rate Select + PB6 Baud Rate Select + PB7 Baud Rate Select + + */ + + // clear to send + + // baud rate select + int osc = BIT(data, 7) ? 28160 : 38400; + int div = 1; + + switch ((data >> 5) & 0x03) + { + case 2: div = 4; break; + case 3: div = 2; break; + } + + m_acia_clock->set_unscaled_clock(osc); + m_acia_clock->set_clock_scale((double) 1 / div); +} + +WRITE_LINE_MEMBER( tek4051_state::com_pia_irqa_w ) +{ + m_com_pia_irqa = state; + update_irq(); +} + +WRITE_LINE_MEMBER( tek4051_state::com_pia_irqb_w ) +{ + m_com_pia_irqb = state; + update_irq(); +} + +WRITE_LINE_MEMBER( tek4051_state::acia_irq_w ) +{ + m_acia_irq = state; + update_irq(); +} + +WRITE_LINE_MEMBER( tek4051_state::write_acia_clock ) +{ + m_acia->write_txc(state); + m_acia->write_rxc(state); +} + + +//************************************************************************** +// MACHINE INITIALIZATION +//************************************************************************** + +void tek4051_state::machine_start() +{ + m_lamps.resolve(); + + address_space &program = m_maincpu->space(AS_PROGRAM); + + // configure RAM + switch (m_ram->size()) + { + case 8*1024: + program.unmap_readwrite(0x2000, 0x7fff); + break; + + case 16*1024: + program.unmap_readwrite(0x4000, 0x7fff); + break; + + case 24*1024: + program.unmap_readwrite(0x6000, 0x7fff); + break; + } + + m_x_pia_irqa = 0; + m_x_pia_irqb = 0; + m_y_pia_irqa = 0; + m_y_pia_irqb = 0; + m_tape_pia_irqa = 0; + m_tape_pia_irqb = 0; + m_kb_pia_irqa = 0; + m_kb_pia_irqb = 0; + m_gpib_pia_irqa = 0; + m_gpib_pia_irqb = 0; + m_com_pia_irqa = 0; + m_com_pia_irqb = 0; + m_acia_irq = 0; + + // register for state saving +} + +void tek4052_state::machine_start() +{ +} + + +//************************************************************************** +// MACHINE CONFIGURATION +//************************************************************************** + +void tek4051_state::tek4051(machine_config &config) +{ + // basic machine hardware + M6800(config, m_maincpu, XTAL(12'500'000)/15); + m_maincpu->set_addrmap(AS_PROGRAM, &tek4051_state::tek4051_mem); + + // video hardware + VECTOR(config, "vector", 0); + screen_device &screen(SCREEN(config, SCREEN_TAG, SCREEN_TYPE_VECTOR)); + screen.set_color(rgb_t::green()); + screen.set_refresh_hz(50); + screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); // not accurate + screen.set_size(1024, 780); + screen.set_visarea(0, 1024-1, 0, 780-1); + screen.set_screen_update("vector", FUNC(vector_device::screen_update)); + + PALETTE(config, "palette", palette_device::MONOCHROME); + + // sound hardware + SPEAKER(config, "mono").front_center(); + SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25); + + // devices + TIMER(config, "keyboard").configure_periodic(FUNC(tek4051_state::keyboard_tick), attotime::from_hz(XTAL(12'500'000)/15/4)); + + pia6821_device &piax(PIA6821(config, MC6820_X_TAG, 0)); + piax.readpa_handler().set(FUNC(tek4051_state::x_pia_pa_r)); + // CB1 viewcause + piax.writepa_handler().set(FUNC(tek4051_state::x_pia_pa_w)); + piax.writepb_handler().set(FUNC(tek4051_state::x_pia_pb_w)); + piax.ca2_handler().set(FUNC(tek4051_state::adot_w)); + piax.cb2_handler().set(FUNC(tek4051_state::bufclk_w)); + piax.irqa_handler().set(FUNC(tek4051_state::x_pia_irqa_w)); + piax.irqb_handler().set(FUNC(tek4051_state::x_pia_irqb_w)); + + pia6821_device &piay(PIA6821(config, MC6820_Y_TAG, 0)); + piay.readpa_handler().set(FUNC(tek4051_state::sa_r)); + // CA1 rdbyte + // CB1 mdata + // CB2 fmark + piay.writepa_handler().set(FUNC(tek4051_state::y_pia_pa_w)); + piay.writepb_handler().set(FUNC(tek4051_state::sb_w)); + piay.ca2_handler().set(FUNC(tek4051_state::sot_w)); + piay.irqa_handler().set(FUNC(tek4051_state::y_pia_irqa_w)); + piay.irqb_handler().set(FUNC(tek4051_state::y_pia_irqb_w)); + + pia6821_device &piakbd(PIA6821(config, MC6820_KB_TAG, 0)); + piakbd.readpa_handler().set(FUNC(tek4051_state::kb_pia_pa_r)); + piakbd.readpb_handler().set(FUNC(tek4051_state::kb_pia_pb_r)); + // CA1 key + piakbd.writepb_handler().set(FUNC(tek4051_state::kb_pia_pb_w)); + piakbd.ca2_handler().set(FUNC(tek4051_state::kb_halt_w)); + piakbd.irqa_handler().set(FUNC(tek4051_state::kb_pia_irqa_w)); + piakbd.irqb_handler().set(FUNC(tek4051_state::kb_pia_irqb_w)); + + pia6821_device &piatape(PIA6821(config, MC6820_TAPE_TAG, 0)); + piatape.readpa_handler().set(FUNC(tek4051_state::tape_pia_pa_r)); + // CA1 rmark + // CB1 lohole + // CA2 filfnd + // CB2 uphole + piatape.writepa_handler().set(FUNC(tek4051_state::tape_pia_pa_w)); + piatape.writepb_handler().set(FUNC(tek4051_state::tape_pia_pb_w)); + piatape.irqa_handler().set(FUNC(tek4051_state::tape_pia_irqa_w)); + piatape.irqb_handler().set(FUNC(tek4051_state::tape_pia_irqb_w)); + + PIA6821(config, m_gpib_pia, 0); + m_gpib_pia->readpa_handler().set(IEEE488_TAG, FUNC(ieee488_device::dio_r)); + m_gpib_pia->readpb_handler().set(FUNC(tek4051_state::gpib_pia_pb_r)); + m_gpib_pia->writepa_handler().set(FUNC(tek4051_state::dio_w)); + m_gpib_pia->writepb_handler().set(FUNC(tek4051_state::gpib_pia_pb_w)); + m_gpib_pia->cb2_handler().set(FUNC(tek4051_state::talk_w)); + m_gpib_pia->irqa_handler().set(FUNC(tek4051_state::gpib_pia_irqa_w)); + m_gpib_pia->irqb_handler().set(FUNC(tek4051_state::gpib_pia_irqb_w)); + + PIA6821(config, m_com_pia, 0); + m_com_pia->readpb_handler().set(FUNC(tek4051_state::com_pia_pb_r)); + //CA1 - SRX (RS-232 pin 12) + m_com_pia->writepa_handler().set(FUNC(tek4051_state::com_pia_pa_w)); + m_com_pia->writepb_handler().set(FUNC(tek4051_state::com_pia_pb_w)); + m_com_pia->irqa_handler().set(FUNC(tek4051_state::com_pia_irqa_w)); + m_com_pia->irqb_handler().set(FUNC(tek4051_state::com_pia_irqb_w)); + + ACIA6850(config, m_acia, 0); + m_acia->irq_handler().set(FUNC(tek4051_state::acia_irq_w)); + + CLOCK(config, m_acia_clock, 38400); + m_acia_clock->signal_handler().set(FUNC(tek4051_state::write_acia_clock)); + + IEEE488(config, m_gpib); + m_gpib->eoi_callback().set(MC6820_GPIB_TAG, FUNC(pia6821_device::ca1_w)); + m_gpib->srq_callback().set(MC6820_GPIB_TAG, FUNC(pia6821_device::cb1_w)); + + // internal ram + RAM(config, RAM_TAG).set_default_size("8K").set_extra_options("16K,24K,32K"); + + // cartridge + GENERIC_CARTSLOT(config, "cartslot1", generic_plain_slot, "tek4050_cart"); + GENERIC_CARTSLOT(config, "cartslot2", generic_plain_slot, "tek4050_cart"); +} + +void tek4052_state::tek4052(machine_config &config) +{ + // basic machine hardware + m6800_cpu_device &cpu(M6800(config, AM2901A_TAG, 1000000)); // should be 4x AM2901A + AM2911 + cpu.set_addrmap(AS_PROGRAM, &tek4052_state::tek4052_mem); + + // video hardware + VECTOR(config, "vector", 0); + screen_device &screen(SCREEN(config, SCREEN_TAG, SCREEN_TYPE_VECTOR)); + screen.set_color(rgb_t::green()); + screen.set_refresh_hz(50); + screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); // not accurate + screen.set_size(1024, 780); + screen.set_visarea(0, 1024-1, 0, 780-1); + screen.set_screen_update("vector", FUNC(vector_device::screen_update)); + + PALETTE(config, "palette", palette_device::MONOCHROME); + + // sound hardware + SPEAKER(config, "mono").front_center(); + SPEAKER_SOUND(config, "speaker").add_route(ALL_OUTPUTS, "mono", 0.25); + + // internal ram + RAM(config, RAM_TAG).set_default_size("32K").set_extra_options("64K"); + + // cartridge + GENERIC_CARTSLOT(config, "cartslot1", generic_plain_slot, "tek4050_cart"); + GENERIC_CARTSLOT(config, "cartslot2", generic_plain_slot, "tek4050_cart"); + + // software lists + SOFTWARE_LIST(config, "cart_list").set_original("tek4052_cart"); +} + +/* +void tek4054_state::tek4054(machine_config &config) +{ + // screen size: 4096, 3125 +} +*/ + + + +//************************************************************************** +// ROMS +//************************************************************************** + +ROM_START( tek4051 ) + ROM_REGION( 0x8000, MC6800_TAG, 0 ) + ROM_LOAD( "156-0659-xx.u585", 0x0000, 0x0800, CRC(0017ba54) SHA1(533bfacb2e698c1df88a00acce6df6a8c536239d) ) // -01 or -02 ? + ROM_LOAD( "156-0660-01.u581", 0x0800, 0x0800, CRC(c4e302e8) SHA1(a0438cbc70ddc1bab000e30c0f835f0948aae969) ) + ROM_LOAD( "156-0661-01.u487", 0x1000, 0x0800, CRC(edb097c8) SHA1(a07b777b6b20de496089730db8097b65b9a8ef31) ) + ROM_LOAD( "156-0662-01.u485", 0x1800, 0x0800, CRC(0a3af548) SHA1(01bcffa7d55b2585348ea96852b4319c6454d19a) ) + ROM_LOAD( "156-0663-01.u481", 0x2000, 0x0800, CRC(f220d24c) SHA1(fb5dc8a617f4b4d5c094c0cbabb9af158c19c2c2) ) + ROM_LOAD( "156-0664-xx.u385", 0x2800, 0x0800, CRC(aa1ae67d) SHA1(8816654c1b0ad0230bf5027f68c2ec1d315ad188) ) // -01 or -02 ? + ROM_LOAD( "156-0665-xx.u381", 0x3000, 0x0800, CRC(90497138) SHA1(2d6bbe169a434581a49fffcab0d2ca18107b67da) ) // -01 or -02 ? + ROM_LOAD( "156-0666-01.u285", 0x3800, 0x0800, CRC(c35ce405) SHA1(10cae122d000fe2886228a178a1a4e4d3ec2c3f5) ) + ROM_LOAD( "156-0667-xx.u595", 0x4000, 0x0800, CRC(e1723a06) SHA1(dde3e64eb6acc77d8e7234235a99ec338cc74717) ) // -01 or -02 ? + ROM_LOAD( "156-0668-xx.u591", 0x4800, 0x0800, CRC(d8b80d7a) SHA1(6c1f00fa2f9ff6ebd84268c2100637ddbdb3bae6) ) // -01 or -02 ? + ROM_LOAD( "156-0669-01.u497", 0x5000, 0x0800, CRC(f760ed39) SHA1(2b30d20d880002ce3950ee7abe40f4e1539208cc) ) + ROM_LOAD( "156-0670-01.u495", 0x5800, 0x0800, CRC(d40a303d) SHA1(111b399f6178e2fe50b1368536f290d4df9883fc) ) + ROM_LOAD( "156-0671-xx.u491", 0x6000, 0x0800, CRC(32060b64) SHA1(af254dc068686fcd7584128258724fd5415ea458) ) // -01 or -02 ? + ROM_LOAD( "156-0672-xx.u395", 0x6800, 0x0800, CRC(93ad68d1) SHA1(8242058bfc89d11cd9ae82d967410714875eface) ) // -01 or -02 ? + ROM_LOAD( "156-0673-xx.u391", 0x7000, 0x0800, CRC(ee1f5d4c) SHA1(a6fb8347a0dfa94268f091fb7ca091c8bfabeabd) ) // -01 or -02 or -03 ? + ROM_LOAD( "156-0674-xx.u295", 0x7800, 0x0800, CRC(50582341) SHA1(1a028176e5d5ca83012e2f75e9daad88cd7d8fc3) ) // -01 or -02 ? + + ROM_REGION( 0x2000, "020_0147_00", 0 ) // Firmware Backpack (020-0147-00) + ROM_LOAD( "156-0747-xx.u101", 0x0000, 0x0800, CRC(9e1facc1) SHA1(7e7a118c3e8c49630f630ee02c3de843dd95d7e1) ) // -00 or -01 ? + ROM_LOAD( "156-0748-xx.u201", 0x0800, 0x0800, CRC(be42bfbf) SHA1(23575b411bd9dcb7d7116628820096e3064ff93b) ) // -00 or -01 ? + + ROM_REGION( 0x2000, "021_0188_00", 0 ) // Communications Backpack (021-0188-00) + ROM_LOAD( "156-0712-00.u101", 0x0000, 0x0800, NO_DUMP ) + ROM_LOAD( "156-0712-01.u101", 0x0000, 0x0800, NO_DUMP ) + ROM_LOAD( "156-0713-00.u111", 0x0800, 0x0800, NO_DUMP ) + ROM_LOAD( "156-0713-01.u111", 0x0800, 0x0800, NO_DUMP ) + ROM_LOAD( "156-0714-00.u121", 0x1000, 0x0800, NO_DUMP ) + ROM_LOAD( "156-0714-01.u121", 0x1000, 0x0800, NO_DUMP ) + ROM_LOAD( "156-0715-01.u131", 0x1800, 0x0800, NO_DUMP ) +/* + ROM_REGION( 0x2000, "4051r01", 0 ) // 4051R01 Matrix Functions + ROM_LOAD( "4051r01", 0x0000, 0x1000, NO_DUMP ) + + ROM_REGION( 0x2000, "4051r05", 0 ) // 4051R05 Binary Program Loader + ROM_LOAD( "156-0856-00.u1", 0x0000, 0x0800, NO_DUMP ) + ROM_LOAD( "156-0857-00.u11", 0x0800, 0x0800, NO_DUMP ) + + ROM_REGION( 0x2000, "4051r06", 0 ) // 4051R06 Editor + ROM_LOAD( "4051r06", 0x0000, 0x1000, NO_DUMP ) +*/ +ROM_END + +ROM_START( tek4052a ) + ROM_REGION( 0x3800, AM2901A_TAG, 0 ) // ALU 670-7705-00 microcode + ROM_LOAD( "160-1689-00.u340", 0x0000, 0x0800, CRC(97ff62d4) SHA1(e25b495fd1b3f8a5bfef5c8f20efacde8366e89c) ) + ROM_LOAD( "160-1688-00.u335", 0x0800, 0x0800, CRC(19033422) SHA1(0f6ea45be5123701940331c4278bcdc5db4f4147) ) + ROM_LOAD( "160-1687-00.u330", 0x1000, 0x0800, CRC(3b2e37dd) SHA1(294b626d0022fbf9bec50680b6b932f21a3cb049) ) + ROM_LOAD( "160-1686-00.u320", 0x1800, 0x0800, CRC(7916cd64) SHA1(d6b3ed783e488667ca203ec605aa27d78261c61b) ) + ROM_LOAD( "160-1695-00.u315", 0x2000, 0x0800, CRC(cdac76a7) SHA1(2a47f34ae63fb7fe96e7c6fc92ca4f629b0e31ec) ) + ROM_LOAD( "160-1694-00.u305", 0x2800, 0x0800, CRC(c33ae212) SHA1(25ed4cc3600391fbc93bb46c92d3f64ca2aca58e) ) + ROM_LOAD( "160-1693-00.u300", 0x3000, 0x0800, CRC(651b7af2) SHA1(7255c682cf74f2e77661d77c8406b36a567eea46) ) + + ROM_REGION( 0x14000, "672_0799_08", 0 ) // Memory Access Sequencer 672-0799-08 + ROM_LOAD16_BYTE( "160-1698-00.u810", 0x00000, 0x2000, CRC(fd0b8bc3) SHA1(ea9caa151295024267a467ba636ad41aa0c517d3) ) + ROM_LOAD16_BYTE( "160-1682-00.u893", 0x00001, 0x2000, CRC(d54104ef) SHA1(b796c320c8f96f6e4b845718bfb62ccb5903f2db) ) + ROM_LOAD16_BYTE( "160-1699-00.u820", 0x04000, 0x2000, CRC(59cc6c2e) SHA1(b6d85cdfaaef360af2a4fc44eae55e512bb08b21) ) + ROM_LOAD16_BYTE( "160-1684-00.u870", 0x04001, 0x2000, CRC(b24cdbaf) SHA1(476032624110bc5c7a7f30d10458e8baffb2f2ff) ) + ROM_LOAD16_BYTE( "160-1700-00.u825", 0x08000, 0x2000, CRC(59f4a4e2) SHA1(81b5f74ec14bb13735382abc123bb9b09dfb7a63) ) + ROM_LOAD16_BYTE( "160-1683-00.u880", 0x08001, 0x2000, CRC(f6bb15d1) SHA1(eca06211876c12236cfeae0417131e8f04728d51) ) + ROM_LOAD16_BYTE( "160-1701-00.u835", 0x0c000, 0x2000, CRC(195988b9) SHA1(995a77963e869f1a461addf58db9ecbf2b9222ba) ) + ROM_LOAD16_BYTE( "160-1691-00.u885", 0x0c001, 0x2000, CRC(0670bf9e) SHA1(a8c39bd7f3f61436296c6bc5f734354371ae8123) ) + ROM_LOAD16_BYTE( "160-1702-00.u845", 0x10000, 0x2000, CRC(013344b1) SHA1(4a79654427e15d0fcedd9519914f6448938ecffd) ) + ROM_LOAD16_BYTE( "160-1685-00.u863", 0x10001, 0x2000, CRC(53ddc8f9) SHA1(431d6f329dedebb54232c623a924d5ecddc5e44e) ) + + ROM_REGION( 0x2000, "020_0147_00", 0 ) // Firmware Backpack (020-0147-00) + ROM_LOAD( "156-0747-xx.u101", 0x0000, 0x0800, CRC(9e1facc1) SHA1(7e7a118c3e8c49630f630ee02c3de843dd95d7e1) ) // -00 or -01 ? + ROM_LOAD( "156-0748-xx.u201", 0x0800, 0x0800, CRC(be42bfbf) SHA1(23575b411bd9dcb7d7116628820096e3064ff93b) ) // -00 or -01 ? + + ROM_REGION( 0x2000, "021_0188_00", 0 ) // Communications Backpack (021-0188-00) + ROM_LOAD( "156-0712-00.u101", 0x0000, 0x0800, NO_DUMP ) + ROM_LOAD( "156-0712-01.u101", 0x0000, 0x0800, NO_DUMP ) + ROM_LOAD( "156-0713-00.u111", 0x0800, 0x0800, NO_DUMP ) + ROM_LOAD( "156-0713-01.u111", 0x0800, 0x0800, NO_DUMP ) + ROM_LOAD( "156-0714-00.u121", 0x1000, 0x0800, NO_DUMP ) + ROM_LOAD( "156-0714-01.u121", 0x1000, 0x0800, NO_DUMP ) + ROM_LOAD( "156-0715-01.u131", 0x1800, 0x0800, NO_DUMP ) +ROM_END + + + +//************************************************************************** +// SYSTEM DRIVERS +//************************************************************************** + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1975, tek4051, 0, 0, tek4051, tek4051, tek4051_state, empty_init, "Tektronix", "Tektronix 4051", MACHINE_NOT_WORKING ) +COMP( 1978, tek4052a, tek4051, 0, tek4052, tek4051, tek4052_state, empty_init, "Tektronix", "Tektronix 4052A", MACHINE_NOT_WORKING ) +//COMP( 1979, tek4054, tek4051, 0, tek4054, tek4054, tek4052_state, empty_init, "Tektronix", "Tektronix 4054", MACHINE_NOT_WORKING ) diff --git a/src/mame/tektronix/tek405x.h b/src/mame/tektronix/tek405x.h new file mode 100644 index 00000000000..93eed3bc563 --- /dev/null +++ b/src/mame/tektronix/tek405x.h @@ -0,0 +1,176 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +#ifndef MAME_INCLUDES_TEK405X_H +#define MAME_INCLUDES_TEK405X_H + +#pragma once + +#include "bus/generic/carts.h" +#include "bus/generic/slot.h" +#include "bus/ieee488/ieee488.h" + +#include "cpu/m6800/m6800.h" + +#include "machine/6821pia.h" +#include "machine/6850acia.h" +#include "machine/clock.h" +#include "machine/ram.h" +#include "machine/timer.h" + +#include "sound/spkrdev.h" + +#include "video/vector.h" + +#include "emupal.h" + + +#define MC6800_TAG "u61" +#define MC6820_Y_TAG "u561" +#define MC6820_X_TAG "u565" +#define MC6820_TAPE_TAG "u361" +#define MC6820_KB_TAG "u461" +#define MC6820_GPIB_TAG "u265" +#define MC6820_COM_TAG "u5" +#define MC6850_TAG "u25" +#define RS232_TAG "rs232" +#define SCREEN_TAG "screen" + +#define AM2901A_TAG "am2901a" + +class tek4051_state : public driver_device +{ +public: + tek4051_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, MC6800_TAG), + m_gpib_pia(*this, MC6820_GPIB_TAG), + m_com_pia(*this, MC6820_COM_TAG), + m_acia(*this, MC6850_TAG), + m_acia_clock(*this, "acia_clock"), + m_gpib(*this, IEEE488_TAG), + m_speaker(*this, "speaker"), + m_ram(*this, RAM_TAG), + m_rom(*this, MC6800_TAG), + m_bsofl_rom(*this, "020_0147_00"), + m_bscom_rom(*this, "021_0188_00"), + m_special(*this, "SPECIAL"), + m_lamps(*this, "lamp%u", 1U) + { } + + void tek4051(machine_config &config); + +private: + void bankswitch(uint8_t data); + void update_irq(); + void update_nmi(); + void scan_keyboard(); + + void lbs_w(uint8_t data); + + uint8_t x_pia_pa_r(); + void x_pia_pa_w(uint8_t data); + void x_pia_pb_w(uint8_t data); + DECLARE_WRITE_LINE_MEMBER( adot_w ); + DECLARE_WRITE_LINE_MEMBER( bufclk_w ); + DECLARE_WRITE_LINE_MEMBER( x_pia_irqa_w ); + DECLARE_WRITE_LINE_MEMBER( x_pia_irqb_w ); + + uint8_t sa_r(); + void y_pia_pa_w(uint8_t data); + void sb_w(uint8_t data); + DECLARE_WRITE_LINE_MEMBER( sot_w ); + DECLARE_WRITE_LINE_MEMBER( y_pia_irqa_w ); + DECLARE_WRITE_LINE_MEMBER( y_pia_irqb_w ); + + uint8_t kb_pia_pa_r(); + uint8_t kb_pia_pb_r(); + void kb_pia_pb_w(uint8_t data); + DECLARE_WRITE_LINE_MEMBER( kb_halt_w ); + DECLARE_WRITE_LINE_MEMBER( kb_pia_irqa_w ); + DECLARE_WRITE_LINE_MEMBER( kb_pia_irqb_w ); + + uint8_t tape_pia_pa_r(); + void tape_pia_pa_w(uint8_t data); + void tape_pia_pb_w(uint8_t data); + DECLARE_WRITE_LINE_MEMBER( tape_pia_irqa_w ); + DECLARE_WRITE_LINE_MEMBER( tape_pia_irqb_w ); + + void dio_w(uint8_t data); + uint8_t gpib_pia_pb_r(); + void gpib_pia_pb_w(uint8_t data); + DECLARE_WRITE_LINE_MEMBER( talk_w ); + DECLARE_WRITE_LINE_MEMBER( gpib_pia_irqa_w ); + DECLARE_WRITE_LINE_MEMBER( gpib_pia_irqb_w ); + + void com_pia_pa_w(uint8_t data); + uint8_t com_pia_pb_r(); + void com_pia_pb_w(uint8_t data); + DECLARE_WRITE_LINE_MEMBER( com_pia_irqa_w ); + DECLARE_WRITE_LINE_MEMBER( com_pia_irqb_w ); + DECLARE_WRITE_LINE_MEMBER( acia_irq_w ); + DECLARE_WRITE_LINE_MEMBER( write_acia_clock ); + + TIMER_DEVICE_CALLBACK_MEMBER(keyboard_tick); + void tek4051_mem(address_map &map); + + virtual void machine_start() override; + virtual void video_start() override; + + required_device m_maincpu; + required_device m_gpib_pia; + required_device m_com_pia; + required_device m_acia; + required_device m_acia_clock; + required_device m_gpib; + required_device m_speaker; + required_device m_ram; + required_memory_region m_rom; + required_memory_region m_bsofl_rom; + required_memory_region m_bscom_rom; + required_ioport m_special; + output_finder<3> m_lamps; + + // interrupts + int m_x_pia_irqa = 0; + int m_x_pia_irqb = 0; + int m_y_pia_irqa = 0; + int m_y_pia_irqb = 0; + int m_tape_pia_irqa = 0; + int m_tape_pia_irqb = 0; + int m_kb_pia_irqa = 0; + int m_kb_pia_irqb = 0; + int m_gpib_pia_irqa = 0; + int m_gpib_pia_irqb = 0; + int m_com_pia_irqa = 0; + int m_com_pia_irqb = 0; + int m_acia_irq = 0; + + // keyboard + int m_kc = 0; + + // GPIB + int m_talk = 0; +}; + +class tek4052_state : public driver_device +{ +public: + tek4052_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, AM2901A_TAG), + m_ram(*this, RAM_TAG) + { } + + void tek4052(machine_config &config); + +private: + void tek4052_mem(address_map &map); + + virtual void machine_start() override; + virtual void video_start() override; + + required_device m_maincpu; + required_device m_ram; +}; + +#endif // MAME_INCLUDES_TEK405X_H diff --git a/src/mame/tektronix/tek410x.cpp b/src/mame/tektronix/tek410x.cpp new file mode 100644 index 00000000000..8329a9729b8 --- /dev/null +++ b/src/mame/tektronix/tek410x.cpp @@ -0,0 +1,378 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder, AJR +/*************************************************************************** + + Tektronix 4107A/4109A + + Skeleton driver. + +****************************************************************************/ + +#include "emu.h" +#include "cpu/i86/i186.h" +#include "machine/i8255.h" +#include "machine/mc68681.h" +#include "tek410x_kbd.h" +#include "video/crt9007.h" +#include "emupal.h" +#include "screen.h" + + +class tek4107a_state : public driver_device +{ +public: + tek4107a_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_duart(*this, "duart%u", 0U) + , m_keyboard(*this, "keyboard") + , m_vpac(*this, "vpac") + , m_ppi_pc(0) + , m_kb_rdata(true) + , m_kb_tdata(true) + , m_kb_rclamp(false) + , m_graphics_control(0) + , m_alpha_control(0) + , m_x_position(0) + , m_y_position(0) + , m_x_cursor(0) + , m_y_cursor(0) + { } + + void tek4109a(machine_config &config); + void tek4107a(machine_config &config); + +protected: + virtual void machine_start() override; + virtual void video_start() override; + +private: + u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + + u8 vpac_r(offs_t offset); + + u16 nmi_enable_r(); + u16 nmi_disable_r(); + u16 system_reset_r(); + + void ppi_pc_w(u8 data); + DECLARE_WRITE_LINE_MEMBER(kb_rdata_w); + DECLARE_WRITE_LINE_MEMBER(kb_tdata_w); + DECLARE_WRITE_LINE_MEMBER(kb_rclamp_w); + + void xpos_w(u16 data); + void ypos_w(u16 data); + void xcur_w(u16 data); + void ycur_w(u16 data); + void tbwin_w(u16 data); + u16 gcntl_r(); + void gcntl_w(u16 data); + u16 acntl_r(); + void acntl_w(u16 data); + u16 test_r(); + u8 font_r(); + + void tek4107a_io(address_map &map); + void tek4107a_mem(address_map &map); + + required_device_array m_duart; + required_device m_keyboard; + required_device m_vpac; + + u8 m_ppi_pc; + bool m_kb_rdata; + bool m_kb_tdata; + bool m_kb_rclamp; + + u16 m_graphics_control; + u16 m_alpha_control; + u16 m_x_position; + u16 m_y_position; + u16 m_x_cursor; + u16 m_y_cursor; +}; + +u8 tek4107a_state::vpac_r(offs_t offset) +{ + return m_vpac->read(offset + 0x20); +} + +u16 tek4107a_state::nmi_enable_r() +{ + // TODO + return 0; +} + +u16 tek4107a_state::nmi_disable_r() +{ + // TODO + return 0; +} + +u16 tek4107a_state::system_reset_r() +{ + // TODO + return 0; +} + +void tek4107a_state::ppi_pc_w(u8 data) +{ + if (!m_kb_rclamp && BIT(m_ppi_pc, 2) != BIT(data, 2)) + m_keyboard->kdo_w(!BIT(data, 2) || m_kb_tdata); + + m_ppi_pc = data; +} + +WRITE_LINE_MEMBER(tek4107a_state::kb_rdata_w) +{ + m_kb_rdata = state; + if (!m_kb_rclamp) + m_duart[0]->rx_a_w(state); +} + +WRITE_LINE_MEMBER(tek4107a_state::kb_rclamp_w) +{ + if (m_kb_rclamp != !state) + { + m_kb_rclamp = !state; + + // Clamp RXDA to 1 and KBRDATA to 0 when DUART asserts RxRDYA + if (m_kb_tdata || !BIT(m_ppi_pc, 2)) + m_keyboard->kdo_w(state); + m_duart[0]->rx_a_w(state ? m_kb_rdata : 1); + } +} + +WRITE_LINE_MEMBER(tek4107a_state::kb_tdata_w) +{ + if (m_kb_tdata != state) + { + m_kb_tdata = state; + + m_duart[0]->ip4_w(!state); + if (BIT(m_ppi_pc, 2) && m_kb_rdata && !m_kb_rclamp) + m_keyboard->kdo_w(state); + } +} + +void tek4107a_state::xpos_w(u16 data) +{ + m_x_position = data & 0x03ff; +} + +void tek4107a_state::ypos_w(u16 data) +{ + m_y_position = data & 0x01ff; +} + +void tek4107a_state::xcur_w(u16 data) +{ + m_x_cursor = data & 0x03ff; +} + +void tek4107a_state::ycur_w(u16 data) +{ + m_y_cursor = data & 0x01ff; +} + +void tek4107a_state::tbwin_w(u16 data) +{ + // TODO +} + +u16 tek4107a_state::gcntl_r() +{ + return m_graphics_control; +} + +void tek4107a_state::gcntl_w(u16 data) +{ + m_graphics_control = data; +} + +u16 tek4107a_state::acntl_r() +{ + return m_alpha_control; +} + +void tek4107a_state::acntl_w(u16 data) +{ + m_alpha_control = data; +} + +u16 tek4107a_state::test_r() +{ + // TODO + return 0; +} + +u8 tek4107a_state::font_r() +{ + // TODO + return 0; +} + + +/* Memory Maps */ + +void tek4107a_state::tek4107a_mem(address_map &map) +{ + map(0x00000, 0x3ffff).ram(); + map(0x40000, 0x7ffff).ram().share("gfxram"); + map(0x80000, 0xbffff).rom().region("firmware", 0); + map(0xf0000, 0xfffff).rom().region("firmware", 0x30000); +} + +void tek4107a_state::tek4107a_io(address_map &map) +{ + map(0x0000, 0x001f).rw(m_duart[0], FUNC(scn2681_device::read), FUNC(scn2681_device::write)).umask16(0x00ff); + map(0x0000, 0x001f).rw(m_duart[1], FUNC(scn2681_device::read), FUNC(scn2681_device::write)).umask16(0xff00); + map(0x0080, 0x00bf).r(FUNC(tek4107a_state::vpac_r)).w(m_vpac, FUNC(crt9007_device::write)).umask16(0x00ff); + map(0x00c0, 0x00c1).w(FUNC(tek4107a_state::xpos_w)); + map(0x00c2, 0x00c3).w(FUNC(tek4107a_state::ypos_w)); + map(0x00c4, 0x00c5).w(FUNC(tek4107a_state::xcur_w)); + map(0x00c6, 0x00c7).w(FUNC(tek4107a_state::ycur_w)); + map(0x00c8, 0x00c9).r(FUNC(tek4107a_state::test_r)); + map(0x00ca, 0x00ca).r(FUNC(tek4107a_state::font_r)); + map(0x00ca, 0x00cb).w(FUNC(tek4107a_state::tbwin_w)); + map(0x00cc, 0x00cd).rw(FUNC(tek4107a_state::gcntl_r), FUNC(tek4107a_state::gcntl_w)); + map(0x00ce, 0x00cf).rw(FUNC(tek4107a_state::acntl_r), FUNC(tek4107a_state::acntl_w)); + map(0x0100, 0x0107).rw("ppi", FUNC(i8255_device::read), FUNC(i8255_device::write)).umask16(0xff00); + map(0x0200, 0x0201).r(FUNC(tek4107a_state::nmi_enable_r)); + map(0x0280, 0x0281).r(FUNC(tek4107a_state::system_reset_r)); + map(0x0300, 0x0301).r(FUNC(tek4107a_state::nmi_disable_r)); +} + +/* Input Ports */ + +static INPUT_PORTS_START( tek4107a ) +INPUT_PORTS_END + +/* Video */ + +void tek4107a_state::video_start() +{ + save_item(NAME(m_graphics_control)); + save_item(NAME(m_alpha_control)); + save_item(NAME(m_x_position)); + save_item(NAME(m_y_position)); + save_item(NAME(m_x_cursor)); + save_item(NAME(m_y_cursor)); +} + +u32 tek4107a_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + return 0; +} + +static const gfx_layout tek4107a_charlayout = +{ + 8, 15, + RGN_FRAC(1,1), + 1, + { 0 }, + { STEP8(0,1) }, + { 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 }, + 16*8 +}; + +static GFXDECODE_START( gfx_tek4107a ) + GFXDECODE_ENTRY( "chargen", 0x0000, tek4107a_charlayout, 0, 1 ) +GFXDECODE_END + +/* Machine Initialization */ + +void tek4107a_state::machine_start() +{ + save_item(NAME(m_ppi_pc)); + save_item(NAME(m_kb_rdata)); + save_item(NAME(m_kb_tdata)); + save_item(NAME(m_kb_rclamp)); +} + +/* Machine Driver */ + +void tek4107a_state::tek4107a(machine_config &config) +{ + /* basic machine hardware */ + i80186_cpu_device &maincpu(I80186(config, "maincpu", 14.7456_MHz_XTAL)); + maincpu.set_addrmap(AS_PROGRAM, &tek4107a_state::tek4107a_mem); + maincpu.set_addrmap(AS_IO, &tek4107a_state::tek4107a_io); + + SCN2681(config, m_duart[0], 14.7456_MHz_XTAL / 4); + m_duart[0]->irq_cb().set("maincpu", FUNC(i80186_cpu_device::int0_w)); + m_duart[0]->outport_cb().set_inputline("maincpu", INPUT_LINE_NMI).bit(5).invert(); // RxRDYB + m_duart[0]->outport_cb().append(FUNC(tek4107a_state::kb_rclamp_w)).bit(4); + m_duart[0]->outport_cb().append(m_keyboard, FUNC(tek410x_keyboard_device::reset_w)).bit(3); + m_duart[0]->a_tx_cb().set(m_keyboard, FUNC(tek410x_keyboard_device::kdi_w)); + + SCN2681(config, m_duart[1], 14.7456_MHz_XTAL / 4); + m_duart[1]->irq_cb().set("maincpu", FUNC(i80186_cpu_device::int2_w)); + + i8255_device &ppi(I8255(config, "ppi")); + ppi.in_pb_callback().set_constant(0x30); + ppi.out_pc_callback().set(FUNC(tek4107a_state::ppi_pc_w)); + + TEK410X_KEYBOARD(config, m_keyboard); + m_keyboard->tdata_callback().set(FUNC(tek4107a_state::kb_tdata_w)); + m_keyboard->rdata_callback().set(FUNC(tek4107a_state::kb_rdata_w)); + + /* video hardware */ + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); + screen.set_raw(25.2_MHz_XTAL, 800, 0, 640, 525, 0, 480); + screen.set_screen_update(FUNC(tek4107a_state::screen_update)); + + CRT9007(config, m_vpac, 25.2_MHz_XTAL / 8); + m_vpac->set_screen("screen"); + m_vpac->set_character_width(8); + m_vpac->int_callback().set("maincpu", FUNC(i80186_cpu_device::int1_w)); + + PALETTE(config, "palette").set_entries(64); + GFXDECODE(config, "gfxdecode", "palette", gfx_tek4107a); +} + +void tek4107a_state::tek4109a(machine_config &config) +{ + tek4107a(config); + + /* video hardware */ + subdevice("palette")->set_entries(4096); +} + +/* ROMs */ + +ROM_START( tek4107a ) + ROM_REGION16_LE( 0x40000, "firmware", 0 ) + ROM_LOAD16_BYTE( "160-2379-03.u60", 0x00000, 0x8000, NO_DUMP ) + ROM_LOAD16_BYTE( "160-2380-03.u160", 0x00001, 0x8000, NO_DUMP ) + ROM_LOAD16_BYTE( "160-2377-03.u70", 0x10000, 0x8000, NO_DUMP ) + ROM_LOAD16_BYTE( "160-2378-03.u170", 0x10001, 0x8000, CRC(feac272f) SHA1(f2018dc9bb5bd6840b2843c709cbc24689054dc0) ) + ROM_LOAD16_BYTE( "160-2375-03.u80", 0x20000, 0x8000, NO_DUMP ) + ROM_LOAD16_BYTE( "160-2376-03.u180", 0x20001, 0x8000, CRC(35a44e75) SHA1(278c7f218105ad3473409b16a8d27a0b9f7a859e) ) + ROM_LOAD16_BYTE( "160-2373-03.u90", 0x30000, 0x8000, CRC(d5e89b15) SHA1(d6eb1a0a684348a8194238d641528fb96fb29087) ) + ROM_LOAD16_BYTE( "160-2374-03.u190", 0x30001, 0x8000, CRC(a3fef76e) SHA1(902845c4aa0cbc392b62c726ac746ca62567d91c) ) + + ROM_REGION( 0x1000, "chargen", 0 ) + ROM_LOAD( "160-2381 v1.0.u855", 0x0000, 0x1000, CRC(ac7ca279) SHA1(4c9de06d1c346f83eb8d0d09a0eb32c40bd8014c) ) +ROM_END + +ROM_START( tek4109a ) + // another set with 160-32xx-03 v10.5 labels exists + ROM_REGION16_LE( 0x40000, "firmware", 0 ) + ROM_LOAD16_BYTE( "160-3283-02 v8.2.u60", 0x00000, 0x8000, CRC(2a821db6) SHA1(b4d8b74bd9fe43885dcdc4efbdd1eebb96e32060) ) + ROM_LOAD16_BYTE( "160-3284-02 v8.2.u160", 0x00001, 0x8000, CRC(ee567b01) SHA1(67b1b0648cfaa28d57473bcc45358ff2bf986acf) ) + ROM_LOAD16_BYTE( "160-3281-02 v8.2.u70", 0x10000, 0x8000, CRC(e2713328) SHA1(b0bb3471539ef24d79b18d0e33bc148ed27d0ec4) ) + ROM_LOAD16_BYTE( "160-3282-02 v8.2.u170", 0x10001, 0x8000, CRC(c109a4f7) SHA1(762019105c1f82200a9c99ccfcfd8ee81d2ac4fe) ) + ROM_LOAD16_BYTE( "160-3279-02 v8.2.u80", 0x20000, 0x8000, CRC(00822078) SHA1(a82e61dafccbaea44e67efaa5940e52ec6d07d7d) ) + ROM_LOAD16_BYTE( "160-3280-02 v8.2.u180", 0x20001, 0x8000, CRC(eec9f70f) SHA1(7b65336219f5fa0d11f8be2b37040b564a53c52f) ) + ROM_LOAD16_BYTE( "160-3277-02 v8.2.u90", 0x30000, 0x8000, CRC(cf6ebc97) SHA1(298db473874c57bf4eec788818179748030a9ad8) ) + ROM_LOAD16_BYTE( "160-3278-02 v8.2.u190", 0x30001, 0x8000, CRC(d6124cd1) SHA1(f826aee5ec07cf5ac369697d93def0259ad225bb) ) + + ROM_REGION( 0x1000, "chargen", 0 ) + ROM_LOAD( "160-3087 v1.0.u855", 0x0000, 0x1000, CRC(97479528) SHA1(e9e15f1f64b3b6bd139accd51950bae71fdc2193) ) +ROM_END + +/* System Drivers */ + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1983, tek4107a, 0, 0, tek4107a, tek4107a, tek4107a_state, empty_init, "Tektronix", "Tektronix 4107A", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +COMP( 1983, tek4109a, tek4107a, 0, tek4109a, tek4107a, tek4107a_state, empty_init, "Tektronix", "Tektronix 4109A", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) diff --git a/src/mame/tektronix/tek410x_kbd.cpp b/src/mame/tektronix/tek410x_kbd.cpp new file mode 100644 index 00000000000..4d0d1beea46 --- /dev/null +++ b/src/mame/tektronix/tek410x_kbd.cpp @@ -0,0 +1,385 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/********************************************************************** + + This emulates the standard serial keyboard used with Tektronix's + 4105, 4106, 4107 and 4109 terminals, including the trademark + octagonal "joy disk". The 4404 keyboard is also compatible. + + The hardware was designed by the Keytronic Corporation, and uses + their 20-pin key strobe driver (22-0950-003) and input receiver + (22-0908-003) ASICs. + + The 8048/8748's DB pins are connected to drivers for up to 5 LEDs, + but only one of these LEDs (CR9, on the Caps Lock key) is actually + populated. + + A different but apparently backward-compatible keyboard was used + with the CX4107 and CX4109, based on a 8051 CPU with space for an + external program ROM and adding an onboard speaker as well as many + extra keys and an IBM 3279-style layout. + + Hexadecimal table of press codes (release codes are the same + 80): + + 00 Caps Lock + 01 Left Shift + 02 Right Shift + 03 Ctrl + 04 DEras/SEras + 05 Break + 06 Back Space + 07 Tab + 08 Line Feed + 09 Return + 0A Esc + 0B Space Bar + 0C " ' + 0D < , + 0E _ - + 0F > . + 10 ? / + 11 ) 0 + 12 ! 1 + 13 @ 2 + 14 # 3 + 15 $ 4 + 16 % 5 + 17 ^ 6 + 18 & 7 + 19 * 8 + 1A ( 9 + 1B : ; + 1C = + 1D A + 1E B + 1F C + 20 D + 21 E + 22 F + 23 G + 24 H + 25 I + 26 J + 27 K + 28 L + 29 M + 2A N + 2B O + 2C P + 2D Q + 2E R + 2F S + 30 T + 31 U + 32 V + 33 W + 34 X + 35 Y + 36 Z + 37 { [ + 38 ` \ + 39 } ] + 3A ~ | + 3B Rub Out + 3C Enter (keypad) + 3D , (keypad) + 3E - (keypad) + 3F . (keypad) + 40 0 (keypad) + 41 1 (keypad) + 42 2 (keypad) + 43 3 (keypad) + 44 4 (keypad) + 45 5 (keypad) + 46 6 (keypad) + 47 7 (keypad) + 48 8 (keypad) + 49 9 (keypad) + 4A F1 + 4B F2 + 4C F3 + 4D F4 + 4E F5 + 4F F6 + 50 F7 + 51 F8 + 52 GEras/Dialog + 53 Cancel/Setup + 54 DCopy/SCopy + 55 Menu + 56 Cursor Right (joystick) + 57 Cursor Up (joystick) + 58 Cursor Left (joystick) + 59 Cursor Down (joystick) + + Additional press codes for CX keyboard only: + + 5A Erase EOF + 5B Dup/PA1 + 5C Reset/Dev Cncl + 5D Field Mark/PA2/_ + 5E Attn Sys Req + 5F Cursr Sel/Clear + 60 < > + 61 Cursr Blink/Alt Cursr + 62 Ident + 63 Down Arrow + 64 Right Arrow/Right Double Arrow + 65 Left Arrow/Left Double Arrow + 66 Up Arrow + 67 Insert/Alpha + 68 Right Alt/Ctrl + + The baud rate is 4800, with 8 data bits and no parity. + +**********************************************************************/ + +#include "emu.h" +#include "tek410x_kbd.h" + +// device type definition +DEFINE_DEVICE_TYPE(TEK410X_KEYBOARD, tek410x_keyboard_device, "tek410x_kbd", "Tektronix 410X Standard Keyboard (119-1592-01)") + +tek410x_keyboard_device::tek410x_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, TEK410X_KEYBOARD, tag, owner, clock) + , m_mcu(*this, "mcu") + , m_key_matrix(*this, "X%u", 0U) + , m_config(*this, "CONFIG") + , m_tdata_callback(*this) + , m_rdata_callback(*this) + , m_select(0) + , m_p2_out(0) + , m_kdi(true) + , m_kdo(false) +{ +} + +void tek410x_keyboard_device::device_resolve_objects() +{ + m_tdata_callback.resolve_safe(); + m_rdata_callback.resolve_safe(); +} + +void tek410x_keyboard_device::device_start() +{ + save_item(NAME(m_select)); + save_item(NAME(m_p2_out)); + save_item(NAME(m_kdi)); + save_item(NAME(m_kdo)); +} + +WRITE_LINE_MEMBER(tek410x_keyboard_device::kdi_w) +{ + m_kdi = state; + if (BIT(m_p2_out, 7)) + { + m_mcu->set_input_line(MCS48_INPUT_IRQ, state ? CLEAR_LINE : ASSERT_LINE); + m_tdata_callback(state); + } +} + +WRITE_LINE_MEMBER(tek410x_keyboard_device::kdo_w) +{ + m_kdo = state; + if (BIT(m_p2_out, 5)) + m_rdata_callback(state); +} + +WRITE_LINE_MEMBER(tek410x_keyboard_device::reset_w) +{ + m_mcu->set_input_line(INPUT_LINE_RESET, state ? CLEAR_LINE : ASSERT_LINE); + if (!state) + p2_w(0xff); +} + +u8 tek410x_keyboard_device::p1_r() +{ + if (m_select < 12) + return m_key_matrix[m_select]->read(); + else + return 0xff; +} + +u8 tek410x_keyboard_device::p2_r() +{ + return 0xb0 | (m_kdo ? (m_p2_out & 0x20) << 1 : 0) | m_config->read(); +} + +void tek410x_keyboard_device::p2_w(u8 data) +{ + if (!BIT(data, 4)) + m_select = m_mcu->p1_r() & 0x0f; + + if (m_kdi && BIT(data, 7) != BIT(m_p2_out, 7)) + { + m_tdata_callback(BIT(data, 7)); + m_mcu->set_input_line(MCS48_INPUT_IRQ, BIT(data, 7) ? CLEAR_LINE : ASSERT_LINE); + } + + if (m_kdo && BIT(data, 5) != BIT(m_p2_out, 5)) + m_rdata_callback(BIT(data, 5)); + + m_p2_out = data; +} + +void tek410x_keyboard_device::ext_map(address_map &map) +{ + map(0x00, 0xff).nopr(); +} + +static INPUT_PORTS_START(tek410x_keyboard) + PORT_START("X0") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) PORT_CODE(KEYCODE_ENTER_PAD) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(COMMA_PAD)) PORT_CODE(KEYCODE_PLUS_PAD) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) PORT_CODE(KEYCODE_3_PAD) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) PORT_CODE(KEYCODE_6_PAD) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) PORT_CODE(KEYCODE_MINUS_PAD) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) PORT_CODE(KEYCODE_9_PAD) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD)) PORT_CODE(KEYCODE_DEL_PAD) + + PORT_START("X1") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) PORT_CODE(KEYCODE_4_PAD) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) PORT_CODE(KEYCODE_2_PAD) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) PORT_CODE(KEYCODE_5_PAD) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) PORT_CODE(KEYCODE_7_PAD) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) PORT_CODE(KEYCODE_1_PAD) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) PORT_CODE(KEYCODE_8_PAD) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) PORT_CODE(KEYCODE_0_PAD) + + PORT_START("X2") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Break") //PORT_CODE(KEYCODE_XXX) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Line Feed") PORT_CHAR(0x0a) //PORT_CODE(KEYCODE_XXX) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Rub Out") PORT_CODE(KEYCODE_BACKSPACE) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(']') PORT_CHAR('}') PORT_CODE(KEYCODE_BACKSLASH) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("X3") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Right Shift") PORT_CODE(KEYCODE_RSHIFT) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('\\') PORT_CHAR('`') PORT_CODE(KEYCODE_OPENBRACE) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('\'') PORT_CHAR('"') PORT_CODE(KEYCODE_QUOTE) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Back Space") PORT_CHAR(0x08) PORT_CODE(KEYCODE_CLOSEBRACE) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('-') PORT_CHAR('_') PORT_CODE(KEYCODE_MINUS) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Return") PORT_CHAR(0x0d) PORT_CODE(KEYCODE_ENTER) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('=') PORT_CHAR('+') PORT_CODE(KEYCODE_EQUALS) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Space Bar") PORT_CHAR(' ') PORT_CODE(KEYCODE_SPACE) + + PORT_START("X4") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_CODE(KEYCODE_DOWN) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_CODE(KEYCODE_LEFT) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F7)) PORT_CODE(KEYCODE_F11) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_CODE(KEYCODE_F6) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F6)) PORT_CODE(KEYCODE_F10) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Setup Cancel") PORT_CODE(KEYCODE_F2) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_CODE(KEYCODE_F7) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("SCopy DCopy") PORT_CODE(KEYCODE_F3) + + PORT_START("X5") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PORT_CODE(KEYCODE_RIGHT) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(UP)) PORT_CODE(KEYCODE_UP) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F8)) PORT_CODE(KEYCODE_F12) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F1)) PORT_CODE(KEYCODE_F5) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F5)) PORT_CODE(KEYCODE_F9) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Dialog GEras") PORT_CODE(KEYCODE_F1) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(F4)) PORT_CODE(KEYCODE_F8) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Menu") PORT_CODE(KEYCODE_F4) + + PORT_START("X6") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X") PORT_CHAR('x') PORT_CHAR('X') PORT_CODE(KEYCODE_X) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W") PORT_CHAR('w') PORT_CHAR('W') PORT_CODE(KEYCODE_W) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S") PORT_CHAR('s') PORT_CHAR('S') PORT_CODE(KEYCODE_S) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q") PORT_CHAR('q') PORT_CHAR('Q') PORT_CODE(KEYCODE_Q) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('2') PORT_CHAR('@') PORT_CODE(KEYCODE_2) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A") PORT_CHAR('a') PORT_CHAR('A') PORT_CODE(KEYCODE_A) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('1') PORT_CHAR('!') PORT_CODE(KEYCODE_1) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z") PORT_CHAR('z') PORT_CHAR('Z') PORT_CODE(KEYCODE_Z) + + PORT_START("X7") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Caps Lock") PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) PORT_CODE(KEYCODE_LCONTROL) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Esc") PORT_CHAR(0x1b) //PORT_CODE(KEYCODE_XXX) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Tab") PORT_CHAR(0x09) //PORT_CODE(KEYCODE_XXX) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('|') PORT_CHAR('~') PORT_CODE(KEYCODE_TAB) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("SEras DEras") //PORT_CODE(KEYCODE_XXX) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ctrl") PORT_CHAR(UCHAR_SHIFT_2) PORT_CODE(KEYCODE_CAPSLOCK) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('[') PORT_CHAR('{') PORT_CODE(KEYCODE_TILDE) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Left Shift") PORT_CHAR(UCHAR_SHIFT_1) PORT_CODE(KEYCODE_LSHIFT) + + PORT_START("X8") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CHAR('c') PORT_CHAR('C') PORT_CODE(KEYCODE_C) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CHAR('e') PORT_CHAR('E') PORT_CODE(KEYCODE_E) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CHAR('d') PORT_CHAR('D') PORT_CODE(KEYCODE_D) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R") PORT_CHAR('r') PORT_CHAR('R') PORT_CODE(KEYCODE_R) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('3') PORT_CHAR('#') PORT_CODE(KEYCODE_3) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F") PORT_CHAR('f') PORT_CHAR('F') PORT_CODE(KEYCODE_F) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('4') PORT_CHAR('$') PORT_CODE(KEYCODE_4) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V") PORT_CHAR('v') PORT_CHAR('V') PORT_CODE(KEYCODE_V) + + PORT_START("X9") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N") PORT_CHAR('n') PORT_CHAR('N') PORT_CODE(KEYCODE_N) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y") PORT_CHAR('y') PORT_CHAR('Y') PORT_CODE(KEYCODE_Y) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H") PORT_CHAR('h') PORT_CHAR('H') PORT_CODE(KEYCODE_H) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T") PORT_CHAR('t') PORT_CHAR('T') PORT_CODE(KEYCODE_T) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('6') PORT_CHAR('^') PORT_CODE(KEYCODE_6) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G") PORT_CHAR('g') PORT_CHAR('G') PORT_CODE(KEYCODE_G) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('5') PORT_CHAR('%') PORT_CODE(KEYCODE_5) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CHAR('b') PORT_CHAR('B') PORT_CODE(KEYCODE_B) + + PORT_START("X10") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M") PORT_CHAR('m') PORT_CHAR('M') PORT_CODE(KEYCODE_M) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U") PORT_CHAR('u') PORT_CHAR('U') PORT_CODE(KEYCODE_U) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J") PORT_CHAR('j') PORT_CHAR('J') PORT_CODE(KEYCODE_J) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I") PORT_CHAR('i') PORT_CHAR('I') PORT_CODE(KEYCODE_I) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('7') PORT_CHAR('&') PORT_CODE(KEYCODE_7) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K") PORT_CHAR('k') PORT_CHAR('K') PORT_CODE(KEYCODE_K) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('8') PORT_CHAR('*') PORT_CODE(KEYCODE_8) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(',') PORT_CHAR('>') PORT_CODE(KEYCODE_COMMA) + + PORT_START("X11") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('/') PORT_CHAR('?') PORT_CODE(KEYCODE_SLASH) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P") PORT_CHAR('p') PORT_CHAR('P') PORT_CODE(KEYCODE_P) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(';') PORT_CHAR(':') PORT_CODE(KEYCODE_COLON) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O") PORT_CHAR('o') PORT_CHAR('O') PORT_CODE(KEYCODE_O) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('0') PORT_CHAR('(') PORT_CODE(KEYCODE_0) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L") PORT_CHAR('l') PORT_CHAR('L') PORT_CODE(KEYCODE_L) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('9') PORT_CHAR(')') PORT_CODE(KEYCODE_9) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR('.') PORT_CHAR('>') PORT_CODE(KEYCODE_STOP) + + PORT_START("CONFIG") + PORT_DIPNAME(0x0f, 0x00, "Keyboard Type") PORT_DIPLOCATION("E:1,2,3,4") + PORT_DIPSETTING(0x00, "North America") + PORT_DIPSETTING(0x08, "United Kingdom (4A)") + PORT_DIPSETTING(0x04, "French (4B)") + PORT_DIPSETTING(0x02, "Swedish (4C)") + PORT_DIPSETTING(0x06, "Danish/Norwegian (4F)") + PORT_DIPSETTING(0x07, "German (4G)") + PORT_DIPSETTING(0x0a, "Katakana (4K)") +INPUT_PORTS_END + +ioport_constructor tek410x_keyboard_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(tek410x_keyboard); +} + +void tek410x_keyboard_device::device_add_mconfig(machine_config &config) +{ + I8748(config, m_mcu, 4.608_MHz_XTAL); + m_mcu->set_addrmap(AS_IO, &tek410x_keyboard_device::ext_map); + m_mcu->bus_out_cb().set_output("led0").bit(0); + m_mcu->p1_in_cb().set(FUNC(tek410x_keyboard_device::p1_r)); + m_mcu->p2_in_cb().set(FUNC(tek410x_keyboard_device::p2_r)); + m_mcu->p2_out_cb().set(FUNC(tek410x_keyboard_device::p2_w)); +} + +ROM_START(tek410x_kbd) + ROM_REGION(0x400, "mcu", 0) + ROM_LOAD("473_8748.bin", 0x000, 0x400, CRC(371553a8) SHA1(165ffc2c0775c1a3c2cc3ec86fb05adc8e8bb3eb)) +ROM_END + +const tiny_rom_entry *tek410x_keyboard_device::device_rom_region() const +{ + return ROM_NAME(tek410x_kbd); +} diff --git a/src/mame/tektronix/tek410x_kbd.h b/src/mame/tektronix/tek410x_kbd.h new file mode 100644 index 00000000000..095f7648094 --- /dev/null +++ b/src/mame/tektronix/tek410x_kbd.h @@ -0,0 +1,69 @@ +// license:BSD-3-Clause +// copyright-holders:AJR + +#ifndef MAME_MACHINE_TEK410X_KEYBOARD_H +#define MAME_MACHINE_TEK410X_KEYBOARD_H + +#pragma once + +#include "cpu/mcs48/mcs48.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> tek410x_keyboard_device + +class tek410x_keyboard_device : public device_t +{ +public: + // device type constructor + tek410x_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + + // callback configuration + auto tdata_callback() { return m_tdata_callback.bind(); } + auto rdata_callback() { return m_rdata_callback.bind(); } + + // line inputs + DECLARE_WRITE_LINE_MEMBER(kdi_w); + DECLARE_WRITE_LINE_MEMBER(kdo_w); + DECLARE_WRITE_LINE_MEMBER(reset_w); + +protected: + // device-level overrides + virtual void device_resolve_objects() override; + virtual void device_start() override; + virtual ioport_constructor device_input_ports() const override; + virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; + +private: + // MCU handlers + u8 p1_r(); + u8 p2_r(); + void p2_w(u8 data); + + // address maps + void ext_map(address_map &map); + + // object finders + required_device m_mcu; + required_ioport_array<12> m_key_matrix; + required_ioport m_config; + + // output callbacks + devcb_write_line m_tdata_callback; + devcb_write_line m_rdata_callback; + + // internal state + u8 m_select; + u8 m_p2_out; + bool m_kdi; + bool m_kdo; +}; + +// device type declaration +DECLARE_DEVICE_TYPE(TEK410X_KEYBOARD, tek410x_keyboard_device) + +#endif // MAME_MACHINE_TEK410X_KEYBOARD_H diff --git a/src/mame/tektronix/tek43xx.cpp b/src/mame/tektronix/tek43xx.cpp new file mode 100644 index 00000000000..544a5113b3d --- /dev/null +++ b/src/mame/tektronix/tek43xx.cpp @@ -0,0 +1,70 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/************************************************************************************************************ + + Skeleton driver for Tektronix 4300 series MC68020-based graphics workstations. + +************************************************************************************************************/ + +#include "emu.h" +#include "cpu/m68000/m68000.h" +#include "screen.h" + + +namespace { + +class tek43xx_state : public driver_device +{ +public: + tek43xx_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + { + } + + void tek4319(machine_config &config); + +private: + u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + + void mem_map(address_map &map); + + required_device m_maincpu; +}; + + +u32 tek43xx_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + return 0; +} + +void tek43xx_state::mem_map(address_map &map) +{ + map(0x00000000, 0x00000007).rom().region("program", 0); + map(0x00000008, 0x000fffff).ram(); + map(0x01cb0000, 0x01cb0003).nopr(); + map(0x10000000, 0x1001ffff).rom().region("program", 0); +} + +static INPUT_PORTS_START(tek4319) +INPUT_PORTS_END + +void tek43xx_state::tek4319(machine_config &config) +{ + M68020(config, m_maincpu, 20'000'000); + m_maincpu->set_addrmap(AS_PROGRAM, &tek43xx_state::mem_map); + + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); + screen.set_raw(60 * 1600 * 1066, 1600, 0, 1280, 1066, 0, 1024); // not confirmed except for displayed resolution + screen.set_screen_update(FUNC(tek43xx_state::screen_update)); +} + +ROM_START(tek4319) + ROM_REGION32_BE(0x20000, "program", 0) + ROM_LOAD16_BYTE("160-5528-00.bin", 0x00000, 0x10000, CRC(a04ffe7f) SHA1(601c27c47138c38dc54b9cbabca8467170cc580b)) + ROM_LOAD16_BYTE("160-5528-01.bin", 0x00001, 0x10000, CRC(869ec49f) SHA1(145a20272b1f9eb42618d0b4aefe9ea79a27dcce)) +ROM_END + +} // anonymous namespace + +COMP(1988, tek4319, 0, 0, tek4319, tek4319, tek43xx_state, empty_init, "Tektronix", "4319 Graphics Workstation", MACHINE_IS_SKELETON) diff --git a/src/mame/tektronix/tek440x.cpp b/src/mame/tektronix/tek440x.cpp new file mode 100644 index 00000000000..be815541d56 --- /dev/null +++ b/src/mame/tektronix/tek440x.cpp @@ -0,0 +1,432 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont, AJR +/*************************************************************************** + + Tektronix 440x "AI Workstations" + + skeleton by R. Belmont + + Hardware overview: + * 68010 (4404) or 68020 (4405) with custom MMU + * Intelligent floppy subsystem with 6502 driving a uPD765 controller + * NS32081 FPU + * 6551 debug console AICA + * SN76496 PSG for sound + * MC146818 RTC + * MC68681 DUART / timer (3.6864 MHz clock) (serial channel A = keyboard, channel B = RS-232 port) + * AM9513 timer (source of timer IRQ) + * NCR5385 SCSI controller + + Video is a 640x480 1bpp window on a 1024x1024 VRAM area; smooth panning around that area + is possible as is flat-out changing the scanout address. + + IRQ levels: + 7 = Debug (NMI) + 6 = VBL + 5 = UART + 4 = Spare (exp slots) + 3 = SCSI + 2 = DMA + 1 = Timer + 0 = Unused + + MMU info: + Map control register (location unk): bit 15 = VM enable, bits 10-8 = process ID + + Map entries: + bit 15 = dirty + bit 14 = write enable + bit 13-11 = process ID + bits 10-0 = address bits 22-12 in the final address + +***************************************************************************/ + +#include "emu.h" +#include "bus/rs232/rs232.h" +#include "cpu/m68000/m68000.h" +#include "cpu/m6502/m6502.h" +#include "machine/am9513.h" +#include "machine/bankdev.h" +#include "machine/mos6551.h" // debug tty +#include "machine/mc146818.h" +#include "machine/mc68681.h" +#include "machine/ncr5385.h" +#include "tek410x_kbd.h" +#include "sound/sn76496.h" +#include "emupal.h" +#include "screen.h" +#include "speaker.h" + + +class tek440x_state : public driver_device +{ +public: + tek440x_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_fdccpu(*this, "fdccpu"), + m_vm(*this, "vm"), + m_duart(*this, "duart"), + m_keyboard(*this, "keyboard"), + m_snsnd(*this, "snsnd"), + m_prom(*this, "maincpu"), + m_mainram(*this, "mainram"), + m_vram(*this, "vram"), + m_map(*this, "map", 0x1000, ENDIANNESS_BIG), + m_map_view(*this, "map"), + m_boot(false), + m_map_control(0), + m_kb_rdata(true), + m_kb_tdata(true), + m_kb_rclamp(false), + m_kb_loop(false) + { } + + void tek4404(machine_config &config); + +private: + virtual void machine_start() override; + virtual void machine_reset() override; + u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + + u16 memory_r(offs_t offset, u16 mem_mask); + void memory_w(offs_t offset, u16 data, u16 mem_mask); + u16 map_r(offs_t offset); + void map_w(offs_t offset, u16 data, u16 mem_mask); + u8 mapcntl_r(); + void mapcntl_w(u8 data); + void sound_w(u8 data); + void diag_w(u8 data); + + DECLARE_WRITE_LINE_MEMBER(kb_rdata_w); + DECLARE_WRITE_LINE_MEMBER(kb_tdata_w); + DECLARE_WRITE_LINE_MEMBER(kb_rclamp_w); + + void logical_map(address_map &map); + void physical_map(address_map &map); + void fdccpu_map(address_map &map); + + required_device m_maincpu; + required_device m_fdccpu; + required_device m_vm; + required_device m_duart; + required_device m_keyboard; + required_device m_snsnd; + required_region_ptr m_prom; + required_shared_ptr m_mainram; + required_shared_ptr m_vram; + memory_share_creator m_map; + memory_view m_map_view; + + bool m_boot; + u8 m_map_control; + bool m_kb_rdata; + bool m_kb_tdata; + bool m_kb_rclamp; + bool m_kb_loop; +}; + +/************************************* + * + * Machine start + * + *************************************/ + +void tek440x_state::machine_start() +{ + save_item(NAME(m_boot)); + save_item(NAME(m_map_control)); + save_item(NAME(m_kb_rdata)); + save_item(NAME(m_kb_tdata)); + save_item(NAME(m_kb_rclamp)); + save_item(NAME(m_kb_loop)); +} + + + +/************************************* + * + * Machine reset + * + *************************************/ + +void tek440x_state::machine_reset() +{ + m_boot = true; + diag_w(0); + m_keyboard->kdo_w(1); + mapcntl_w(0); +} + + + +/************************************* + * + * Video refresh + * + *************************************/ + +u32 tek440x_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + for (int y = 0; y < 480; y++) + { + u16 *const line = &bitmap.pix(y); + u16 const *video_ram = &m_vram[y * 64]; + + for (int x = 0; x < 640; x += 16) + { + u16 const word = *(video_ram++); + for (int b = 0; b < 16; b++) + { + line[x + b] = BIT(word, 15 - b); + } + } + } + + return 0; +} + + + +/************************************* + * + * CPU memory handlers + * + *************************************/ + +u16 tek440x_state::memory_r(offs_t offset, u16 mem_mask) +{ + if (m_boot) + return m_prom[offset & 0x3fff]; + + const offs_t offset0 = offset; + if (BIT(m_map_control, 4)) + offset = BIT(offset, 0, 11) | BIT(m_map[offset >> 11], 0, 11) << 11; + if (offset < 0x300000 && offset >= 0x100000 && !machine().side_effects_disabled()) + { + m_maincpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE); + m_maincpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE); + m_maincpu->set_buserror_details(offset0 << 1, 1, m_maincpu->get_fc()); + } + + return m_vm->read16(offset, mem_mask); +} + +void tek440x_state::memory_w(offs_t offset, u16 data, u16 mem_mask) +{ + const offs_t offset0 = offset; + if (BIT(m_map_control, 4)) + offset = BIT(offset, 0, 11) | BIT(m_map[offset >> 11], 0, 11) << 11; + if (offset < 0x300000 && offset >= 0x100000 && !machine().side_effects_disabled()) + { + m_maincpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE); + m_maincpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE); + m_maincpu->set_buserror_details(offset0 << 1, 0, m_maincpu->get_fc()); + } + + m_vm->write16(offset, data, mem_mask); +} + +u16 tek440x_state::map_r(offs_t offset) +{ + return m_map[offset >> 11]; +} + +void tek440x_state::map_w(offs_t offset, u16 data, u16 mem_mask) +{ + COMBINE_DATA(&m_map[offset >> 11]); +} + +u8 tek440x_state::mapcntl_r() +{ + return m_map_control; +} + +void tek440x_state::mapcntl_w(u8 data) +{ + if (BIT(data, 5)) + m_map_view.select(0); + else + m_map_view.disable(); + m_map_control = data & 0x1f; +} + +void tek440x_state::sound_w(u8 data) +{ + m_snsnd->write(data); + m_boot = false; +} + +void tek440x_state::diag_w(u8 data) +{ + if (!m_kb_rclamp && m_kb_loop != BIT(data, 7)) + m_keyboard->kdo_w(!BIT(data, 7) || m_kb_tdata); + + m_kb_loop = BIT(data, 7); +} + +WRITE_LINE_MEMBER(tek440x_state::kb_rdata_w) +{ + m_kb_rdata = state; + if (!m_kb_rclamp) + m_duart->rx_a_w(state); +} + +WRITE_LINE_MEMBER(tek440x_state::kb_rclamp_w) +{ + if (m_kb_rclamp != !state) + { + m_kb_rclamp = !state; + + // Clamp RXDA to 1 and KBRDATA to 0 when DUART asserts RxRDYA + if (m_kb_tdata || !m_kb_loop) + m_keyboard->kdo_w(state); + m_duart->rx_a_w(state ? m_kb_rdata : 1); + } +} + +WRITE_LINE_MEMBER(tek440x_state::kb_tdata_w) +{ + if (m_kb_tdata != state) + { + m_kb_tdata = state; + + m_duart->ip4_w(!state); + if (m_kb_loop && m_kb_rdata && !m_kb_rclamp) + m_keyboard->kdo_w(state); + } +} + +void tek440x_state::logical_map(address_map &map) +{ + map(0x000000, 0x7fffff).rw(FUNC(tek440x_state::memory_r), FUNC(tek440x_state::memory_w)); + map(0x800000, 0xffffff).view(m_map_view); + m_map_view[0](0x800000, 0xffffff).rw(FUNC(tek440x_state::map_r), FUNC(tek440x_state::map_w)); +} + +void tek440x_state::physical_map(address_map &map) +{ + map(0x000000, 0x1fffff).ram().share("mainram"); + map(0x600000, 0x61ffff).ram().share("vram"); + map(0x740000, 0x747fff).rom().mirror(0x8000).region("maincpu", 0); + map(0x760000, 0x760fff).ram().mirror(0xf000); // debug RAM + map(0x780000, 0x780000).rw(FUNC(tek440x_state::mapcntl_r), FUNC(tek440x_state::mapcntl_w)); + // 782000-783fff: video address registers + // 784000-785fff: video control registers + map(0x788000, 0x788000).w(FUNC(tek440x_state::sound_w)); + // 78a000-78bfff: NS32081 FPU + map(0x78c000, 0x78c007).rw("aica", FUNC(mos6551_device::read), FUNC(mos6551_device::write)).umask16(0xff00); + map(0x7b0000, 0x7b0000).w(FUNC(tek440x_state::diag_w)); + // 7b1000-7b2fff: diagnostic registers + // 7b2000-7b3fff: Centronics printer data + map(0x7b4000, 0x7b401f).rw(m_duart, FUNC(mc68681_device::read), FUNC(mc68681_device::write)).umask16(0xff00); + // 7b6000-7b7fff: Mouse + map(0x7b8000, 0x7b8003).mirror(0x100).rw("timer", FUNC(am9513_device::read16), FUNC(am9513_device::write16)); + // 7ba000-7bbfff: MC146818 RTC + // 7bc000-7bdfff: SCSI bus address registers + map(0x7be000, 0x7be01f).mirror(0x1fe0).rw("scsic", FUNC(ncr5385_device::read), FUNC(ncr5385_device::write)).umask16(0xff00).cswidth(16); +} + +void tek440x_state::fdccpu_map(address_map &map) +{ + map(0x0000, 0x1000).ram(); + map(0xf000, 0xffff).rom().region("fdccpu", 0); +} + +/************************************* + * + * Port definitions + * + *************************************/ + +static INPUT_PORTS_START( tek4404 ) +INPUT_PORTS_END + +/************************************* + * + * Machine driver + * + *************************************/ + +void tek440x_state::tek4404(machine_config &config) +{ + /* basic machine hardware */ + M68010(config, m_maincpu, 40_MHz_XTAL / 4); // MC68010L10 + m_maincpu->set_addrmap(AS_PROGRAM, &tek440x_state::logical_map); + + ADDRESS_MAP_BANK(config, m_vm); + m_vm->set_addrmap(0, &tek440x_state::physical_map); + m_vm->set_data_width(16); + m_vm->set_addr_width(23); + m_vm->set_endianness(ENDIANNESS_BIG); + + M6502(config, m_fdccpu, 16_MHz_XTAL / 8); + m_fdccpu->set_addrmap(AS_PROGRAM, &tek440x_state::fdccpu_map); + + /* video hardware */ + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); + screen.set_video_attributes(VIDEO_UPDATE_BEFORE_VBLANK); + screen.set_raw(25.2_MHz_XTAL, 800, 0, 640, 525, 0, 480); // 31.5 kHz horizontal (guessed), 60 Hz vertical + screen.set_screen_update(FUNC(tek440x_state::screen_update)); + screen.set_palette("palette"); + PALETTE(config, "palette", palette_device::MONOCHROME); + + mos6551_device &aica(MOS6551(config, "aica", 40_MHz_XTAL / 4 / 10)); + aica.set_xtal(1.8432_MHz_XTAL); + aica.txd_handler().set("rs232", FUNC(rs232_port_device::write_txd)); + aica.irq_handler().set_inputline(m_maincpu, M68K_IRQ_7); + + MC68681(config, m_duart, 3.6864_MHz_XTAL); + m_duart->irq_cb().set_inputline(m_maincpu, M68K_IRQ_5); // auto-vectored + m_duart->outport_cb().set(FUNC(tek440x_state::kb_rclamp_w)).bit(4); + m_duart->outport_cb().append(m_keyboard, FUNC(tek410x_keyboard_device::reset_w)).bit(3); + m_duart->a_tx_cb().set(m_keyboard, FUNC(tek410x_keyboard_device::kdi_w)); + + TEK410X_KEYBOARD(config, m_keyboard); + m_keyboard->tdata_callback().set(FUNC(tek440x_state::kb_tdata_w)); + m_keyboard->rdata_callback().set(FUNC(tek440x_state::kb_rdata_w)); + + AM9513(config, "timer", 40_MHz_XTAL / 4 / 10); // from CPU E output + + //MC146818(config, "calendar", 32.768_MHz_XTAL); + + NCR5385(config, "scsic", 40_MHz_XTAL / 4).irq().set_inputline(m_maincpu, M68K_IRQ_3); + + rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, nullptr)); + rs232.rxd_handler().set("aica", FUNC(mos6551_device::write_rxd)); + rs232.dcd_handler().set("aica", FUNC(mos6551_device::write_dcd)); + rs232.dsr_handler().set("aica", FUNC(mos6551_device::write_dsr)); + rs232.cts_handler().set("aica", FUNC(mos6551_device::write_cts)); + + SPEAKER(config, "mono").front_center(); + + SN76496(config, m_snsnd, 25.2_MHz_XTAL / 8).add_route(ALL_OUTPUTS, "mono", 0.80); +} + + + +/************************************* + * + * ROM definition(s) + * + *************************************/ + +ROM_START( tek4404 ) + ROM_REGION( 0x8000, "maincpu", 0 ) + ROM_LOAD16_BYTE( "tek_u158.bin", 0x000000, 0x004000, CRC(9939e660) SHA1(66b4309e93e4ff20c1295dc2ec2a8d6389b2578c) ) + ROM_LOAD16_BYTE( "tek_u163.bin", 0x000001, 0x004000, CRC(a82dcbb1) SHA1(a7e4545e9ea57619faacc1556fa346b18f870084) ) + + ROM_REGION( 0x1000, "fdccpu", 0 ) + ROM_LOAD( "tek_u130.bin", 0x000000, 0x001000, CRC(2c11a3f1) SHA1(b29b3705692d50f15f7e8bbba12a24c69817d52e) ) + + ROM_REGION( 0x2000, "scsimfm", 0 ) + ROM_LOAD( "scsi_mfm.bin", 0x000000, 0x002000, CRC(b4293435) SHA1(5e2b96c19c4f5c63a5afa2de504d29fe64a4c908) ) +ROM_END + +/************************************* + * + * Game driver(s) + * + *************************************/ +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1984, tek4404, 0, 0, tek4404, tek4404, tek440x_state, empty_init, "Tektronix", "4404 Artificial Intelligence System", MACHINE_NOT_WORKING ) diff --git a/src/mame/tektronix/tekigw.cpp b/src/mame/tektronix/tekigw.cpp new file mode 100644 index 00000000000..3000d55ccd3 --- /dev/null +++ b/src/mame/tektronix/tekigw.cpp @@ -0,0 +1,967 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +/* + * Tektronix Intelligent Graphics Workstations (6110, 6120, 6130, 6205, 6210, 6212, 4132) + * + * Sources: + * - http://bitsavers.trailing-edge.com/pdf/tektronix/6130/6100_Series_Hardware_Descriptions.pdf + * - https://archive.org/details/tektronix_Tektronix_1985 + * + * TODO: + * - am9516 dma controller + * - slots and cards + * - gpib devices + * - graphics and keyboard + */ +/* + * WIP + * - novram chip select not asserted when trying to read ethernet mac address? + * - aborts to firmware monitor on second serial port after failing to boot + */ + +#include "emu.h" + +// cpus and memory +#include "cpu/ns32000/ns32000.h" +#include "machine/ram.h" + +// various hardware +//#include "machine/am9516a.h" +#include "machine/am9517a.h" +#include "machine/eepromser.h" +#include "machine/i82586.h" +#include "machine/mm58167.h" +//#include "machine/ncr5385.h" +#include "machine/ns32081.h" +#include "machine/ns32082.h" +#include "machine/ns32202.h" +#include "machine/tms9914.h" +#include "machine/wd_fdc.h" +#include "machine/wd1010.h" +#include "machine/z80scc.h" + +#include "machine/input_merger.h" + +// busses and connectors +#include "bus/ieee488/ieee488.h" +#include "machine/nscsi_bus.h" +#include "bus/nscsi/hd.h" +#include "bus/rs232/rs232.h" +#include "imagedev/floppy.h" +#include "imagedev/harddriv.h" + +// graphics +#include "cpu/mcs51/mcs51.h" +#include "video/mc6845.h" +#include "screen.h" + +#define VERBOSE 0 +#include "logmacro.h" + +namespace { + +class tekigw_state_base : public driver_device +{ +protected: + tekigw_state_base(machine_config const &mconfig, device_type type, char const *tag) + : driver_device(mconfig, type, tag) + , m_cpu(*this, "cpu") + , m_fpu(*this, "fpu") + , m_mmu(*this, "mmu") + , m_icu(*this, "icu") + , m_ram(*this, "ram") + , m_scc(*this, "scc") + , m_serial(*this, "port%u", 0U) + , m_rtc(*this, "rtc") + , m_nov(*this, "nov%u", 0U) + //, m_dma(*this, "dma") + , m_lan(*this, "lan") + , m_led(*this, "led") + { + } + + void common_config(machine_config &config); + void common_init(); + + // driver_device overrides + virtual void machine_start() override; + virtual void machine_reset() override; + + // address maps + template void cpu_map(address_map &map); + + // computer board control registers + u8 nov_r() { return m_nmr; } + u8 scr_r() { return m_scr; } + u8 ssr_r() { return m_ssr; } + void led_w(u8 data) { m_led = data; } + void nov_w(u8 data); + void scr_w(u8 data); + + // novram data out handler + void nov_do(int state); + + void buserror(s32 param); + + required_device m_cpu; + required_device m_fpu; + required_device m_mmu; + required_device m_icu; + required_device m_ram; + + required_device m_scc; + required_device_array m_serial; + required_device m_rtc; + optional_device_array m_nov; + //required_device m_dma; + required_device m_lan; + + output_finder<> m_led; + + emu_timer *m_buserror = nullptr; + +private: + u8 m_nmr = 0; // nonvolatile memory register + u16 m_per = 0; // parity error register + u8 m_scr = 0; // system control register + u8 m_ssr = 0; // system status register + + // ram parity state + memory_passthrough_handler m_parity_mph; + std::unique_ptr m_parity_flag; + unsigned m_parity_bad = 0; + bool m_parity_check = 0; +}; + +class tek6100_state : public tekigw_state_base +{ +public: + tek6100_state(machine_config const &mconfig, device_type type, char const *tag) + : tekigw_state_base(mconfig, type, tag) + , m_gpib(*this, "gpib") + , m_fdc(*this, "fdc") + , m_fdd(*this, "fdc:%u:525dd", 0U) + , m_hdc(*this, "hdc") + , m_hdd(*this, "hdc:0") + , m_dpu_cpu(*this, "dpu_cpu") + , m_dpu_cram(*this, "dpu_cram") + , m_dpu_vram(*this, "dpu_vram") + { + } + + void tek6130(machine_config &config); + void init() { tekigw_state_base::common_init(); } + +protected: + // driver_device overrides + virtual void machine_start() override; + virtual void machine_reset() override; + + // address maps + template void cpu_map(address_map &map); + void lan_map(address_map &map); + template void dpu_cpu_map(address_map &map); + +private: + // computer board control registers + void fcr_w(u8 data); + void gcr_w(u8 data); + void hcr_w(u8 data); + + // hard disk buffer handlers + template T buf_r(); + template void buf_w(T data); + + u32 screen_update(screen_device& screen, bitmap_rgb32& bitmap, rectangle const& cliprect) { return 0; } + + required_device m_gpib; + required_device m_fdc; + optional_device_array m_fdd; + required_device m_hdc; + required_device m_hdd; + + optional_device m_dpu_cpu; + optional_device m_dpu_cram; + optional_device m_dpu_vram; + + u8 m_hcr = 0; // hard disk control register + + // hard disk controller buffer + u16 m_hdc_ptr = 0; + std::unique_ptr m_hdc_buf; +}; + +class tek4132_state : public tekigw_state_base +{ +public: + tek4132_state(machine_config const &mconfig, device_type type, char const *tag) + : tekigw_state_base(mconfig, type, tag) + , m_scsibus(*this, "scsi") + //, m_scsi(*this, "scsi:7:ncr5385") + , m_sdma(*this, "sdma") + , m_sirq(*this, "sirq") + { + } + + void tek4132(machine_config &config); + void init() { tekigw_state_base::common_init(); } + +protected: + // driver_device overrides + //virtual void machine_start() override; + //virtual void machine_reset() override; + + // address maps + template void cpu_map(address_map &map); + void lan_map(address_map &map); + +private: + required_device m_scsibus; + //required_device m_scsi; + required_device m_sdma; + + required_device m_sirq; +}; + +void tekigw_state_base::machine_start() +{ + save_item(NAME(m_nmr)); + save_item(NAME(m_per)); + save_item(NAME(m_scr)); + save_item(NAME(m_ssr)); + + m_per = 0; + m_ssr = 0; + + m_parity_check = false; + + m_buserror = timer_alloc(FUNC(tek4132_state::buserror), this); +} + +void tekigw_state_base::machine_reset() +{ + nov_w(0); + scr_w(0); +} + +void tek6100_state::machine_start() +{ + tekigw_state_base::machine_start(); + + m_hdc_buf = std::make_unique(4096); + + save_item(NAME(m_hcr)); + + save_item(NAME(m_hdc_ptr)); + save_pointer(NAME(m_hdc_buf), 4096); +} + +void tek6100_state::machine_reset() +{ + tekigw_state_base::machine_reset(); + + hcr_w(0); + fcr_w(0); + + m_icu->ir_w<0>(1); // mmu present + m_icu->ir_w<3>(1); + m_icu->ir_w<4>(1); + m_icu->ir_w<5>(1); + m_icu->ir_w<6>(1); + m_icu->ir_w<7>(1); + m_icu->ir_w<8>(1); + m_icu->ir_w<9>(1); + m_icu->ir_w<14>(1); // fpu present +} + +void tekigw_state_base::common_init() +{ + m_led.resolve(); + + m_lan->space(0).install_ram(0, m_ram->mask(), m_ram->pointer()); +} + +enum fcr_mask : u8 +{ + FCR_DRIVE = 0x01, // drive select + FCR_SIDE = 0x02, // side select + FCR_DDEN = 0x04, // double density enable + FCR_FDEN = 0x08, // flexible disk enable +}; + +void tek6100_state::fcr_w(u8 data) +{ + floppy_image_device *fdd = nullptr; + if (data & FCR_FDEN) + fdd = m_fdd[data & FCR_DRIVE]; + + m_fdc->set_floppy(fdd); + if (fdd) + fdd->ss_w(bool(data & FCR_SIDE)); + + m_fdc->dden_w(bool(data & FCR_DDEN)); +} + +enum gcr_mask : u8 +{ + GCR_SYSCTL = 0x02, // gpib line driver enable +}; + +void tek6100_state::gcr_w(u8 data) +{ + // TODO: enable/disable line drivers +} + +enum scr_mask : u8 +{ + SCR_RAME = 0x01, // ram enable + SCR_NMIE = 0x04, // nmi enable + SCR_LLOP = 0x08, // lan loopback enable + SCR_BERRE = 0x10, // bus error enable + SCR_DMAE = 0x20, // dma enable + SCR_PARB = 0x40, // parity bad + SCR_PARE = 0x80, // parity enable +}; + +enum ssr_mask : u8 +{ + SSR_DMACH = 0x0f, // dma channel + SSR_BERR = 0x10, // bus error + SSR_PWRSW = 0x20, // power switch + SSR_PFAIL = 0x40, // power fail + SSR_PERR = 0x80, // parity error +}; + +enum per_mask : u16 +{ + PER_PARADR = 0x3fff, // parity address + PER_HIERR = 0x4000, + PER_LOERR = 0x8000, +}; + +void tekigw_state_base::scr_w(u8 data) +{ + if (!(m_scr & SCR_RAME) && (data & SCR_RAME)) + m_cpu->space(0).install_ram(0, m_ram->mask(), m_ram->pointer()); + + if ((m_scr ^ data) & SCR_LLOP) + m_lan->set_loopback(data & SCR_LLOP); + + if (m_scr & SCR_BERRE && !(data & SCR_BERRE)) + m_ssr &= ~(SSR_BERR | SSR_DMACH); + + // install parity handlers + if (!(m_scr & SCR_PARB) && (data & SCR_PARB) && !m_parity_check) + { + m_parity_flag = std::make_unique(m_ram->size() / 32); + m_parity_bad = 0; + m_parity_check = true; + + m_parity_mph = m_cpu->space(0).install_readwrite_tap( + 0, m_ram->mask(), + "parity", + [this] (offs_t offset, u16 &data, u16 mem_mask) + { + if (m_scr & SCR_PARE) + { + bool error = false; + + // check bad parity (lo) + if ((mem_mask & 0x00ff) && BIT(m_parity_flag[offset / 32], (offset & 31) + 0)) + { + m_ssr |= SSR_PERR; + m_per &= ~PER_PARADR; + m_per |= PER_LOERR | ((offset >> 9) & PER_PARADR); + + error = true; + } + + // check bad parity (hi) + if ((mem_mask & 0xff00) && BIT(m_parity_flag[offset / 32], (offset & 31) + 1)) + { + m_ssr |= SSR_PERR; + m_per &= ~PER_PARADR; + m_per |= PER_HIERR | ((offset >> 9) & PER_PARADR); + + error = true; + } + + if (error && (m_scr & SCR_NMIE)) + m_cpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE); + } + }, + [this] (offs_t offset, u16 &data, u16 mem_mask) + { + if (m_scr & SCR_PARB) + { + // mark bad parity (lo) + if ((mem_mask & 0x00ff) && !BIT(m_parity_flag[offset / 32], (offset & 31) + 0)) + { + m_parity_flag[offset / 32] |= 1U << ((offset & 31) + 0); + m_parity_bad++; + } + + // mark bad parity (hi) + if ((mem_mask & 0xff00) && !BIT(m_parity_flag[offset / 32], (offset & 31) + 1)) + { + m_parity_flag[offset / 32] |= 1U << ((offset & 31) + 1); + m_parity_bad++; + } + } + else + { + // clear bad parity (lo) + if ((mem_mask & 0x00ff) && BIT(m_parity_flag[offset / 32], (offset & 31) + 0)) + { + m_parity_flag[offset / 32] &= ~(1U << ((offset & 31) + 0)); + m_parity_bad--; + } + + // clear bad parity (hi) + if ((mem_mask & 0xff00) && BIT(m_parity_flag[offset / 32], (offset & 31) + 1)) + { + m_parity_flag[offset / 32] &= ~(1U << ((offset & 31) + 1)); + m_parity_bad--; + } + + // stop checking parity if all clear + if (!m_parity_bad) + { + m_parity_flag.reset(); + m_parity_mph.remove(); + m_parity_check = false; + } + } + }, + &m_parity_mph); + } + + // stop checking parity if all clear + if ((m_scr & SCR_PARB) && !(data & SCR_PARB) && m_parity_check && !m_parity_bad) + { + m_parity_flag.reset(); + m_parity_mph.remove(); + m_parity_check = false; + } + + if (data & SCR_PARE) + m_per = 0; + else + m_ssr &= ~SSR_PERR; + + m_scr = data; +} + +enum nov_mask : u8 +{ + NOV_NDAT = 0x01, // nonvolatile memory data + NOV_SK = 0x02, // serial clock + NOV_CS0 = 0x04, // chip select 0 + NOV_CS1 = 0x08, // chip select 1 + NOV_LED = 0x10, // power-on led + NOV_PON = 0x20, // system power enable + NOV_MSK = 0x3e, +}; + +void tekigw_state_base::nov_w(u8 data) +{ + bool const cs0 = data & NOV_CS0; + bool const cs1 = data & NOV_CS1; + + if (m_nov[0] && ((m_nmr ^ data) & NOV_CS0)) + m_nov[0]->cs_write(cs0); + if (m_nov[1] && ((m_nmr ^ data) & NOV_CS1)) + m_nov[1]->cs_write(cs1); + + if (m_nov[0] && cs0) + { + m_nov[0]->di_write(bool(data & NOV_NDAT)); + m_nov[0]->clk_write(bool(data & NOV_SK)); + } + + if (m_nov[1] && cs1) + { + m_nov[1]->di_write(bool(data & NOV_NDAT)); + m_nov[1]->clk_write(bool(data & NOV_SK)); + } + + m_nmr = (m_nmr & ~NOV_MSK) | (data & NOV_MSK); +} + +void tekigw_state_base::nov_do(int state) +{ + if (state) + m_nmr |= NOV_NDAT; + else + m_nmr &= ~NOV_NDAT; +} + +void tekigw_state_base::buserror(s32 param) +{ + if (m_scr & SCR_BERRE) + { + m_ssr |= SSR_BERR | (param & SSR_DMACH); + + if (m_scr & SCR_NMIE) + m_cpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE); + } +} + +enum hcr_mask : u8 +{ + HCR_HDSEL = 0x0f, // head select + HCR_DRSEL = 0x10, // drive select + HCR_MULT = 0x20, // multiple sector + HCR_BFRDY = 0x40, // buffer ready + HCR_BCCLR = 0x80, // buffer counter clear +}; + +void tek6100_state::hcr_w(u8 data) +{ + m_hdc->drdy_w(m_hdd->exists() && bool(data & HCR_DRSEL)); + m_hdc->brdy_w(bool(data & HCR_BFRDY)); + + if (!(data & HCR_BCCLR)) + m_hdc_ptr = 0; + + m_hdc->head_w(data & 7); + m_hdc->sc_w(bool(data & HCR_DRSEL)); + + m_hcr = data; +} + +template T tek6100_state::buf_r() +{ + T data = 0; + + for (unsigned i = 0; i < sizeof(T); i++) + data |= T(m_hdc_buf[m_hdc_ptr++ & 0xfff]) << (i * 8); + + return data; +} + +template void tek6100_state::buf_w(T data) +{ + for (unsigned i = 0; i < sizeof(T); i++) + m_hdc_buf[m_hdc_ptr++ & 0xfff] = u8(data >> (i * 8)); +} + +template void tekigw_state_base::cpu_map(address_map &map) +{ + map(0xfff004, 0xfff005).lw16([this](u16 data) { m_lan->ca(1); }, "lan_ca"); + map(0xfff006, 0xfff006).rw(FUNC(tekigw_state_base::nov_r), FUNC(tekigw_state_base::nov_w)); + map(0xfff008, 0xfff009).portr("config"); + map(0xfff008, 0xfff008).w(FUNC(tekigw_state_base::led_w)); + map(0xfff00a, 0xfff00b).lr16([this]() { return m_per; }, "per_r"); + map(0xfff00c, 0xfff00c).rw(FUNC(tekigw_state_base::scr_r), FUNC(tekigw_state_base::scr_w)); + map(0xfff00e, 0xfff00e).r(FUNC(tekigw_state_base::ssr_r)); + + map(0xfff800, 0xfff83f).rw(m_rtc, FUNC(mm58167_device::read), FUNC(mm58167_device::write)).umask16(0xff); + map(0xfffa00, 0xfffa07).rw(m_scc, FUNC(z80scc_device::ab_dc_r), FUNC(z80scc_device::ab_dc_w)).umask16(0xff); + //map(0xfffd00, 0xfffdff); // dma controller + map(0xfffe00, 0xfffeff).m(m_icu, FUNC(ns32202_device::map)).umask16(0xff); +} + +template void tek6100_state::cpu_map(address_map &map) +{ + tekigw_state_base::cpu_map(map); + + map(0x000000, 0x007fff).rom().region("kernel", 0); + + //map(0x300000, 0x7fffff); // external bus + map(0x800000, 0x807fff).rom().region("kernel", 0); + //map(0x820000, 0xfdffff); // external bus + map(0xfe0000, 0xfeffff).lr8( + [this](address_space &space) + { + // FIXME: Should be 20μs according to 6100 documentation; CPU is still + // too fast, and timing may differ on 4132. Also DMACH field should be + // 7 for CPU, but diagnostic expects F; maybe 4132 is different? + m_buserror->adjust(attotime::from_ticks(10, m_cpu->clock()), 0x7); + + return 0; // space.unmap(); + }, "buserror"); // expansion I/O + + map(0xff0000, 0xff7fff).rw(FUNC(tek6100_state::buf_r), FUNC(tek6100_state::buf_w)); + + map(0xfff000, 0xfff000).w(FUNC(tek6100_state::fcr_w)); + map(0xfff002, 0xfff002).w(FUNC(tek6100_state::gcr_w)); + + map(0xfff900, 0xfff90f).rw(m_gpib, FUNC(tms9914_device::read), FUNC(tms9914_device::write)).umask16(0xff); + map(0xfffb00, 0xfffb0f).rw(m_hdc, FUNC(wd1010_device::read), FUNC(wd1010_device::write)).umask16(0xff); + map(0xfffb10, 0xfffb10).w(FUNC(tek6100_state::hcr_w)); + map(0xfffc00, 0xfffc07).rw(m_fdc, FUNC(wd1770_device::read), FUNC(wd1770_device::write)).umask16(0xff); + map(0xffff00, 0xffffff).rom().region("kernel", 0x7f00); +} + +void tek6100_state::lan_map(address_map &map) +{ + map.global_mask(0x3fffff); + + map(0x3fff00, 0x3fffff).rom().region("kernel", 0x7f00); // 0xf00000-0xffffff +} + +template void tek6100_state::dpu_cpu_map(address_map &map) +{ + map(0x000000, 0x007fff).rom().region("dpu", 0); + + map(0x100000, 0x107fff).rom().region("dpu", 0); + + + map(0x20000e, 0x20000e).lr8([]() { return 0x20; }, "fpu_present"); + + //map(0x200026, 0x200026); + map(0x200028, 0x200028).lw8( + [this](u8 data) + { + if (!BIT(data, 7) && m_dpu_cpu) + { + m_dpu_cpu->space(0).install_ram(0, m_dpu_cram->mask(), m_dpu_cram->pointer()); + m_dpu_cpu->space(0).install_ram(0x400000, 0x400000 | m_dpu_vram->mask(), m_dpu_vram->pointer()); + } + }, "ram_enable"); + //map(0x20002a, 0x20002a); + //map(0x20002c, 0x20002c); + + //map(0x300000, 0x300000); // PUbram - pattern ram + map(0xc00000, 0xc0000f).ram(); // PUpixm1 (1/2 bit x 4 planes) +} + +enum csr_mask : u8 +{ + CSR_IDENT = 0x07, // scsi bus id (inverted) + CSR_RESET = 0x08, // scsi bus reset + CSR_FEOP = 0x10, // dma force eop + CSR_IENBL = 0x20, // scsi interrupt enable + CSR_DIPEND = 0x40, // dma interrupt pending + CSR_SIPEND = 0x80, // scsi interrupt pending +}; + +template void tek4132_state::cpu_map(address_map &map) +{ + map(0x000000, 0xffffff).lr8( + [this](address_space &space) + { + // FIXME: Should be 20μs according to 6100 documentation; CPU is still + // too fast, and timing may differ on 4132. Also DMACH field should be + // 7 for CPU, but diagnostic expects F; maybe 4132 is different? + m_buserror->adjust(attotime::from_ticks(50, m_cpu->clock()), 0xf); + + return space.unmap(); + }, "buserror"); + + tekigw_state_base::cpu_map(map); + + map(0x000000, 0x00ffff).rom().region("kernel", 0); + map(0x800000, 0x80ffff).rom().region("kernel", 0); + + //map(0xfff000, 0xfff000).w(FUNC(tek6100_state::fcr_w)); // rsaa_dmaaos serial dma address offset register + //map(0xfff002, 0xfff002).w(FUNC(tek6100_state::gcr_w)); // rsaa_auxlatch serial auxiliary control register + + map(0xfff900, 0xfff91f).rw(m_sdma, FUNC(am9517a_device::read), FUNC(am9517a_device::write)).umask16(0xff); + //map(0xfffa08, 0xfffa08); // rsaa_status + + //map(0xfffc00, 0xfffc1f); // signature + map(0xfffc20, 0xfffc3f).lw8( + [this](u8 data) + { + LOG("csr_w 0x%02x (%s)\n", data, machine().describe_context()); + + //m_scsi->set_own_id(~data & CSR_IDENT); + //m_sirq->in_w<1>(bool(data & CSR_IENBL)); + }, "csr_w"); + //map(0xfffc40, 0xfffc5f).m(m_scsi, FUNC(ncr5385_device::map)).umask16(0xff); + map(0xfffc60, 0xfffc61).ram(); // 9516 data + map(0xfffc62, 0xfffc63).ram(); // 9516 pointer + map(0xfffd00, 0xfffdff).ram(); // stub out 9516 + + map(0xffff00, 0xffffff).rom().region("kernel", 0xff00); +} + +void tek4132_state::lan_map(address_map &map) +{ + map.global_mask(0x3fffff); + + map(0x3fff00, 0x3fffff).rom().region("kernel", 0xff00); // 0xf00000-0xffffff +} + +void tekigw_state_base::common_config(machine_config &config) +{ + NS32016(config, m_cpu, 20_MHz_XTAL / 2); + + NS32081(config, m_fpu, 20_MHz_XTAL / 2); + m_cpu->set_fpu(m_fpu); + + NS32082(config, m_mmu, 20_MHz_XTAL / 2); + m_cpu->set_mmu(m_mmu); + + NS32202(config, m_icu, 20_MHz_XTAL / 1000); + m_icu->out_int().set_inputline(m_cpu, INPUT_LINE_IRQ0).invert(); + + RAM(config, m_ram); + m_ram->set_default_size("1M"); + + SCC8530N(config, m_scc, 16_MHz_XTAL / 4); + m_scc->out_int_callback().set(m_icu, FUNC(ns32202_device::ir_w<1>)).invert(); + m_scc->configure_channels(2'457'600, 0, 2'457'600, 0); + + RS232_PORT(config, m_serial[0], default_rs232_devices, "terminal"); + m_serial[0]->cts_handler().set(m_scc, FUNC(z80scc_device::ctsa_w)); + m_serial[0]->dcd_handler().set(m_scc, FUNC(z80scc_device::dcda_w)); + m_serial[0]->rxd_handler().set(m_scc, FUNC(z80scc_device::rxa_w)); + m_scc->out_dtra_callback().set(m_serial[0], FUNC(rs232_port_device::write_dtr)); + m_scc->out_rtsa_callback().set(m_serial[0], FUNC(rs232_port_device::write_rts)); + m_scc->out_txda_callback().set(m_serial[0], FUNC(rs232_port_device::write_txd)); + + RS232_PORT(config, m_serial[1], default_rs232_devices, nullptr); + m_serial[1]->cts_handler().set(m_scc, FUNC(z80scc_device::ctsb_w)); + m_serial[1]->dcd_handler().set(m_scc, FUNC(z80scc_device::dcdb_w)); + m_serial[1]->rxd_handler().set(m_scc, FUNC(z80scc_device::rxb_w)); + m_scc->out_dtrb_callback().set(m_serial[1], FUNC(rs232_port_device::write_dtr)); + m_scc->out_rtsb_callback().set(m_serial[1], FUNC(rs232_port_device::write_rts)); + m_scc->out_txdb_callback().set(m_serial[1], FUNC(rs232_port_device::write_txd)); + + MM58167(config, m_rtc, 32.768_kHz_XTAL); + + EEPROM_X24C44_16BIT(config, m_nov[0]); // X2443P + m_nov[0]->do_callback().set(FUNC(tekigw_state_base::nov_do)); + + I82586(config, m_lan, 16_MHz_XTAL / 2); + m_lan->out_irq_cb().set(m_icu, FUNC(ns32202_device::ir_w<11>)).invert(); +} + +void tek6100_state::tek6130(machine_config &config) +{ + tekigw_state_base::common_config(config); + + m_cpu->set_addrmap(0, &tek6100_state::cpu_map<0>); + m_cpu->set_addrmap(6, &tek6100_state::cpu_map<6>); + + m_lan->set_addrmap(0, &tek6100_state::lan_map); + + /* + * Interrupt sources + * 0 interval clock + * 1 serial + * 2 hard disk + * 3 display + * 4 backplane slot 1 + * 5 backplane slot 2 + * 6 backplane slot 3 + * 7 backplane slot 4 + * 8 backplane slot 5 + * 9 backplane slot 6 + * 10 gpib + * 11 local area network + * 12 power switch + * 13 flexible disk + * 14 network level + * 15 software clock + */ + + WD1770(config, m_fdc, 8_MHz_XTAL); // clock? + m_fdc->intrq_wr_callback().set(m_icu, FUNC(ns32202_device::ir_w<13>)); + //m_fdc->drq_wr_callback().set(m_dma, FUNC(::)); + FLOPPY_CONNECTOR(config, "fdc:0", "525dd", FLOPPY_525_DD, true, floppy_image_device::default_mfm_floppy_formats).enable_sound(true); + + WD1010(config, m_hdc, 20_MHz_XTAL / 4); + m_hdc->out_intrq_callback().set(m_icu, FUNC(ns32202_device::ir_w<2>)); + m_hdc->in_data_callback().set(FUNC(tek6100_state::buf_r)); + m_hdc->out_data_callback().set(FUNC(tek6100_state::buf_w)); + m_hdc->out_bcr_callback().set([this](int state) { if (state) m_hdc_ptr = 0; }); + + /* + * Supported hard drives (c,h,s,bps): + * - Micropolis 1302 (830,3,16,512) + * - Micropolis 1304 (830,6,16,512) + * - Maxtor XT-1105 (918,11,16,512) + */ + HARDDISK(config, m_hdd, 0); + + TMS9914(config, m_gpib, 20_MHz_XTAL / 4); + m_gpib->int_write_cb().set(m_icu, FUNC(ns32202_device::ir_w<10>)); + m_gpib->dio_read_cb().set(IEEE488_TAG, FUNC(ieee488_device::dio_r)); + m_gpib->dio_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_dio_w)); + m_gpib->eoi_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_eoi_w)); + m_gpib->dav_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_dav_w)); + m_gpib->nrfd_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_nrfd_w)); + m_gpib->ndac_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_ndac_w)); + m_gpib->ifc_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_ifc_w)); + m_gpib->srq_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_srq_w)); + m_gpib->atn_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_atn_w)); + m_gpib->ren_write_cb().set(IEEE488_TAG, FUNC(ieee488_device::host_ren_w)); + + ieee488_device &ieee(IEEE488(config, IEEE488_TAG)); + ieee.eoi_callback().set(m_gpib, FUNC(tms9914_device::eoi_w)); + ieee.dav_callback().set(m_gpib, FUNC(tms9914_device::dav_w)); + ieee.nrfd_callback().set(m_gpib, FUNC(tms9914_device::nrfd_w)); + ieee.ndac_callback().set(m_gpib, FUNC(tms9914_device::ndac_w)); + ieee.ifc_callback().set(m_gpib, FUNC(tms9914_device::ifc_w)); + ieee.srq_callback().set(m_gpib, FUNC(tms9914_device::srq_w)); + ieee.atn_callback().set(m_gpib, FUNC(tms9914_device::atn_w)); + ieee.ren_callback().set(m_gpib, FUNC(tms9914_device::ren_w)); + + IEEE488_SLOT(config, "ieee_rem", 0, remote488_devices, nullptr); + + // TODO: graphics board disabled for now + if (false) + { + NS32016(config, m_dpu_cpu, 0); // 8'000'000); + m_dpu_cpu->set_addrmap(0, &tek6100_state::dpu_cpu_map<0>); + + ns32081_device &dpu_fpu(NS32081(config, "dpu_fpu", 8'000'000)); + m_dpu_cpu->set_fpu(dpu_fpu); + + ns32202_device &dpu_icu(NS32202(config, "dpu_icu", 20'000)); + dpu_icu.out_int().set_inputline(m_dpu_cpu, INPUT_LINE_IRQ0).invert(); + + i8744_device &dpu_mcu(I8744(config, "dpu_mcu", 0)); // 10'000'000)); // 8744H-10 + (void)dpu_mcu; + + mc6845_device &dpu_crtc(SY6845E(config, "dpu_crtc", 25.2_MHz_XTAL)); // SYP6845EA + dpu_crtc.set_screen("dpu_screen"); + + // 32 x HM50256-15 (256K x 1 DRAM) total 1MiB + RAM(config, m_dpu_cram); + m_dpu_cram->set_default_size("1MiB"); + + // 32 x IMS2620P-12 (16K x 4 DRAM) total 256KiB + RAM(config, m_dpu_vram); + m_dpu_vram->set_default_size("256KiB"); + + // 13-inch 640x480 60Hz 4-bit color + // 15-inch 640x480 60Hz monochrome + screen_device &dpu_screen(SCREEN(config, "dpu_screen", SCREEN_TYPE_RASTER)); + dpu_screen.set_raw(25200000, 800, 0, 640, 525, 0, 480); + dpu_screen.set_screen_update(FUNC(tek6100_state::screen_update)); + } +} + +static void scsi_devices(device_slot_interface &device) +{ + device.option_add("harddisk", NSCSI_HARDDISK); +} + +void tek4132_state::tek4132(machine_config &config) +{ + tekigw_state_base::common_config(config); + + m_cpu->set_addrmap(0, &tek4132_state::cpu_map<0>); + m_cpu->set_addrmap(6, &tek4132_state::cpu_map<6>); + + m_lan->set_addrmap(0, &tek4132_state::lan_map); + + m_scc->configure_channels(3'686'400, 0, 3'686'400, 0); + + /* + * Interrupt sources + * 0 interval clock + * 1 serial + * 2 display + * 3 serial dma + * 4 scsi controller + * 5 backplane slot 1 + * 6 backplane slot 2 + * 7 backplane slot 3 + * 8 backplane slot 4 + * 9 backplane slot 5 + * 10 backplane slot 6 + * 11 local area network + * 12 power switch interrupt + * 13 time of day clock + * 14 network level + * 15 software clock + */ + + m_rtc->irq().set(m_icu, FUNC(ns32202_device::ir_w<13>)); + + EEPROM_X24C44_16BIT(config, m_nov[1]); // X2443P + m_nov[1]->do_callback().set(FUNC(tek4132_state::nov_do)); + + AM9517A(config, m_sdma, 4'000'000); // clock? + m_sdma->dreq_active_low(); + + INPUT_MERGER_ALL_HIGH(config, m_sirq); + //m_sirq->output_handler().set(m_icu, FUNC(ns32202_device::ir_w<4>)); + + NSCSI_BUS(config, m_scsibus); + NSCSI_CONNECTOR(config, "scsi:0", scsi_devices, "harddisk"); + NSCSI_CONNECTOR(config, "scsi:1", scsi_devices, nullptr); + NSCSI_CONNECTOR(config, "scsi:2", scsi_devices, nullptr); + NSCSI_CONNECTOR(config, "scsi:3", scsi_devices, nullptr); + NSCSI_CONNECTOR(config, "scsi:4", scsi_devices, nullptr); + NSCSI_CONNECTOR(config, "scsi:5", scsi_devices, nullptr); + NSCSI_CONNECTOR(config, "scsi:6", scsi_devices, nullptr); +#if 1 + NSCSI_CONNECTOR(config, "scsi:7", scsi_devices, nullptr); +#else + NSCSI_CONNECTOR(config, "scsi:7").option_set("ncr5385", NCR5385).clock(10'000'000).machine_config( + [this](device_t *device) + { + ncr5385_device &adapter = downcast(*device); + + //adapter.irq().set(m_sirq, FUNC(input_merger_all_high_device::in_w<0>)); + adapter.irq().set(m_icu, FUNC(ns32202_device::ir_w<4>)); + //adapter.drq_handler_cb().set(m_mct_adr, FUNC(mct_adr_device::drq<0>)); + + //subdevice(":mct_adr")->dma_r_cb<0>().set(adapter, FUNC(ncr53c94_device::dma_r)); + //subdevice(":mct_adr")->dma_w_cb<0>().set(adapter, FUNC(ncr53c94_device::dma_w)); + }); +#endif +} + +static INPUT_PORTS_START(tekigw) + PORT_START("config") + PORT_DIPNAME(0x80, 0x00, "Mode") PORT_DIPLOCATION("SW:1") + PORT_DIPSETTING( 0x00, "Normal") + PORT_DIPSETTING( 0x80, "Service") + PORT_DIPNAME(0x60, 0x20, "Console") PORT_DIPLOCATION("SW:3,2") + PORT_DIPSETTING( 0x00, "Display") + PORT_DIPSETTING( 0x20, "9600 baud RS-232-C terminal (port 0)") + PORT_DIPSETTING( 0x40, "1200 baud RS-232-C modem/terminal (port 1)") + PORT_DIPSETTING( 0x60, "300 baud model/terminal (port 1)") + PORT_DIPNAME(0x10, 0x00, "Boot") PORT_DIPLOCATION("SW:4") + PORT_DIPSETTING( 0x00, "UTek") + PORT_DIPSETTING( 0x10, "File") + PORT_DIPNAME(0x0c, 0x00, "Boot Device") PORT_DIPLOCATION("SW:6,5") + PORT_DIPSETTING( 0x00, "Autoboot") + PORT_DIPSETTING( 0x04, "Hard disk") + PORT_DIPSETTING( 0x08, "Diskette drive") + PORT_DIPSETTING( 0x0c, "LAN port") + PORT_DIPNAME(0x03, 0x00, "Diagnostic") PORT_DIPLOCATION("SW:8,7") + PORT_DIPSETTING( 0x00, "0") + PORT_DIPSETTING( 0x01, "1") + PORT_DIPSETTING( 0x02, "2") + PORT_DIPSETTING( 0x03, "3") +INPUT_PORTS_END + +ROM_START(tek6130) + ROM_REGION16_LE(0x8000, "kernel", 0) + ROM_SYSTEM_BIOS(0, "5.107", "5.107 85/02/20 13:51:51") + ROMX_LOAD("160-2921-02.bin", 0x00000, 0x4000, CRC(44688258) SHA1(645ceaa6ea9ef76ba8b557dec0387fce73f669c0), ROM_BIOS(0) | ROM_SKIP(1)) + ROMX_LOAD("160-2922-02.bin", 0x00001, 0x4000, CRC(5d84dff3) SHA1(08e74f0157a5c002397b3c8644613dc0ae8355a0), ROM_BIOS(0) | ROM_SKIP(1)) + + ROM_SYSTEM_BIOS(1, "5.105", "5.105 85/02/16 11:03:32") + ROMX_LOAD("pwr_up__5.105__adb_lo.bin", 0x00000, 0x4000, CRC(429a6a4a) SHA1(5ec5a045ec14a1b546d75e9406f0ad21163298f6), ROM_BIOS(1) | ROM_SKIP(1)) + ROMX_LOAD("pwr_up__5.105__adb_hi.bin", 0x00001, 0x4000, CRC(1ad7a762) SHA1(98472c30f1148c43f43d2131ebc9644d8ebf376a), ROM_BIOS(1) | ROM_SKIP(1)) + + ROM_REGION16_LE(0x8000, "dpu", 0) + ROMX_LOAD("l__sdpu__1.73.bin", 0x00000, 0x4000, CRC(cd1be127) SHA1(9c16ab7e8b195e9ae660288b4b26566581a029e5), ROM_SKIP(1)) + ROMX_LOAD("h__sdpu__1.73.bin", 0x00001, 0x4000, CRC(1adf3130) SHA1(966f839de0b10aff3ffc6af64d94e4b19ece52c7), ROM_SKIP(1)) + + ROM_REGION(0x1000, "dpu_mcu", 0) + ROM_LOAD("2960-01.bin", 0x0, 0x1000, CRC(5974eaec) SHA1(362cdfb7be162636429d614807b9066ca8bbab28)) +ROM_END + +ROM_START(tek4132) + ROM_REGION16_LE(0x10000, "kernel", 0) + ROM_SYSTEM_BIOS(0, "1.7", "5.107 85/02/20 13:51:51") + ROMX_LOAD("160-4018-00__v1.7.u3130", 0x00000, 0x8000, CRC(cdf154ab) SHA1(381d012b0ec85db03d8cb164ef22f92e33d40b57), ROM_BIOS(0) | ROM_SKIP(1)) + ROMX_LOAD("160-4019-00__v1.7.u3140", 0x00001, 0x8000, CRC(5fe870b1) SHA1(369507763e37e947bbbfde080ba3d83bb6f3a7bf), ROM_BIOS(0) | ROM_SKIP(1)) +ROM_END +} // anonymous namespace + +/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ +COMP(1984, tek6130, 0, 0, tek6130, tekigw, tek6100_state, init, "Tektronix", "6130", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW) +COMP(1984, tek4132, 0, 0, tek4132, tekigw, tek4132_state, init, "Tektronix", "4132", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW) diff --git a/src/mame/tektronix/tekxp33x.cpp b/src/mame/tektronix/tekxp33x.cpp new file mode 100644 index 00000000000..ed2e4bb74f1 --- /dev/null +++ b/src/mame/tektronix/tekxp33x.cpp @@ -0,0 +1,132 @@ +// license:BSD-3-Clause +// copyright-holders:Justin Kerk +/*************************************************************************** + + Tektronix TekXpress XP33x series X terminals + + Skeleton driver. + +****************************************************************************/ + +/* + + TODO: + + - everything + + Technical info: + https://www.linux-mips.org/wiki/Tektronix_TekXPress_XP338 + https://web.archive.org/web/20061013084616/http://tekxp-linux.hopto.org/pmwiki/pmwiki.php/Hardware/XP33x + http://bio.gsi.de/DOCS/NCD/xp.html + + CPU: IDT 79R3052E (MIPS I R3000 embedded core. Big Endian. With MMU, without FPU.) + Graphic Chipset: Texas Instruments (34020AGBL-40) TI 34010 (TIGA) + Graphic RAMDAC: Brooktree BT458LPJ135 (Supported in XFree86) + RAM: 4MB onboard, upgradeable to 52MB, 3 slots for 5V FPM NoParity SIMMs + ROM: 256Kb, 2 x 27c1024 (64Kx16), with BootMonitor + Peripherals: + 1x Ethernet Port (AUI and UTP) -- AMD AM79C98 Chipset + 2x Serial Ports -- Philips SCC2692 Dual UART chipset + Keyboard and Mouse controller is a generic PC-Style i8742 with Phoenix BIOS. + 1x "ERGO" Port (Combined Monitor, Keyboard, Mouse) + 16K (2K*8) EEPROM is SEEQ NQ2816A-250, AT28C16 compatible. Contains Boot Monitor settings. The content is compressed. + Micron MT56C0816 - ??? Flash + +*/ + + +#include "emu.h" +#include "cpu/mips/mips1.h" +#include "cpu/tms34010/tms34010.h" +#include "emupal.h" +#include "screen.h" + + +#define SCREEN_TAG "screen" + +class tekxp330_state : public driver_device +{ +public: + tekxp330_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) { } + + void tekxp330(machine_config &config); + +private: + virtual void machine_start() override; + + virtual void video_start() override; + uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + void cpu_map(address_map &map); + void tms_map(address_map &map); +}; + +/* Memory Maps */ + +void tekxp330_state::cpu_map(address_map &map) +{ + map(0x00000000, 0x003fffff).ram(); + map(0x1fc00000, 0x1fdfffff).rom().region("maincpu", 0); +} + +void tekxp330_state::tms_map(address_map &map) +{ +} + +/* Input Ports */ + +static INPUT_PORTS_START( tekxp330 ) +INPUT_PORTS_END + +/* Video */ + +void tekxp330_state::video_start() +{ +} + +uint32_t tekxp330_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + return 0; +} + +/* Machine Initialization */ + +void tekxp330_state::machine_start() +{ +} + +/* Machine Driver */ + +void tekxp330_state::tekxp330(machine_config &config) +{ + /* basic machine hardware */ + r3052e_device &maincpu(R3052E(config, "maincpu", XTAL(20'000'000))); /* IDT 79R3052E, clock unknown */ + maincpu.set_endianness(ENDIANNESS_BIG); + maincpu.set_addrmap(AS_PROGRAM, &tekxp330_state::cpu_map); + + tms34010_device &tms(TMS34010(config, "tms", XTAL(40'000'000))); /* clock unknown */ + tms.set_addrmap(AS_PROGRAM, &tekxp330_state::tms_map); + + /* video hardware */ + screen_device &screen(SCREEN(config, SCREEN_TAG, SCREEN_TYPE_RASTER)); + screen.set_refresh_hz(60); + screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */ + screen.set_screen_update(FUNC(tekxp330_state::screen_update)); + screen.set_size(640, 480); + screen.set_visarea(0, 640-1, 0, 480-1); + + PALETTE(config, "palette").set_entries(64); +} + +/* ROMs */ + +ROM_START( tekxp330 ) + ROM_REGION( 0x200000, "maincpu", 0 ) + /* TekXpress XP300 Boot ROM V1.0 Thu Feb 6 14:50:16 PST 1992 */ + ROM_LOAD32_DWORD( "xp300.bin", 0x000000, 0x200000, CRC(9a324588) SHA1(a6e10275f8215f446be91128bab4c643693da653) ) +ROM_END + +/* System Drivers */ + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1992, tekxp330, 0, 0, tekxp330, tekxp330, tekxp330_state, empty_init, "Tektronix", "TekXpress XP330", MACHINE_IS_SKELETON ) -- cgit v1.2.3