Generalities

Usage of this CPU

The MB86232/86233/86234/FDSP-4, also known as the TGP, is used in Sega Model 1, 2 and 2A. There are two, one is used as a T&L unit, the other as a coprocessor. In Model 1, both programs are internal to the CPUs. In Model 2/2A, the T&L program is internal while the coprocessor program is uploaded.

Model 2B uses a pair of SHARCs to replace the TGPs, 2c a pair of TGPx4 (MB86235, FDSP-5 in spirit but not in name), which only has the name in common with the original TGP.

Known information

The datasheet is the best information we have at that point. Grab it, read it, it won't be repeated in here. The copy/paste eagerness of the original author that makes us miss the op-B operations is a pity though. Other sources:

  • An IEEE article: "Implementation Of A 4.8 Kbps Voice Codec Based On Pitch-Synchronous DFT Coding".
  • US patent 5,099,417 may be related to the chip. Type is correct (32 bits DSP), time is correct. DSP-3 was 16 bits, and TGPx4 was 64bits. Patents are quite hard on the reading though.

The CPU seems to do everything on 32-bits words, so endianness is irrelevant. The main CPU of Model 2 (i960) is little-endian though, so the program are stored that way.

Known programs

One can use an emulator to get the uploaded TGP programs, but the simplest way is probably to get them from the ROMs themselves. Use the MAME source to check which files to use and the interleave. Sizes are in 32bits words. As the md5 shows, some programs are identical.

Game Region Address Size MD5
zeroguna CPU1 008cc4 b28 3164f056a727dbd84966dabafa542040
vf2 CPU1 003e90 eda 514f0ebd82cc03a5c99ff0c20227aa46
srallyc CPU1 05ae94 682 ca706c08f84f1c721d5401ea0e50988a
manxtt CPU1 0787e8 6b6 2a9f8b8e5cd4d71527d75b07eb5b45e0
skytargt USER1 e7114c b2b 12c49cd5e99ae89b7c1d7d8521ca3443
vcop2 CPU1 05d480 6f2 59675510722a18b847eec08f75d55d05
dynamcop CPU1 0b6084 e80 2389379b14042147626cd83cfb98811f
dyndeka2 CPU1 0b6074 e80 2389379b14042147626cd83cfb98811f
pltkidsa CPU1 01a378 94b 5fbd0626f6cb73ced9026b420873a27b
doaa CPU1 009664 b2b 12c49cd5e99ae89b7c1d7d8521ca3443
daytona USER1 800020 7e8 8b6f2d1decf8a6be6c4c9005d8361aa5
vcop CPU1 0070c0 7e8 dff894ca077cb02cb66e6d1dec8e9020
desert CPU1 0016a0 7e8 8b6f2d1decf8a6be6c4c9005d8361aa5

Subset encodings

Registers

Register numbers are encoded in 3+6 bits. The first 3 bits are some kind of type.

Type 0 and 3 address the same registers. 3 adds a "Hi, I'm the destination of the move" twist to it though. Here are the known registers:

Value Register
00-0f Register file
10-12 a, a.e, a.m
13-15 b, b.e, b.m
16-18 c, c.e, c.m
19-1b d, d.e, d.m
1c p
21 fifo_in
22 fifo_out

Type 6 looks like special registers. Only value 21 is known as being some kind of indirect access register.

ALU op-A operations

ALU operations are encoded in 6 bits. According to the datasheet the shift operations are not supposed to be there but should be opcodes by themselves.

Value Type Operation Value Type Operation Value Type Operation Value Type Operation
00 000000 nop 10 010000 f32 p = a * b 20 100000  ?  ? 30 110000 int a = a >> c
01 000001 nop 11 010001 f32 p = a * b 21 100001  ?  ? 31 110001 int a = a >> d
02 000010 int c = c & a 12 010010 f32 c = c + p, p = a * b 22 100010  ?  ? 32 110010  ?  ?
03 000011 int d = d & a 13 010011 f32 d = d + p, p = a * b 23 100011  ?  ? 33 110011  ?  ?
04 000100  ?  ? 14 010100 f32 c = c - p, p = a * b 24 100100  ?  ? 34 110100 i24 c = c + a
05 000101  ?  ? 15 010101 f32 d = d - p, p = a * b 25 100101  ?  ? 35 110101 i24 d = d + a
06 000110  ?  ? 16 010110  ?  ? 26 100110  ?  ? 36 110110 i24 c = c - a
07 000111  ?  ? 17 010111  ?  ? 27 100111  ?  ? 37 110111 i24 d = d - a
08 001000  ?  ? 18 011000 f32 c = a + b 28 101000 f32 c = a - b 38 111000  ?  ?
09 001001  ?  ? 19 011001 f32 d = a + b 29 101001 f32 d = a - b 39 111001  ?  ?
0a 001010  ?  ? 1a 011010 f32 c = p, p = a * b 2a 101010  ?  ? 3a 111010  ?  ?
0b 001011  ?  ? 1b 011011 f32 d = p, p = a * b 2b 101011  ?  ? 3b 111011  ?  ?
0c 001100 f32 c = c + a 1c 011100  ?  ? 2c 101100  ?  ? 3c 111100  ?  ?
0d 001101 f32 d = d + a 1d 011101  ?  ? 2d 101101  ?  ? 3d 111101  ?  ?
0e 001110 f32 c = c - a 1e 011110  ?  ? 2e 101110 int a = a << c 3e 111110  ?  ?
0f 001111 f32 d = d - a 1f 011111  ?  ? 2f 101111 int a = a << d 3f 111111  ?  ?

Known missing: xor, not, neg, abs, comparisons (sub). Operations 36 and 37 (at least) are known to set flags though.

ALU op-B operations

Unknown, should be somewhere in the "single move" and "dual move" pattern.

Known instructions

Single move

Single move, y=x,op-A
1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00
000111 op-A  ?? source register destination register

'??' is usually, but not always, 11. The source can actually be the destination when its type is '3', cf registers description. There is supposed to be an op-B somewhere in there.

Dual move

Dual move, r1=x, r2=y,op-A
1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00
000000 op-A type? register 1 register 2

Possible types found in the datasheet are load A&B, load A&C, load A&D, load A store C, load A store D, load C store C, load D store D. 2 bits are not enough. Also, there should be an op-B somewhere.

Branches

Branches encoding
1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00
1011111 condition type 0 destination
Branches types
Value 0 1 2 3 4 5 6 7
Type branch absolute branch indirect bsr absolute bsr indirect  ? rts  ? rti
Conditionals (known incorrect)
Value 00 01 02 06 10 11 12 16
Type == <= => never  != > < always

One or both of types 4/6 may be load conditional. For absolute branches, the destination is the 16-bits address. For the indirect one, encoding is unknown except for 40xx which designates a register. The conditional values are known wrong except for 6/16, they'll be fixed later when the code around them is sorted a little better. The top bit is the "if/unless" bit, inverting the condition.

Load 24-bits integer

Load immediate 24bits
1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00
001110 dest value
Destinations
Value 0 1 2 3
Register p a b d

Load floating point

Load immediate 24bits
1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00
010110 dest value (8 bits only for exponent)
Destinations
Value 0 1 2 3
Type c.exponent c.mantissa d.exponent d.mantissa