summaryrefslogtreecommitdiffstats
path: root/src/mame/drivers/adam.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/adam.c')
-rw-r--r--src/mame/drivers/adam.c1147
1 files changed, 1147 insertions, 0 deletions
diff --git a/src/mame/drivers/adam.c b/src/mame/drivers/adam.c
new file mode 100644
index 00000000000..75682bad25d
--- /dev/null
+++ b/src/mame/drivers/adam.c
@@ -0,0 +1,1147 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/***************************************************************************
+
+ Coleco Adam
+
+ The Coleco ADAM is a Z80-based micro with all peripheral devices
+ attached to an internal serial serial bus (ADAMnet) managed by 6801
+ microcontrollers (processor, internal RAM, internal ROM, serial port).Each
+ device had its own 6801, and the ADAMnet was managed by a "master" 6801 on
+ the ADAM motherboard. Each device was allotted a block of 21 bytes in Z80
+ address space; device control was accomplished by poking function codes into
+ the first byte of each device control block (hereafter DCB) after setup of
+ other DCB locations with such things as: buffer address in Z80 space, # of
+ bytes to transfer, block # to access if it was a block device like a tape
+ or disk drive, etc. The master 6801 would interpret this data, and pass
+ along internal ADAMnet requests to the desired peripheral, which would then
+ send/receive its data and return the status of the operation. The status
+ codes were left in the same byte of the DCB as the function request, and
+ certain bits of the status byte would reflect done/working on it/error/
+ not present, and error codes were left in another DCB byte for things like
+ CRC error, write protected disk, missing block, etc.
+
+ ADAM's ROM operating system, EOS (Elementary OS), was constructed
+ similar to CP/M in that it provided both a filesystem (like BDOS) and raw
+ device interface (BIOS). At the file level, sequential files could be
+ created, opened, read, written, appended, closed, and deleted. Forward-
+ only random access was implemented (you could not move the R/W pointer
+ backward, except clear to the beginning!), and all files had to be
+ contiguous on disk/tape. Directories could be initialized or searched
+ for a matching filename (no wildcards allowed). At the device level,
+ individual devices could be read/written by block (for disks/tapes) or
+ character-by-character (for printer, keyboard, and a prototype serial
+ board which was never released). Devices could be checked for their
+ ADAMnet status, and reset if necessary. There was no function provided
+ to do low-level formatting of disks/tapes.
+
+ At system startup, the EOS was loaded from ROM into the highest
+ 8K of RAM, a function call made to initialize the ADAMnet, and then
+ any disks or tapes were checked for a boot medium; if found, block 0 of
+ the medium was loaded in, and a jump made to the start of the boot code.
+ The boot block would take over loading in the rest of the program. If no
+ boot media were found, a jump would be made to a ROM word processor (called
+ SmartWriter).
+
+ Coleco designed the ADAMnet to have up to 15 devices attached.
+ Before they went bankrupt, Coleco had released a 64K memory expander and
+ a 300-baud internal modem, but surprisingly neither of these was an
+ ADAMnet device. Disassembly of the RAMdisk drivers in ADAM CP/M 2.2, and
+ of the ADAMlink terminal program revealed that these were simple port I/O
+ devices, banks of XRAM being accessed by a special memory switch port not
+ documented as part of the EOS. The modem did not even use the interrupt
+ capabilities of the Z80--it was simply polled. A combination serial/
+ parallel interface, each port of which *was* an ADAMnet device, reached the
+ prototype stage, as did a 5MB hard disk, but neither was ever released to
+ the public. (One prototype serial/parallel board is still in existence,
+ but the microcontroller ROMs have not yet been succcessfully read.) So
+ when Coleco finally bailed out of the computer business, a maximum ADAM
+ system consisted of a daisy wheel printer, a keyboard, 2 tape drives, and
+ 2 disk drives (all ADAMnet devices), a 64K expander and a 300-baud modem
+ (which were not ADAMnet devices).
+
+ Third-party vendors reverse-engineered the modem (which had a
+ 2651 UART at its heart) and made a popular serial interface board. It was
+ not an ADAMnet device, however, because nobody knew how to make a new ADAMnet
+ device (no design specs were ever released), and the 6801 microcontrollers
+ had unreadable mask ROMs. Disk drives, however, were easily upgraded from
+ 160K to as high as 1MB because, for some unknown reason, the disk controller
+ boards used a separate microprocessor and *socketed* EPROM (which was
+ promptly disassembled and reworked). Hard drives were cobbled together from
+ a Kaypro-designed board and accessed as standard I/O port devices. A parallel
+ interface card was similarly set up at its own I/O port.
+
+ Devices (15 max):
+ Device 0 = Master 6801 ADAMnet controller (uses the adam_pcb as DCB)
+ Device 1 = Keyboard
+ Device 2 = ADAM printer
+ Device 3 = Copywriter (projected)
+ Device 4 = Disk drive 1
+ Device 5 = Disk drive 2
+ Device 6 = Disk drive 3 (third party)
+ Device 7 = Disk drive 4 (third party)
+ Device 8 = Tape drive 1
+ Device 9 = Tape drive 3 (projected)
+ Device 10 = Unused
+ Device 11 = Non-ADAMlink modem
+ Device 12 = Hi-resolution monitor
+ Device 13 = ADAM parallel interface (never released)
+ Device 14 = ADAM serial interface (never released)
+ Device 15 = Gateway
+ Device 24 = Tape drive 2 (share DCB with Tape1)
+ Device 25 = Tape drive 4 (projected, may have share DCB with Tape3)
+ Device 26 = Expansion RAM disk drive (third party ID, not used by Coleco)
+
+ Terminology:
+ EOS = Elementary Operating System
+ DCB = Device Control Block Table (21bytes each DCB, DCB+16=dev#, DCB+0=Status Byte) (0xFD7C)
+
+ 0 Status byte
+ 1-2 Buffer start address (lobyte, hibyte)
+ 3-4 Buffer length (lobyte, hibyte)
+ 5-8 Block number accessed (loword, hiword in lobyte, hibyte format)
+ 9 High nibble of device number
+ 10-15 Always zero (unknown purpose)
+ 16 Low nibble of device number
+ 17-18 Maximum block length (lobyte, hibyte)
+ 19 Device type (0 for block device, 1 for character device)
+ 20 Node type
+
+ - Writing to byte0 requests the following operations:
+ 1 Return current status
+ 2 Soft reset
+ 3 Write
+ 4 Read
+
+
+ FCB = File Control Block Table (32bytes, 2 max each application) (0xFCB0)
+ OCB = Overlay Control Block Table
+ adam_pcb = Processor Control Block Table, 4bytes (adam_pcb+3 = Number of valid DCBs) (0xFEC0 relocatable), current adam_pcb=[0xFD70]
+ adam_pcb+0 = Status, 0=Request Status of Z80 -> must return 0x81..0x82 to sync Master 6801 clk with Z80 clk
+ adam_pcb+1,adam_pcb+2 = address of adam_pcb start
+ adam_pcb+3 = device #
+
+ - Writing to byte0:
+ 1 Synchronize the Z80 clock (should return 0x81)
+ 2 Synchronize the Master 6801 clock (should return 0x82)
+ 3 Relocate adam_pcb
+
+ - Status values:
+ 0x80 -> Success
+ 0x81 -> Z80 clock in sync
+ 0x82 -> Master 6801 clock in sync
+ 0x83 -> adam_pcb relocated
+ 0x9B -> Time Out
+
+ DEV_ID = Device id
+
+
+ The ColecoAdam I/O map is contolled by the MIOC (Memory Input Output Controller):
+
+ 20-3F (W) = Adamnet Writes
+ 20-3F (R) = Adamnet Reads
+
+ 42-42 (W) = Expansion RAM page selection, only useful if expansion greater than 64k
+
+ 40-40 (W) = Printer Data Out
+ 40-40 (R) = Printer (Returns 0x41)
+
+ 5E-5E (RW)= Modem Data I/O
+ 5F-5F (RW)= Modem Data Control Status
+
+ 60-7F (W) = Set Memory configuration
+ 60-7F (R) = Read Memory configuration
+
+ 80-9F (W) = Set both controllers to keypad mode
+ 80-9F (R) = Not Connected
+
+ A0-BF (W) = Video Chip (TMS9928A), A0=0 -> Write Register 0 , A0=1 -> Write Register 1
+ A0-BF (R) = Video Chip (TMS9928A), A0=0 -> Read Register 0 , A0=1 -> Read Register 1
+
+ C0-DF (W) = Set both controllers to joystick mode
+ C0-DF (R) = Not Connected
+
+ E0-FF (W) = Sound Chip (SN76489A)
+ E0-FF (R) = Read Controller data, A1=0 -> read controller 1, A1=1 -> read controller 2
+*/
+
+/*
+ Detailed Coleco ADAM Computer I/O Address Map
+
+Port # Device Input Output
+__________________________________________________________________________________________
+
+00 Powermate SASI Hard Drive Input Data Output Data
+01 Powermate SASI Hard Drive Status Register Command Register
+01 MIB2 RESET line * Not Used on MIB2 * Bit 3 = 1 for MIB2 RESET
+01 Powermate IDE Hard Drive Error Register * Not Used on IDE HD *
+02 Powermate IDE Hard Drive Sector Count Register Sector Count Register
+03 Powermate IDE Hard Drive Sector Number Register Sector Number Register
+04 Powermate IDE Hard Drive Cylinder Low Register Cylinder Low Register
+05 Powermate IDE Hard Drive Cylinder High Register Cylinder High Register
+06 Powermate IDE Hard Drive SDH Register SDH Register
+07 Powermate IDE Hard Drive Status Register Command Register
+08 Bonafide Sys MIDI Interface
+09 Bonafide Sys MIDI Interface
+0A Bonafide Sys MIDI Interface
+0B Bonafide Sys MIDI Interface
+0C Bonafide Sys MIDI Interface
+0D Bonafide Sys MIDI Interface
+0E Bonafide Sys MIDI Interface
+0F Bonafide Sys MIDI Interface
+10 Powermate Serial ports Mode Register A Mode Register A
+11 Powermate Serial ports Status Register A Clock Select Reg A
+12 Powermate Serial ports * DO NOT USE * Command Register A
+13 Powermate Serial ports RX Holding Register A TX Holding Reg A
+14 Powermate Serial ports Input Port Change Reg Aux Control Register
+15 Powermate Serial ports Interrupt Status Reg Interrupt Mask Reg
+16 Powermate Serial ports Read Counter Upper Set C/T Upper Register
+17 Powermate Serial ports Read Counter Lower Set C/T Lower Register
+18 Powermate Serial ports Mode Register B Mode Register B
+19 Powermate Serial ports Status Register B Clock Select Reg B
+1A Powermate Serial ports * DO NOT USE * Command Register B
+1B Powermate Serial ports RX Holding Register B TX Holding Register B
+1C Powermate Serial ports * Reserved (note 5) * MIB3 Serial Port RESET
+1D Powermate Serial ports Read Input Port Bits Output Port Config Reg
+1E Coleco AutoDialer ?? ??
+1E Powermate Serial ports Start Counter Cmd Port Set Output Port Bits
+1F Powermate Serial ports Stop Counter Cmd Port Reset Output Port Bits
+20-3F AdamNet Reset Input MAY be available Output is NOT available
+40 Parallel Printer interface Printer status Output Data
+41 May be unused (see note 1) Input may NOT be avail Output MAY be available
+42 Expansion Memory * Not Used * Bank Number
+43 May be unused (see note 1) Input may NOT be avail Output MAY be available
+44-47 Eve/Orphanware Serial Port
+48-4B Eve Speech Synth/Clock Card
+4C-4F Orphanware Serial Port 2 (Standard Eve 80 column terminal ports)
+4F Coleco Steering controller (Listed in Hackers guide as Expansion conn #2)
+50-53 Super Game Module
+54-57 Orphanware Serial Port 3 (Standard Orphanware 80 column terminal ports)
+58 Powermate IDE Hard Disk Input Data Lower 8 bits Output Data Lower 8 bits
+59 Powermate IDE Hard Disk Input Data Upper 8 bits Output Data Upper 8 bits
+5A Powermate IDE Hard Disk Alternate Status Reg Fixed Disk Control Reg
+5B Powermate IDE Hard Disk Digital Input Register ** Not Used by IDE HD **
+5C-5F Orphanware Serial Port 4
+5E Adamlink Modem Input Data Output Data
+5F Adamlink Modem Status Control
+60-7F Memory Bank Switch Port Input MAY be available Output is NOT available
+80-8F *** Unused *** (see note 2) STA (?)
+90-9F Orphanware Hard Drive STA (?)
+A0-BF Video Display Processor
+C0 Strobe Reset STB (?)
+C1-DF *** Unused *** (see note 2) STB (?)
+EO-FF Sound Chip (Out only)
+FC Joystick #1 (In only)
+FE Joystick #2 (In only)
+
+
+Notes:
+
+1) Port 41 or port 43 is used by the Eve 80 column unit as a keyboard input port.
+2) Not useable from expansion card slots (can't read or write data to or from ports) -
+ may be available on side port.
+3) Powermate IDE hard disk drive will not interfere with Powermate serial ports.
+4) Powermate serial ports will probably interfere with autodialer.
+5) Reserved ports in Powermate serial port map: Input ports 12 and 1A - screw up serial
+ ports if used; Input port 1C doesn't bother anything but the 2681 drives the bus;
+6) Orphanware serial port number 4 probably interferes with the ADAMlink modem.
+ 7) According to my analysis of circuit U6 in the ADAM computer, all of upper I/O address
+ space is decoded (by an LS138). However, not all outputs appear to be used. The
+ circuit description follows. Please correct any misassumptions I've made. Note that
+ if my analysis is correct, then the Orphanware hard disk should be interfering with
+ the signal STA\ (which is associated with the joysticks in some way).
+
+
+
+ U6
+ 74LS138 A6 A5 WR\
+ |--------------|
+ WR\ -----|A Y0|o---- 0 0 0 80-9F Write (STA\)
+ | |
+ A5 -----|B Y1|o---- 0 0 1 80-9F Read (Not Used)
+ | |
+ A6 -----|C Y2|o---- 0 1 0 A0-BF Write (VDP CSW\)
+ | |
+ A7 -----|G1 Y3|o---- 0 1 1 A0-BF Read (VDP CSR\)
+ | |
+IORQ\ ----o|G2A Y4|o---- 1 0 0 C0-DF Write (STB\)
+ | |
+WAIT\ ----o|G2B Y5|o---- 1 0 1 C0-DF Read (Not Used)
+ | |
+ | Y6|o---- 1 1 0 E0-FF Write (Sound CE\)
+ | |
+ | Y7|o---- 1 1 1 E0-FF Read (Joystick Enables)
+ |--------------|
+
+Conventions:
+
+1) The "o" symbol next to an input or an output implies that the pin requires an active
+ low signal.
+2) The "\" symbol following a signal mnemonic indicates that the signal is active low.
+
+
+Rev. 3
+8/30/92
+Mark Gordon
+*/
+
+/*
+
+ TODO:
+
+ - spinner INT
+ - printer
+ - SPI
+
+ http://drushel.cwru.edu/atm/atm.html
+ http://rich.dirocco.org/Coleco/adam/ADAM.htm
+ http://users.stargate.net/~drushel/pub/coleco/twwmca/index.html
+
+*/
+
+#include "includes/adam.h"
+
+
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+enum
+{
+ LO_SMARTWRITER = 0,
+ LO_INTERNAL_RAM,
+ LO_RAM_EXPANSION,
+ LO_OS7_ROM_INTERNAL_RAM
+};
+
+
+enum
+{
+ HI_INTERNAL_RAM = 0,
+ HI_ROM_EXPANSION,
+ HI_RAM_EXPANSION,
+ HI_CARTRIDGE_ROM
+};
+
+
+enum
+{
+ ADAMNET_MASTER = 0,
+ ADAMNET_KEYBOARD,
+ ADAMNET_DDP,
+ ADAMNET_PRINTER,
+ ADAMNET_FDC
+};
+
+
+
+//**************************************************************************
+// MEMORY BANKING
+//**************************************************************************
+
+//-------------------------------------------------
+// mreq_r - memory request read
+//-------------------------------------------------
+
+READ8_MEMBER( adam_state::mreq_r )
+{
+ int bmreq = 0, biorq = 1, eos_enable = 1, boot_rom_cs = 1, aux_decode_1 = 1, aux_rom_cs = 1, cas1 = 1, cas2 = 1, cs1 = 1, cs2 = 1, cs3 = 1, cs4 = 1;
+
+ UINT8 data = 0;
+
+ if (offset < 0x8000)
+ {
+ switch (m_mioc & 0x03)
+ {
+ case LO_SMARTWRITER:
+ boot_rom_cs = 0;
+ eos_enable = BIT(m_an, 1);
+ break;
+
+ case LO_INTERNAL_RAM:
+ cas1 = 0;
+ break;
+
+ case LO_RAM_EXPANSION:
+ cas2 = 0;
+ break;
+
+ case LO_OS7_ROM_INTERNAL_RAM:
+ if (offset < 0x2000)
+ {
+ aux_decode_1 = 0;
+ }
+ else
+ {
+ cas1 = 0;
+ }
+ break;
+ }
+ }
+ else
+ {
+ switch ((m_mioc >> 2) & 0x03)
+ {
+ case HI_INTERNAL_RAM:
+ cas1 = 0;
+ break;
+
+ case HI_ROM_EXPANSION:
+ aux_rom_cs = 0;
+ break;
+
+ case HI_RAM_EXPANSION:
+ if (m_game)
+ {
+ aux_decode_1 = 0;
+ }
+ else
+ {
+ cas2 = 0;
+ }
+ break;
+
+ case HI_CARTRIDGE_ROM:
+ aux_decode_1 = 0;
+ break;
+ }
+ }
+
+ if (!cas1)
+ {
+ data = m_ram->pointer()[offset];
+ }
+
+ if (!boot_rom_cs)
+ {
+ if (offset < 0x6000)
+ {
+ data = m_boot_rom->base()[offset];
+ }
+ else
+ {
+ data = m_boot_rom->base()[(eos_enable << 13) + offset];
+ }
+ }
+
+ if (!aux_decode_1)
+ {
+ switch (offset >> 13)
+ {
+ case 0: // U2
+ data = m_os7_rom->base()[offset];
+ break;
+
+ case 1: break;
+ case 2: break;
+
+ case 4:
+ cs1 = 0;
+ break;
+
+ case 5:
+ cs2 = 0;
+ break;
+
+ case 6:
+ cs3 = 0;
+ break;
+
+ case 7:
+ cs4 = 0;
+ break;
+ }
+ }
+
+ data = m_cart->bd_r(space, offset & 0x7fff, data, cs1, cs2, cs3, cs4);
+ data = m_slot1->bd_r(space, offset & 0xff, data, 1, biorq, 1, 1, 1);
+ data = m_slot2->bd_r(space, offset, data, bmreq, biorq, aux_rom_cs, 1, cas2);
+ data = m_slot3->bd_r(space, offset, data, 1, 1, 1, cas1, cas2);
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// mreq_w - memory request write
+//-------------------------------------------------
+
+WRITE8_MEMBER( adam_state::mreq_w )
+{
+ int bmreq = 0, biorq = 1, aux_rom_cs = 1, cas1 = 1, cas2 = 1;
+
+ if (offset < 0x8000)
+ {
+ switch (m_mioc & 0x03)
+ {
+ case LO_INTERNAL_RAM:
+ cas1 = 0;
+ break;
+
+ case LO_RAM_EXPANSION:
+ cas2 = 0;
+ break;
+
+ case LO_OS7_ROM_INTERNAL_RAM:
+ if (offset >= 0x2000)
+ {
+ cas1 = 0;
+ }
+ break;
+ }
+ }
+ else
+ {
+ switch ((m_mioc >> 2) & 0x03)
+ {
+ case HI_INTERNAL_RAM:
+ cas1 = 0;
+ break;
+
+ case HI_RAM_EXPANSION:
+ if (!m_game)
+ {
+ cas2 = 0;
+ }
+ break;
+ }
+ }
+
+ if (!cas1)
+ {
+ m_ram->pointer()[offset] = data;
+ }
+
+ m_slot1->bd_w(space, offset & 0xff, data, 1, biorq, 1, 1, 1);
+ m_slot2->bd_w(space, offset, data, bmreq, biorq, aux_rom_cs, 1, cas2);
+ m_slot3->bd_w(space, offset, data, 1, 1, 1, cas1, cas2);
+}
+
+
+//-------------------------------------------------
+// iorq_r - I/O request read
+//-------------------------------------------------
+
+READ8_MEMBER( adam_state::iorq_r )
+{
+ int bmreq = 1, biorq = 0, aux_rom_cs = 1, cas1 = 1, cas2 = 1;
+
+ UINT8 data = 0;
+
+ switch ((offset >> 5) & 0x07)
+ {
+ case 1:
+ data = adamnet_r(space, 0);
+ break;
+
+ case 3:
+ data = mioc_r(space, 0);
+ break;
+
+ case 5:
+ if (BIT(offset, 0))
+ {
+ data = m_vdc->register_read(space, 0);
+ }
+ else
+ {
+ data = m_vdc->vram_read(space, 0);
+ }
+ break;
+
+ case 7:
+ if (BIT(offset, 1))
+ {
+ data = m_joy2->read();
+ }
+ else
+ {
+ data = m_joy1->read();
+ }
+ break;
+ }
+
+ data = m_slot1->bd_r(space, offset & 0xff, data, 1, biorq, 1, 1, 1);
+ data = m_slot2->bd_r(space, offset, data, bmreq, biorq, aux_rom_cs, 1, cas2);
+ data = m_slot3->bd_r(space, offset, data, 1, 1, 1, cas1, cas2);
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// iorq_w - I/O request write
+//-------------------------------------------------
+
+WRITE8_MEMBER( adam_state::iorq_w )
+{
+ int bmreq = 1, biorq = 0, aux_rom_cs = 1, cas1 = 1, cas2 = 1;
+
+ switch ((offset >> 5) & 0x07)
+ {
+ case 1:
+ adamnet_w(space, 0, data);
+ break;
+
+ case 3:
+ mioc_w(space, 0, data);
+ break;
+
+ case 4:
+ m_joy1->common0_w(1);
+ m_joy1->common1_w(0);
+ m_joy2->common0_w(1);
+ m_joy2->common1_w(0);
+ break;
+
+ case 5:
+ if (BIT(offset, 0))
+ {
+ m_vdc->register_write(space, 0, data);
+ }
+ else
+ {
+ m_vdc->vram_write(space, 0, data);
+ }
+ break;
+
+ case 6:
+ m_joy1->common0_w(0);
+ m_joy1->common1_w(1);
+ m_joy2->common0_w(0);
+ m_joy2->common1_w(1);
+ break;
+
+ case 7:
+ m_psg->write(space, 0, data);
+ break;
+ }
+
+ m_slot1->bd_w(space, offset & 0xff, data, 1, biorq, 1, 1, 1);
+ m_slot2->bd_w(space, offset, data, bmreq, biorq, aux_rom_cs, 1, cas2);
+ m_slot3->bd_w(space, offset, data, 1, 1, 1, cas1, cas2);
+}
+
+
+//-------------------------------------------------
+// mioc_r -
+//-------------------------------------------------
+
+READ8_MEMBER( adam_state::mioc_r )
+{
+ return m_mioc & 0x0f;
+}
+
+
+//-------------------------------------------------
+// mioc_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( adam_state::mioc_w )
+{
+ /*
+
+ bit description
+
+ 0 Lower memory option 0
+ 1 Lower memory option 1
+ 2 Upper memory option 0
+ 3 Upper memory option 1
+ 4
+ 5
+ 6
+ 7
+
+ */
+
+ m_mioc = data;
+}
+
+
+
+//**************************************************************************
+// ADAMNET
+//**************************************************************************
+
+//-------------------------------------------------
+// adamnet_r -
+//-------------------------------------------------
+
+READ8_MEMBER( adam_state::adamnet_r )
+{
+ return m_an & 0x0f;
+}
+
+
+//-------------------------------------------------
+// adamnet_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( adam_state::adamnet_w )
+{
+ /*
+
+ bit description
+
+ 0 Network reset
+ 1 EOS enable
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+
+ */
+
+ if (BIT(m_an, 0) && !BIT(data, 0))
+ {
+ // network reset
+ m_adamnet->reset_w(ASSERT_LINE);
+ m_adamnet->reset_w(CLEAR_LINE);
+ }
+
+ m_an = data;
+}
+
+
+//-------------------------------------------------
+// m6801_p1_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( adam_state::m6801_p1_w )
+{
+ /*
+
+ bit description
+
+ 0 BA8
+ 1 BA9
+ 2 BA10
+ 3 BA11
+ 4 BA12
+ 5 BA13
+ 6 BA14
+ 7 BA15
+
+ */
+
+ m_ba = (data << 8) | (m_ba & 0xff);
+}
+
+
+//-------------------------------------------------
+// m6801_p2_r -
+//-------------------------------------------------
+
+READ8_MEMBER( adam_state::m6801_p2_r )
+{
+ /*
+
+ bit description
+
+ 0 M6801 mode bit 0
+ 1 M6801 mode bit 1
+ 2 M6801 mode bit 2
+ 3 NET RXD
+ 4
+
+ */
+
+ UINT8 data = M6801_MODE_7;
+
+ // NET RXD
+ data |= m_adamnet->rxd_r() << 3;
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// m6801_p2_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( adam_state::m6801_p2_w )
+{
+ /*
+
+ bit description
+
+ 0 _DMA
+ 1
+ 2 _BWR
+ 3
+ 4 NET TXD
+
+ */
+
+ // DMA
+ m_dma = BIT(data, 0);
+
+ // write
+ m_bwr = BIT(data, 2);
+
+ // NET TXD
+ m_adamnet->txd_w(BIT(data, 4));
+}
+
+
+//-------------------------------------------------
+// m6801_p3_r -
+//-------------------------------------------------
+
+READ8_MEMBER( adam_state::m6801_p3_r )
+{
+ /*
+
+ bit description
+
+ 0 BD0
+ 1 BD1
+ 2 BD2
+ 3 BD3
+ 4 BD4
+ 5 BD5
+ 6 BD6
+ 7 BD7
+
+ */
+
+ return m_data_out;
+}
+
+
+//-------------------------------------------------
+// m6801_p3_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( adam_state::m6801_p3_w )
+{
+ /*
+
+ bit description
+
+ 0 BD0
+ 1 BD1
+ 2 BD2
+ 3 BD3
+ 4 BD4
+ 5 BD5
+ 6 BD6
+ 7 BD7
+
+ */
+
+ m_data_in = data;
+}
+
+
+//-------------------------------------------------
+// m6801_p4_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( adam_state::m6801_p4_w )
+{
+ /*
+
+ bit description
+
+ 0 BA0
+ 1 BA1
+ 2 BA2
+ 3 BA3
+ 4 BA4
+ 5 BA5
+ 6 BA6
+ 7 BA7
+
+ */
+
+ m_ba = (m_ba & 0xff00) | data;
+}
+
+
+
+//**************************************************************************
+// ADDRESS MAPS
+//**************************************************************************
+
+//-------------------------------------------------
+// ADDRESS_MAP( adam_mem )
+//-------------------------------------------------
+
+static ADDRESS_MAP_START( adam_mem, AS_PROGRAM, 8, adam_state )
+ AM_RANGE(0x0000, 0xffff) AM_READWRITE(mreq_r, mreq_w)
+ADDRESS_MAP_END
+
+
+//-------------------------------------------------
+// ADDRESS_MAP( adam_io )
+//-------------------------------------------------
+
+static ADDRESS_MAP_START( adam_io, AS_IO, 8, adam_state )
+ AM_RANGE(0x0000, 0xffff) AM_READWRITE(iorq_r, iorq_w)
+ADDRESS_MAP_END
+
+
+//-------------------------------------------------
+// ADDRESS_MAP( m6801_mem )
+//-------------------------------------------------
+
+static ADDRESS_MAP_START( m6801_mem, AS_PROGRAM, 8, adam_state )
+ AM_RANGE(0x0000, 0x001f) AM_DEVREADWRITE(M6801_TAG, m6801_cpu_device, m6801_io_r, m6801_io_w)
+ AM_RANGE(0x0080, 0x00ff) AM_RAM
+ AM_RANGE(0xf800, 0xffff) AM_ROM AM_REGION(M6801_TAG, 0)
+ADDRESS_MAP_END
+
+
+//-------------------------------------------------
+// ADDRESS_MAP( m6801_io )
+//-------------------------------------------------
+
+static ADDRESS_MAP_START( m6801_io, AS_IO, 8, adam_state )
+ AM_RANGE(M6801_PORT1, M6801_PORT1) AM_WRITE(m6801_p1_w)
+ AM_RANGE(M6801_PORT2, M6801_PORT2) AM_READWRITE(m6801_p2_r, m6801_p2_w)
+ AM_RANGE(M6801_PORT3, M6801_PORT3) AM_READWRITE(m6801_p3_r, m6801_p3_w)
+ AM_RANGE(M6801_PORT4, M6801_PORT4) AM_WRITE(m6801_p4_w)
+ADDRESS_MAP_END
+
+
+
+//**************************************************************************
+// INPUT PORTS
+//**************************************************************************
+
+//-------------------------------------------------
+// INPUT_PORTS( adam )
+//-------------------------------------------------
+
+static INPUT_PORTS_START( adam )
+ // defined in bus/adamnet/kb.c
+INPUT_PORTS_END
+
+
+
+//**************************************************************************
+// DEVICE CONFIGURATION
+//**************************************************************************
+
+//-------------------------------------------------
+// TMS9928A_INTERFACE( vdc_intf )
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( adam_state::vdc_int_w )
+{
+ if (state && !m_vdp_nmi)
+ {
+ m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
+ }
+
+ m_vdp_nmi = state;
+}
+
+//-------------------------------------------------
+// M6801_INTERFACE( m6801_intf )
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( adam_state::os3_w )
+{
+ if (state && !m_dma)
+ {
+ if (!m_bwr)
+ {
+ //logerror("Master 6801 write to %04x data %02x\n", m_ba, m_data_in);
+
+ m_ram->pointer()[m_ba] = m_data_in;
+ }
+ else
+ {
+ m_data_out = m_ram->pointer()[m_ba];
+
+ //logerror("Master 6801 read from %04x data %02x\n", m_ba, m_data_out);
+
+ m_netcpu->set_input_line(M6801_SC1_LINE, ASSERT_LINE);
+ m_netcpu->set_input_line(M6801_SC1_LINE, CLEAR_LINE);
+ }
+ }
+}
+
+
+WRITE_LINE_MEMBER( adam_state::joy1_irq_w )
+{
+ // TODO
+}
+
+WRITE_LINE_MEMBER( adam_state::joy2_irq_w )
+{
+ // TODO
+}
+
+
+
+//**************************************************************************
+// MACHINE INITIALIZATION
+//**************************************************************************
+
+//-------------------------------------------------
+// MACHINE_START( adam )
+//-------------------------------------------------
+
+void adam_state::machine_start()
+{
+ // state saving
+ save_item(NAME(m_mioc));
+ save_item(NAME(m_game));
+ save_item(NAME(m_an));
+ save_item(NAME(m_ba));
+ save_item(NAME(m_dma));
+ save_item(NAME(m_bwr));
+ save_item(NAME(m_data_in));
+ save_item(NAME(m_data_out));
+ save_item(NAME(m_spindis));
+ save_item(NAME(m_vdp_nmi));
+}
+
+
+void adam_state::machine_reset()
+{
+ if (m_cart->exists())
+ {
+ // game reset
+ m_game = 1;
+ m_mioc = (HI_CARTRIDGE_ROM << 2) | LO_OS7_ROM_INTERNAL_RAM;
+ }
+ else
+ {
+ // computer reset
+ m_game = 0;
+ m_mioc = 0;
+ }
+
+ m_an = 0;
+
+ m_maincpu->reset();
+ m_netcpu->reset();
+}
+
+
+
+//**************************************************************************
+// MACHINE CONFIGURATION
+//**************************************************************************
+
+//-------------------------------------------------
+// DEVICE_INPUT_DEFAULTS( drive2 )
+//-------------------------------------------------
+
+DEVICE_INPUT_DEFAULTS_START( drive2 )
+ DEVICE_INPUT_DEFAULTS("SW3", 0x01, 0x01)
+DEVICE_INPUT_DEFAULTS_END
+
+
+//-------------------------------------------------
+// MACHINE_CONFIG( adam )
+//-------------------------------------------------
+
+static MACHINE_CONFIG_START( adam, adam_state )
+ // basic machine hardware
+ MCFG_CPU_ADD(Z80_TAG, Z80, XTAL_7_15909MHz/2)
+ MCFG_CPU_PROGRAM_MAP(adam_mem)
+ MCFG_CPU_IO_MAP(adam_io)
+
+ MCFG_CPU_ADD(M6801_TAG, M6801, XTAL_4MHz)
+ MCFG_CPU_PROGRAM_MAP(m6801_mem)
+ MCFG_CPU_IO_MAP(m6801_io)
+ MCFG_M6801_SC2(WRITELINE(adam_state, os3_w))
+ MCFG_QUANTUM_PERFECT_CPU(M6801_TAG)
+
+ // video hardware
+ MCFG_DEVICE_ADD(TMS9928A_TAG, TMS9928A, XTAL_10_738635MHz / 2 )
+ MCFG_TMS9928A_VRAM_SIZE(0x4000)
+ MCFG_TMS9928A_OUT_INT_LINE_CB(WRITELINE(adam_state, vdc_int_w))
+ MCFG_TMS9928A_SCREEN_ADD_NTSC(SCREEN_TAG)
+ MCFG_SCREEN_UPDATE_DEVICE(TMS9928A_TAG, tms9928a_device, screen_update)
+
+ // sound hardware
+ MCFG_SPEAKER_STANDARD_MONO("mono")
+ MCFG_SOUND_ADD(SN76489A_TAG, SN76489A, XTAL_7_15909MHz/2)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
+ MCFG_SN76496_READY_HANDLER(INPUTLINE(Z80_TAG, Z80_INPUT_LINE_WAIT))
+
+ // devices
+ MCFG_ADAMNET_BUS_ADD()
+ MCFG_ADAMNET_SLOT_ADD("net1", adamnet_devices, "kb")
+ MCFG_ADAMNET_SLOT_ADD("net2", adamnet_devices, "prn")
+ MCFG_ADAMNET_SLOT_ADD("net3", adamnet_devices, "ddp")
+ MCFG_ADAMNET_SLOT_ADD("net4", adamnet_devices, "fdc")
+ MCFG_ADAMNET_SLOT_ADD("net5", adamnet_devices, "fdc")
+ MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("fdc", drive2)
+ MCFG_ADAMNET_SLOT_ADD("net6", adamnet_devices, NULL)
+ MCFG_ADAMNET_SLOT_ADD("net7", adamnet_devices, NULL)
+ MCFG_ADAMNET_SLOT_ADD("net8", adamnet_devices, NULL)
+ MCFG_ADAMNET_SLOT_ADD("net9", adamnet_devices, NULL)
+ MCFG_ADAMNET_SLOT_ADD("net10", adamnet_devices, NULL)
+ MCFG_ADAMNET_SLOT_ADD("net11", adamnet_devices, NULL)
+ MCFG_ADAMNET_SLOT_ADD("net12", adamnet_devices, NULL)
+ MCFG_ADAMNET_SLOT_ADD("net13", adamnet_devices, NULL)
+ MCFG_ADAMNET_SLOT_ADD("net14", adamnet_devices, NULL)
+ MCFG_ADAMNET_SLOT_ADD("net15", adamnet_devices, NULL)
+
+ MCFG_COLECOVISION_CARTRIDGE_SLOT_ADD(COLECOVISION_CARTRIDGE_SLOT_TAG, colecovision_cartridges, NULL)
+ MCFG_ADAM_EXPANSION_SLOT_ADD(ADAM_LEFT_EXPANSION_SLOT_TAG, XTAL_7_15909MHz/2, adam_slot1_devices, "adamlink")
+ MCFG_ADAM_EXPANSION_SLOT_IRQ_CALLBACK(INPUTLINE(Z80_TAG, INPUT_LINE_IRQ0))
+ MCFG_ADAM_EXPANSION_SLOT_ADD(ADAM_CENTER_EXPANSION_SLOT_TAG, XTAL_7_15909MHz/2, adam_slot2_devices, NULL)
+ MCFG_ADAM_EXPANSION_SLOT_IRQ_CALLBACK(INPUTLINE(Z80_TAG, INPUT_LINE_IRQ0))
+ MCFG_ADAM_EXPANSION_SLOT_ADD(ADAM_RIGHT_EXPANSION_SLOT_TAG, XTAL_7_15909MHz/2, adam_slot3_devices, "ram")
+
+ MCFG_COLECOVISION_CONTROL_PORT_ADD(CONTROL1_TAG, colecovision_control_port_devices, "hand")
+ MCFG_COLECOVISION_CONTROL_PORT_IRQ_CALLBACK(WRITELINE(adam_state, joy1_irq_w))
+ MCFG_COLECOVISION_CONTROL_PORT_ADD(CONTROL2_TAG, colecovision_control_port_devices, NULL)
+ MCFG_COLECOVISION_CONTROL_PORT_IRQ_CALLBACK(WRITELINE(adam_state, joy2_irq_w))
+
+ // internal ram
+ MCFG_RAM_ADD(RAM_TAG)
+ MCFG_RAM_DEFAULT_SIZE("64K")
+
+ // software lists
+ MCFG_SOFTWARE_LIST_ADD("colec_cart_list", "coleco")
+ MCFG_SOFTWARE_LIST_ADD("adam_cart_list", "adam_cart")
+ MCFG_SOFTWARE_LIST_ADD("cass_list", "adam_cass")
+ MCFG_SOFTWARE_LIST_ADD("flop_list", "adam_flop")
+MACHINE_CONFIG_END
+
+
+
+//**************************************************************************
+// ROMS
+//**************************************************************************
+
+//-------------------------------------------------
+// ROM( adam )
+//-------------------------------------------------
+
+ROM_START( adam )
+ ROM_REGION( 0x2000, "os7", 0)
+ ROM_LOAD( "os7.u2", 0x0000, 0x2000, CRC(3aa93ef3) SHA1(45bedc4cbdeac66c7df59e9e599195c778d86a92) )
+
+ ROM_REGION( 0xa000, "boot", 0)
+ ROM_LOAD( "alf #1 rev 57 e3d5.u8", 0x0000, 0x2000, CRC(565b364a) SHA1(ebdafad6e268e7ed1674c1fb89607622748a5b36) )
+ ROM_LOAD( "alf #2 rev 57 ae6a.u20", 0x2000, 0x2000, CRC(44a1cff4) SHA1(661cdf36d9699d6c21c5f9e205ebc41c707359dd) )
+ ROM_LOAD( "alf #3 rev 57 8534.u21", 0x4000, 0x2000, CRC(77657b90) SHA1(d25d32ab6c8fafbc21b4b925b3e644fa26d111f7) )
+ ROM_LOAD( "eos 6 rev 57 08dd.u22", 0x8000, 0x2000, CRC(ef6403c5) SHA1(28c7616cd02e4286f9b4c1c4a8b8850832b49fcb) )
+ ROM_CONTINUE( 0x6000, 0x2000 )
+ ROM_LOAD( "wp_r80.rom", 0x0000, 0x8000, BAD_DUMP CRC(58d86a2a) SHA1(d4aec4efe1431e56fe52d83baf9118542c525255) ) // should be separate 8/16K ROMs
+
+ ROM_REGION( 0x800, M6801_TAG, 0 )
+ ROM_LOAD( "master rev a 174b.u6", 0x000, 0x800, CRC(035a7a3d) SHA1(0426e6eaf18c2be9fe08066570c214ab5951ee14) )
+ROM_END
+
+
+
+//**************************************************************************
+// SYSTEM DRIVERS
+//**************************************************************************
+
+// YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS
+COMP( 1982, adam, 0, coleco, adam, adam, driver_device, 0, "Coleco", "Adam", MACHINE_SUPPORTS_SAVE )