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

📄 decoder.c

📁 linux下的MPEG1
💻 C
📖 第 1 页 / 共 2 页
字号:
      break;    case 6: /*  Set system reg 8 (Highlighted button) */      data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 31); /*  Not system reg!! */      if(cond) {	command->registers->SPRM[8] = data;      }      break;  }  if(vm_getbits(command, 51, 4)) {    return eval_link_instruction(command, cond, return_values);  }  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(command_t* command, int32_t op, int32_t reg, int32_t reg2, int32_t data) {  const int32_t shortmax = 0xffff;  int32_t     tmp;   switch(op) {    case 1:      set_GPRM(command->registers, reg, data);      break;    case 2: /* SPECIAL CASE - SWAP! */      set_GPRM(command->registers, reg2, get_GPRM(command->registers, reg));      set_GPRM(command->registers, reg, data);      break;    case 3:      tmp = get_GPRM(command->registers, reg) + data;      if(tmp > shortmax) tmp = shortmax;      set_GPRM(command->registers, reg, (uint16_t)tmp);      break;    case 4:      tmp = get_GPRM(command->registers, reg) - data;      if(tmp < 0) tmp = 0;      set_GPRM(command->registers, reg, (uint16_t)tmp);      break;    case 5:      tmp = get_GPRM(command->registers, reg) * data;      if(tmp > shortmax) tmp = shortmax;      set_GPRM(command->registers, reg, (uint16_t)tmp);      break;    case 6:      if (data != 0) {        set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) / data) );      } else {        set_GPRM(command->registers, reg, 0xffff); /* Avoid that divide by zero! */      }      break;    case 7:      if (data != 0) {        set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) % data) );      } else {        set_GPRM(command->registers, reg, 0xffff); /* Avoid that divide by zero! */      }      break;    case 8: /* SPECIAL CASE - RND! Return numbers between 1 and data. */      set_GPRM(command->registers, reg, 1 + ((uint16_t) ((float) data * rand()/(RAND_MAX+1.0))) );      break;    case 9:      set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) & data) );      break;    case 10:      set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) | data) );      break;    case 11:      set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) ^ data) );      break;  }}/* Evaluate set instruction, combined with either Link or Compare. */static void eval_set_version_1(command_t* command, int32_t cond) {  uint8_t  op   = vm_getbits(command, 59, 4);  uint8_t  reg  = vm_getbits(command, 35, 4); /* FIXME: This is different from vmcmd.c!!! */  uint8_t  reg2 = vm_getbits(command, 19, 4);  uint16_t data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 31);  if(cond) {    eval_set_op(command, op, reg, reg2, data);  }}/* Evaluate set instruction, combined with both Link and Compare. */static void eval_set_version_2(command_t* command, int32_t cond) {  uint8_t  op   = vm_getbits(command, 59, 4);  uint8_t  reg  = vm_getbits(command, 51, 4);  uint8_t  reg2 = vm_getbits(command, 35, 4); /* FIXME: This is different from vmcmd.c!!! */  uint16_t data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 47);  if(cond) {    eval_set_op(command, 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 int32_t eval_command(uint8_t *bytes, registers_t* registers, link_t *return_values) {  int32_t cond, res = 0;  command_t command;  command.instruction =( (uint64_t) bytes[0] << 56 ) |        ( (uint64_t) bytes[1] << 48 ) |        ( (uint64_t) bytes[2] << 40 ) |        ( (uint64_t) bytes[3] << 32 ) |        ( (uint64_t) bytes[4] << 24 ) |        ( (uint64_t) bytes[5] << 16 ) |        ( (uint64_t) bytes[6] <<  8 ) |          (uint64_t) bytes[7] ;  command.examined = 0;  command.registers = registers;  memset(return_values, 0, sizeof(link_t));  switch(vm_getbits(&command, 63, 3)) { /* three first old_bits */    case 0: /*  Special instructions */      cond = eval_if_version_1(&command);      res = eval_special_instruction(&command, cond);      if(res == -1) {	fprintf(MSG_OUT, "libdvdnav: Unknown Instruction!\n");	abort();      }      break;    case 1: /*  Link/jump instructions */      if(vm_getbits(&command, 60, 1)) {        cond = eval_if_version_2(&command);        res = eval_jump_instruction(&command, cond, return_values);      } else {        cond = eval_if_version_1(&command);        res = eval_link_instruction(&command, cond, return_values);      }      if(res)	res = -1;      break;    case 2: /*  System set instructions */      cond = eval_if_version_2(&command);      res = eval_system_set(&command, cond, return_values);      if(res)	res = -1;      break;    case 3: /*  Set instructions, either Compare or Link may be used */      cond = eval_if_version_3(&command);      eval_set_version_1(&command, cond);      if(vm_getbits(&command, 51, 4)) {	res = eval_link_instruction(&command, cond, return_values);      }      if(res)	res = -1;      break;    case 4: /*  Set, Compare -> Link Sub-Instruction */      eval_set_version_2(&command, /*True*/ 1);      cond = eval_if_version_4(&command);      res = eval_link_subins(&command, cond, return_values);      if(res)	res = -1;      break;    case 5: /*  Compare -> (Set and Link Sub-Instruction) */      /* FIXME: These are wrong. Need to be updated from vmcmd.c */      cond = eval_if_version_4(&command);      eval_set_version_2(&command, cond);      res = eval_link_subins(&command, cond, return_values);      if(res)	res = -1;      break;    case 6: /*  Compare -> Set, allways Link Sub-Instruction */      /* FIXME: These are wrong. Need to be updated from vmcmd.c */      cond = eval_if_version_4(&command);      eval_set_version_2(&command, cond);      res = eval_link_subins(&command, /*True*/ 1, return_values);      if(res)	res = -1;      break;    default: /* Unknown command */      fprintf(MSG_OUT, "libdvdnav: WARNING: Unknown Command=%x\n", vm_getbits(&command, 63, 3));      abort();  }  /*  Check if there are bits not yet examined */  if(command.instruction & ~ command.examined) {    fprintf(MSG_OUT, "libdvdnav: decoder.c: [WARNING, unknown bits:");    fprintf(MSG_OUT, " %08llx", (command.instruction & ~ command.examined) );    fprintf(MSG_OUT, "]\n");  }  return res;}/* Evaluate a set of commands in the given register set (which is modified) */int32_t vmEval_CMD(vm_cmd_t commands[], int32_t num_commands, 	       registers_t *registers, link_t *return_values) {  int32_t i = 0;  int32_t total = 0;  #ifdef TRACE  /*  DEBUG */  fprintf(MSG_OUT, "libdvdnav: Registers before transaction\n");  vm_print_registers( registers );  fprintf(MSG_OUT, "libdvdnav: Full list of commands to execute\n");  for(i = 0; i < num_commands; i++)    vm_print_cmd(i, &commands[i]);  fprintf(MSG_OUT, "libdvdnav: --------------------------------------------\n");  fprintf(MSG_OUT, "libdvdnav: Single stepping commands\n");#endif  i = 0;   while(i < num_commands && total < 100000) {    int32_t line;    #ifdef TRACE    vm_print_cmd(i, &commands[i]);#endif    line = eval_command(&commands[i].bytes[0], registers, return_values);        if (line < 0) { /*  Link command */#ifdef TRACE      fprintf(MSG_OUT, "libdvdnav: Registers after transaction\n");      vm_print_registers( registers );      fprintf(MSG_OUT, "libdvdnav: 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));#ifdef TRACE  fprintf(MSG_OUT, "libdvdnav: Registers after transaction\n");  vm_print_registers( registers );#endif  return 0;}#ifdef TRACEstatic 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 vm_print_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(MSG_OUT, "libdvdnav: %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(MSG_OUT, "libdvdnav: %s %d\n", cmd, value.data1);    break;  case LinkPTTN:  case LinkPGN:  case LinkCN:    fprintf(MSG_OUT, "libdvdnav: %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(MSG_OUT, "libdvdnav: %s\n", cmd);    break;  case JumpVTS_PTT:    fprintf(MSG_OUT, "libdvdnav: %s %d:%d\n", cmd, value.data1, value.data2);    break;  case JumpSS_VTSM:    fprintf(MSG_OUT, "libdvdnav: %s vts %d title %d menu %d\n", 	    cmd, value.data1, value.data2, value.data3);    break;  case CallSS_FP:    fprintf(MSG_OUT, "libdvdnav: %s resume cell %d\n", cmd, value.data1);    break;  case CallSS_VMGM_MENU: /*  == 2 -> Title Menu */  case CallSS_VTSM:    fprintf(MSG_OUT, "libdvdnav: %s %d resume cell %d\n", cmd, value.data1, value.data2);    break;  case CallSS_VMGM_PGC:    fprintf(MSG_OUT, "libdvdnav: %s %d resume cell %d\n", cmd, value.data1, value.data2);    break;  } }void vm_print_registers( registers_t *registers ) {  int32_t i;  fprintf(MSG_OUT, "libdvdnav:    #   ");  for(i = 0; i < 24; i++)    fprintf(MSG_OUT, " %2d |", i);  fprintf(MSG_OUT, "\nlibdvdnav: SRPMS: ");  for(i = 0; i < 24; i++)    fprintf(MSG_OUT, "%04x|", registers->SPRM[i]);  fprintf(MSG_OUT, "\nlibdvdnav: GRPMS: ");  for(i = 0; i < 16; i++)    fprintf(MSG_OUT, "%04x|", get_GPRM(registers, i) );  fprintf(MSG_OUT, "\nlibdvdnav: Gmode: ");  for(i = 0; i < 16; i++)    fprintf(MSG_OUT, "%04x|", registers->GPRM_mode[i]);  fprintf(MSG_OUT, "\nlibdvdnav: Gtime: ");  for(i = 0; i < 16; i++)    fprintf(MSG_OUT, "%04lx|", registers->GPRM_time[i].tv_sec & 0xffff);  fprintf(MSG_OUT, "\n");}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -