Added driver for Heurikon HK68K/V10 VME board

Added some SCC support in the z80dart driver
This commit is contained in:
Joakim Larsson Edström 2015-08-30 14:04:51 +02:00
parent d32cc1334d
commit 807bdf0a06
5 changed files with 613 additions and 17 deletions

View File

@ -736,6 +736,7 @@ function linkProjects_mame_mess(_target, _subtarget)
"heathkit",
"hec2hrp",
"hegener",
"heurikon",
"hitachi",
"homebrew",
"homelab",
@ -1635,6 +1636,11 @@ files {
MAME_DIR .. "src/mess/drivers/interact.c",
}
createMESSProjects(_target, _subtarget, "heurikon")
files {
MAME_DIR .. "src/mess/drivers/hk68v10.c",
}
createMESSProjects(_target, _subtarget, "intel")
files {
MAME_DIR .. "src/mess/drivers/basic52.c",

View File

@ -6,6 +6,7 @@
NEC uPD7201 Multiprotocol Serial Communications Controller emulation
Z80-DART Dual Asynchronous Receiver/Transmitter emulation
Z80-SIO/0/1/2/3/4 Serial Input/Output Controller emulation
Z80-SCC Serial Communications Controller emulation (experimental)
The z80dart/z80sio itself is based on an older intel serial chip, the i8274 MPSC
(see http://doc.chipfind.ru/pdf/intel/8274.pdf), which also has almost identical
@ -13,6 +14,10 @@
scheme which uses write register 2 on channel A, that register which is unused on
the z80dart and z80sio.
The z80scc is an updated version of the z80sio, with additional support for CRC
checks and a number of data link layer protocols such as HDLC, SDLC and BiSync.
(See https://en.wikipedia.org/wiki/Zilog_SCC).
***************************************************************************/
/*
@ -25,8 +30,9 @@
- wait/ready
- 1.5 stop bits
- synchronous mode (Z80-SIO/1,2)
- SDLC mode (Z80-SIO/1,2)
- SDLC mode (Z80-SIO/1,2/SCC)
- HDLC, BiSync support (Z80-SCC)
- CRC support (Z80-SCC)
*/
#include "z80dart.h"
@ -60,6 +66,7 @@ const device_type Z80SIO3 = &device_creator<z80sio3_device>;
const device_type Z80SIO4 = &device_creator<z80sio4_device>;
const device_type I8274 = &device_creator<i8274_device>;
const device_type UPD7201 = &device_creator<upd7201_device>;
const device_type Z80SCC = &device_creator<scc8530_device>;
//-------------------------------------------------
@ -181,6 +188,11 @@ upd7201_device::upd7201_device(const machine_config &mconfig, const char *tag, d
{
}
scc8530_device::scc8530_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: z80dart_device(mconfig, Z80SCC, "Z80 SCC", tag, owner, clock, TYPE_Z80SCC, "z80scc", __FILE__)
{
}
//-------------------------------------------------
// device_start - device-specific startup
@ -438,6 +450,10 @@ READ8_MEMBER( z80dart_device::cd_ba_r )
int cd = BIT(offset, 1);
z80dart_channel *channel = ba ? m_chanB : m_chanA;
cd = (m_variant == TYPE_Z80SCC) ? !cd : cd; // Inverted logic on SCC
// LOG(("z80dart_device::cd_ba_r ba:%02x cd:%02x\n", ba, cd));
return cd ? channel->control_read() : channel->data_read();
}
@ -452,6 +468,10 @@ WRITE8_MEMBER( z80dart_device::cd_ba_w )
int cd = BIT(offset, 1);
z80dart_channel *channel = ba ? m_chanB : m_chanA;
cd = (m_variant == TYPE_Z80SCC) ? !cd : cd; // Inverted logic on SCC
// LOG(("z80dart_device::cd_ba_w ba:%02x cd:%02x\n", ba, cd));
if (cd)
channel->control_write(data);
else
@ -469,6 +489,10 @@ READ8_MEMBER( z80dart_device::ba_cd_r )
int cd = BIT(offset, 0);
z80dart_channel *channel = ba ? m_chanB : m_chanA;
cd = (m_variant == TYPE_Z80SCC) ? !cd : cd; // Inverted logic on SCC
// LOG(("z80dart_device::ba_cd_r ba:%02x cd:%02x\n", ba, cd));
return cd ? channel->control_read() : channel->data_read();
}
@ -483,14 +507,16 @@ WRITE8_MEMBER( z80dart_device::ba_cd_w )
int cd = BIT(offset, 0);
z80dart_channel *channel = ba ? m_chanB : m_chanA;
cd = (m_variant == TYPE_Z80SCC) ? !cd : cd; // Inverted logic on SCC
LOG(("z80dart_device::ba_cd_w ba:%02x cd:%02x\n", ba, cd));
if (cd)
channel->control_write(data);
else
channel->data_write(data);
}
//**************************************************************************
// DART CHANNEL
//**************************************************************************
@ -518,10 +544,10 @@ z80dart_channel::z80dart_channel(const machine_config &mconfig, const char *tag,
m_rts(0),
m_sync(0)
{
for (int i = 0; i < 3; i++)
for (int i = 0; i < sizeof(m_rr); i++)
m_rr[i] = 0;
for (int i = 0; i < 6; i++)
for (int i = 0; i < sizeof(m_wr); i++)
m_wr[i] = 0;
for (int i = 0; i < 3; i++)
@ -540,6 +566,7 @@ void z80dart_channel::device_start()
{
m_uart = downcast<z80dart_device *>(owner());
m_index = m_uart->get_channel_index(this);
m_ph = 0;
// state saving
save_item(NAME(m_rr));
@ -560,6 +587,7 @@ void z80dart_channel::device_start()
save_item(NAME(m_dtr));
save_item(NAME(m_rts));
save_item(NAME(m_sync));
save_item(NAME(m_ph));
device_serial_interface::register_save_state(machine().save(), this);
}
@ -787,13 +815,17 @@ int z80dart_channel::get_tx_word_length()
UINT8 z80dart_channel::control_read()
{
UINT8 data = 0;
int reg = m_wr[0];
int regmask = (WR0_REGISTER_MASK | m_ph);
int reg = m_wr[0] & WR0_REGISTER_MASK;
m_ph = 0; // The "Point High" command is only valid for one access
reg &= regmask;
if (reg != 0)
{
// mask out register index
m_wr[0] &= ~WR0_REGISTER_MASK;
m_wr[0] &= ~regmask;
}
switch (reg)
@ -808,9 +840,33 @@ UINT8 z80dart_channel::control_read()
if (m_index == z80dart_device::CHANNEL_B)
data = m_rr[reg];
break;
/* registers 4-7 are specific to SCC. TODO: Check variant and log/stop misuse */
case 4: /* (ESCC and 85C30 Only) */
/*On the ESCC, Read Register 4 reflects the contents of Write Register 4 provided the Extended
Read option is enabled. Otherwise, this register returns an image of RR0. On the NMOS/CMOS version,
a read to this location returns an image of RR0.*/
case 5: /* (ESCC and 85C30 Only) */
/*On the ESCC, Read Register 5 reflects the contents of Write Register 5 provided the Extended
Read option is enabled. Otherwise, this register returns an image of RR1. On the NMOS/CMOS version,
a read to this register returns an image of RR1.*/
data = BIT(m_wr[7], 6) ? m_wr[reg] : m_rr[reg - 4];
break;
/* registers 8-15 are specific to SCC and misuse captured by test around Point High command in control_write() */
case 8:
data = data_read();
break;
case 10:
data = 0;
LOG(("Z80DART Read Register 10 Misc Status Bits, SDLC related, not implemented yet.\n"));
break;
case 13:
data = m_wr[13];
break;
default:
logerror("Z80DART \"%s\" Channel %c : Unsupported RRx register:%02x\n", m_owner->tag(), 'A' + m_index, reg);
}
//LOG(("Z80DART \"%s\" Channel %c : Control Register Read '%02x'\n", m_owner->tag(), 'A' + m_index, data));
//LOG(("Z80DART \"%s\" Channel %c : Register R%d read '%02x'\n", m_owner->tag(), 'A' + m_index, reg, data));
return data;
}
@ -822,9 +878,13 @@ UINT8 z80dart_channel::control_read()
void z80dart_channel::control_write(UINT8 data)
{
int reg = m_wr[0] & WR0_REGISTER_MASK;
int reg = m_wr[0];
int regmask = (WR0_REGISTER_MASK | m_ph);
m_ph = 0; // The "Point High" command is only valid for one access
reg &= regmask;
LOG(("Z80DART \"%s\" Channel %c : Control Register Write '%02x'\n", m_owner->tag(), 'A' + m_index, data));
// write data to selected register
if (reg < 6)
@ -833,9 +893,11 @@ void z80dart_channel::control_write(UINT8 data)
if (reg != 0)
{
// mask out register index
m_wr[0] &= ~WR0_REGISTER_MASK;
m_wr[0] &= ~regmask;
}
LOG(("reg %02x, regmask %02x, WR0 %02x, data %02x\n", reg, regmask, m_wr[0], data));
switch (reg)
{
case 0:
@ -845,9 +907,21 @@ void z80dart_channel::control_write(UINT8 data)
LOG(("Z80DART \"%s\" Channel %c : Null\n", m_owner->tag(), 'A' + m_index));
break;
//case WR0_POINT_HIGH: // Same value so doesn't compile...
case WR0_SEND_ABORT:
LOG(("Z80DART \"%s\" Channel %c : Send Abort\n", m_owner->tag(), 'A' + m_index));
logerror("Z80DART \"%s\" Channel %c : unsupported command: Send Abort\n", m_owner->tag(), 'A' + m_index);
if (((z80dart_device *)m_owner)->m_variant == z80dart_device::TYPE_Z80SCC)
{
/* This is the Point High command for SCC, it will latch access to the high
registers for the next read or write to the control registers */
LOG(("Z80DART \"%s\" Channel %c : Point High\n", m_owner->tag(), 'A' + m_index));
m_ph = 8;
}
else
{
/* Send Abort is only valid for the original Z80 SIO, not the DART or SCC */
LOG(("Z80DART \"%s\" Channel %c : Send Abort\n", m_owner->tag(), 'A' + m_index));
logerror("Z80DART \"%s\" Channel %c : unsupported command: Send Abort\n", m_owner->tag(), 'A' + m_index);
}
break;
case WR0_RESET_EXT_STATUS:
@ -892,6 +966,8 @@ void z80dart_channel::control_write(UINT8 data)
LOG(("Z80DART \"%s\" Channel %c : Return from Interrupt\n", m_owner->tag(), 'A' + m_index));
m_uart->z80daisy_irq_reti();
break;
default:
logerror("Z80DART \"%s\" Channel %c : Unsupported WR0 command:%02x\n", m_owner->tag(), 'A' + m_index, data & WR0_COMMAND_MASK);
}
break;
@ -989,6 +1065,70 @@ void z80dart_channel::control_write(UINT8 data)
LOG(("Z80DART \"%s\" Channel %c : Receive Sync %02x\n", m_owner->tag(), 'A' + m_index, data));
m_sync = (data << 8) | (m_sync & 0xff);
break;
/* registers 8-15 are specific to SCC and misuse captured by test around Point High command above */
case 8:
LOG(("Z80DART \"%s\" Channel %c : Transmit Buffer read %02x\n", m_owner->tag(), 'A' + m_index, data));
data_write(data);
break;
case 9:
switch (data & WR9_CMD_MASK)
{
case WR9_CMD_NORESET:
LOG(("Z80DART \"%s\" Channel %c : Master Interrupt Control - No reset %02x\n", m_owner->tag(), 'A' + m_index, data));
break;
case WR9_CMD_CHNB_RESET:
LOG(("Z80DART \"%s\" Channel %c : Master Interrupt Control - Channel B reset %02x\n", m_owner->tag(), 'A' + m_index, data));
m_uart->m_chanB->reset();
break;
case WR9_CMD_CHNA_RESET:
LOG(("Z80DART \"%s\" Channel %c : Master Interrupt Control - Channel A reset %02x\n", m_owner->tag(), 'A' + m_index, data));
m_uart->m_chanA->reset();
break;
case WR9_CMD_HW_RESET:
LOG(("Z80DART \"%s\" Channel %c : Master Interrupt Control - Device reset %02x\n", m_owner->tag(), 'A' + m_index, data));
/*"The effects of this command are identical to those of a hardware reset, except that the Shift Right/Shift Left bit is
not changed and the MIE, Status High/Status Low and DLC bits take the programmed values that accompany this command."
The Shift Right/Shift Left bits of the WR0 is only valid on SCC8030 device hence not implemented yet, just the SCC8530 */
if (data & (WR9_BIT_MIE | WR9_BIT_IACK | WR9_BIT_SHSL | WR9_BIT_DLC | WR9_BIT_NV))
logerror("Z80DART: SCC Interrupt system not yet implemented, please be patient!\n");
m_uart->device_reset();
break;
default:
logerror("Z80DART Code is broken in WR9, please report!\n");
}
break;
case 10:
LOG(("Z80DART \"%s\" Channel %c : unsupported command: Misc Tx/Rx Control %02x\n", m_owner->tag(), 'A' + m_index, data));
break;
case 11:
LOG(("Z80DART \"%s\" Channel %c : incomplete command: Clock Mode Control %02x\n", m_owner->tag(), 'A' + m_index, data));
m_wr[11] = data;
break;
case 12:
LOG(("Z80DART \"%s\" Channel %c : incomplete command: Low Byte of Baudrate Generator Time Constant %02x\n", m_owner->tag(), 'A' + m_index, data));
m_wr[12] = data;
break;
case 13:
LOG(("Z80DART \"%s\" Channel %c : incomplete command: High Byte of Baudrate Generator Time Constant %02x\n", m_owner->tag(), 'A' + m_index, data));
m_wr[13] = data;
break;
case 14:
switch (data & WR14_DPLL_CMD_MASK)
{
case WR14_CMD_NULL:
LOG(("Z80DART \"%s\" Channel %c : Misc Control Bits: DPLL Null Command %02x\n", m_owner->tag(), 'A' + m_index, data));
break;
default:
logerror("Z80DART \"%s\" Channel %c : incomplete command: Misc Control Bits %02x\n", m_owner->tag(), 'A' + m_index, data);
}
// TODO: Add support for clock source to Baudrate generator
m_wr[14] = data;
break;
case 15:
LOG(("Z80DART \"%s\" Channel %c : unsupported command: External/Status Control Bits %02x\n", m_owner->tag(), 'A' + m_index, data));
break;
default:
logerror("Z80DART \"%s\" Channel %c : Unsupported WRx register:%02x\n", m_owner->tag(), 'A' + m_index, reg);
}
}

View File

@ -6,6 +6,7 @@
NEC uPD7201 Multiprotocol Serial Communications Controller emulation
Z80-DART Dual Asynchronous Receiver/Transmitter emulation
Z80-SIO/0/1/2/3/4 Serial Input/Output Controller emulation
Z80-SCC Serial Communications Controller emulation (experimental)
****************************************************************************
_____ _____
@ -140,6 +141,29 @@
_DCDA 19 | | 22 _DCDB
CLK 20 |_____________| 21 _RESET
_____ _____
D1 1 |* \_/ | 40 D0
D3 2 | | 39 D2
D5 3 | | 38 D4
D7 4 | | 37 D6
_INT 5 | | 36 _RD
IEO 6 | | 35 _WR
IEI 7 | | 34 B/_A
_INTAK 8 | | 33 _CE
VCC 9 | | 32 C/_D
_W/REQA 10| Z80-SCC | 31 GND
_SYNCA 11| Z8530 | 30 _W/REQB
_RTxCA 12| | 29 _SYNCB
RxDA 13| | 28 _RTxCB
_TRxCA 14| | 27 RxDB
TxDA 15| | 26 _TRxCB
_DTR/REQA 16| | 25 TxDB
_RTSA 17| | 24 _DTR/REQB
_CTSA 18| | 23 _RTSB
_DCDA 19| | 22 _CTSB
CLK 20|_____________| 21 _DCDB
***************************************************************************/
#ifndef __Z80DART_H__
@ -185,6 +209,10 @@
MCFG_DEVICE_ADD(_tag, UPD7201, _clock) \
MCFG_Z80DART_OFFSETS(_rxa, _txa, _rxb, _txb)
#define MCFG_Z80SCC_ADD(_tag, _clock, _rxa, _txa, _rxb, _txb) \
MCFG_DEVICE_ADD(_tag, Z80SCC, _clock) \
MCFG_Z80DART_OFFSETS(_rxa, _txa, _rxb, _txb)
#define MCFG_Z80DART_OFFSETS(_rxa, _txa, _rxb, _txb) \
z80dart_device::configure_channels(*device, _rxa, _txa, _rxb, _txb);
@ -282,8 +310,8 @@ public:
int m_txc;
// register state
UINT8 m_rr[3]; // read register
UINT8 m_wr[6]; // write register
UINT8 m_rr[16]; // read registers, DART=3 SCC=16
UINT8 m_wr[16]; // write register, DART=6 SCC=16
protected:
enum
@ -336,6 +364,13 @@ protected:
WR0_CRC_RESET_TX_UNDERRUN = 0xc0 // not supported
};
enum /* SCC specifics */
{
WR0_REGISTER_MASK_SCC = 0x0f,
WR0_POINT_HIGH = 0x08,
};
enum
{
WR1_EXT_INT_ENABLE = 0x01,
@ -418,6 +453,34 @@ protected:
WR5_DTR = 0x80
};
/* SCC specifics */
enum
{
WR9_CMD_MASK = 0xC0,
WR9_CMD_NORESET = 0x00,
WR9_CMD_CHNB_RESET = 0x40,
WR9_CMD_CHNA_RESET = 0x80,
WR9_CMD_HW_RESET = 0xC0,
WR9_BIT_VIS = 0x01,
WR9_BIT_NV = 0x02,
WR9_BIT_DLC = 0x04,
WR9_BIT_MIE = 0x08,
WR9_BIT_SHSL = 0x10,
WR9_BIT_IACK = 0x20
};
enum
{
WR14_DPLL_CMD_MASK = 0xe0,
WR14_CMD_NULL = 0x00,
WR14_CMD_ESM = 0x20,
WR14_CMD_RMC = 0x40,
WR14_CMD_SS_BGR = 0x80,
WR14_CMD_SS_RTXC = 0xa0,
WR14_CMD_SET_FM = 0xc0,
WR14_CMD_SET_NRZI = 0xe0
};
void update_serial();
void set_dtr(int state);
void set_rts(int state);
@ -455,6 +518,9 @@ protected:
int m_index;
z80dart_device *m_uart;
// SCC specifics
int m_ph; // Point high command to access regs 08-0f
};
@ -555,7 +621,8 @@ protected:
TYPE_SIO3,
TYPE_SIO4,
TYPE_I8274,
TYPE_UPD7201
TYPE_UPD7201,
TYPE_Z80SCC
};
enum
@ -669,6 +736,16 @@ public:
};
// ======================> scc8530_device
class scc8530_device : public z80dart_device
{
public :
// construction/destruction
scc8530_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
};
// device type definition
extern const device_type Z80DART_CHANNEL;
extern const device_type Z80DART;
@ -679,6 +756,7 @@ extern const device_type Z80SIO3;
extern const device_type Z80SIO4;
extern const device_type I8274;
extern const device_type UPD7201;
extern const device_type Z80SCC;
#endif

