📄 decoder.c
字号:
} return 0;}/* Evaluate set operation Sets the register given to the value indicated by op and data. For the swap case the contents of reg is stored in reg2.*/static void eval_set_op(int op, int reg, int reg2, int data){ /* General parameters and System Parameters (GPRMS and SPRMS) * are treated as 16-bit unsigned integers. * in case of overflow, 0xFFFF must be assigned * in case of underflow, 0x0 must be assigned */ const int shortmax = 0xffff; int tmp; switch(op) { case 1: /* = (assignment) */ state->GPRM[reg] = data; break; case 2: /* Swap */ tmp = state->GPRM[reg]; state->GPRM[reg] = state->GPRM[reg2]; state->GPRM[reg2] = tmp; break; case 3: /* += (addition) */ tmp = state->GPRM[reg] + data; if(tmp >= shortmax) tmp = shortmax; state->GPRM[reg] = (uint16_t)tmp; break; case 4: /* -= (subtraction) */ tmp = state->GPRM[reg] - data; if(tmp < 0) tmp = 0; state->GPRM[reg] = (uint16_t)tmp; break; case 5: /* *= (multiplication) */ tmp = state->GPRM[reg] * data; if(tmp >= shortmax) tmp = shortmax; state->GPRM[reg] = (uint16_t)tmp; break; case 6: /* /= (division) */ if(data != 0) state->GPRM[reg] /= data; else state->GPRM[reg] = 65535; break; case 7: /* %= (modulo) */ if(data != 0) state->GPRM[reg] %= data; else state->GPRM[reg] = 0; /* really an error I guess */ break; break; case 8: /* SPECIAL CASE - RANDOM! */ if(data != 0) /* TODO rand() might only return 0-32768 */ state->GPRM[reg] = (rand() % data) + 1; else state->GPRM[reg] = 0; /* really an error I guess */ break; case 9: /* &= (bitwise and) */ state->GPRM[reg] &= data; break; case 10: /* |= (bitwise or) */ state->GPRM[reg] |= data; break; case 11: /* ^= (bitwise xor) */ state->GPRM[reg] ^= data; break; }}/* Evaluate set instruction, combined with either Link or Compare. * PPP0SSSS ******** ******** 0AAAAAAA ******** BBBBBBBB ******** ******** * PPP1SSSS ******** ******** 0AAAAAAA DDDDDDDD DDDDDDDD ******** ******** * where PPP is 011 * "r[A] `S` r[B]" resp "r[A] `S` D" */static void eval_set_version_1(int cond){ uint8_t op = bits(0, 4, 4); uint8_t reg = bits(3, 0, 8); // GPRM uint8_t reg2 = bits(5, 4, 4); // GPRM or SPRM uint16_t data = eval_reg_or_data(bits(0, 3, 1), 4); // or Imm if(cond) { eval_set_op(op, reg, reg2, data); }}/* Evaluate set instruction for Set Compare Link. * PPP0SSSS ****AAAA ******** BBBBBBBB ******** ******** ******** ******** * PPP1SSSS ****AAAA DDDDDDDD DDDDDDDD ******** ******** ******** ******** * when PPP is 101 * "g[A] `S` r[B]" resp "g[A] `S` D" */static void eval_set_version_2(int cond){ uint8_t op = bits(0, 4, 4); uint8_t reg = bits(1, 4, 4); // GPRM uint8_t reg2 = bits(3, 0, 8); // GPRM or SPRM uint16_t data = eval_reg_or_data(bits(0, 3, 1), 2); // or Imm if(cond) { eval_set_op(op, reg, reg2, data); }}/* Evaluate set instruction for, Compare & Set-Link, Compare-Set & Link. * PPP0SSSS ****AAAA BBBBBBBB ******** ******** ******** ******** ******** * PPP1SSSS 0***AAAA DDDDDDDD DDDDDDDD ******** ******** ******** ******** * when PPP is 100 or 110 * "g[A] `S` r[B]" resp "g[A] `S` D" */static void eval_set_version_3(int cond){ uint8_t op = bits(0, 4, 4); uint8_t reg = bits(1, 4, 4); // GPRM uint8_t reg2 = bits(2, 0, 8); // GPRM or SPRM uint16_t data; if(bits(0, 3, 1)) { // immediate data = bits(2, 0, 16); } else { data = eval_reg(reg2); } if(cond) { eval_set_op(op, reg, reg2, data); }}/* Evaluate a command returns row number of goto, 0 if no goto, -1 if link. Link command in return_values */static int eval_command(uint8_t *bytes, link_t *return_values){ int i, extra_bits; int cond, res = 0; for(i = 0; i < 8; i++) { cmd.bits[i] = bytes[i]; cmd.examined[i] = 0; } memset(return_values, 0, sizeof(link_t)); switch(bits(0, 0, 3)) { /* three first bits */ case 0: // Special instructions cond = eval_if_version_1(); res = eval_special_instruction(cond); if(res == -1) { fprintf(stderr, "Unknown Instruction!\n"); //exit(0); } break; case 1: // Link/jump instructions if(bits(0, 3, 1)) { cond = eval_if_version_2(); res = eval_jump_instruction(cond, return_values); } else { cond = eval_if_version_1(); res = eval_link_instruction(cond, return_values); } if(res) res = -1; break; case 2: // System set instructions cond = eval_if_version_2(); res = eval_system_set(cond, return_values); if(res) res = -1; break; case 3: // Set instructions, either Compare or Link may be used cond = eval_if_version_3(); eval_set_version_1(cond); if(bits(1, 4, 4)) { res = eval_link_instruction(cond, return_values); } if(res) res = -1; break; case 4: // Set, Compare -> Link Sub-Instruction eval_set_version_2(/*True*/ 1); cond = eval_if_version_4(); res = eval_link_subins(cond, return_values); if(res) res = -1; break; case 5: // Compare -> (Set and Link Sub-Instruction) if(bits(0, 3, 1)) cond = eval_if_version_5(); else cond = eval_if_version_1(); eval_set_version_3(cond); res = eval_link_subins(cond, return_values); if(res) res = -1; break; case 6: // Compare -> Set, always Link Sub-Instruction if(bits(0, 3, 1)) cond = eval_if_version_5(); else cond = eval_if_version_1(); eval_set_version_3(cond); res = eval_link_subins(/*True*/ 1, return_values); if(res) res = -1; break; } // Check if there are bits not yet examined extra_bits = 0; for(i = 0; i < 8; i++) if(cmd.bits [i] & ~cmd.examined [i]) { extra_bits = 1; break; } if(extra_bits) { fprintf(stderr, "[WARNING, unknown bits:"); for(i = 0; i < 8; i++) fprintf(stderr, " %02x", cmd.bits [i] & ~cmd.examined [i]); fprintf(stderr, "]\n"); } return res;}/* Evaluate a set of commands in the given register set (which is * modified */int vmEval_CMD(vm_cmd_t commands[], int num_commands, registers_t *registers, link_t *return_values){ int i = 0; int total = 0; state = registers; // TODO FIXME#ifdef TRACE // DEBUG if(1) { int i; fprintf(stderr, " # "); for(i = 0; i < 24; i++) fprintf(stderr, " %2d |", i); fprintf(stderr, "\nSPRMS: "); for(i = 0; i < 24; i++) fprintf(stderr, "%04x|", state->SPRM[i]); fprintf(stderr, "\nGPRMS: "); for(i = 0; i < 16; i++) fprintf(stderr, "%04x|", state->GPRM[i]); fprintf(stderr, "\n"); } if(1) { int i; for(i = 0; i < num_commands; i++) vmPrint_CMD(i, &commands[i]); fprintf(stderr, "--------------------------------------------\n"); } // end DEBUG#endif while(i < num_commands && total < 100000) { int line; if(0) vmPrint_CMD(i, &commands[i]); line = eval_command(&commands[i].bytes[0], return_values); if (line < 0) { // Link command#ifdef TRACE fprintf(stderr, "eval: Doing Link/Jump/Call\n");#endif return 1; } if (line > 0) // Goto command i = line - 1; else // Just continue on the next line i++; total++; } memset(return_values, 0, sizeof(link_t)); return 0;}static char *linkcmd2str(link_cmd_t cmd){ switch(cmd) { case LinkNoLink: return "LinkNoLink"; case LinkTopC: return "LinkTopC"; case LinkNextC: return "LinkNextC"; case LinkPrevC: return "LinkPrevC"; case LinkTopPG: return "LinkTopPG"; case LinkNextPG: return "LinkNextPG"; case LinkPrevPG: return "LinkPrevPG"; case LinkTopPGC: return "LinkTopPGC"; case LinkNextPGC: return "LinkNextPGC"; case LinkPrevPGC: return "LinkPrevPGC"; case LinkGoUpPGC: return "LinkGoUpPGC"; case LinkTailPGC: return "LinkTailPGC"; case LinkRSM: return "LinkRSM"; case LinkPGCN: return "LinkPGCN"; case LinkPTTN: return "LinkPTTN"; case LinkPGN: return "LinkPGN"; case LinkCN: return "LinkCN"; case Exit: return "Exit"; case JumpTT: return "JumpTT"; case JumpVTS_TT: return "JumpVTS_TT"; case JumpVTS_PTT: return "JumpVTS_PTT"; case JumpSS_FP: return "JumpSS_FP"; case JumpSS_VMGM_MENU: return "JumpSS_VMGM_MENU"; case JumpSS_VTSM: return "JumpSS_VTSM"; case JumpSS_VMGM_PGC: return "JumpSS_VMGM_PGC"; case CallSS_FP: return "CallSS_FP"; case CallSS_VMGM_MENU: return "CallSS_VMGM_MENU"; case CallSS_VTSM: return "CallSS_VTSM"; case CallSS_VMGM_PGC: return "CallSS_VMGM_PGC"; case PlayThis: return "PlayThis"; } return "*** (bug)";}void vmPrint_LINK(link_t value){ char *cmd = linkcmd2str(value.command); switch(value.command) { case LinkNoLink: case LinkTopC: case LinkNextC: case LinkPrevC: case LinkTopPG: case LinkNextPG: case LinkPrevPG: case LinkTopPGC: case LinkNextPGC: case LinkPrevPGC: case LinkGoUpPGC: case LinkTailPGC: case LinkRSM: fprintf(stderr, "%s (button %d)\n", cmd, value.data1); break; case LinkPGCN: case JumpTT: case JumpVTS_TT: case JumpSS_VMGM_MENU: // == 2 -> Title Menu case JumpSS_VMGM_PGC: fprintf(stderr, "%s %d\n", cmd, value.data1); break; case LinkPTTN: case LinkPGN: case LinkCN: fprintf(stderr, "%s %d (button %d)\n", cmd, value.data1, value.data2); break; case Exit: case JumpSS_FP: case PlayThis: // Humm.. should we have this at all.. fprintf(stderr, "%s\n", cmd); break; case JumpVTS_PTT: fprintf(stderr, "%s %d:%d\n", cmd, value.data1, value.data2); break; case JumpSS_VTSM: fprintf(stderr, "%s vts %d title %d menu %d\n", cmd, value.data1, value.data2, value.data3); break; case CallSS_FP: fprintf(stderr, "%s resume cell %d\n", cmd, value.data1); break; case CallSS_VMGM_MENU: // == 2 -> Title Menu case CallSS_VTSM: fprintf(stderr, "%s %d resume cell %d\n", cmd, value.data1, value.data2); break; case CallSS_VMGM_PGC: fprintf(stderr, "%s %d resume cell %d\n", cmd, value.data1, value.data2); break; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -