RE Blog

Documenting the reverse engineering process

22: The remaining memory loads & new vector register

I guess it’s time to deal with 0xc8 and 0xc9 opcodes. Merely enabling these instructions in hwtest gives worrying results: not only we see the obvious errors from their unimplemented behavior, but we get mismatches on 0xb6 and 0xb7 instructions, even when executed on their own. So… yet another piece of unknown context. But, since […]

Posted in VP1 | No Comments

21: The data store

It’s time to talk about the data store again. What we know so far: 8kB treated as 2D array, with 0×10, 0×20, 0×40, or 0×80 byte stride depending on the stride, the low 4 bits of address are mangled there are three kinds of load/store instructions: 16 bytes horizontal (to $v), 16 bytes vertical (to […]

Posted in VP1 | No Comments

20: hwtest and vector instructions, part 5

There are 12 unknown vector opcodes left: 0×84, 0×86, 0×87, 0×96, 0×97, 0xa6, 0xa7, and 0xb3-0xb7. Let’s finish them off. If 0×80-0×83 are any indication, 0×84 should be a version of 0×85 with no $v write. And so it is. Also, 0×86, 0×87, 0×97 should be versions of 0×84, 0×85, 0×95 that add to the […]

Posted in VP1 | No Comments

19: the scalar -> vector path

The only unknowns still left in scalar and vector units involve the scalar to vector bus. Time to deal with it. Starting with 0×85 and 0×95, together with 0x0f scalar opcode. What we learned before from manual testing is that the instruction looks like dst = src1 * (sc1 + sc2) + src2, with the […]

Posted in VP1 | No Comments

18: hwtest improvements

hwtest is a great tool, but its current implementation for VP1 has a problem I mentioned last time: instead of randomizing $c, $vc, and $va state on each run, the state from previous run is kept, since we have no easy way of writing it. While it’s not a problem for $c and $vc, since […]

Posted in VP1 | No Comments

17: hwtest and vector instructions, part 4

Now it’s time for either the hidden state instructions or the scalar -> vector instructions. Since I already have a failed attempt at the latter, let’s try with the hidden state. The first thing to note is an unknown instruction used in the clear all registers microcode sequence: 0×80000000. There’s a high chance it clears […]

Posted in VP1 | No Comments

16: hwtest and vector instructions, part 3

Today we’ll try to make some sense out of the hidden state instructions. We’ll start by assuming that 0xbb, which always reads the same value into destination register no matter what non-hidden inputs or opcode bits we change, is just a plain read of the hidden state. We’ll model it in hwtest like $c registers: […]

Posted in VP1 | No Comments

15: hwtest and vector instructions, part 2

Last time I’ve said there are three possibilities for the weird vector instructions. Let’s figure them out. First, we’ll look at the microcode samples looking for example usage. As it turns out, most of the unknown vector instructions are always used in pairs with unknown scalar instructions. A few common combinations are: 0f 85 0f […]

Posted in VP1 | No Comments

14: hwtest miscellany

Continuing with the vector instruction set, we run into a problem: the results of the python script are very irregular and suggest we’re pulling data from an unknown source. In particular, the 0×82 opcode is worrying: regardless of inputs, on first few dozen runs after running hwtest, it spits out some interesting values, then reverts […]

Posted in VP1 | 3 Comments

13: hwtest and vector instructions, part 1

It’s time to finally take a look at the vector instructions. Some quick testing reveals that 0×81, 0×82, 0×87-0x8e, 0×90-0×92, 0×94, 0×95, 0×97-0x9f, 0xa1, 0xa2, 0xa4, 0xa5, 0xa7-0xaf, 0xb1-0xb3, 0xb6-0xbe are valid opcodes. First, let’s look at 0xad. It’s used to clear the $v registers in the “init” microcode piece, so there’s a high chance […]

Posted in VP1 | No Comments