View File

@ -2614,6 +2614,7 @@ eacc
argo
applix
mzr8105
hk68v10
fccpu1
68ksbc
lcmate2

371
src/mess/drivers/hk68v10.c Normal file
View File

@ -0,0 +1,371 @@
// license:BSD-3-Clause
// copyright-holders:Joakim Larsson Edstrom
/***************************************************************************
*
* Heurikon HK68/V10 6U SBC driver, initially derived from hk68v10.c
*
* 21/08/2015
*
* I baught this board from http://www.retrotechnology.com without documentation.
* It has a Motorola 68010 CPU @ 10MHz and two 2764 EPROMS with HBUG firmware
* The board is very populated and suitable to run a real server OS supported by
* FPU,MMU and DMA controller chips. The firmware supports SCSI, Centronics/FPI
* and a serial port. I have not found so much on the FPI interface yet and it is
* possibly Heurikon specific. There is also a Heurikon Multibus board called
* HK68/M10 for which I might add support from specs, however would need a ROM
* to verify.
*
* ||
* || ||
* ||||--||
* ||||--||
* || ||____________________________________________________________ ___
* || | | | 12 PALs 68/V-... | | | | | |_| |
* || | | 2 x | |74 |74 |74 |74 | | | |
* || | | 74273 | VS4-01 VM4-00 | 244 573 645 645 | | |
* \==||| |SCSI | | VS3-00 VM3-03 | | | | | | | |
* ||| | | | VS2-01 VM2-02 |___|___|___|___| | | |
* || |NCR | | VS1-00 VM1-01 | | | | | | |
* || | 8530| 2 x | VBX-00 VDB-00 |74 |74 |74 | | |VME|
* || | | 74245 | VI1-00 VI2-00 | 244 641 245 | | |
* || | | | (90 deg ccw) | | | | | |P1 |
* SCSI || |_____| |_____________________|___|___|___| | | |
* port || | | _________ _________________________________ | | |
* || | | | || |74 |PAL | | | | |
* || | | | || 5 x | 244 MP2| 2 x | | | |
* || |CIO | | MC68881 || 74373 | | -00| 74646| | | |
* || |paral| | FPU || | | | | | | |
* || |Z8536| |_________||_________________|_ _| | | |_| |
* ||| | | | | | | ------------ |___|
* /==||| | | | | | | | 3 PALs | |
* FSM || | | | MC68010 | MC68451 | MC68450 | | MP1-00 | |
* 1234 || | | | CPU | MMU | DMA | | MX2-00 | |
* LEDs || |-----| |_________|__________|_________|__| MX1-01 |---|
* || | | ____ ____ ---| |__________|74 |
* \==||| | | | | | | |74| 4 x | 3 PALs |145|
* ||| |SCC | | | | | |804 74245 | CS3-00 |___|
* FPI || |seria| |U12 | |U23 | | | | CS2-00 | |
* paralell |Z8530| |HBUG| |HBUG| | | | CS1-00 | |___
* port || | | | | | | ---_---------------|__________| _| |
* || | | | | | | |MTTLDL|MDLDM| 2 x |___________ | | |
* ||| | | |____|_|____|_|____40|TTL75|74280| | | | |
* /==||| | || |19. | | | | | |_____| | | | |
* \==||| |_____||75 |6608|16 |20 |74|74| ______| 9 x 4 | | | |
* ||| +--------+|173| MHz| MHz | MHz| 74 08| | | RAM chips| | |VME|
* || | ||___|____|_____|____|__|__||74 74 | on SIL | | | |
* || | 2 x || | | |259|257 boards | | |P2 |
* || | SIL || 12 PALs 90 deg ccw|74| -______- | | | |
* || | boards || |240 | | | | | | |
* || | with 2 || BER-00 FPI-01 | | |74 74 | | | | |
* Serial|| | DIP16 || AC4-00 ARB-01 |__|___|138|257 | | | |
* port || | surf || AC3-00 INT-00 |______| | | | |
* || | mounted|| AC2-01 IAK-00 | | | | | | |
* || | chips || AC1-01 PAS-01 |74 |74| | | | |
* || | each || RFS-01 |590|257 | | | |
* ||| | || RCT-01 | | | | |_| |
* /==||| +--------+|__________________________|___|__|__________| |___|
* || ||------------------------------------------------------------+-+
* ||||--||
* ||||--||
* ||
*
* History of Heurikon
*---------------------
* The company was founded 1972 as cellar company. Heurikon was aquired
* 1989 by Computer Products, 1990 by Artesyn and finally in 2005 by Emerson
* Electric who consilidated it fully by 2009 and closed the office.
*
* Misc links about Heurikon and this board:
* http://www.heurikon.com/
* http://www.nytimes.com/1992/01/07/business/company-news-briefs.html
* http://bitsavers.informatik.uni-stuttgart.de/pdf/heurikon/brochures/HK68_V10_Brochure.pdf
* http://bitsavers.informatik.uni-stuttgart.de/pdf/heurikon/Heurikon_UNIX_System_V_and_V.2_Reference_Guide_Apr87.pdf
*
* Address Map from the UNIX Ref Guide
* --------------------------------------------------------------------------
* Address Range Memory Space (physical) Notes
* --------------------------------------------------------------------------
* 0xffffff (top of memory)
* 0xffc200 0xffc220 Sky FFP 68881 FPU
* 0xff8000 ... MCT Reel-to-reel tape (V10) VME
* 0xff0000 0xff0100 Tapemaster(00B0,00B1) Reel-to-reel tape (M10) Multibus
* Ethernet(0010,0011)
* 0xff0000 (base of bus I/O)
*
* 0xfea000 SCC8530 device
* 0xfe9000 offset 6 seems also to be 2 access registers, ie register offset + data pairs
* 0xfe8000 offset E reading single byte
* 0xfe4000 front LED:s? or move ROM from 0x0 to 0xfc0000...
* 0xfe2000 cleared
* 0xfe0000 HK68 On-card I/O MMU, DMAC, SCC, SCSI
* 0xfc0000 HK68 ROM (128K) Hbug monitor
* 0xf00000 (reserved)
* (shared memory and logical area
* for shared text.)
* 0x800000 (Twilight Zone) (top of /dev/mem)
* 0x7c0000 (reserved)
* 0x780000 8 Chnl serial Expn(1-4) (CDC)
* HK68 (1-15) VRTX
* MLZ-93 (1-4) CP/M Shell
* 0x700000
* (open)
* 0x*00000 (maxmeml)
* RAM (bus) (optional)
* 0x200000 (top of 2 meg RAM)
* RAM (bus) (optional)
* 0x100000 (top of 1 meg RAM)
* User RAM
* 0x001000 UNIX Kernel
* Exception Vectors
* 0x000000 (bottom of memory)
* --------------------------------------------------------------------------
*
* Interrupt sources M10/V10
* ----------------------------------------------------------
* Description Device Lvl IRQ VME board
* /Board Vector Address
* ----------------------------------------------------------
* On board Sources M10/V10
*
* Off board Sources (other VME boards)
* EXOS Ethernet 5 4
* TapeMaster Reel-to-Reel Tape 3
* MCT Reel-to-Reel Tape 5
* CDC MB1031 Serial Expansion 2 2
* IT 2190 SMD Interface 1 3
* IT 3200 SMD Interface 3
* ----------------------------------------------------------
*
* DMAC Channel Assignments
* ----------------------------------------------------------
* Channel M10 V10
* ----------------------------------------------------------
* 0 SCSI SCSI
* 1 Streamer (P3) n/a
* 2 n/a n/a
* 3 SBX-FDIO n/a
* ----------------------------------------------------------
*
* TODO:
* - Dump the ROMs (DONE)
* - Setup a working address map (DONE)
* - Fix terminal for HBUG (DONE)
* - Add VME bus driver
* - Add DMA/MMU devices
* - Add CIO port
* - ADD SCSI controller device
* - dump PALs and describe descrete logic
* - Setup BAUD generation correctly, (eg find that x32 divider)
* - Add LED:s
* - Add Jumpers and strap areas
* - Find and Boot Heurikon Unix from a SCSI device
* - Support that optional 68881 FPU
*
****************************************************************************/
#include "emu.h"
#include "cpu/m68000/m68000.h"
#include "machine/z80dart.h"
#include "bus/rs232/rs232.h"
#include "machine/clock.h"
#define LOG(x) /* x */
#define BAUDGEN_CLOCK XTAL_19_6608MHz /* Raltron */
/*
*/
#define SCC_CLOCK (BAUDGEN_CLOCK / 128) /* This will give prompt */
//#define SCC_CLOCK (BAUDGEN_CLOCK / 4) /* This is correct */
class hk68v10_state : public driver_device
{
public:
hk68v10_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device (mconfig, type, tag),
m_maincpu (*this, "maincpu")
,m_sccterm(*this, "scc")
// ,m_cart(*this, "exp_rom1")
{
}
DECLARE_READ16_MEMBER (bootvect_r);
DECLARE_WRITE16_MEMBER (bootvect_w);
DECLARE_READ16_MEMBER (vme_a24_r);
DECLARE_WRITE16_MEMBER (vme_a24_w);
DECLARE_READ16_MEMBER (vme_a16_r);
DECLARE_WRITE16_MEMBER (vme_a16_w);
virtual void machine_start ();
virtual void machine_reset ();
DECLARE_WRITE_LINE_MEMBER (write_sccterm_clock);
protected:
private:
required_device<cpu_device> m_maincpu;
required_device<scc8530_device> m_sccterm;
// Pointer to System ROMs needed by bootvect_r and masking RAM buffer for post reset accesses
UINT16 *m_sysrom;
UINT16 m_sysram[4];
};
static ADDRESS_MAP_START (hk68v10_mem, AS_PROGRAM, 16, hk68v10_state)
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE (0x000000, 0x000007) AM_ROM AM_READ (bootvect_r) /* ROM mirror just durin reset */
AM_RANGE (0x000000, 0x000007) AM_RAM AM_WRITE (bootvect_w) /* After first write we act as RAM */
AM_RANGE (0x000008, 0x1fffff) AM_RAM /* 2 Mb RAM */
AM_RANGE (0xFC0000, 0xFC3fff) AM_ROM /* System EPROM Area 16Kb HBUG */
AM_RANGE (0xFC4000, 0xFDffff) AM_ROM /* System EPROM Area an additional 112Kb for System ROM */
AM_RANGE (0xFE9000, 0xFE9009) AM_RAM //AM_DEVREADWRITE8("scc", scc8530_device, ba_cd_r, ba_cd_w, 0xffff) /* Z80-PIO? */
AM_RANGE (0xFEA000, 0xFEA001) AM_DEVREADWRITE8("scc", scc8530_device, ca_r, ca_w, 0xff00) /* Dual serial port Z80-SCC */
AM_RANGE (0xFEA002, 0xFEA003) AM_DEVREADWRITE8("scc", scc8530_device, cb_r, cb_w, 0xff00) /* Dual serial port Z80-SCC */
AM_RANGE (0xFEA004, 0xFEA005) AM_DEVREADWRITE8("scc", scc8530_device, da_r, da_w, 0xff00) /* Dual serial port Z80-SCC */
AM_RANGE (0xFEA006, 0xFEA007) AM_DEVREADWRITE8("scc", scc8530_device, db_r, db_w, 0xff00) /* Dual serial port Z80-SCC */
//AM_RANGE(0x100000, 0xfeffff) AM_READWRITE(vme_a24_r, vme_a24_w) /* VMEbus Rev B addresses (24 bits) - not verified */
//AM_RANGE(0xff0000, 0xffffff) AM_READWRITE(vme_a16_r, vme_a16_w) /* VMEbus Rev B addresses (16 bits) - not verified */
ADDRESS_MAP_END
/* Input ports */
static INPUT_PORTS_START (hk68v10)
INPUT_PORTS_END
/* Start it up */
void hk68v10_state::machine_start ()
{
LOG (logerror ("machine_start\n"));
/* Setup pointer to bootvector in ROM for bootvector handler bootvect_r */
m_sysrom = (UINT16*)(memregion ("maincpu")->base () + 0x0fc0000);
}
/* Support CPU resets
TODO: Investigate why the user need two 'softreset' commands for the below to work. Eg F3 + F11 + F3 + F11
If only one 'softreset' is given the reset PC gets the RAM content, not the intended ROM vector.
Race conditions? Wrong call order in memory system? Debugger prefetch accesses? Better way to to this?
*/
void hk68v10_state::machine_reset ()
{
LOG (logerror ("machine_reset\n"));
/* Reset pointer to bootvector in ROM for bootvector handler bootvect_r */
if (m_sysrom == &m_sysram[0]) /* Condition needed because memory map is not setup first time */
m_sysrom = (UINT16*)(memregion ("maincpu")->base () + 0x0fc0000);
}
/* Boot vector handler, the PCB hardwires the first 8 bytes from 0xfc0000 to 0x0 at reset*/
/*
Right after HBUG reset the bootvector is masked by RAM:
FC001C: move.w #$700, $fe4000.l
FC0024: move.l #$0, $0.l # <- zeroing the reset vector
FC002E: move.l #$0, $4.l # There is for sure some hardware mapping going in here
*/
READ16_MEMBER (hk68v10_state::bootvect_r){
//LOG (logerror ("bootvect_r %s\n", m_sysrom != &m_sysram[0] ? "as reset" : "as swapped"));
return m_sysrom [offset];
}
WRITE16_MEMBER (hk68v10_state::bootvect_w){
LOG (logerror("bootvect_w offset %08x, mask %08x, data %04x\n", offset, mem_mask, data));
m_sysram[offset % sizeof(m_sysram)] &= ~mem_mask;
m_sysram[offset % sizeof(m_sysram)] |= (data & mem_mask);
m_sysrom = &m_sysram[0]; // redirect all upcomming accesses to masking RAM until reset.
}
#if 0
/* Dummy VME access methods until the VME bus device is ready for use */
READ16_MEMBER (hk68v10_state::vme_a24_r){
LOG (logerror ("vme_a24_r\n"));
return (UINT16) 0;
}
WRITE16_MEMBER (hk68v10_state::vme_a24_w){
LOG (logerror ("vme_a24_w\n"));
}
READ16_MEMBER (hk68v10_state::vme_a16_r){
LOG (logerror ("vme_16_r\n"));
return (UINT16) 0;
}
WRITE16_MEMBER (hk68v10_state::vme_a16_w){
LOG (logerror ("vme_a16_w\n"));
}
#endif
/*
* Serial port clock source depends on the CPU clock and divider settings
* HBUG has a control byte that needs to be patched accordingly:
*
* CPU clock SCC clock Baud rate offset 0x0b value
* 10 Mhz 4.9152MHz 9600 15
* 10 Mhz 4.9152MHz 19200 55
* 12 Mhz 4.9152MHz 9600 16
* 12 Mhz 4.9152MHz 19200 56
*
* Configuration word detail:
* D15-D8 reserved ( = 0 )
* D7(MSB) = 0
* D6 = 0 for console default 9600 baud
* D6 = 1 for console default 19,200 baud
* D5,D4,D3,D2 = 0101 for 4.9152 Mhz SCC clock
* D1,DO
* 01 for 10 Mhz MPU clock
* D1,DO = 10 for 12 Mhz MPU clock
*
* Original HBUG configuration word: 0x003D = 0000 0000 0011 1101
*
*/
WRITE_LINE_MEMBER (hk68v10_state::write_sccterm_clock){
m_sccterm->txca_w (state);
m_sccterm->rxca_w (state);
}
/*
* Machine configuration
*/
static MACHINE_CONFIG_START (hk68v10, hk68v10_state)
/* basic machine hardware */
MCFG_CPU_ADD ("maincpu", M68010, XTAL_10MHz)
MCFG_CPU_PROGRAM_MAP (hk68v10_mem)
/* Terminal Port config */
MCFG_Z80SCC_ADD("scc", XTAL_4MHz, 0, 0, 0, 0 )
MCFG_Z80DART_OUT_TXDA_CB(DEVWRITELINE("rs232trm", rs232_port_device, write_txd))
MCFG_Z80DART_OUT_DTRA_CB(DEVWRITELINE("rs232trm", rs232_port_device, write_dtr))
MCFG_Z80DART_OUT_RTSA_CB(DEVWRITELINE("rs232trm", rs232_port_device, write_rts))
MCFG_RS232_PORT_ADD ("rs232trm", default_rs232_devices, "terminal")
MCFG_RS232_RXD_HANDLER (DEVWRITELINE ("scc", scc8530_device, rxa_w))
MCFG_RS232_CTS_HANDLER (DEVWRITELINE ("scc", scc8530_device, ctsa_w))
MCFG_DEVICE_ADD ("sccterm_clock", CLOCK, SCC_CLOCK)
MCFG_CLOCK_SIGNAL_HANDLER (WRITELINE (hk68v10_state, write_sccterm_clock))
MACHINE_CONFIG_END
/* ROM definitions */
ROM_START (hk68v10)
ROM_REGION (0x1000000, "maincpu", 0)
ROM_LOAD16_BYTE ("hk68kv10U23.bin", 0xFC0001, 0x2000, CRC (632aa026) SHA1 (f2b1ed0cc38dfbeb1602c013e00757015400720d))
ROM_LOAD16_BYTE ("hk68kv10U12.bin", 0xFC0000, 0x2000, CRC (f2d688e9) SHA1 (e68699965645f0ce53de47625163c3eb02c8b727))
/*
* System ROM information
*
* The ROMs contains HBUG v1.8, known commands from different sources:
*
* 'uc' Print HK68 Configuration
* 'um' Perform RAM test
* 'dm adrs' Display Memory
* 'sb adrs' Substitute Byte at adrs
* 'c adrs' Call Routine at adrs
* 'bw' Boot from Winchester
* 'bf' Boot from floppy (MIO, SBX-FDIO)
* 'bsf' Boot from floppy (SCSI)
*
*/
ROM_END
/* Driver */
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
COMP (1985, hk68v10, 0, 0, hk68v10, hk68v10, driver_device, 0, "Heurikon Corporation", "HK68/V10", MACHINE_NO_SOUND_HW | MACHINE_TYPE_COMPUTER )