1
/*************************************************************************
5
The Vertigo vector CPU consists of four AMD 2901 bit slice
6
processors, logic to control microcode program flow and a digital
7
vector generator. The microcode for the bit slice CPUs is stored in 13
8
bipolar proms for a total of 512 52bit wide micro instructions. The
9
microcode not only crontrols the 2901s but also loading and storing
10
of operands and results, program flow control and vector generation.
12
+----+----+----+----+----+----+-------+-----+-----+------+-----+----+---+
13
|VUC |VUC |VUC |VUC |VUC |VUC | VUC | VUC | VUC | VUC | VUC |VUC |VUC| labels
14
| 10 | 13 | 9 | 8 | 7 | 6 | 5 | 12 | 11 | 2 | 1 | 4 | 3 |
15
+----+----+----+----+----+----+-------+-----+-----+------+-----+----+---+
16
| | | | | | | | | | | |PR5/|R5/| schematics
17
|J5/4|G5/1|K5/5|L5/6|M5/7|N5/8| P5/9 |H5/2 |HJ5/3|S5/12 |T5/13| 10 |11 |
18
+----+----+----+----+----+----+-------+-----+-----+------+-----+----+---+
19
55 44|4444|4444|3333|3333|3322|2 2 2 2|2 222|11 11|1 1 11|110 0|0000|0000
20
21 98|7654|3210|9876|5432|1098|7 6 5 4|3 210|98 76|5 4 32|109 8|7654|3210
22
xx|xxxx|aaaa|bbbb|iiii|iiii|i c m r|r ooo|ii oo| j jj|jjj m|mmmm|mmmm
23
54|3210|3210|3210|8765|4321|0 n r s|w fff|ff aa| p 43|210 a|aaaa|aaaa
24
e e|r 210|10 10| o | 8|7654|3210
28
x: address for 64 words of 16 bit wide SRAM
33
mreq, rsel, rwrite: signals for memory access
35
if: vector RAM/ROM data select
36
oa: vector RAM/ROM address select
37
jpos: jump condition inverted
38
j: jump condition and type
41
Variables, enums and defines are named as in the schematics (pp. 6, 7)
44
*************************************************************************/
48
#include "video/vector.h"
49
#include "includes/vertigo.h"
52
/*************************************
56
*************************************/
58
#define V_ADDPOINT(m,h,v,c,i) \
59
vector_add_point (m, ((h) & 0x7ff) << 14, (0x6ff - ((v) & 0x7ff)) << 14, VECTOR_COLOR444(c), (i))
61
#define ADD(r,s,c) (((r) + (s) + (c)) & 0xffff)
62
#define SUBR(r,s,c) ((~(r) + (s) + (c)) & 0xffff)
63
#define SUBS(r,s,c) (((r) + ~(s) + (c)) & 0xffff)
64
#define OR(r,s) ((r) | (s))
65
#define AND(r,s) ((r) & (s))
66
#define NOTRS(r,s) (~(r) & (s))
67
#define EXOR(r,s) ((r) ^ (s))
68
#define EXNOR(r,s) (~((r) ^ (s)))
70
/* values for MC_DST */
82
/* values for MC_IF */
88
/* values for MC_OA */
95
/* values for MC_JMP */
103
/* values for MC_JCON */
115
/*************************************
117
* Vector processor initialization
119
*************************************/
121
void vertigo_vproc_init(running_machine &machine)
123
vertigo_state *state = machine.driver_data<vertigo_state>();
124
state_save_register_item_array(machine, "vector_proc", NULL, 0, state->m_vs.sram);
125
state_save_register_item(machine, "vector_proc", NULL, 0, state->m_vs.ramlatch);
126
state_save_register_item(machine, "vector_proc", NULL, 0, state->m_vs.rom_adr);
127
state_save_register_item(machine, "vector_proc", NULL, 0, state->m_vs.pc);
128
state_save_register_item(machine, "vector_proc", NULL, 0, state->m_vs.ret);
130
state_save_register_item_array(machine, "vector_proc", NULL, 0, state->m_bsp.ram);
131
state_save_register_item(machine, "vector_proc", NULL, 0, state->m_bsp.d);
132
state_save_register_item(machine, "vector_proc", NULL, 0, state->m_bsp.q);
133
state_save_register_item(machine, "vector_proc", NULL, 0, state->m_bsp.f);
134
state_save_register_item(machine, "vector_proc", NULL, 0, state->m_bsp.y);
136
state->m_vgen.set_machine(machine);
137
state_save_register_item(machine, "vector_proc", NULL, 0, state->m_vgen.sreg);
138
state_save_register_item(machine, "vector_proc", NULL, 0, state->m_vgen.l1);
139
state_save_register_item(machine, "vector_proc", NULL, 0, state->m_vgen.l2);
140
state_save_register_item(machine, "vector_proc", NULL, 0, state->m_vgen.c_v);
141
state_save_register_item(machine, "vector_proc", NULL, 0, state->m_vgen.c_h);
142
state_save_register_item(machine, "vector_proc", NULL, 0, state->m_vgen.c_l);
143
state_save_register_item(machine, "vector_proc", NULL, 0, state->m_vgen.adder_s);
144
state_save_register_item(machine, "vector_proc", NULL, 0, state->m_vgen.adder_a);
145
state_save_register_item(machine, "vector_proc", NULL, 0, state->m_vgen.color);
146
state_save_register_item(machine, "vector_proc", NULL, 0, state->m_vgen.intensity);
147
state_save_register_item(machine, "vector_proc", NULL, 0, state->m_vgen.brez);
148
state_save_register_item(machine, "vector_proc", NULL, 0, state->m_vgen.vfin);
149
state_save_register_item(machine, "vector_proc", NULL, 0, state->m_vgen.hud1);
150
state_save_register_item(machine, "vector_proc", NULL, 0, state->m_vgen.hud2);
151
state_save_register_item(machine, "vector_proc", NULL, 0, state->m_vgen.vud1);
152
state_save_register_item(machine, "vector_proc", NULL, 0, state->m_vgen.vud2);
153
state_save_register_item(machine, "vector_proc", NULL, 0, state->m_vgen.hc1);
154
state_save_register_item(machine, "vector_proc", NULL, 0, state->m_vgen.ven);
158
void vertigo_vproc_reset(running_machine &machine)
160
vertigo_state *state = machine.driver_data<vertigo_state>();
164
state->m_vectorrom = (UINT16 *)machine.region("user1")->base();
165
mcode = (UINT64 *)machine.region("proms")->base();
167
/* Decode microcode */
168
for (i = 0; i < MC_LENGTH; i++)
170
state->m_mc[i].x = (mcode[i] >> 44) & 0x3f;
171
state->m_mc[i].a = (mcode[i] >> 40) & 0xf;
172
state->m_mc[i].b = (mcode[i] >> 36) & 0xf;
173
state->m_mc[i].inst = (mcode[i] >> 27) & 077;
174
state->m_mc[i].dest = (mcode[i] >> 33) & 07;
175
state->m_mc[i].cn = (mcode[i] >> 26) & 0x1;
176
state->m_mc[i].mreq = (mcode[i] >> 25) & 0x1;
177
state->m_mc[i].rwrite = (mcode[i] >> 23) & 0x1;
178
state->m_mc[i].rsel = state->m_mc[i].rwrite & ((mcode[i] >> 24) & 0x1);
179
state->m_mc[i].of = (mcode[i] >> 20) & 0x7;
180
state->m_mc[i].iif = (mcode[i] >> 18) & 0x3;
181
state->m_mc[i].oa = (mcode[i] >> 16) & 0x3;
182
state->m_mc[i].jpos = (mcode[i] >> 14) & 0x1;
183
state->m_mc[i].jmp = (mcode[i] >> 12) & 0x3;
184
state->m_mc[i].jcon = (mcode[i] >> 9) & 0x7;
185
state->m_mc[i].ma = mcode[i] & 0x1ff;
188
memset(&state->m_vs, 0, sizeof(state->m_vs));
189
memset(&state->m_bsp, 0, sizeof(state->m_bsp));
190
memset(&state->m_vgen, 0, sizeof(state->m_vgen));
194
/********************************************
196
* 4 x AM2901 bit slice processors
197
* Q3 and IN3 are hardwired
199
********************************************/
201
static void am2901x4 (am2901 *bsp, microcode *mc)
205
case 000: bsp->f = ADD(bsp->ram[mc->a], bsp->q, mc->cn); break;
206
case 001: bsp->f = ADD(bsp->ram[mc->a], bsp->ram[mc->b], mc->cn); break;
207
case 002: bsp->f = ADD(0, bsp->q, mc->cn); break;
208
case 003: bsp->f = ADD(0, bsp->ram[mc->b], mc->cn); break;
209
case 004: bsp->f = ADD(0, bsp->ram[mc->a], mc->cn); break;
210
case 005: bsp->f = ADD(bsp->d, bsp->ram[mc->a], mc->cn); break;
211
case 006: bsp->f = ADD(bsp->d, bsp->q, mc->cn); break;
212
case 007: bsp->f = ADD(bsp->d, 0, mc->cn); break;
214
case 010: bsp->f = SUBR(bsp->ram[mc->a], bsp->q, mc->cn); break;
215
case 011: bsp->f = SUBR(bsp->ram[mc->a], bsp->ram[mc->b], mc->cn); break;
216
case 012: bsp->f = SUBR(0, bsp->q, mc->cn); break;
217
case 013: bsp->f = SUBR(0, bsp->ram[mc->b], mc->cn); break;
218
case 014: bsp->f = SUBR(0, bsp->ram[mc->a], mc->cn); break;
219
case 015: bsp->f = SUBR(bsp->d, bsp->ram[mc->a], mc->cn); break;
220
case 016: bsp->f = SUBR(bsp->d, bsp->q, mc->cn); break;
221
case 017: bsp->f = SUBR(bsp->d, 0, mc->cn); break;
223
case 020: bsp->f = SUBS(bsp->ram[mc->a], bsp->q, mc->cn); break;
224
case 021: bsp->f = SUBS(bsp->ram[mc->a], bsp->ram[mc->b], mc->cn); break;
225
case 022: bsp->f = SUBS(0, bsp->q, mc->cn); break;
226
case 023: bsp->f = SUBS(0, bsp->ram[mc->b], mc->cn); break;
227
case 024: bsp->f = SUBS(0, bsp->ram[mc->a], mc->cn); break;
228
case 025: bsp->f = SUBS(bsp->d, bsp->ram[mc->a], mc->cn); break;
229
case 026: bsp->f = SUBS(bsp->d, bsp->q, mc->cn); break;
230
case 027: bsp->f = SUBS(bsp->d, 0, mc->cn); break;
232
case 030: bsp->f = OR(bsp->ram[mc->a], bsp->q); break;
233
case 031: bsp->f = OR(bsp->ram[mc->a], bsp->ram[mc->b]); break;
234
case 032: bsp->f = OR(0, bsp->q); break;
235
case 033: bsp->f = OR(0, bsp->ram[mc->b]); break;
236
case 034: bsp->f = OR(0, bsp->ram[mc->a]); break;
237
case 035: bsp->f = OR(bsp->d, bsp->ram[mc->a]); break;
238
case 036: bsp->f = OR(bsp->d, bsp->q); break;
239
case 037: bsp->f = OR(bsp->d, 0); break;
241
case 040: bsp->f = AND(bsp->ram[mc->a], bsp->q); break;
242
case 041: bsp->f = AND(bsp->ram[mc->a], bsp->ram[mc->b]); break;
243
case 042: bsp->f = AND(0, bsp->q); break;
244
case 043: bsp->f = AND(0, bsp->ram[mc->b]); break;
245
case 044: bsp->f = AND(0, bsp->ram[mc->a]); break;
246
case 045: bsp->f = AND(bsp->d, bsp->ram[mc->a]); break;
247
case 046: bsp->f = AND(bsp->d, bsp->q); break;
248
case 047: bsp->f = AND(bsp->d, 0); break;
250
case 050: bsp->f = NOTRS(bsp->ram[mc->a], bsp->q); break;
251
case 051: bsp->f = NOTRS(bsp->ram[mc->a], bsp->ram[mc->b]); break;
252
case 052: bsp->f = NOTRS(0, bsp->q); break;
253
case 053: bsp->f = NOTRS(0, bsp->ram[mc->b]); break;
254
case 054: bsp->f = NOTRS(0, bsp->ram[mc->a]); break;
255
case 055: bsp->f = NOTRS(bsp->d, bsp->ram[mc->a]); break;
256
case 056: bsp->f = NOTRS(bsp->d, bsp->q); break;
257
case 057: bsp->f = NOTRS(bsp->d, 0); break;
259
case 060: bsp->f = EXOR(bsp->ram[mc->a], bsp->q); break;
260
case 061: bsp->f = EXOR(bsp->ram[mc->a], bsp->ram[mc->b]); break;
261
case 062: bsp->f = EXOR(0, bsp->q); break;
262
case 063: bsp->f = EXOR(0, bsp->ram[mc->b]); break;
263
case 064: bsp->f = EXOR(0, bsp->ram[mc->a]); break;
264
case 065: bsp->f = EXOR(bsp->d, bsp->ram[mc->a]); break;
265
case 066: bsp->f = EXOR(bsp->d, bsp->q); break;
266
case 067: bsp->f = EXOR(bsp->d, 0); break;
268
case 070: bsp->f = EXNOR(bsp->ram[mc->a], bsp->q); break;
269
case 071: bsp->f = EXNOR(bsp->ram[mc->a], bsp->ram[mc->b]); break;
270
case 072: bsp->f = EXNOR(0, bsp->q); break;
271
case 073: bsp->f = EXNOR(0, bsp->ram[mc->b]); break;
272
case 074: bsp->f = EXNOR(0, bsp->ram[mc->a]); break;
273
case 075: bsp->f = EXNOR(bsp->d, bsp->ram[mc->a]); break;
274
case 076: bsp->f = EXNOR(bsp->d, bsp->q); break;
275
case 077: bsp->f = EXNOR(bsp->d, 0); break;
288
bsp->y = bsp->ram[mc->a];
289
bsp->ram[mc->b] = bsp->f;
293
bsp->ram[mc->b] = bsp->f;
297
bsp->q = (bsp->q >> 1) & 0x7fff; /* Q3 is low */
298
bsp->ram[mc->b] = (bsp->f >> 1) | 0x8000; /* IN3 is high! */
302
bsp->ram[mc->b] = (bsp->f >> 1) | 0x8000; /* IN3 is high! */
306
bsp->ram[mc->b] = (bsp->f << 1) & 0xffff;
307
bsp->q = (bsp->q << 1) & 0xffff;
311
bsp->ram[mc->b] = (bsp->f << 1) & 0xffff;
317
/********************************************
321
* This part of the hardware draws vectors
322
* under control of the bit slice processors.
323
* It is just a bunch of counters, latches
326
********************************************/
328
static void vertigo_vgen (vector_generator *vg)
333
vg->c_l = (vg->c_l+1) & 0xfff;
335
if ((vg->c_l & 0x800) == 0)
341
if (vg->brez) /* H/V counter enabled */
343
/* Depending on MSB of adder only one or both
344
counters are de-/incremented. This is all
345
defined by the shift register which is
346
latched in bits 12-15 of L1/L2.
348
if (vg->adder_s & 0x800)
351
vg->c_h += vg->hud1? -1: 1;
353
vg->c_v += vg->vud1? -1: 1;
354
vg->adder_a = vg->l1;
358
vg->c_h += vg->hud2? -1: 1;
359
vg->c_v += vg->vud2? -1: 1;
360
vg->adder_a = vg->l2;
363
/* H/V counters are 12 bit */
368
vg->adder_s = (vg->adder_s + vg->adder_a) & 0xfff;
371
if (vg->brez ^ vg->ven)
374
V_ADDPOINT (vg->machine(), vg->c_h, vg->c_v, 0, 0);
376
V_ADDPOINT (vg->machine(), vg->c_h, vg->c_v, vg->color, vg->intensity);
381
/*************************************
385
*************************************/
387
void vertigo_vproc(running_machine &machine, int cycles, int irq4)
389
vertigo_state *state = machine.driver_data<vertigo_state>();
393
if (irq4) vector_clear_list();
395
g_profiler.start(PROFILER_USER1);
399
/* Microcode at current PC */
400
cmc = &state->m_mc[state->m_vs.pc];
403
if (cmc->iif == S_RAMDE)
405
state->m_bsp.d = state->m_vs.ramlatch;
407
else if (cmc->iif == S_ROMDE)
409
if (state->m_vs.rom_adr < 0x2000)
411
state->m_bsp.d = state->m_vectorram[state->m_vs.rom_adr & 0xfff];
415
state->m_bsp.d = state->m_vectorrom[state->m_vs.rom_adr & 0x7fff];
419
/* SRAM selected ? */
424
state->m_bsp.d = state->m_vs.sram[cmc->x];
428
/* Data can be transferred between vector ROM/RAM
429
and SRAM without going through the 2901 */
430
state->m_vs.sram[cmc->x] = state->m_bsp.d;
434
am2901x4 (&state->m_bsp, cmc);
440
state->m_vs.ramlatch = state->m_bsp.y;
441
if (cmc->iif==S_RAMDE && (cmc->rsel == 0) && (cmc->rwrite == 0))
442
state->m_vs.sram[cmc->x] = state->m_vs.ramlatch;
445
state->m_vs.rom_adr = state->m_bsp.y;
448
/* FPOS is shifted into sreg */
449
state->m_vgen.sreg = (state->m_vgen.sreg >> 1) | ((state->m_bsp.f >> 9) & 4);
455
/* Vector generator setup */
459
state->m_vgen.color = state->m_bsp.y & 0xfff;
462
state->m_vgen.intensity = state->m_bsp.y & 0xff;
465
state->m_vgen.l1 = state->m_bsp.y & 0xfff;
466
state->m_vgen.adder_s = 0;
467
state->m_vgen.adder_a = state->m_vgen.l2;
468
state->m_vgen.hud1 = state->m_vgen.sreg & 1;
469
state->m_vgen.vud1 = state->m_vgen.sreg & 2;
470
state->m_vgen.hc1 = state->m_vgen.sreg & 4;
471
state->m_vgen.brez = 1;
474
state->m_vgen.l2 = state->m_bsp.y & 0xfff;
475
state->m_vgen.adder_s = (state->m_vgen.adder_s + state->m_vgen.adder_a) & 0xfff;
476
if (state->m_vgen.adder_s & 0x800)
477
state->m_vgen.adder_a = state->m_vgen.l1;
479
state->m_vgen.adder_a = state->m_vgen.l2;
480
state->m_vgen.hud2 = state->m_vgen.sreg & 1;
481
state->m_vgen.vud2 = state->m_vgen.sreg & 2;
484
state->m_vgen.c_v = state->m_bsp.y & 0xfff;
487
state->m_vgen.c_h = state->m_bsp.y & 0xfff;
490
/* Loading the c_l counter starts
491
* the vector counters if MSB is set
493
state->m_vgen.c_l = state->m_bsp.y & 0xfff;
497
vertigo_vgen (&state->m_vgen);
499
/* Microcode program flow */
503
/* ALU most significant bit */
504
jcond = (state->m_bsp.f >> 15) & 1;
508
jcond = (state->m_bsp.f == 0)? 1 : 0;
511
jcond = (state->m_bsp.y >> 10) & 1;
514
jcond = state->m_vgen.vfin;
518
jcond = (state->m_bsp.f >> 11) & 1;
522
/* Detect idle loop. If the code takes a jump
523
on irq4 or !irq4 the destination is a idle loop
524
waiting for irq4 state change. We then take a short
525
cut and run for just 100 cycles to make sure the
526
loop is actually entered.
528
if ((cmc->jpos != irq4) && cycles > 100)
538
if (jcond ^ cmc->jpos)
540
/* Except for JBK, address bit 8 isn't changed
545
/* JBK is the only jump where MA8 is used */
546
state->m_vs.pc = cmc->ma;
549
/* call and store return address */
550
state->m_vs.ret = (state->m_vs.pc + 1) & 0xff;
551
state->m_vs.pc = (state->m_vs.pc & 0x100) | (cmc->ma & 0xff);
554
/* OPT is used for microcode jump tables. The first
555
four address bits are defined by bits 12-15
557
state->m_vs.pc = (state->m_vs.pc & 0x100) | (cmc->ma & 0xf0) | ((state->m_bsp.d >> 12) & 0xf);
560
/* return from call */
561
state->m_vs.pc = (state->m_vs.pc & 0x100) | state->m_vs.ret;
567
state->m_vs.pc = (state->m_vs.pc & 0x100) | ((state->m_vs.pc + 1) & 0xff);