Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/genplus-gx/core/cart_hw/svp/svpdoc.txt
2 views
1
-------------------------------------------------------------------------------
2
notaz's SVP doc
3
$Id: svpdoc.txt 349 2008-02-04 23:13:59Z notaz $
4
Copyright 2008, Grazvydas Ignotas (notaz)
5
-------------------------------------------------------------------------------
6
7
If you use this, please credit me in your work or it's documentation.
8
Tasco Deluxe should also be credited for his pioneering work on the subject.
9
Thanks.
10
11
Use monospace font and disable word wrap when reading this document.
12
13
-------------------------------------------------------------------------------
14
Table of Contents
15
-------------------------------------------------------------------------------
16
17
0. Introduction
18
1. Overview
19
2. The SSP160x DSP
20
2.1. General registers
21
2.2. External registers
22
2.3. Pointer registers
23
2.4. The instruction set
24
3. Memory map
25
4. Other notes
26
27
28
-------------------------------------------------------------------------------
29
0. Introduction
30
-------------------------------------------------------------------------------
31
32
This document is an attempt to provide technical information needed to
33
emulate Sega's SVP chip. It is based on reverse engineering Virtua Racing
34
game and on various internet sources. None of information provided here
35
was verified on the real hardware, so some things are likely to be
36
inaccurate.
37
38
The following information sources were used while writing this document
39
and emulator implementation:
40
41
[1] SVP Reference Guide (annotated) and SVP Register Guide (annotated)
42
by Tasco Deluxe < tasco.deluxe @ gmail.com >
43
http://www.sharemation.com/TascoDLX/SVP%20Reference%20Guide%202007.02.11.txt
44
http://www.sharemation.com/TascoDLX/SVP%20Register%20Guide%202007.02.11.txt
45
[2] SSP1610 disassembler
46
written by Pierpaolo Prazzoli, MAME source code.
47
http://mamedev.org/
48
[3] SSP1601 DSP datasheet
49
http://notaz.gp2x.de/docs/SSP1601.pdf
50
[4] DSP page (with code samples) in Samsung Semiconductor website from 1997
51
retrieved from Internet Archive: The Wayback Machine
52
http://web.archive.org/web/19970607052826/www.sec.samsung.com/Products/dsp/dspcore.htm
53
[5] Sega's SVP Chip: The Road not Taken?
54
Ken Horowitz, Sega-16
55
http://sega-16.com/feature_page.php?id=37&title=Sega's%20SVP%20Chip:%20The%20Road%20not%20Taken?
56
57
58
-------------------------------------------------------------------------------
59
1. Overview
60
-------------------------------------------------------------------------------
61
62
The only game released with SVP chip was Virtua Racing. There are at least 4
63
versions of the game: USA, Jap and 2 different Eur revisions. Three of them
64
share identical SSP160x code, one of the Eur revisions has some differences.
65
66
From the software developer's point of view, the game cartridge contains
67
at least:
68
69
* Samsung SSP160x 16-bit DSP core, which includes [3]:
70
* Two independent high-speed RAM banks, accessed in single clock cycle,
71
256 words each.
72
* 16 x 16 bit multiply unit.
73
* 32-bit ALU, status register.
74
* Hardware stack of 6 levels.
75
* 128KB of DRAM.
76
* 2KB of IRAM (instruction RAM).
77
* Memory controller with address mapping capability.
78
* 2MB of game ROM.
79
80
[5] claims there is also "2 Channels PWM" in the cartridge, but it's either
81
not used or not there at all.
82
Various sources claim that SSP160x is SSP1601 which is likely to be true,
83
because the code doesn't seem to use any SSP1605+ features.
84
85
86
-------------------------------------------------------------------------------
87
2. The SSP160x DSP
88
-------------------------------------------------------------------------------
89
90
SSP160x is 16-bit DSP, capable of performing multiplication + addition in
91
single clock cycle [3]. It has 8 general, 8 external and 8 pointer registers.
92
There is a status register which has operation control bits and condition
93
flags. Condition flags are set/cleared during ALU (arithmetic, logic)
94
operations. It also has 6-level hardware stack and 2 internal RAM banks
95
RAM0 and RAM1, 256 words each.
96
97
The device is only capable of addressing 16-bit words, so all addresses refer
98
to words (16bit value in ROM, accessed by 68k through address 0x84 would be
99
accessed by SSP160x using address 0x42).
100
101
[3] mentions interrupt pins, but interrupts don't seem to be used by SVP code
102
(actually there are functions which look like interrupt handler routines, but
103
they don't seem to do anything important).
104
105
2.1. General registers
106
----------------------
107
108
There are 8 general registers: -, X, Y, A, ST, STACK, PC and P ([2] [4]).
109
Size is given in bits.
110
111
2.1.1. "-"
112
Constant register with all bits set (0xffff). Also used for programming
113
external registers (blind reads/writes, see 2.2).
114
size: 16
115
116
2.1.2. "X"
117
Generic register. Also acts as a multiplier 1 for P register.
118
size: 16
119
120
2.1.3. "Y"
121
Generic register. Also acts as a multiplier 2 for P register.
122
size: 16
123
124
2.1.4. "A"
125
Accumulator. Stores the result of all ALU (but not multiply) operations,
126
status register is updated according to this. When directly accessed,
127
only upper word is read/written. Low word can be accessed by using AL
128
(see 2.2.8).
129
size: 32
130
131
2.1.5. "ST"
132
STatus register. Bits 0-9 are CONTROL, other are FLAG [2]. Only some of
133
them are actually used by SVP.
134
Bits: fedc ba98 7654 3210
135
210 - RPL "Loop size". If non-zero, makes (rX+) and (rX-) respectively
136
modulo-increment and modulo-decrement (see 2.3). The value
137
shows which power of 2 to use, i.e. 4 means modulo by 16.
138
43 - RB Unknown. Not used by SVP code.
139
5 - ST5 Affects behavior of external registers. See 2.2.
140
6 - ST6 Affects behavior of external registers. See 2.2.
141
According to [3] (5,6) bits correspond to hardware pins.
142
7 - IE Interrupt enable? Not used by SVP code.
143
8 - OP Saturated value? Not used by SVP code.
144
9 - MACS MAC shift? Not used by SVP code.
145
a - GPI_0 Interrupt 0 enable/status? Not used by SVP code.
146
b - GPI_1 Interrupt 1 enable/status? Not used by SVP code.
147
c - L L flag. Similar to carry? Not used by SVP code.
148
d - Z Zero flag. Set after ALU operations, when all 32 accumulator
149
bits become zero.
150
e - OV Overflow flag. Not used by SVP code.
151
f - N Negative flag. Set after ALU operations, when bit31 in
152
accumulator is 1.
153
size: 16
154
155
2.1.6. "STACK"
156
Hardware stack of 6 levels [3]. Values are "pushed" by directly writing to
157
it, or by "call" instruction. "Pop" is performed by directly reading the
158
register or by "ret" instruction.
159
size: 16
160
161
2.1.7. "PC"
162
Program Counter. Can be written directly to perform a jump. It is not clear
163
if it is possible to read it (SVP code never does).
164
size: 16
165
166
2.1.8. "P"
167
multiply Product - multiplication result register.
168
Always contains 32-bit multiplication result of X, Y and 2 (P = X * Y * 2).
169
X and Y are sign-extended before performing the multiplication.
170
size: 32
171
172
2.2. External registers
173
-----------------------
174
175
The external registers, as the name says, are external to SSP160x, they are
176
hooked to memory controller in SVP, so by accessing them we actually program
177
the memory controller. They act as programmable memory access registers or
178
external status registers [1]. Some of them can act as both, depending on how
179
ST5 ans ST6 bits are set in status register. After a register is programmed,
180
accessing it causes reads/writes from/to external memory (see section 3 for
181
the memory map). The access may also cause some additional effects, like
182
incremental of address, associated with accessed register.
183
In this document and my emu, instead of using names EXT0-EXT7
184
from [4] I used different names for these registers. Those names are from
185
Tasco Deluxe's [1] doc.
186
187
All these registers can be blind-accessed (as said in [1]) by performing
188
(ld -, PMx) or (ld PMx, -). This programs them to access memory (except PMC,
189
where the effect is different).
190
All registers are 16-bit.
191
192
2.2.1. "PM0"
193
If ST5 or ST6 is set, acts as Programmable Memory access register
194
(see 2.2.7). Else it acts as status of XST (2.2.4). It is also mapped
195
to a15004 on 68k side:
196
???????? ??????10
197
0: set, when SSP160x has written something to XST
198
(cleared when 015004 is read by 68k)
199
1: set, when 68k has written something to a15000 or a15002
200
(cleared on PM0 read by SSP160x)
201
Note that this is likely to be incorrect, but such behavior is OK for
202
emulation to work.
203
204
2.2.2. "PM1"
205
Programmable Memory access register. Only accessed with ST bits set by
206
SVP code.
207
208
2.2.3. "PM2"
209
Same as PM1.
210
211
2.2.4. "XST"
212
If ST5 or ST6 is set, acts as Programmable Memory access register
213
(only used by memory test code). Else it acts as eXternal STatus
214
register, which is also mapped to a15000 and a15002 on 68k side.
215
Affects PM0 when written to.
216
217
2.2.5. "PM4"
218
Programmable Memory access register. Not affected by ST5 and ST6 bits,
219
always stays in PMAR mode.
220
221
2.2.6. "EXT5"
222
Not used by SVP, so not covered by this document.
223
224
2.2.7. "PMC"
225
Programmable Memory access Control. It is set using 2 16bit writes, first
226
address, then mode word. After setting PMAC, PMx should be blind accessed
227
using (ld -, PMx) or (ld PMx, -) to program it for reading or writing
228
external memory respectively. Every PMx register can be programmed to
229
access it's own memory location with it's own mode. Registers are programmed
230
separately for reading and writing.
231
232
Reading PMC register also shifts it's state (from "waiting for address" to
233
"waiting for mode" and back). Reads always return address word related to
234
last PMx register accessed, or last address word written to PMC (whichever
235
event happened last before PMC read).
236
237
The address word contains bits 0-15 of the memory word-address.
238
The mode word format is as follows:
239
dsnnnv?? ???aaaaa
240
a: bits 16-20 of memory word-address.
241
n: auto-increment value. If set, after every access of PMx, word-address
242
value related to it will be incremented by (words):
243
1 - 1 5 - 16
244
2 - 2 6 - 32
245
3 - 4 7 - 128
246
4 - 8
247
d: make auto-increment negative - decrement by count listed above.
248
s: special-increment mode. If current address is even (when accessing
249
programmed PMx), increment it by 1. Else, increment by 32. It is not
250
clear what happens if d and n bits are also set (never done by SVP).
251
v: over-write mode when writing, unknown when reading (not used).
252
Over-write mode splits the word being written into 4 half-bytes and
253
only writes those half-bytes, which are not zero.
254
When auto-increment is performed, it affects all 21 address bits.
255
256
2.2.8. "AL"
257
This register acts more like a general register.
258
If this register is blind-accessed, it is "dummy programmed", i.e. nothing
259
happens and PMC is reset to "waiting for address" state.
260
In all other cases, it is Accumulator Low, 16 least significant bits of
261
accumulator. Normally reading acc (ld X, A) you get 16 most significant
262
bits, so this allows you access the low word of 32bit accumulator.
263
264
2.3. Pointer registers
265
----------------------
266
267
There are 8 8-bit pointer registers rX, which are internal to SSP160x and are
268
used to access internal RAM banks RAM0 and RAM1, or program memory indirectly.
269
r0-r3 (ri) point to RAM0, r4-r7 (rj) point to RAM1. Each bank has 256 words of
270
RAM, so 8bit registers can fully address them. The registers can be accessed
271
directly, or 2 indirection levels can be used [ (rX), ((rX)) ]. They work
272
similar to * and ** operators in C, only they use different types of memory
273
and ((rX)) also performs post-increment. First indirection level (rX) accesses
274
a word in RAMx, second accesses program memory at address read from (rX), and
275
increments value in (rX).
276
277
Only r0,r1,r2,r4,r5,r6 can be directly modified (ldi r0, 5), or by using
278
modifiers. 3 modifiers can be applied when using first indirection level
279
(optional):
280
+ : post-increment (ld a, (r0+) ). Increment register value after operation.
281
Can be made modulo-increment by setting RPL bits in status register
282
(see 2.1.5).
283
- : post-decrement. Also can be made modulo-decrement by using RPL bits in ST.
284
+!: post-increment, unaffected by RPL (probably).
285
These are only used on 1st indirection level, so things like ( ld a, ((r0+)) )
286
and (ld X, r6-) are probably invalid.
287
288
r3 and r7 are special and can not be changed (at least Samsung samples [4] and
289
SVP code never do). They are fixed to the start of their RAM banks. (They are
290
probably changeable for ssp1605+, Samsung's old DSP page claims that).
291
1 of these 4 modifiers must be used on these registers (short form direct
292
addressing? [2]):
293
|00: RAMx[0] The very first word in the RAM bank.
294
|01: RAMx[1] Second word
295
|10: RAMx[2] ...
296
|11: RAMx[3]
297
298
2.4. The instruction set
299
------------------------
300
301
The Samsung SSP16 series assembler uses right-to-left notation ([2] [4]):
302
ld X, Y
303
means value from Y should be copied to X.
304
305
Size of every instruction is word, some have extension words for immediate
306
values. When writing an interpreter, 7 most significant bits are usually
307
enough to determine which opcode it is.
308
309
encoding bits are marked as:
310
rrrr - general or external register, in order specified in 2.1 and 2.2
311
(0 is '-', 1 'X', ..., 8 is 'PM0', ..., 0xf is 'AL')
312
dddd - same as above, as destination operand
313
ssss - same as above, as source operand
314
jpp - pointer register index, 0-7
315
j - specifies RAM bank, i.e. RAM0 or RAM1
316
i* - immediate value bits
317
a* - offset in internal RAM bank
318
mm - modifier for pointer register, depending on register:
319
r0-r2,r4-r6 r3,r7 examples
320
0: (none) |00 ld a, (r0) cmp a, (r7|00)
321
1: +! |01 ld (r0+!), a ld (r7|01), a
322
2: - |10 add a, (r0-)
323
3: + |11
324
cccc - encodes condition, only 3 used by SVP, see check_cond() below
325
ooo - operation to perform
326
327
Operation is written in C-style pseudo-code, where:
328
program_memory[X] - access program memory at address X
329
RAMj[X] - access internal RAM bank j=0,1 (RAM0 or RAM1), word
330
offset X
331
RIJ[X] - pointer register rX, X=0-7
332
pr_modif_read(m,X) - read pointer register rX, applying modifier m:
333
if register is r3 or r7, return value m
334
else switch on value m:
335
0: return rX;
336
1: tmp = rX; rX++; return tmp; // rX+!
337
2: tmp = rX; modulo_decrement(rX); return tmp; // rX-
338
3: tmp = rX; modulo_increment(rX); return tmp; // rX+
339
the modulo value used (if used at all) depends on ST
340
RPL bits (see 2.1.5)
341
check_cond(c,f) - checks if a flag matches f bit:
342
switch (c) {
343
case 0: return true;
344
case 5: return (Z == f) ? true : false; // check Z flag
345
case 7: return (N == f) ? true : false; // check N flag
346
} // other conditions are possible, but they are not used
347
update_flags() - update ST flags according to last ALU operation.
348
sign_extend(X) - sign extend 16bit value X to 32bits.
349
next_op_address() - address of instruction after current instruction.
350
351
2.4.1. ALU instructions
352
353
All of these instructions update flags, which are set according to full 32bit
354
accumulator. The SVP code only checks N and Z flags, so it is not known when
355
exactly OV and L flags are set. Operations are performed on full A, so
356
(andi A, 0) would clear all 32 bits of A.
357
358
They share the same addressing modes. The exact arithmetic operation is
359
determined by 3 most significant (ooo) bits:
360
001 - sub - subtract (OP -=)
361
011 - cmp - compare (OP -, flags are updated according to result)
362
100 - add - add (OP +=)
363
101 - and - binary AND (OP &=)
364
110 - or - binary OR (OP |=)
365
111 - eor - exclusive OR (OP ^=)
366
367
syntax encoding operation
368
OP A, s ooo0 0000 0000 rrrr A OP r << 16;
369
OP A, (ri) ooo0 001j 0000 mmpp A OP RAMj[pr_modif_read(m,jpp)] << 16;
370
OP A, adr ooo0 011j aaaa aaaa A OP RAMj[a] << 16;
371
OPi A, imm ooo0 1000 0000 0000 A OP i << 16;
372
iiii iiii iiii iiii
373
op A, ((ri)) ooo0 101j 0000 mmpp tmp = pr_modif_read(m,jpp);
374
A OP program_memory[RAMj[tmp]] << 16;
375
RAMj[tmp]++;
376
op A, ri ooo1 001j 0000 00pp A OP RIJ[jpp] << 16;
377
OPi simm ooo1 1000 iiii iiii A OP i << 16;
378
379
There is also "perform operation on accumulator" instruction:
380
381
syntax encoding operation
382
mod cond, op 1001 000f cccc 0ooo if (check_cond(c,f)) switch(o) {
383
case 2: A >>= 1; break; // arithmetic shift
384
case 3: A <<= 1; break;
385
case 6: A = -A; break; // negate A
386
case 7: A = abs(A); break; // absolute val.
387
} // other operations are possible, but
388
// they are not used by SVP.
389
390
2.4.2. Load (move) instructions
391
392
These instructions never affect flags (even ld A).
393
If destination is A, and source is 16bit, only upper word is transfered (same
394
thing happens on opposite). If dest. is A, and source is P, whole 32bit value
395
is transfered. It is not clear if P can be destination operand (probably not,
396
no code ever does this).
397
Writing to STACK pushes a value there, reading pops. It is not known what
398
happens on overflow/underflow (never happens in SVP code).
399
ld -, - is used as a nop.
400
401
syntax encoding operation
402
ld d, s 0000 0000 dddd ssss d = s;
403
ld d, (ri) 0000 001j dddd mmpp d = RAMj[pr_modif_read(m,jpp)];
404
ld (ri), s 0000 010j ssss mmpp RAMj[pr_modif_read(m,jpp)] = s;
405
ldi d, imm 0000 1000 dddd 0000 d = i;
406
iiii iiii iiii iiii
407
ld d, ((ri)) 0000 101j dddd mmpp tmp = pr_modif_read(m,jpp);
408
d = program_memory[RAMj[tmp]];
409
RAMj[tmp]++;
410
ldi (ri), imm 0000 110l 0000 mmpp RAMj[pr_modif_read(m,jpp)] = i;
411
iiii iiii iiii iiii
412
ld adr, a 0000 111j aaaa aaaa RAMj[a] = A;
413
ld d, ri 0001 001j dddd 00pp d = RIJ[jpp];
414
ld ri, s 0001 010j ssss 00pp RIJ[jpp] = s;
415
ldi ri, simm 0001 1jpp iiii iiii RIJ[jpp] = i;
416
ld d, (a) 0100 1010 dddd 0000 d = program_memory[A[31:16]];
417
// read a word from program memory. Offset
418
// is the upper word in A.
419
420
2.4.3. Program control instructions
421
422
Only 3 instructions: call, ret (alias of ld PC, STACK) and branch. Indirect
423
jumps can be performed by simply writing to PC.
424
425
syntax encoding operation
426
call cond, addr 0100 100f cccc 0000 if (check_cond(c,f)) {
427
aaaa aaaa aaaa aaaa STACK = next_op_address(); PC = a;
428
}
429
bra cond, addr 0100 110f cccc 0000 if (check_cond(c,f)) PC = a;
430
aaaa aaaa aaaa aaaa
431
ret 0000 0000 0110 0101 PC = STACK; // same as ld PC, STACK
432
433
2.4.4. Multiply-accumulate instructions
434
435
Not sure if (ri) and (rj) really get loaded into X and Y, but multiplication
436
result surely is loaded into P. There is probably optional 3rd operand (1, 0;
437
encoded by bit16, default 1), but it's not used by SVP code.
438
439
syntax encoding operation
440
mld (rj), (ri) 1011 0111 nnjj mmii A = 0; update_flags();
441
X = RAM0[pr_modif_read(m,0ii)];
442
Y = RAM1[pr_modif_read(m,1jj)];
443
P = sign_extend(X) * sign_extend(Y) * 2
444
mpya (rj), (ri) 1001 0111 nnjj mmii A += P; update_flags();
445
X = RAM0[pr_modif_read(m,0ii)];
446
Y = RAM1[pr_modif_read(m,1jj)];
447
P = sign_extend(X) * sign_extend(Y) * 2
448
mpys (rj), (ri) 0011 0111 nnjj mmii A -= P; update_flags();
449
X = RAM0[pr_modif_read(m,0ii)];
450
Y = RAM1[pr_modif_read(m,1jj)];
451
P = sign_extend(X) * sign_extend(Y) * 2
452
453
-------------------------------------------------------------------------------
454
3. Memory map
455
-------------------------------------------------------------------------------
456
457
The SSp160x can access it's own program memory, and external memory through EXT
458
registers (see 2.2). Program memory is read-execute-only, the size of this
459
space is 64K words (this is how much 16bit PC can address):
460
461
byte address word address name
462
0- 7ff 0- 3ff IRAM
463
800-1ffff 400-ffff ROM
464
465
There were reports that SVP has internal ROM, but fortunately they were wrong.
466
The location 800-1ffff is mapped from the same location in the 2MB game ROM.
467
The IRAM is read-only (as SSP160x doesn't have any means of writing to it's
468
program memory), but it can be changed through external memory space, as it's
469
also mapped there.
470
471
The external memory space seems to match the one visible by 68k, with some
472
differences:
473
474
68k space SVP space word address name
475
0-1fffff 0-1fffff 0- fffff game ROM
476
300000-31ffff 300000-31ffff 180000-18ffff DRAM
477
? 390000-3907ff 1c8000-1c83ff IRAM
478
390000-39ffff ? ? "cell arrange" 1
479
3a0000-3affff ? ? "cell arrange" 2
480
a15000-a15009 n/a n/a Status/control registers
481
482
The external memory can be read/written by SSP160x (except game ROM, which can
483
only be read).
484
485
"cell arrange" 1 and 2 are similar to the one used in SegaCD, they map
486
300000-30ffff location to 390000-39ffff and 3a0000-3affff, where linear image
487
written to 300000 can be read as VDP patterns at 390000. Virtua Racing doesn't
488
seem to use this feature, it is only used by memory test code.
489
490
Here is the list of status/control registers (16bit size):
491
a15000 - w/r command/result register. Visible as XST for SSP160x (2.2.4).
492
a15002 - mirror of the above.
493
a15004 - status of command/result register (see 2.2.1).
494
a15006 - possibly halts the SVP. Before doing DMA from DRAM, 68k code writes
495
0xa, and after it's finished, writes 0. This is probably done to
496
prevent SVP accessing DRAM and avoid bus clashes.
497
a15008 - possibly causes an interrupt. There is (unused?) code which writes
498
0, 1, and again 0 in sequence.
499
500
501
-------------------------------------------------------------------------------
502
4. Other notes
503
-------------------------------------------------------------------------------
504
505
The game has arcade-style memory self-check mode, which can be accessed by
506
pressing _all_ buttons (including directions) on 3-button controller. There was
507
probably some loopback plug for this.
508
509
SVP seems to have DMA latency issue similar to one in Sega CD, as the code
510
always sets DMA source address value larger by 2, then intended for copy.
511
This is even true for DMAs from ROM, as it's probably hooked through SVP's
512
memory controller.
513
514
The entry point for the code seems to be at address 0x800 (word 0x400) in ROM,
515
but it is not clear where the address is fetched from when the system powers
516
up. The memory test code also sets up "ld PC, .." opcodes at 0x7f4, 0x7f8 and
517
0x7fc, which jump to some routines, possibly interrupt handlers. This means
518
that mentioned addresses might be built-in interrupt vectors.
519
520
The SVP code doesn't seem to be timing sensitive, so it can be emulated without
521
knowing timing of the instructions or even how fast the chip is clocked.
522
Overclocking doesn't have any effect, underclocking causes slowdowns. Running
523
10-12M instructions/sec (or possibly less) is sufficient.
524
525
526