1 // license:BSD-3-Clause
2 // copyright-holders:Philip Bennett
3 /***************************************************************************
4
5 Bell-Fruit/ATD RasterSpeed hardware
6
7 driver by Phil Bennett
8
9 Games supported:
10 * Rise of the Robots (prototype)
11
12 ROMs wanted:
13 * Zool (prototype)
14 * Football Crazy (need HDD/CD image)
15
16 ****************************************************************************/
17
18 #include "emu.h"
19 #include "bus/nscsi/hd.h"
20 #include "cpu/i386/i386.h"
21 #include "cpu/tms32031/tms32031.h"
22 #include "machine/53c7xx.h"
23 #include "machine/mc146818.h"
24 #include "machine/nvram.h"
25 #include "machine/timer.h"
26 #include "sound/dac.h"
27 #include "emupal.h"
28 #include "screen.h"
29 #include "speaker.h"
30
31 /*************************************
32 *
33 * Defines
34 *
35 *************************************/
36
37 #define SOUND_CLOCK XTAL(12'288'000)
38 #define PLL_CLOCK XTAL(14'318'181)
39 #define NVRAM_SIZE 0x8000
40
41 #define USE_SPEEDUP_HACK 1
42
43
44 /*************************************
45 *
46 * Driver class
47 *
48 *************************************/
49
50 class rastersp_state : public driver_device
51 {
52 public:
rastersp_state(const machine_config & mconfig,device_type type,const char * tag)53 rastersp_state(const machine_config &mconfig, device_type type, const char *tag)
54 : driver_device(mconfig, type, tag)
55 , m_maincpu(*this, "maincpu")
56 , m_dsp(*this, "dsp")
57 , m_dram(*this, "dram")
58 , m_ldac(*this, "ldac")
59 , m_rdac(*this, "rdac")
60 , m_palette(*this, "palette")
61 , m_nvram(*this, "nvram")
62 , m_tms_timer1(nullptr)
63 , m_tms_tx_timer(nullptr)
64 {
65 }
66
67 void rastersp(machine_config &config);
68
69 private:
70 #define VIDEO_ADDR_MASK 0x3fffffff
71
72 enum tms_regs
73 {
74 DMA_GLOBAL_CTL = 0x00,
75 DMA_SOURCE_ADDR = 0x04,
76 DMA_DEST_ADDR = 0x06,
77 DMA_TRANSFER_COUNT = 0x08,
78
79 TIMER0_GLOBAL_CTL = 0x20,
80 TIMER0_COUNTER = 0x24,
81 TIMER0_PERIOD = 0x28,
82
83 TIMER1_GLOBAL_CTL = 0x30,
84 TIMER1_COUNTER = 0x34,
85 TIMER1_PERIOD = 0x38,
86
87 SPORT_GLOBAL_CTL = 0x40,
88 SPORT_TX_CTL = 0x42,
89 SPORT_RX_CTL = 0x43,
90 SPORT_TIMER_CTL = 0x44,
91 SPORT_TIMER_COUNTER = 0x45,
92 SPORT_TIMER_PERIOD = 0x46,
93 SPORT_DATA_TX = 0x48,
94 SPORT_DATA_RX = 0x4c
95 };
96
97 enum irq_status
98 {
99 IRQ_RTC = 1,
100 IRQ_UART = 2,
101 IRQ_DSP = 4,
102 IRQ_VBLANK = 5,
103 IRQ_SCSI = 7
104 };
105
106 required_device<i486_device> m_maincpu;
107 required_device<tms3203x_device> m_dsp;
108 required_shared_ptr<uint32_t> m_dram;
109 required_device<dac_16bit_r2r_twos_complement_device> m_ldac;
110 required_device<dac_16bit_r2r_twos_complement_device> m_rdac;
111 required_device<palette_device> m_palette;
112 required_device<nvram_device> m_nvram;
113
114 emu_timer *m_tms_timer1;
115 emu_timer *m_tms_tx_timer;
116
117 void cyrix_cache_w(uint32_t data);
118 uint8_t nvram_r(offs_t offset);
119 void nvram_w(offs_t offset, uint8_t data);
120 void port1_w(uint32_t data);
121 void port2_w(uint32_t data);
122 void port3_w(uint32_t data);
123 void dpylist_w(uint32_t data);
124 uint32_t tms32031_control_r(offs_t offset);
125 void tms32031_control_w(offs_t offset, uint32_t data);
126 void dsp_unk_w(uint32_t data);
127 void dsp_ctrl_w(uint32_t data);
128 void dsp_486_int_w(uint32_t data);
129 uint32_t dsp_speedup_r();
130 void dsp_speedup_w(uint32_t data);
131 uint32_t ncr53c700_read(offs_t offset, uint32_t mem_mask = ~0);
132 void ncr53c700_write(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
133 DECLARE_WRITE_LINE_MEMBER(scsi_irq);
134
135 TIMER_CALLBACK_MEMBER(tms_timer1);
136 TIMER_CALLBACK_MEMBER(tms_tx_timer);
137 DECLARE_WRITE_LINE_MEMBER(vblank_irq);
138
139 std::unique_ptr<uint8_t[]> m_nvram8;
140 uint8_t m_irq_status;
141 uint32_t m_dpyaddr;
142 std::unique_ptr<uint16_t[]> m_paletteram;
143 uint32_t m_speedup_count;
144 uint32_t m_tms_io_regs[0x80];
145 bitmap_ind16 m_update_bitmap;
146
147 uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
148 void update_irq(uint32_t which, uint32_t state);
149 void upload_palette(uint32_t word1, uint32_t word2);
150 IRQ_CALLBACK_MEMBER(irq_callback);
151 nscsi_connector &add_rastersp_scsi_slot(machine_config &config, const char *tag, const char *default_slot);
152 static void ncr53c700_config(device_t *device);
153 void cpu_map(address_map &map);
154 void dsp_map(address_map &map);
155 void io_map(address_map &map);
156
157 // driver_device overrides
158 virtual void machine_reset() override;
159 virtual void machine_start() override;
160 virtual void video_start() override;
161 };
162
163
164
165 /*************************************
166 *
167 * Initialisation
168 *
169 *************************************/
170
machine_start()171 void rastersp_state::machine_start()
172 {
173 m_nvram8 = std::make_unique<uint8_t[]>(NVRAM_SIZE);
174 m_nvram->set_base(m_nvram8.get(),NVRAM_SIZE);
175 m_paletteram = std::make_unique<uint16_t[]>(0x8000);
176
177 membank("bank1")->set_base(m_dram);
178 membank("bank2")->set_base(&m_dram[0x10000/4]);
179 membank("bank3")->set_base(&m_dram[0x300000/4]);
180
181 if (!m_tms_timer1)
182 m_tms_timer1 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(rastersp_state::tms_timer1), this));
183
184 if (!m_tms_tx_timer)
185 m_tms_tx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(rastersp_state::tms_tx_timer), this));
186
187 #if USE_SPEEDUP_HACK
188 m_dsp->space(AS_PROGRAM).install_read_handler(0x809923, 0x809923, read32smo_delegate(*this, FUNC(rastersp_state::dsp_speedup_r)));
189 m_dsp->space(AS_PROGRAM).install_write_handler(0x809923, 0x809923, write32smo_delegate(*this, FUNC(rastersp_state::dsp_speedup_w)));
190 #endif
191 }
192
193
machine_reset()194 void rastersp_state::machine_reset()
195 {
196 m_irq_status = 0;
197 m_dpyaddr = 0;
198
199 // Halt the 486 on reset - the DSP will release it from reset
200 m_maincpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
201
202 // Set IRQ1 line to cause DSP to boot from 0x400000
203 m_dsp->set_input_line(TMS3203X_IRQ1, ASSERT_LINE);
204 m_dsp->set_input_line(TMS3203X_IRQ1, CLEAR_LINE);
205
206 // Reset DSP internal registers
207 m_tms_io_regs[SPORT_GLOBAL_CTL] = 0;
208
209 m_tms_timer1->adjust(attotime::never);
210 m_tms_tx_timer->adjust(attotime::never);
211 }
212
213
214
215 /*************************************
216 *
217 * Video hardware
218 *
219 *************************************/
220
video_start()221 void rastersp_state::video_start()
222 {
223 m_update_bitmap.allocate(320, 240);
224 }
225
226
dpylist_w(uint32_t data)227 void rastersp_state::dpylist_w(uint32_t data)
228 {
229 m_dpyaddr = data;
230
231 // Update the video now
232 // TODO: This should probably be done in sync with the video scan
233 if (m_dpyaddr == 0)
234 {
235 m_update_bitmap.fill(m_palette->black_pen());
236 return;
237 }
238
239 uint32_t dpladdr = (m_dpyaddr & ~0xff) >> 6;
240
241 if ((m_dpyaddr & 0xff) != 0xb2 && (m_dpyaddr & 0xff) != 0xf2)
242 logerror("Unusual display list data: %x\n", m_dpyaddr);
243
244 int y = 0;
245 int x = 0;
246 uint16_t *bmpptr = &m_update_bitmap.pix(0, 0);
247
248 while (y < 240)
249 {
250 uint32_t word1 = m_dram[dpladdr/4];
251
252 if (word1 & 0x80000000)
253 {
254 // TODO: What does this signify?
255 dpladdr += 4;
256 }
257 else
258 {
259 uint32_t word2 = m_dram[(dpladdr + 4)/4];
260
261 dpladdr += 8;
262
263 if (word2 & 0x10000000)
264 {
265 if ((word2 & 0xfe000000) != 0x94000000)
266 logerror("Unusual display list entry: %x %x\n", word1, word2);
267
268 uint32_t srcaddr = word1 >> 8;
269 uint32_t pixels = (word2 >> 16) & 0x1ff;
270 uint32_t palbase = (word2 >> 4) & 0xf00;
271
272 uint16_t* palptr = &m_paletteram[palbase];
273 uint8_t* srcptr = reinterpret_cast<uint8_t*>(&m_dram[0]);
274
275 uint32_t acc = srcaddr << 8;
276
277 int32_t incr = word2 & 0xfff;
278
279 // Sign extend for our convenience
280 incr |= ~((incr & 0x800) - 1) & ~0xff;
281
282 // TODO: Assumes 8-bit palettized mode - the hardware also supports 16-bit direct
283 while (y < 240 && pixels)
284 {
285 while (x < 320 && pixels)
286 {
287 *bmpptr++ = palptr[srcptr[BYTE_XOR_LE(acc >> 8)]];
288 acc = (acc + incr) & VIDEO_ADDR_MASK;
289
290 --pixels;
291 ++x;
292 }
293
294 // Advance to the next scanline
295 if (x >= 320)
296 {
297 x = 0;
298 ++y;
299 }
300 }
301 }
302 else
303 {
304 if ((word2 & 0x0c000000) != 0x0c000000)
305 logerror("Unknown palette upload: %.8x %.8x\n", word1, word2);
306
307 upload_palette(word1, word2);
308 }
309 }
310 }
311 }
312
313
upload_palette(uint32_t word1,uint32_t word2)314 void rastersp_state::upload_palette(uint32_t word1, uint32_t word2)
315 {
316 if (word1 & 3)
317 fatalerror("Unalligned palette address! (%x, %x)\n", word1, word2);
318
319 uint32_t addr = word1 >> 8;
320 uint32_t entries = (word2 >> 16) & 0x1ff;
321 uint32_t index = ((word2 >> 12) & 0x1f) * 256;
322
323 // The third byte of each entry in RAM appears to contain an index
324 // but appears to be discared when written to palette RAM
325 while (entries--)
326 {
327 uint32_t data = m_dram[addr / 4];
328 m_paletteram[index++] = data & 0xffff;
329 addr += 4;
330 }
331 }
332
333
334 /*******************************************************************************
335
336 Display list register:
337
338 ..xxxxxx xxxxxxxx xxxxxxxx ........ Display list base (DWORD granularity)
339 ........ ........ ........ xxxxxxxx ? (number of entries? Only seems to be valid for basic stuff)
340
341 Display list format:
342
343 [0] ..xxxxxx xxxxxxxx xxxxxxxx ........ Source address (4MB mask?)
344
345 Palette update: (8d000400)
346 [1] 1....... ........ ........ ........ ?
347 ...0.... ........ ........ ........ 0 for palette upload?
348 ....11.. ........ ........ ........ ?
349 .......x xxxxxxxx ........ ........ Entry count
350 ........ ........ .....1.. ........ ? (Usually 1)
351
352 Pixel data: (94040100)
353 [2] 1....... ........ ........ ........ ?
354 ...1.... ........ ........ ........ 1 for video update?
355 .....1.. ........ ........ ........ ?
356 .......x xxxxxxxx ........ ........ Pixel count
357 ........ ........ xxxx.... ........ Palette
358 ........ ........ ....xxxx xxxxxxxx Scale (4.8 signed fixed point)
359
360 Unknown: (D4000100) - Present at start of a list
361 [3] 1....... ........ ........ .........
362 .1...... ........ ........ ......... ?
363 ..1..... ........ ........ .........
364 .....1.. ........ ........ ......... ?
365 ........ ........ .......1 ......... ?
366
367
368 TODO: I'm not sure about bit 28. When creating the display list if it's 0,
369 0x1000 is added to the source address.
370
371 *******************************************************************************/
372
screen_update(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)373 uint32_t rastersp_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
374 {
375 copybitmap(bitmap, m_update_bitmap, 0, 0, 0, 0, cliprect);
376 return 0;
377 }
378
379
380
381 /*************************************
382 *
383 * Interrupt handling
384 *
385 *************************************/
386
IRQ_CALLBACK_MEMBER(rastersp_state::irq_callback)387 IRQ_CALLBACK_MEMBER(rastersp_state::irq_callback)
388 {
389 uint8_t vector = 0;
390
391 if (m_irq_status & (1 << IRQ_SCSI))
392 {
393 vector = 11;
394 }
395 else if (m_irq_status & (1 << IRQ_DSP))
396 {
397 update_irq(IRQ_DSP, CLEAR_LINE);
398 vector = 12;
399 }
400 else if (m_irq_status & (1 << IRQ_VBLANK))
401 {
402 update_irq(IRQ_VBLANK, CLEAR_LINE);
403 vector = 13;
404 }
405 else
406 {
407 fatalerror("Unknown x86 IRQ (m_irq_status = %x)", m_irq_status);
408 }
409
410 return vector;
411 }
412
413
update_irq(uint32_t which,uint32_t state)414 void rastersp_state::update_irq(uint32_t which, uint32_t state)
415 {
416 uint32_t mask = 1 << which;
417
418 if (state)
419 m_irq_status |= mask;
420 else
421 m_irq_status &= ~mask;
422
423 m_maincpu->set_input_line(0, m_irq_status ? HOLD_LINE : CLEAR_LINE);
424 }
425
426
WRITE_LINE_MEMBER(rastersp_state::scsi_irq)427 WRITE_LINE_MEMBER( rastersp_state::scsi_irq )
428 {
429 update_irq(IRQ_SCSI, state);
430 }
431
432
WRITE_LINE_MEMBER(rastersp_state::vblank_irq)433 WRITE_LINE_MEMBER( rastersp_state::vblank_irq )
434 {
435 if (state)
436 update_irq(IRQ_VBLANK, ASSERT_LINE);
437 }
438
439
440
441 /*************************************
442 *
443 * 486 I/O
444 *
445 *************************************/
446
port1_w(uint32_t data)447 void rastersp_state::port1_w(uint32_t data)
448 {
449 // x... .... - LED?
450 // ..x. .... - DSP IRQ2 line
451 // .... ..xx - LEDs?
452
453 if (data & 0x20)
454 {
455 m_dsp->set_input_line(TMS3203X_IRQ2, ASSERT_LINE);
456 m_dsp->set_input_line(TMS3203X_IRQ2, CLEAR_LINE);
457 }
458 }
459
460
port2_w(uint32_t data)461 void rastersp_state::port2_w(uint32_t data)
462 {
463 // .x.. .... - X9313WP /INC
464 // ..x. .... - X9313WP U/#D
465 }
466
467
port3_w(uint32_t data)468 void rastersp_state:: port3_w(uint32_t data)
469 {
470 // xxxx xxxx - 8 LED cluster?
471 }
472
473
474
475 /*************************************
476 *
477 * NVRAM
478 *
479 *************************************/
480
nvram_w(offs_t offset,uint8_t data)481 void rastersp_state::nvram_w(offs_t offset, uint8_t data)
482 {
483 offset *= 4;
484
485 if ((offset & 0xc000) || !(offset & 0x2000))
486 {
487 logerror("Unmapped NVRAM write to offset: %x", offset);
488 }
489
490 offset &= ~0x2000;
491
492 uint32_t addr = ((offset & 0x00f0000) >> 5) | ((offset & 0x1fff) / 4);
493
494 m_nvram8[addr] = data & 0xff;
495 }
496
497
nvram_r(offs_t offset)498 uint8_t rastersp_state::nvram_r(offs_t offset)
499 {
500 offset *= 4;
501
502 if ((offset & 0xc000) || !(offset & 0x2000))
503 {
504 logerror("Unmapped NVRAM read from offset: %x", offset);
505 }
506
507 offset &= ~0x2000;
508
509 uint32_t addr = ((offset & 0x00f0000) >> 5) | ((offset & 0x1fff) / 4);
510
511 return m_nvram8[addr];
512 }
513
514
cyrix_cache_w(uint32_t data)515 void rastersp_state::cyrix_cache_w(uint32_t data)
516 {
517 // TODO?
518 }
519
520
521
522 /*************************************
523 *
524 * DSP
525 *
526 *************************************/
527
TIMER_CALLBACK_MEMBER(rastersp_state::tms_tx_timer)528 TIMER_CALLBACK_MEMBER(rastersp_state::tms_tx_timer)
529 {
530 // Is the transmit shifter full?
531 if (m_tms_io_regs[SPORT_GLOBAL_CTL] & (1 << 3))
532 {
533 uint32_t data = m_tms_io_regs[SPORT_DATA_TX];
534
535 m_ldac->write(data & 0xffff);
536 m_rdac->write(data >> 16);
537 }
538
539 // Set XSREMPTY
540 m_tms_io_regs[SPORT_GLOBAL_CTL] &= ~(1 << 3);
541
542 // Set XRDY
543 m_tms_io_regs[SPORT_GLOBAL_CTL] |= (1 << 1);
544
545 // Signal a transmit interrupt
546 if (m_tms_io_regs[SPORT_GLOBAL_CTL] & (1 << 23))
547 {
548 m_dsp->set_input_line(TMS3203X_XINT0, ASSERT_LINE);
549 m_dsp->set_input_line(TMS3203X_XINT0, CLEAR_LINE);
550 }
551 }
552
553
TIMER_CALLBACK_MEMBER(rastersp_state::tms_timer1)554 TIMER_CALLBACK_MEMBER(rastersp_state::tms_timer1)
555 {
556 }
557
558
tms32031_control_r(offs_t offset)559 uint32_t rastersp_state::tms32031_control_r(offs_t offset)
560 {
561 uint32_t val = m_tms_io_regs[offset];
562
563 switch (offset)
564 {
565 case TIMER1_COUNTER:
566 {
567 attotime elapsed = m_tms_timer1->elapsed();
568 val = m_tms_io_regs[TIMER1_PERIOD] - (elapsed.as_ticks(m_dsp->clock() / 2 / 2));
569
570 break;
571 }
572 default:
573 {
574 logerror("TMS32031: Unhandled I/O read: %x\n", offset);
575 }
576 }
577
578 return val;
579 }
580
581
tms32031_control_w(offs_t offset,uint32_t data)582 void rastersp_state::tms32031_control_w(offs_t offset, uint32_t data)
583 {
584 uint32_t old = m_tms_io_regs[offset];
585
586 m_tms_io_regs[offset] = data;
587
588 switch (offset)
589 {
590 case TIMER1_GLOBAL_CTL:
591 {
592 // Calculate the DSP clocks
593 attotime period = attotime::from_hz(m_dsp->clock() / 2 / 2);
594
595 period *= m_tms_io_regs[TIMER1_PERIOD];
596
597 m_tms_timer1->adjust(period, 0, period);
598
599 break;
600 }
601 case SPORT_GLOBAL_CTL:
602 {
603 if (!(data & (1 << 26)))
604 {
605 // Reset transmitter
606 m_tms_tx_timer->adjust(attotime::never);
607 }
608 else if (!(old & (1 << 26)) && (data & (1 << 26)))
609 {
610 // Sample rate is 24KHz
611 attotime period = attotime::from_hz(SOUND_CLOCK / 512);
612
613 // Set XRDY
614 m_tms_io_regs[SPORT_GLOBAL_CTL] |= (1 << 1);
615
616 // Set XSREMPTY
617 m_tms_io_regs[SPORT_GLOBAL_CTL] &= ~(1 << 3);
618
619 // Run transmitter
620 m_tms_tx_timer->adjust(period, 0, period);
621 }
622
623 break;
624 }
625 case SPORT_DATA_TX:
626 {
627 // Clear XRDY
628 m_tms_io_regs[SPORT_GLOBAL_CTL] &= ~(1 << 1);
629
630 // Clear XSREMPTY
631 m_tms_io_regs[SPORT_GLOBAL_CTL] |= (1 << 3);
632
633 break;
634 }
635 default:
636 {
637 logerror("TMS32031: Unhandled I/O write: %x %x\n", offset, data);
638 }
639 }
640 }
641
642
dsp_unk_w(uint32_t data)643 void rastersp_state::dsp_unk_w(uint32_t data)
644 {
645 // TODO: Looks like a debug port?
646 }
647
648
dsp_486_int_w(uint32_t data)649 void rastersp_state::dsp_486_int_w(uint32_t data)
650 {
651 update_irq(IRQ_DSP, ASSERT_LINE);
652 }
653
654
dsp_ctrl_w(uint32_t data)655 void rastersp_state::dsp_ctrl_w(uint32_t data)
656 {
657 // x... .... LED?
658 // .xx. .... 486 reset control?
659
660 m_maincpu->set_input_line(INPUT_LINE_RESET, (data & 0x60) == 0x60 ? CLEAR_LINE : ASSERT_LINE);
661 }
662
663
dsp_speedup_w(uint32_t data)664 void rastersp_state::dsp_speedup_w(uint32_t data)
665 {
666 // 809e90 48fd, 48d5
667 if (m_dsp->pc() == 0x809c23)
668 {
669 int32_t cycles_left = m_dsp->cycles_remaining();
670 data += cycles_left / 6;
671 m_dsp->spin();
672 }
673
674 m_speedup_count = data;
675 }
676
677
dsp_speedup_r()678 uint32_t rastersp_state::dsp_speedup_r()
679 {
680 return m_speedup_count;
681 }
682
683
684 /*************************************
685 *
686 * Memory maps
687 *
688 *************************************/
689
cpu_map(address_map & map)690 void rastersp_state::cpu_map(address_map &map)
691 {
692 map(0x00000000, 0x003fffff).ram().share("dram");
693 map(0x01000000, 0x010bffff).noprw(); // External ROM
694 map(0x010c0000, 0x010cffff).rom().region("bios", 0);
695 map(0x02200000, 0x022fffff).rw(FUNC(rastersp_state::nvram_r), FUNC(rastersp_state::nvram_w)).umask32(0x000000ff);
696 map(0x02200800, 0x02200803).nopw(); // ?
697 map(0x02208000, 0x02208fff).rw("scsibus:7:ncr53c700", FUNC(ncr53c7xx_device::read), FUNC(ncr53c7xx_device::write));
698 map(0x0220e000, 0x0220e003).w(FUNC(rastersp_state::dpylist_w));
699 map(0xfff00000, 0xffffffff).bankrw("bank3");
700 }
701
io_map(address_map & map)702 void rastersp_state::io_map(address_map &map)
703 {
704 map(0x0020, 0x0023).w(FUNC(rastersp_state::cyrix_cache_w));
705 map(0x1000, 0x1003).portr("P1").w(FUNC(rastersp_state::port1_w));
706 map(0x1004, 0x1007).portr("P2").w(FUNC(rastersp_state::port2_w));
707 map(0x1008, 0x100b).portr("COMMON").w(FUNC(rastersp_state::port3_w));
708 map(0x100c, 0x100f).portr("DSW2");
709 map(0x1010, 0x1013).portr("DSW1");
710 map(0x1014, 0x1017).portr("EXTRA");
711 map(0x4000, 0x4007).rw("rtc", FUNC(mc146818_device::read), FUNC(mc146818_device::write)).umask32(0x000000ff);
712 map(0x6008, 0x600b).nopr().nopw(); // RS232
713 }
714
715
dsp_map(address_map & map)716 void rastersp_state::dsp_map(address_map &map)
717 {
718 map(0x000000, 0x0fffff).bankrw("bank1");
719 map(0x400000, 0x40ffff).rom().region("dspboot", 0);
720 map(0x808000, 0x80807f).rw(FUNC(rastersp_state::tms32031_control_r), FUNC(rastersp_state::tms32031_control_w));
721 map(0x880402, 0x880402).w(FUNC(rastersp_state::dsp_unk_w));
722 map(0x883c00, 0x883c00).w(FUNC(rastersp_state::dsp_486_int_w));
723 map(0xc00000, 0xc03fff).bankrw("bank2");
724 map(0xc80000, 0xc80000).w(FUNC(rastersp_state::dsp_ctrl_w));
725 map(0xfc0000, 0xffffff).bankrw("bank3");
726 }
727
728
729
730 /*************************************
731 *
732 * Inputs
733 *
734 *************************************/
735
736 static INPUT_PORTS_START( rotr )
737 PORT_START("P1")
738 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1)
739 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1)
740 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1)
741 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1)
742 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
743 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
744 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)
745 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1)
746
747 PORT_START("P2")
748 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2)
749 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)
750 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2)
751 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2)
752 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
753 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
754 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
755 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2)
756
757 PORT_START("COMMON")
758 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
759 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 )
760 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START1 )
761 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START2 )
762 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_SERVICE )
763 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_TILT )
764 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
765 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
766
767 PORT_START("EXTRA")
768 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(1)
769 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_PLAYER(1)
770 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_PLAYER(1)
771 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_PLAYER(1)
772 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(2)
773 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_PLAYER(2)
774 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_PLAYER(2)
775 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_PLAYER(2)
776
777 PORT_START("DSW1")
778 PORT_DIPNAME( 0x01, 0x01, "Setup Disk" )
DEF_STR(Off)779 PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
780 PORT_DIPSETTING( 0x01, DEF_STR( On ) )
781
782 PORT_DIPNAME( 0x02, 0x00, DEF_STR( Service_Mode ) )
783 PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
784 PORT_DIPSETTING( 0x02, DEF_STR( On ) )
785
786 PORT_DIPNAME( 0x3c, 0x00, "Load PROG" )
787 PORT_DIPSETTING( 0x00, "0" )
788 PORT_DIPSETTING( 0x04, "1" )
789 PORT_DIPSETTING( 0x08, "2" )
790 PORT_DIPSETTING( 0x0c, "3" )
791 PORT_DIPSETTING( 0x10, "4" )
792 PORT_DIPSETTING( 0x14, "5" )
793 PORT_DIPSETTING( 0x18, "6" )
794 PORT_DIPSETTING( 0x1c, "7" )
795 PORT_DIPSETTING( 0x20, "8" )
796 PORT_DIPSETTING( 0x24, "9" )
797 PORT_DIPSETTING( 0x28, "A" )
798 PORT_DIPSETTING( 0x2c, "B" )
799 PORT_DIPSETTING( 0x30, "C" )
800 PORT_DIPSETTING( 0x34, "D" )
801 PORT_DIPSETTING( 0x38, "E" )
802 PORT_DIPSETTING( 0x3c, "F" )
803
804 PORT_DIPNAME( 0x40, 0x00, "Reserved" )
805 PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
806 PORT_DIPSETTING( 0x40, DEF_STR( On ) )
807
808 PORT_DIPNAME( 0x80, 0x00, "Enable Cache" )
809 PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
810 PORT_DIPSETTING( 0x80, DEF_STR( On ) )
811
812 PORT_START("DSW2")
813 PORT_DIPNAME( 0x01, 0x00, "Debug Screen" )
814 PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
815 PORT_DIPSETTING( 0x01, DEF_STR( On ) )
816
817 PORT_DIPNAME( 0x0e, 0x00, "FPGA File Source" )
818 PORT_DIPSETTING( 0x00, "Serial PROMs" )
819 PORT_DIPSETTING( 0x0e, "Cable" )
820
821 PORT_DIPNAME( 0x70, 0x50, "Clock speed" )
822 PORT_DIPSETTING( 0x00, "4" )
823 PORT_DIPSETTING( 0x10, "8" )
824 PORT_DIPSETTING( 0x20, "16" )
825 PORT_DIPSETTING( 0x30, "20" )
826 PORT_DIPSETTING( 0x40, "25" )
827 PORT_DIPSETTING( 0x50, "33" )
828 PORT_DIPSETTING( 0x60, "40" )
829 PORT_DIPSETTING( 0x70, "50" )
830
831 PORT_DIPNAME( 0x80, 0x00, "SCSI bus terminated" )
832 PORT_DIPSETTING( 0x00, DEF_STR( Yes ) )
833 PORT_DIPSETTING( 0x80, DEF_STR( No ) )
834 INPUT_PORTS_END
835
836
837
838 /*************************************
839 *
840 * SCSI
841 *
842 *************************************/
843
844 uint32_t rastersp_state::ncr53c700_read(offs_t offset, uint32_t mem_mask)
845 {
846 return m_maincpu->space(AS_PROGRAM).read_dword(offset, mem_mask);
847 }
848
ncr53c700_write(offs_t offset,uint32_t data,uint32_t mem_mask)849 void rastersp_state::ncr53c700_write(offs_t offset, uint32_t data, uint32_t mem_mask)
850 {
851 m_maincpu->space(AS_PROGRAM).write_dword(offset, data, mem_mask);
852 }
853
ncr53c700_config(device_t * device)854 void rastersp_state::ncr53c700_config(device_t *device)
855 {
856 auto *state = device->subdevice<rastersp_state>(":");
857 ncr53c7xx_device &scsictrl = downcast<ncr53c7xx_device &>(*device);
858 scsictrl.set_clock(66000000);
859 scsictrl.irq_handler().set(*state, FUNC(rastersp_state::scsi_irq));
860 scsictrl.host_read().set(*state, FUNC(rastersp_state::ncr53c700_read));
861 scsictrl.host_write().set(*state, FUNC(rastersp_state::ncr53c700_write));
862 }
863
864 /*************************************
865 *
866 * Machine driver
867 *
868 *************************************/
869
rastersp(machine_config & config)870 void rastersp_state::rastersp(machine_config &config)
871 {
872 I486(config, m_maincpu, 33330000);
873 m_maincpu->set_addrmap(AS_PROGRAM, &rastersp_state::cpu_map);
874 m_maincpu->set_addrmap(AS_IO, &rastersp_state::io_map);
875 m_maincpu->set_irq_acknowledge_callback(FUNC(rastersp_state::irq_callback));
876
877 TMS32031(config, m_dsp, 33330000);
878 m_dsp->set_addrmap(AS_PROGRAM, &rastersp_state::dsp_map);
879 m_dsp->set_mcbl_mode(true); // Boot-loader mode
880
881 MC146818(config, "rtc", 32.768_kHz_XTAL);
882
883 NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
884
885 NSCSI_BUS(config, "scsibus", 0);
886
887 nscsi_connector &connector0(NSCSI_CONNECTOR(config, "scsibus:0", 0));
888 connector0.option_add("harddisk", NSCSI_HARDDISK);
889 connector0.option_add_internal("ncr53c700", NCR53C7XX);
890 connector0.set_default_option("harddisk");
891 connector0.set_fixed(true);
892
893 nscsi_connector &connector7(NSCSI_CONNECTOR(config, "scsibus:7", 0));
894 connector7.option_add("harddisk", NSCSI_HARDDISK);
895 connector7.option_add_internal("ncr53c700", NCR53C7XX);
896 connector7.set_default_option("ncr53c700");
897 connector7.set_fixed(true);
898 connector7.set_option_machine_config("ncr53c700", ncr53c700_config);
899
900 /* Video */
901 screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
902 screen.set_size(320, 240);
903 screen.set_visarea(0, 320-1, 0, 240-1);
904 screen.set_screen_update(FUNC(rastersp_state::screen_update));
905 screen.set_refresh_hz(50);
906 screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
907 screen.set_palette(m_palette);
908 screen.screen_vblank().set(FUNC(rastersp_state::vblank_irq));
909
910 PALETTE(config, m_palette, palette_device::RGB_565);
911
912 /* Sound */
913 SPEAKER(config, "lspeaker").front_left();
914 SPEAKER(config, "rspeaker").front_right();
915
916 DAC_16BIT_R2R_TWOS_COMPLEMENT(config, m_ldac, 0);
917 DAC_16BIT_R2R_TWOS_COMPLEMENT(config, m_rdac, 0);
918 m_ldac->add_route(ALL_OUTPUTS, "lspeaker", 0.5); // unknown DAC
919 m_rdac->add_route(ALL_OUTPUTS, "rspeaker", 0.5); // unknown DAC
920 }
921
922
923
924 /*************************************
925 *
926 * ROM definitions
927 *
928 *************************************/
929
930 ROM_START( rotr )
931 ROM_REGION32_LE(0x100000, "bios", 0)
932 ROM_LOAD( "rasterspeed2.1_bootrom4.u10", 0x00000, 0x10000, CRC(6da142d1) SHA1(e2dbd479034677726fc26fd1ba85c4458d89286c) )
933
934 ROM_REGION32_LE(0x1000000, "dspboot", 0)
935 ROM_LOAD32_BYTE( "rasterspeed2.1_bootrom4.u10", 0x00000, 0x10000, CRC(6da142d1) SHA1(e2dbd479034677726fc26fd1ba85c4458d89286c) )
936
937 ROM_REGION(0x8000, "proms", 0) /* Xilinx FPGA PROMs */
938 ROM_LOAD( "17128dpc.u72", 0x0000, 0x4000, CRC(5ddf6ee3) SHA1(f3d15b649b5641374a9e14877cea84ba9c57ef3c) )
939 ROM_LOAD( "17128dpc.u73", 0x2000, 0x4000, CRC(9e274cea) SHA1(e974cad4e4b965bf2c9df7d3d0b4eec64629eeb0) )
940
941 ROM_REGION(0x8000, "nvram", 0) /* Default NVRAM */
942 ROM_LOAD( "rotr.nv", 0x0000, 0x8000, CRC(62543517) SHA1(a4bf3431cdab956839bb155c4a8c140d30e5c7ec) )
943
944 DISK_REGION( "scsibus:0:harddisk:image" )
945 DISK_IMAGE( "rotr", 0, SHA1(d67d7feb52d8c7ba1d2a190a40d97e84871f2d80) )
946 ROM_END
947
948
949 ROM_START( rotra )
950 ROM_REGION32_LE(0x100000, "bios", 0)
951 ROM_LOAD( "rasterspeed2.1_bootrom4.u10", 0x00000, 0x10000, CRC(6da142d1) SHA1(e2dbd479034677726fc26fd1ba85c4458d89286c) )
952
953 ROM_REGION32_LE(0x1000000, "dspboot", 0)
954 ROM_LOAD32_BYTE( "rasterspeed2.1_bootrom4.u10", 0x00000, 0x10000, CRC(6da142d1) SHA1(e2dbd479034677726fc26fd1ba85c4458d89286c) )
955
956 ROM_REGION(0x8000, "proms", 0) /* Xilinx FPGA PROMs */
957 ROM_LOAD( "17128dpc.u72", 0x0000, 0x4000, CRC(5ddf6ee3) SHA1(f3d15b649b5641374a9e14877cea84ba9c57ef3c) )
958 ROM_LOAD( "17128dpc.u73", 0x2000, 0x4000, CRC(9e274cea) SHA1(e974cad4e4b965bf2c9df7d3d0b4eec64629eeb0) )
959
960 ROM_REGION(0x8000, "nvram", 0) /* Default NVRAM */
961 ROM_LOAD( "rotr.nv", 0x0000, 0x8000, CRC(62543517) SHA1(a4bf3431cdab956839bb155c4a8c140d30e5c7ec) )
962
963 DISK_REGION( "scsibus:0:harddisk:image" )
964 DISK_IMAGE( "rotra", 0, SHA1(570d402e5e9bba123edf7dfa9db7a0e6bdb23823) )
965 ROM_END
966
967 /*
968 Football Crazy runs on the (c)1997 "RASTERSPEED 2.1 31-599-001 ISS 4" PCB, which seems to be a more modern production version.
969 a PCB photo with the rom sticker showing the text below has also been seen
970
971 Football Crazy Cashflow
972 95 750 956
973 STANDARD UK 64K
974 VER. FOOT 3.2 BFM
975
976
977
978 */
979
980 // the rom also exists in some odd hex format like this
981 // ROM_LOAD( "95751937.hex", 0x0000, 0x025f91, CRC(8f412e97) SHA1(a5ff924fbc327114e59d75de644ed0d5cd7fa6b3) )
982 ROM_START( fbcrazy )
983 ROM_REGION32_LE(0x100000, "bios", 0)
984 ROM_LOAD( "95751937.bin", 0x0000, 0x010000, CRC(4a99ee11) SHA1(335398ebc64bbfe86e2652ac080a5943dd413928) )
985
986 ROM_REGION32_LE(0x1000000, "dspboot", 0)
987 ROM_LOAD32_BYTE( "95751937.bin", 0x0000, 0x010000, CRC(4a99ee11) SHA1(335398ebc64bbfe86e2652ac080a5943dd413928) )
988
989 ROM_REGION(0x8000, "proms", ROMREGION_ERASEFF )
990 /* not on this PCB type? */
991
992 ROM_REGION(0x8000, "nvram", ROMREGION_ERASEFF )
993
994 DISK_REGION( "scsibus:0:harddisk:image" )
995 DISK_IMAGE( "fbcrazy_hdd", 0, NO_DUMP )
996 ROM_END
997
998 /*************************************
999 *
1000 * Game drivers
1001 *
1002 *************************************/
1003
1004 GAME( 1994, rotr, 0, rastersp, rotr, rastersp_state, empty_init, ROT0, "BFM/Mirage", "Rise of the Robots (prototype)", 0 )
1005 GAME( 1994, rotra, rotr, rastersp, rotr, rastersp_state, empty_init, ROT0, "BFM/Mirage", "Rise of the Robots (prototype, older)", 0 )
1006 GAME( 1997, fbcrazy, 0, rastersp, rotr, rastersp_state, empty_init, ROT0, "BFM", "Football Crazy (Video Quiz)", MACHINE_NOT_WORKING )
1007