Oopho2ei Guest

Posts: n/a





An typical instruction I (32 bit) is decoded like that:

Code: Instruction I: C R[X], R[Y], R[Z] C = I >> 0x1A X = ((I >> 0x13) & 0x7C) >> 2 Y = ((I >> 0x0E) & 0x7C) >> 2 Z = ((I >> 0x09) & 0x7C) >> 2



The machine:

- 32 registers each 32 bit long

- probably big endian

- 4MB address space (first 128 bytes are register?)



instruction/command decoding:

Code: cmd00: NOP cmd01: ADD R[X],R[Y],R[Z] -> R[X] = R[Y] + R[Z] cmd02: SUB R[X],R[Y],R[Z] -> R[X] = R[Y] - R[Z] cmd03: MUL R[X],R[Y],R[Z] -> R[X] = R[Y] * R[Z] cmd04: IDIV R[X],R[Y],R[Z] -> R[X] = unsigned(R[Y]) / R[Z] cmd05: DIV R[X],R[Y],R[Z] -> R[X] = signed(R[Y]) / R[Z] cmd06: SHL R[X],R[Y],R[Z] -> R[X] = R[Y] << (R[Z] & 0x1F) cmd07: SHR R[X],R[Y],R[Z] -> R[X] = R[Y] >> (R[Z] & 0x1F) cmd08: SAR R[X],R[Y],R[Z] -> R[X] = signed(R[Y]) >> (R[Z] & 0x1F) cmd09: AND R[X],R[Y],R[Z] -> R[X] = R[Y] & R[Z] cmd0A: OR R[X],R[Y],R[Z] -> R[X] = R[Y] | R[Z] cmd0B: XOR R[X],R[Y],R[Z] -> R[X] = R[Y] ^ R[Z] cmd0C: EQU R[X],R[Y],R[Z] -> if (R[Y] == R[Z]) R[X] = 1 else R[X] = 0 cmd0D: NEQU R[X],R[Y],R[Z] -> if (R[Y] != R[Z]) R[X] = 1 else R[X] = 0 cmd0E: LESS R[X],R[Y],R[Z] -> if (signed(R[Y]) < signed(R[Z])) R[X] = 1 else R[X] = 0 cmd0F: BLW R[X],R[Y],R[Z] -> if (unsigned(R[Y]) < unsigned(R[Z])) R[X] = 1 else R[X] = 0 cmd10: GRE R[X],R[Y],R[Z] -> if (signed(R[Y]) > signed(R[Z])) R[X] = 1 else R[X] = 0 cmd11: ABV R[X],R[Y],R[Z] -> if (unsigned(R[Y]) > unsigned(R[Z])) R[X] = 1 else R[X] = 0 cmd12: LEQ R[X],R[Y],R[Z] -> if (signed(R[Y]) <= signed(R[Z])) R[X] = 1 else R[X] = 0 cmd13: BEQ R[X],R[Y],R[Z] -> if (unsigned(R[Y]) <= unsigned(R[Z])) R[X] = 1 else R[X] = 0 cmd14: GEQ R[X],R[Y],R[Z] -> if (signed(R[Y]) >= signed(R[Z])) R[X] = 1 else R[X] = 0 cmd15: AEQ R[X],R[Y],R[Z] -> if (unsigned(R[Y]) >= unsigned(R[Z])) R[X] = 1 else R[X] = 0 cmd16: JMP R[Y] -> PC = R[Y] cmd17: CALL R[Y] -> R[0x1F] = PC; PC = R[Y] cmd18: ADDE R[X],R[Y],C -> C = sign_extend(I & 0xFFFF); R[X] := R[Y] + C cmd19: ADD R[X],R[Y],C -> C = I & 0xFFFF; R[X] := R[Y] + C cmd1A: SUBE R[X],R[Y],C -> C = sign_extend(I & 0xFFFF); R[X] := R[Y] - C cmd1B: SUB R[X],R[Y],C -> C = I & 0xFFFF; R[X] := R[Y] - C cmd1C: SHL R[X],R[Y],C -> C = I & 0x1F; R[X] = unsigned(R[Y]) << C cmd1D: SHR R[X],R[Y],C -> C = I & 0x1F; R[X] = unsigned(R[Y]) >> C cmd1E: SAR R[X],R[Y],C -> C = I & 0x1F; R[X] = signed(R[Y]) >> C cmd1F: AND R[X],R[Y],C -> C = I & 0xFFFF; R[X] = R[Y] & C cmd20: OR R[X],R[Y],C -> C = I & 0xFFFF; R[X] := R[Y] | C cmd21: XOR R[X],R[Y],C -> C = I & 0xFFFF; R[X] := R[Y] ^ C cmd22: EQU R[X],R[Y],C -> C = sign_extend(I & 0xFFFF); if (R[Y] == C) R[X] = 1 else R[X] = 0 cmd23: NEQU R[X],R[Y],C -> C = sign_extend(I & 0xFFFF); if (R[Y] != C) R[X] = 1 else R[X] = 0 cmd24: GRE R[X],R[Y],C -> C = sign_extend(I & 0xFFFF); if (signed(C) > signed(R[Y])) R[X] = 1 else R[X] = 0 cmd25: ABV R[X],R[Y],C -> C = I & 0xFFFF; if (unsigned(C) > unsigned(R[Y])) R[X] = 1 else R[X] = 0 cmd26: LESS R[X],R[Y],C -> C = sign_extend(I & 0xFFFF); if (signed(C) < signed(R[Y])) R[X] = 1 else R[X] = 0 cmd27: BLW R[X],R[Y],C -> C = I & 0xFFFF; if (unsigned(t0) < unsigned(R[Y])) R[X] = 1 else R[X] = 0 cmd28: GEQ R[X],R[Y],C -> C = sign_extend(I & 0xFFFF); if (signed(C) >= signed(R[Y])) R[X] = 1 else R[X] = 0 cmd29: AEQ R[X],R[Y],C -> C = I & 0xFFFF; if (unsigned(C) >= unsigned(R[Y])) R[X] = 1 else R[X] = 0 cmd2A: LEQ R[X],R[Y],C -> C = sign_extend(I & 0xFFFF); if (signed(C) <= signed(R[Y])) R[X] = 1 else R[X] = 0 cmd2B: BEQ R[X],R[Y],C -> C = I & 0xFFFF; if (unsigned(C) <= unsigned(R[Y])) R[X] = 1 else R[X] = 0 cmd2C: JMP C -> C = PC + signed(unsigned(I) << 6) >> 6; PC = C cmd2D: CALL C -> C = PC + signed(unsigned(I) << 6) >> 6; R[0x1F] = PC; PC = C cmd2E: JZ R[Y], C -> C = PC + sign_extend(I & 0xFFFF); if (R[Y] == 0) PC = C cmd2F: JNZ R[Y], C -> C = PC + sign_extend(I & 0xFFFF); if (R[Y] != 0) PC = C cmd30: STR R[X] -> R[X] = I << 0x10 cmd31: LBSE R[X],R[Y] -> R[X] = sign_extended(mem[((R[Y] + sign_extended(I & 0xFFFF)) & 0x3FFFFF) ^ 0x03] & 0xFF) cmd32: LB R[X],R[Y] -> R[X] = mem[((R[Y] + sign_extended(I & 0xFFFF)) & 0x3FFFFF) ^ 0x03] & 0xFF cmd33: LWSE R[X],R[Y] -> R[X] = sign_extended(mem[((R[Y] + sign_extended(I & 0xFFFF)) & 0x3FFFFE) ^ 0x02] & 0xFFFF) cmd34: LW R[X],R[Y] -> R[X] = mem[((R[Y] + sign_extended(I & 0xFFFF)) & 0x3FFFFE) ^ 0x02] & 0xFFFF) cmd35: LDW R[X],R[Y] -> R[X] = mem[(R[Y] + sign_extended(I & 0xFFFF)) & 0x3FFFFC] cmd36: MOVB R[X],[R[Y]+C] -> C = sign_extended(I & 0xFFFF); mem[((R[Y]+C) & 0x3FFFFF) ^ 0x03] = (unsigned char) R[X] cmd37: MOVW R[X],[R[Y]+C] -> C = sign_extended(I & 0xFFFF); mem[((R[Y]+C) & 0x3FFFFE) ^ 0x02] = (unsigned int16) R[X] cmd38: MOVDW R[X],[R[Y]+C] -> C = sign_extended(I & 0xFFFF); mem[(R[Y]+C) & 0x3FFFFC] = (unsigned int32) R[X] cmd39: TRAP C -> trap[immediate] cmd3A: SWDC R[Y] -> watch_cat_counter = R[Y]; cmd3B-cmd3F: NOP

PC = program counter

C = a constant (part of instruction word)

I = the instruction word (uint32)

watchcat_counter = some counter which is set by cmd3A and decremented by every instruction by a command specific value. As long as the counter is > 0 program execution continues.

mem[] = the virtual machine memory

R[X] = register number X (uint32 R[32])

sign_extend(V) = MSB(V) ? 0xFFFF0000 | V : V;

MSB() = get the most significant bit

signed() = make it a signed integer (int32)

unsigned() = make it an unsigned integer (uint32)





Note that by the time the command handler is called the program counter (pc) has already been incremented by 4 (pointing at the next instruction).



It would be great if someone could start implementing the command interpreter (open source please). Please feel free to ask for more details. I will post the purpose of the remaining commands soon. The VM is at least involved (if not doing it all alone) in the decryption of those sections.An typical instruction I (32 bit) is decoded like that:C is the command number (6 bit so 64 possible commands) and X,Y,Z are register numbers (in this case). (>> means 'shift right').The machine:- 32 registers each 32 bit long- probably big endian- 4MB address space (first 128 bytes are register?)instruction/command decoding:Notation:PC = program counterC = a constant (part of instruction word)I = the instruction word (uint32)watchcat_counter = some counter which is set by cmd3A and decremented by every instruction by a command specific value. As long as the counter is > 0 program execution continues.mem[] = the virtual machine memoryR[X] = register number X (uint32 R[32])sign_extend(V) = MSB(V) ? 0xFFFF0000 | V : V;MSB() = get the most significant bitsigned() = make it a signed integer (int32)unsigned() = make it an unsigned integer (uint32)Note that by the time the command handler is called the program counter (pc) has already been incremented by 4 (pointing at the next instruction).It would be great if someone could start implementing the command interpreter (open source please). Please feel free to ask for more details. I will post the purpose of the remaining commands soon. Last edited by Oopho2ei; 3rd September 2008 at 17:38 . Reason: added some commands; fixed some mistakes;