Generalities
Usage of this CPU
The mb86232/86233/86234, 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.
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
|