1010 *
1111 * TODO:
1212 * - scsi dma controllers
13+ * - networking
1314 * - serial dma
1415 * - vme interface
1516 * - interrupt enables/masking
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" )
0 commit comments