diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index b25c03b8f3e..0d81b3892d2 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -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", diff --git a/src/devices/machine/z80dart.c b/src/devices/machine/z80dart.c index 6254d1d81f1..5a3b5439247 100644 --- a/src/devices/machine/z80dart.c +++ b/src/devices/machine/z80dart.c @@ -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; const device_type Z80SIO4 = &device_creator; const device_type I8274 = &device_creator; const device_type UPD7201 = &device_creator; +const device_type Z80SCC = &device_creator; //------------------------------------------------- @@ -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(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); } } diff --git a/src/devices/machine/z80dart.h b/src/devices/machine/z80dart.h index 2674f84758a..c4893ef90db 100644 --- a/src/devices/machine/z80dart.h +++ b/src/devices/machine/z80dart.h @@ -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 diff --git a/src/mame/mess.lst b/src/mame/mess.lst index cea61196da1..ac6f4ad82d9 100644 --- a/src/mame/mess.lst +++ b/src/mame/mess.lst @@ -2614,6 +2614,7 @@ eacc argo applix mzr8105 +hk68v10 fccpu1 68ksbc lcmate2 diff --git a/src/mess/drivers/hk68v10.c b/src/mess/drivers/hk68v10.c new file mode 100644 index 00000000000..8e1c766bbe4 --- /dev/null +++ b/src/mess/drivers/hk68v10.c @@ -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 m_maincpu; +required_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 )