⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 decoder.c

📁 基于linux的DVD播放器程序
💻 C
📖 第 1 页 / 共 2 页
字号:
  }  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 + -