Skip to content

Commit 11a760c

Browse files
committed
vme/tp881v: boot to monitor
1 parent b1da4a1 commit 11a760c

2 files changed

Lines changed: 149 additions & 119 deletions

File tree

src/devices/bus/vme/tp881v.cpp

Lines changed: 148 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
*
1111
* TODO:
1212
* - scsi dma controllers
13+
* - networking
1314
* - serial dma
1415
* - vme interface
1516
* - interrupt enables/masking
@@ -19,85 +20,128 @@
1920
#include "emu.h"
2021
#include "tp881v.h"
2122

23+
#include "bus/rs232/rs232.h"
24+
#include "bus/nscsi/devices.h"
25+
#include "cpu/m88000/m88000.h"
26+
#include "machine/eepromser.h"
27+
#include "machine/i82586.h"
2228
#include "machine/input_merger.h"
23-
24-
#include "bus/nscsi/hd.h"
25-
#include "bus/nscsi/cd.h"
29+
#include "machine/hd63450.h"
30+
#include "machine/mc88200.h"
31+
#include "machine/ncr53c90.h"
32+
#include "machine/timekpr.h"
33+
#include "machine/z80scc.h"
34+
#include "machine/z8536.h"
2635

2736
#define VERBOSE 0
2837
#include "logmacro.h"
2938

30-
DEFINE_DEVICE_TYPE(VME_TP881V, vme_tp881v_card_device, "tp881v", "Tadpole Technology TP881V")
31-
32-
vme_tp881v_card_device::vme_tp881v_card_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
33-
: device_t(mconfig, VME_TP881V, tag, owner, clock)
34-
, device_vme_card_interface(mconfig, *this)
35-
, m_cpu(*this, "cpu")
36-
, m_mmu(*this, "mmu%u", 0U)
37-
, m_cio(*this, "cio%u", 0U)
38-
, m_rtc(*this, "rtc")
39-
, m_scsi(*this, "ncr53c90a_%u", 0U)
40-
, m_net(*this, "net")
41-
, m_scc(*this, "scc%u", 0U)
42-
, m_scc_dma(*this, "scc_dma")
43-
, m_vcs(*this, "vcs")
44-
, m_gcs(*this, "gcs%u", 0U)
45-
, m_eeprom(*this, "eeprom")
46-
, m_serial(*this, "serial%u", 0U)
47-
{
48-
}
39+
namespace {
4940

50-
ROM_START(tp881v)
51-
ROM_REGION32_BE(0x40000, "eprom", 0)
52-
ROM_SYSTEM_BIOS(0, "v504", "TP881 Multiprocessor Monitor V5.04")
53-
ROMX_LOAD("881v__5.04l.bin", 0x0002, 0x20000, CRC(d9027c64) SHA1(88cca011dee005d273a1cd7048480ff3fac9c06a), ROM_REVERSE | ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(0))
54-
ROMX_LOAD("881v__5.04h.bin", 0x0000, 0x20000, CRC(74de0772) SHA1(8e5bfd427c0bdea4ab350333fd5a814712014302), ROM_REVERSE | ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(0))
55-
ROM_END
56-
57-
static INPUT_PORTS_START(tp881v)
58-
INPUT_PORTS_END
59-
60-
const tiny_rom_entry *vme_tp881v_card_device::device_rom_region() const
61-
{
62-
return ROM_NAME(tp881v);
63-
}
64-
65-
ioport_constructor vme_tp881v_card_device::device_input_ports() const
41+
class vme_tp881v_device
42+
: public device_t
43+
, public device_vme_card_interface
6644
{
67-
return INPUT_PORTS_NAME(tp881v);
68-
}
69-
70-
void vme_tp881v_card_device::device_start()
45+
public:
46+
vme_tp881v_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
47+
: device_t(mconfig, VME_TP881V, tag, owner, clock)
48+
, device_vme_card_interface(mconfig, *this)
49+
, m_cpu(*this, "cpu")
50+
, m_mmu(*this, "mmu%u", 0U)
51+
, m_cio(*this, "cio%u", 0U)
52+
, m_rtc(*this, "rtc")
53+
, m_scsi(*this, "ncr53c90a%u", 0U)
54+
, m_net(*this, "net")
55+
, m_scc(*this, "scc%u", 0U)
56+
, m_scc_dma(*this, "scc_dma")
57+
, m_vcs(*this, "vcs")
58+
, m_gcs(*this, "gcs%u", 0U)
59+
, m_eeprom(*this, "eeprom")
60+
, m_serial(*this, "serial%u", 0U)
61+
{}
62+
63+
protected:
64+
virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD;
65+
virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
66+
virtual ioport_constructor device_input_ports() const override ATTR_COLD;
67+
virtual void device_start() override ATTR_COLD;
68+
virtual void device_reset() override ATTR_COLD;
69+
70+
private:
71+
void cpu_mem(address_map &map) ATTR_COLD;
72+
void net_mem(address_map &map) ATTR_COLD;
73+
74+
template <unsigned IRQ> void cio0_pa_w(int state);
75+
u8 cio0_pa_r() { return m_cio0_pa; }
76+
77+
required_device<mc88100_device> m_cpu;
78+
required_device_array<mc88200_device, 2> m_mmu;
79+
required_device_array<z8036_device, 8> m_cio;
80+
81+
required_device<m48t02_device> m_rtc;
82+
required_device_array<ncr53c90a_device, 2> m_scsi;
83+
required_device<i82596_device> m_net;
84+
required_device_array<scc8030_device, 2> m_scc;
85+
required_device<hd63450_device> m_scc_dma;
86+
87+
required_device<z8036_device> m_vcs; // vme control and status cio
88+
required_device_array<z8036_device, 2> m_gcs; // global control and status cio
89+
required_device<eeprom_serial_93cxx_device> m_eeprom;
90+
91+
required_device_array<rs232_port_device, 4> m_serial;
92+
93+
u8 m_cio0_pa;
94+
u8 m_gcs0_pb;
95+
};
96+
97+
void vme_tp881v_device::device_start()
7198
{
99+
save_item(NAME(m_cio0_pa));
100+
save_item(NAME(m_gcs0_pb));
72101
}
73102

74-
void vme_tp881v_card_device::device_reset()
103+
void vme_tp881v_device::device_reset()
75104
{
105+
m_cio0_pa = 0xfe;
106+
m_gcs0_pb = 0;
76107
}
77108

78-
static void scsi_devices(device_slot_interface &device)
109+
template <unsigned IRQ> void vme_tp881v_device::cio0_pa_w(int state)
79110
{
80-
device.option_add("cdrom", NSCSI_CDROM);
81-
device.option_add("harddisk", NSCSI_HARDDISK);
111+
if (state)
112+
m_cio0_pa &= u8(~(1U << IRQ));
113+
else
114+
m_cio0_pa |= u8(1U << IRQ);
115+
116+
switch (IRQ)
117+
{
118+
case 1: m_cio[0]->pa1_w(!state); break;
119+
case 2: m_cio[0]->pa2_w(!state); break;
120+
case 3: m_cio[0]->pa3_w(!state); break;
121+
case 4: m_cio[0]->pa4_w(!state); break;
122+
case 5: m_cio[0]->pa5_w(!state); break;
123+
case 6: m_cio[0]->pa6_w(!state); break;
124+
case 7: m_cio[0]->pa7_w(!state); break;
125+
}
82126
}
83127

84-
void vme_tp881v_card_device::device_add_mconfig(machine_config &config)
128+
void vme_tp881v_device::device_add_mconfig(machine_config &config)
85129
{
86130
MC88100(config, m_cpu, 40_MHz_XTAL / 2);
87-
m_cpu->set_addrmap(AS_PROGRAM, &vme_tp881v_card_device::cpu_mem);
131+
m_cpu->set_addrmap(AS_PROGRAM, &vme_tp881v_device::cpu_mem);
88132
m_cpu->set_cmmu_code([this](u32 const address) -> mc88200_device & { return *m_mmu[0]; });
89133
m_cpu->set_cmmu_data([this](u32 const address) -> mc88200_device & { return *m_mmu[1]; });
90134

91135
MC88200(config, m_mmu[0], 40_MHz_XTAL / 2, 0x00).set_mbus(m_cpu, AS_PROGRAM);
92-
MC88200(config, m_mmu[1], 40_MHz_XTAL / 2, 0x01).set_mbus(m_cpu, AS_PROGRAM);
136+
MC88200(config, m_mmu[1], 40_MHz_XTAL / 2, 0x08).set_mbus(m_cpu, AS_PROGRAM);
93137

94138
// per-jp interrupt controllers
95139
// 4MHz input clock, ct3 gives 100Hz clock, ct2 counts at 10kHz
96140
Z8036(config, m_cio[0], 4'000'000); // Z0803606VSC
97141
/*
98142
* port a bit mode ddr 0xff
99143
* bit i/o function
100-
* 0 i porta int?
144+
* 0 i cpu present
101145
* 1 i ethernet
102146
* 2 i scc dma
103147
* 3 i scsi0
@@ -124,6 +168,8 @@ void vme_tp881v_card_device::device_add_mconfig(machine_config &config)
124168
* 2 i
125169
* 3 i
126170
*/
171+
m_cio[0]->pa_rd_cb().set(FUNC(vme_tp881v_device::cio0_pa_r));
172+
m_cio[0]->pb_rd_cb().set_constant(0xff);
127173
m_cio[0]->irq_wr_cb().set_inputline(m_cpu, INPUT_LINE_IRQ0);
128174

129175
Z8036(config, m_cio[1], 4'000'000); // Z0803606VSC
@@ -137,37 +183,37 @@ void vme_tp881v_card_device::device_add_mconfig(machine_config &config)
137183
M48T02(config, m_rtc);
138184

139185
auto &scsi0(NSCSI_BUS(config, "scsi0"));
140-
NSCSI_CONNECTOR(config, "scsi0:0", scsi_devices, nullptr, false);
141-
NSCSI_CONNECTOR(config, "scsi0:1", scsi_devices, nullptr, false);
142-
NSCSI_CONNECTOR(config, "scsi0:2", scsi_devices, nullptr, false);
143-
NSCSI_CONNECTOR(config, "scsi0:3", scsi_devices, nullptr, false);
144-
NSCSI_CONNECTOR(config, "scsi0:4", scsi_devices, nullptr, false);
145-
NSCSI_CONNECTOR(config, "scsi0:5", scsi_devices, nullptr, false);
146-
NSCSI_CONNECTOR(config, "scsi0:6", scsi_devices, nullptr, false);
186+
NSCSI_CONNECTOR(config, "scsi0:0", default_scsi_devices, nullptr, false);
187+
NSCSI_CONNECTOR(config, "scsi0:1", default_scsi_devices, nullptr, false);
188+
NSCSI_CONNECTOR(config, "scsi0:2", default_scsi_devices, nullptr, false);
189+
NSCSI_CONNECTOR(config, "scsi0:3", default_scsi_devices, nullptr, false);
190+
NSCSI_CONNECTOR(config, "scsi0:4", default_scsi_devices, nullptr, false);
191+
NSCSI_CONNECTOR(config, "scsi0:5", default_scsi_devices, nullptr, false);
192+
NSCSI_CONNECTOR(config, "scsi0:6", default_scsi_devices, nullptr, false);
147193

148194
NCR53C90A(config, m_scsi[0], 20'000'000);
149195
scsi0.set_external_device(7, m_scsi[0]);
150-
m_scsi[0]->irq_handler_cb().set(m_cio[0], FUNC(z8036_device::pa3_w));
196+
m_scsi[0]->irq_handler_cb().set(FUNC(vme_tp881v_device::cio0_pa_w<3>));
151197

152198
auto &scsi1(NSCSI_BUS(config, "scsi1"));
153-
NSCSI_CONNECTOR(config, "scsi1:0", scsi_devices, nullptr, false);
154-
NSCSI_CONNECTOR(config, "scsi1:1", scsi_devices, nullptr, false);
155-
NSCSI_CONNECTOR(config, "scsi1:2", scsi_devices, nullptr, false);
156-
NSCSI_CONNECTOR(config, "scsi1:3", scsi_devices, nullptr, false);
157-
NSCSI_CONNECTOR(config, "scsi1:4", scsi_devices, nullptr, false);
158-
NSCSI_CONNECTOR(config, "scsi1:5", scsi_devices, nullptr, false);
159-
NSCSI_CONNECTOR(config, "scsi1:6", scsi_devices, nullptr, false);
199+
NSCSI_CONNECTOR(config, "scsi1:0", default_scsi_devices, nullptr, false);
200+
NSCSI_CONNECTOR(config, "scsi1:1", default_scsi_devices, nullptr, false);
201+
NSCSI_CONNECTOR(config, "scsi1:2", default_scsi_devices, nullptr, false);
202+
NSCSI_CONNECTOR(config, "scsi1:3", default_scsi_devices, nullptr, false);
203+
NSCSI_CONNECTOR(config, "scsi1:4", default_scsi_devices, nullptr, false);
204+
NSCSI_CONNECTOR(config, "scsi1:5", default_scsi_devices, nullptr, false);
205+
NSCSI_CONNECTOR(config, "scsi1:6", default_scsi_devices, nullptr, false);
160206

161207
NCR53C90A(config, m_scsi[1], 20'000'000);
162208
scsi1.set_external_device(7, m_scsi[1]);
163-
m_scsi[1]->irq_handler_cb().set(m_cio[0], FUNC(z8036_device::pa4_w));
209+
m_scsi[1]->irq_handler_cb().set(FUNC(vme_tp881v_device::cio0_pa_w<4>));
164210

165211
I82596_BE32(config, m_net, 20'000'000); // A82596DX-25
166-
m_net->out_irq_cb().set(m_cio[0], FUNC(z8036_device::pa1_w));
167-
m_net->set_addrmap(0, &vme_tp881v_card_device::net_mem);
212+
m_net->out_irq_cb().set(FUNC(vme_tp881v_device::cio0_pa_w<1>)).invert();
213+
m_net->set_addrmap(0, &vme_tp881v_device::net_mem);
168214

169215
input_merger_any_high_device &scc_irq(INPUT_MERGER_ANY_HIGH(config, "scc_irq"));
170-
scc_irq.output_handler().set(m_cio[0], FUNC(z8036_device::pa5_w));
216+
scc_irq.output_handler().set(FUNC(vme_tp881v_device::cio0_pa_w<5>));
171217

172218
SCC8030(config, m_scc[0], 3.6864_MHz_XTAL); // Z0803006VSC
173219
m_scc[0]->configure_channels(m_scc[0]->clock(), m_scc[0]->clock(), m_scc[0]->clock(), m_scc[0]->clock());
@@ -214,7 +260,7 @@ void vme_tp881v_card_device::device_add_mconfig(machine_config &config)
214260
// TODO: MC68440 is function and pin compatible with MC68450/HD63450, but
215261
// has only two DMA channels instead of four.
216262
HD63450(config, m_scc_dma, 10'000'000, m_cpu, AS_PROGRAM); // MC68440FN10
217-
m_scc_dma->irq_callback().set(m_cio[0], FUNC(z8036_device::pa2_w));
263+
m_scc_dma->irq_callback().set(FUNC(vme_tp881v_device::cio0_pa_w<2>));
218264

219265
// VME control and status CIO
220266
Z8036(config, m_vcs, 4'000'000); // Z0803606VSC
@@ -233,6 +279,7 @@ void vme_tp881v_card_device::device_add_mconfig(machine_config &config)
233279

234280
// general control and status CIO 0
235281
Z8036(config, m_gcs[0], 4'000'000); // Z0803606VSC
282+
m_gcs[0]->pb_wr_cb().set([this](u8 data) { m_gcs0_pb = data; });
236283
/*
237284
* port a ddr 0x01
238285
* bit i/o function
@@ -295,15 +342,19 @@ void vme_tp881v_card_device::device_add_mconfig(machine_config &config)
295342
EEPROM_93C06_16BIT(config, m_eeprom);
296343
}
297344

298-
void vme_tp881v_card_device::cpu_mem(address_map &map)
345+
void vme_tp881v_device::cpu_mem(address_map &map)
299346
{
300347
map(0x0000'0000, 0x0003'ffff).rom().region("eprom", 0);
301348
//map(0x2000'0000, 0x20ff'ffff); // vme short space (a24 d32)
302349

350+
//map(0x4000'0000, 0x7fff'ffff); // ram space
303351
map(0x4000'0000, 0x41ff'ffff).ram().share("ram");
352+
304353
//map(0x8000'0000, 0xbfff'ffff); // vme extended space (a32 d32)
305354
//map(0xc000'0000, 0xc0ff'ffff); // vsb space
306355

356+
map(0xfff0'0000, 0xfff1'ffff).noprw(); // silence control space
357+
307358
map(0xfff3'0000, 0xfff3'003f).m(m_scsi[0], FUNC(ncr53c90a_device::map)).umask32(0x000000ff);
308359
//0xfff30080; // dmac scsi0
309360
map(0xfff3'8000, 0xfff3'803f).m(m_scsi[1], FUNC(ncr53c90a_device::map)).umask32(0x000000ff);
@@ -316,6 +367,7 @@ void vme_tp881v_card_device::cpu_mem(address_map &map)
316367
map(0xfff5'a000, 0xfff5'a0bf).rw(m_vcs, FUNC(z8036_device::read), FUNC(z8036_device::write)).umask32(0x000000ff);
317368
map(0xfff5'e000, 0xfff5'ffff).rw(m_rtc, FUNC(m48t02_device::read), FUNC(m48t02_device::write)).umask32(0x000000ff);
318369
//0xfff60000; // vme iack
370+
map(0xfff7'0000, 0xfff7'00ff).rw(m_scc_dma, FUNC(hd63450_device::read), FUNC(hd63450_device::write));
319371
//map(0xfff7'8002, 0xfff7'8003).w(m_net, FUNC(i82596_device::port));
320372
//map(0xfff7'c000, 0xfffc'0000).lw8([this](u8 data) { m_net->ca(1); }, "net_ca");
321373
map(0xfff8'0000, 0xfff8'00bf).rw(m_cio[0], FUNC(z8036_device::read), FUNC(z8036_device::write)).umask32(0x000000ff);
@@ -328,7 +380,31 @@ void vme_tp881v_card_device::cpu_mem(address_map &map)
328380
map(0xfff9'0c00, 0xfff9'0cbf).rw(m_cio[7], FUNC(z8036_device::read), FUNC(z8036_device::write)).umask32(0x000000ff);
329381
}
330382

331-
void vme_tp881v_card_device::net_mem(address_map &map)
383+
void vme_tp881v_device::net_mem(address_map &map)
332384
{
333385
map(0x4000'0000, 0x41ff'ffff).ram().share("ram");
334386
}
387+
388+
ROM_START(tp881v)
389+
ROM_REGION32_BE(0x40000, "eprom", 0)
390+
ROM_SYSTEM_BIOS(0, "v504", "TP881 Multiprocessor Monitor V5.04")
391+
ROMX_LOAD("881v__5.04l.bin", 0x0002, 0x20000, CRC(d9027c64) SHA1(88cca011dee005d273a1cd7048480ff3fac9c06a), ROM_REVERSE | ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(0))
392+
ROMX_LOAD("881v__5.04h.bin", 0x0000, 0x20000, CRC(74de0772) SHA1(8e5bfd427c0bdea4ab350333fd5a814712014302), ROM_REVERSE | ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(0))
393+
ROM_END
394+
395+
const tiny_rom_entry *vme_tp881v_device::device_rom_region() const
396+
{
397+
return ROM_NAME(tp881v);
398+
}
399+
400+
static INPUT_PORTS_START(tp881v)
401+
INPUT_PORTS_END
402+
403+
ioport_constructor vme_tp881v_device::device_input_ports() const
404+
{
405+
return INPUT_PORTS_NAME(tp881v);
406+
}
407+
408+
} // anonymous namespace
409+
410+
DEFINE_DEVICE_TYPE_PRIVATE(VME_TP881V, device_vme_card_interface, vme_tp881v_device, "tp881v", "Tadpole Technology TP881V")

src/devices/bus/vme/tp881v.h

Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -6,54 +6,8 @@
66

77
#pragma once
88

9-
#include "cpu/m88000/m88000.h"
10-
#include "machine/eepromser.h"
11-
#include "machine/i82586.h"
12-
#include "machine/hd63450.h"
13-
#include "machine/mc88200.h"
14-
#include "machine/ncr53c90.h"
15-
#include "machine/timekpr.h"
16-
#include "machine/z80scc.h"
17-
#include "machine/z8536.h"
18-
199
#include "bus/vme/vme.h"
20-
#include "bus/rs232/rs232.h"
21-
22-
class vme_tp881v_card_device
23-
: public device_t
24-
, public device_vme_card_interface
25-
{
26-
public:
27-
vme_tp881v_card_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
28-
29-
protected:
30-
virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD;
31-
virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
32-
virtual ioport_constructor device_input_ports() const override ATTR_COLD;
33-
virtual void device_start() override ATTR_COLD;
34-
virtual void device_reset() override ATTR_COLD;
35-
36-
private:
37-
void cpu_mem(address_map &map) ATTR_COLD;
38-
void net_mem(address_map &map) ATTR_COLD;
39-
40-
required_device<mc88100_device> m_cpu;
41-
required_device_array<mc88200_device, 2> m_mmu;
42-
required_device_array<z8036_device, 8> m_cio;
43-
44-
required_device<m48t02_device> m_rtc;
45-
required_device_array<ncr53c90a_device, 2> m_scsi;
46-
required_device<i82596_device> m_net;
47-
required_device_array<scc8030_device, 2> m_scc;
48-
required_device<hd63450_device> m_scc_dma;
49-
50-
required_device<z8036_device> m_vcs; // vme control and status cio
51-
required_device_array<z8036_device, 2> m_gcs; // global control and status cio
52-
required_device<eeprom_serial_93c06_16bit_device> m_eeprom;
53-
54-
required_device_array<rs232_port_device, 4> m_serial;
55-
};
5610

57-
DECLARE_DEVICE_TYPE(VME_TP881V, vme_tp881v_card_device)
11+
DECLARE_DEVICE_TYPE(VME_TP881V, device_vme_card_interface)
5812

5913
#endif // MAME_BUS_VME_TP881V_H

0 commit comments

Comments
 (0)