00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef HAVE_CONFIG_H
00024 #include "config.h"
00025 #endif
00026
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include <inttypes.h>
00030 #include <limits.h>
00031 #include <string.h>
00032 #include <sys/time.h>
00033 #include "dvdread/nav_types.h"
00034 #include "dvdread/ifo_types.h"
00035
00036 #include "dvdnav/dvdnav.h"
00037 #include "remap.h"
00038 #include "decoder.h"
00039 #include "vm.h"
00040 #include "vmcmd.h"
00041 #include "dvdnav_internal.h"
00042
00043 uint32_t vm_getbits(command_t *command, int32_t start, int32_t count) {
00044 uint64_t result = 0;
00045 uint64_t bit_mask = 0;
00046 uint64_t examining = 0;
00047 int32_t bits;
00048
00049 if (count == 0) return 0;
00050
00051 if ( ((start - count) < -1) ||
00052 (count > 32) ||
00053 (start > 63) ||
00054 (count < 0) ||
00055 (start < 0) ) {
00056 fprintf(MSG_OUT, "libdvdnav: Bad call to vm_getbits. Parameter out of range\n");
00057 abort();
00058 }
00059
00060 bit_mask = ~bit_mask;
00061 bit_mask >>= 63 - start;
00062 bits = start + 1 - count;
00063 examining = ((bit_mask >> bits) << bits );
00064 command->examined |= examining;
00065 result = (command->instruction & bit_mask) >> bits;
00066 return (uint32_t) result;
00067 }
00068
00069 static uint16_t get_GPRM(registers_t* registers, uint8_t reg) {
00070 if (registers->GPRM_mode[reg] & 0x01) {
00071 struct timeval current_time, time_offset;
00072 uint16_t result;
00073
00074
00075 gettimeofday(¤t_time, NULL);
00076 time_offset.tv_sec = current_time.tv_sec - registers->GPRM_time[reg].tv_sec;
00077 time_offset.tv_usec = current_time.tv_usec - registers->GPRM_time[reg].tv_usec;
00078 if (time_offset.tv_usec < 0) {
00079 time_offset.tv_sec--;
00080 time_offset.tv_usec += 1000000;
00081 }
00082 result = (uint16_t) (time_offset.tv_sec & 0xffff);
00083 registers->GPRM[reg]=result;
00084 return result;
00085
00086 } else {
00087
00088 return registers->GPRM[reg];
00089 }
00090
00091 }
00092
00093 static void set_GPRM(registers_t* registers, uint8_t reg, uint16_t value) {
00094 if (registers->GPRM_mode[reg] & 0x01) {
00095 struct timeval current_time;
00096
00097
00098 gettimeofday(¤t_time, NULL);
00099 registers->GPRM_time[reg] = current_time;
00100 registers->GPRM_time[reg].tv_sec -= value;
00101 }
00102 registers->GPRM[reg] = value;
00103 }
00104
00105
00106
00107 static uint16_t eval_reg(command_t* command, uint8_t reg) {
00108 if(reg & 0x80) {
00109 if ((reg & 0x1f) == 20) {
00110 fprintf(MSG_OUT, "libdvdnav: Suspected RCE Region Protection!!!\n");
00111 }
00112 return command->registers->SPRM[reg & 0x1f];
00113 } else {
00114 return get_GPRM(command->registers, reg & 0x0f) ;
00115 }
00116 }
00117
00118
00119
00120
00121 static uint16_t eval_reg_or_data(command_t* command, int32_t imm, int32_t start) {
00122 if(imm) {
00123 return vm_getbits(command, start, 16);
00124 } else {
00125 return eval_reg(command, vm_getbits(command, (start - 8), 8));
00126 }
00127 }
00128
00129
00130
00131
00132
00133 static uint16_t eval_reg_or_data_2(command_t* command,
00134 int32_t imm, int32_t start) {
00135 if(imm)
00136 return vm_getbits(command, (start - 1), 7);
00137 else
00138 return get_GPRM(command->registers, (vm_getbits(command, (start - 4), 4)) );
00139 }
00140
00141
00142
00143
00144 static int32_t eval_compare(uint8_t operation, uint16_t data1, uint16_t data2) {
00145 switch(operation) {
00146 case 1:
00147 return data1 & data2;
00148 case 2:
00149 return data1 == data2;
00150 case 3:
00151 return data1 != data2;
00152 case 4:
00153 return data1 >= data2;
00154 case 5:
00155 return data1 > data2;
00156 case 6:
00157 return data1 <= data2;
00158 case 7:
00159 return data1 < data2;
00160 }
00161 fprintf(MSG_OUT, "libdvdnav: eval_compare: Invalid comparison code\n");
00162 return 0;
00163 }
00164
00165
00166
00167
00168 static int32_t eval_if_version_1(command_t* command) {
00169 uint8_t op = vm_getbits(command, 54, 3);
00170 if(op) {
00171 return eval_compare(op, eval_reg(command, vm_getbits(command, 39, 8)),
00172 eval_reg_or_data(command, vm_getbits(command, 55, 1), 31));
00173 }
00174 return 1;
00175 }
00176
00177
00178
00179 static int32_t eval_if_version_2(command_t* command) {
00180 uint8_t op = vm_getbits(command, 54, 3);
00181 if(op) {
00182 return eval_compare(op, eval_reg(command, vm_getbits(command, 15, 8)),
00183 eval_reg(command, vm_getbits(command, 7, 8)));
00184 }
00185 return 1;
00186 }
00187
00188
00189
00190 static int32_t eval_if_version_3(command_t* command) {
00191 uint8_t op = vm_getbits(command, 54, 3);
00192 if(op) {
00193 return eval_compare(op, eval_reg(command, vm_getbits(command, 47, 8)),
00194 eval_reg_or_data(command, vm_getbits(command, 55, 1), 15));
00195 }
00196 return 1;
00197 }
00198
00199
00200
00201
00202 static int32_t eval_if_version_4(command_t* command) {
00203 uint8_t op = vm_getbits(command, 54, 3);
00204 if(op) {
00205 return eval_compare(op, eval_reg(command, vm_getbits(command, 51, 4)),
00206 eval_reg_or_data(command, vm_getbits(command, 55, 1), 31));
00207 }
00208 return 1;
00209 }
00210
00211
00212
00213 static int32_t eval_special_instruction(command_t* command, int32_t cond) {
00214 int32_t line, level;
00215
00216 switch(vm_getbits(command, 51, 4)) {
00217 case 0:
00218 line = 0;
00219 return cond ? line : 0;
00220 case 1:
00221 line = vm_getbits(command, 7, 8);
00222 return cond ? line : 0;
00223 case 2:
00224
00225 line = 256;
00226 return cond ? 256 : 0;
00227 case 3:
00228 line = vm_getbits(command, 7, 8);
00229 level = vm_getbits(command, 11, 4);
00230 if(cond) {
00231
00232
00233 command->registers->SPRM[13] = level;
00234 }
00235 return cond ? line : 0;
00236 }
00237 return 0;
00238 }
00239
00240
00241
00242
00243 static int32_t eval_link_subins(command_t* command, int32_t cond, link_t *return_values) {
00244 uint16_t button = vm_getbits(command, 15, 6);
00245 uint8_t linkop = vm_getbits(command, 4, 5);
00246
00247 if(linkop > 0x10)
00248 return 0;
00249
00250
00251 return_values->command = linkop;
00252 return_values->data1 = button;
00253 return cond;
00254 }
00255
00256
00257
00258
00259
00260 static int32_t eval_link_instruction(command_t* command, int32_t cond, link_t *return_values) {
00261 uint8_t op = vm_getbits(command, 51, 4);
00262
00263 switch(op) {
00264 case 1:
00265 return eval_link_subins(command, cond, return_values);
00266 case 4:
00267 return_values->command = LinkPGCN;
00268 return_values->data1 = vm_getbits(command, 14, 15);
00269 return cond;
00270 case 5:
00271 return_values->command = LinkPTTN;
00272 return_values->data1 = vm_getbits(command, 9, 10);
00273 return_values->data2 = vm_getbits(command, 15, 6);
00274 return cond;
00275 case 6:
00276 return_values->command = LinkPGN;
00277 return_values->data1 = vm_getbits(command, 6, 7);
00278 return_values->data2 = vm_getbits(command, 15, 6);
00279 return cond;
00280 case 7:
00281 return_values->command = LinkCN;
00282 return_values->data1 = vm_getbits(command, 7, 8);
00283 return_values->data2 = vm_getbits(command, 15, 6);
00284 return cond;
00285 }
00286 return 0;
00287 }
00288
00289
00290
00291
00292
00293 static int32_t eval_jump_instruction(command_t* command, int32_t cond, link_t *return_values) {
00294
00295 switch(vm_getbits(command, 51, 4)) {
00296 case 1:
00297 return_values->command = Exit;
00298 return cond;
00299 case 2:
00300 return_values->command = JumpTT;
00301 return_values->data1 = vm_getbits(command, 22, 7);
00302 return cond;
00303 case 3:
00304 return_values->command = JumpVTS_TT;
00305 return_values->data1 = vm_getbits(command, 22, 7);
00306 return cond;
00307 case 5:
00308 return_values->command = JumpVTS_PTT;
00309 return_values->data1 = vm_getbits(command, 22, 7);
00310 return_values->data2 = vm_getbits(command, 41, 10);
00311 return cond;
00312 case 6:
00313 switch(vm_getbits(command, 23, 2)) {
00314 case 0:
00315 return_values->command = JumpSS_FP;
00316 return cond;
00317 case 1:
00318 return_values->command = JumpSS_VMGM_MENU;
00319 return_values->data1 = vm_getbits(command, 19, 4);
00320 return cond;
00321 case 2:
00322 return_values->command = JumpSS_VTSM;
00323 return_values->data1 = vm_getbits(command, 31, 8);
00324 return_values->data2 = vm_getbits(command, 39, 8);
00325 return_values->data3 = vm_getbits(command, 19, 4);
00326 return cond;
00327 case 3:
00328 return_values->command = JumpSS_VMGM_PGC;
00329 return_values->data1 = vm_getbits(command, 46, 15);
00330 return cond;
00331 }
00332 break;
00333 case 8:
00334 switch(vm_getbits(command, 23, 2)) {
00335 case 0:
00336 return_values->command = CallSS_FP;
00337 return_values->data1 = vm_getbits(command, 31, 8);
00338 return cond;
00339 case 1:
00340 return_values->command = CallSS_VMGM_MENU;
00341 return_values->data1 = vm_getbits(command, 19, 4);
00342 return_values->data2 = vm_getbits(command, 31, 8);
00343 return cond;
00344 case 2:
00345 return_values->command = CallSS_VTSM;
00346 return_values->data1 = vm_getbits(command, 19, 4);
00347 return_values->data2 = vm_getbits(command, 31, 8);
00348 return cond;
00349 case 3:
00350 return_values->command = CallSS_VMGM_PGC;
00351 return_values->data1 = vm_getbits(command, 46, 15);
00352 return_values->data2 = vm_getbits(command, 31, 8);
00353 return cond;
00354 }
00355 break;
00356 }
00357 return 0;
00358 }
00359
00360
00361
00362 static int32_t eval_system_set(command_t* command, int32_t cond, link_t *return_values) {
00363 int32_t i;
00364 uint16_t data, data2;
00365
00366 switch(vm_getbits(command, 59, 4)) {
00367 case 1:
00368 for(i = 1; i <= 3; i++) {
00369 if(vm_getbits(command, 63 - ((2 + i)*8), 1)) {
00370 data = eval_reg_or_data_2(command, vm_getbits(command, 60, 1), (47 - (i*8)));
00371 if(cond) {
00372 command->registers->SPRM[i] = data;
00373 }
00374 }
00375 }
00376 break;
00377 case 2:
00378 data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 47);
00379 data2 = vm_getbits(command, 23, 8);
00380 if(cond) {
00381 command->registers->SPRM[9] = data;
00382 command->registers->SPRM[10] = data2;
00383 }
00384 break;
00385 case 3:
00386 data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 47);
00387 data2 = vm_getbits(command, 19, 4);
00388 if(vm_getbits(command, 23, 1)) {
00389 command->registers->GPRM_mode[data2] |= 1;
00390 } else {
00391 command->registers->GPRM_mode[data2] &= ~ 0x01;
00392 }
00393 if(cond) {
00394 set_GPRM(command->registers, data2, data);
00395 }
00396 break;
00397 case 6:
00398 data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 31);
00399 if(cond) {
00400 command->registers->SPRM[8] = data;
00401 }
00402 break;
00403 }
00404 if(vm_getbits(command, 51, 4)) {
00405 return eval_link_instruction(command, cond, return_values);
00406 }
00407 return 0;
00408 }
00409
00410
00411
00412
00413
00414
00415 static void eval_set_op(command_t* command, int32_t op, int32_t reg, int32_t reg2, int32_t data) {
00416 static const int32_t shortmax = 0xffff;
00417 int32_t tmp;
00418 switch(op) {
00419 case 1:
00420 set_GPRM(command->registers, reg, data);
00421 break;
00422 case 2:
00423 set_GPRM(command->registers, reg2, get_GPRM(command->registers, reg));
00424 set_GPRM(command->registers, reg, data);
00425 break;
00426 case 3:
00427 tmp = get_GPRM(command->registers, reg) + data;
00428 if(tmp > shortmax) tmp = shortmax;
00429 set_GPRM(command->registers, reg, (uint16_t)tmp);
00430 break;
00431 case 4:
00432 tmp = get_GPRM(command->registers, reg) - data;
00433 if(tmp < 0) tmp = 0;
00434 set_GPRM(command->registers, reg, (uint16_t)tmp);
00435 break;
00436 case 5:
00437 tmp = get_GPRM(command->registers, reg) * data;
00438 if(tmp > shortmax) tmp = shortmax;
00439 set_GPRM(command->registers, reg, (uint16_t)tmp);
00440 break;
00441 case 6:
00442 if (data != 0) {
00443 set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) / data) );
00444 } else {
00445 set_GPRM(command->registers, reg, 0xffff);
00446 }
00447 break;
00448 case 7:
00449 if (data != 0) {
00450 set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) % data) );
00451 } else {
00452 set_GPRM(command->registers, reg, 0xffff);
00453 }
00454 break;
00455 case 8:
00456 set_GPRM(command->registers, reg, 1 + ((uint16_t) ((float) data * rand()/(RAND_MAX+1.0))) );
00457 break;
00458 case 9:
00459 set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) & data) );
00460 break;
00461 case 10:
00462 set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) | data) );
00463 break;
00464 case 11:
00465 set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) ^ data) );
00466 break;
00467 }
00468 }
00469
00470
00471 static void eval_set_version_1(command_t* command, int32_t cond) {
00472 uint8_t op = vm_getbits(command, 59, 4);
00473 uint8_t reg = vm_getbits(command, 35, 4);
00474 uint8_t reg2 = vm_getbits(command, 19, 4);
00475 uint16_t data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 31);
00476
00477 if(cond) {
00478 eval_set_op(command, op, reg, reg2, data);
00479 }
00480 }
00481
00482
00483
00484 static void eval_set_version_2(command_t* command, int32_t cond) {
00485 uint8_t op = vm_getbits(command, 59, 4);
00486 uint8_t reg = vm_getbits(command, 51, 4);
00487 uint8_t reg2 = vm_getbits(command, 35, 4);
00488 uint16_t data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 47);
00489
00490 if(cond) {
00491 eval_set_op(command, op, reg, reg2, data);
00492 }
00493 }
00494
00495
00496
00497
00498
00499 static int32_t eval_command(uint8_t *bytes, registers_t* registers, link_t *return_values) {
00500 int32_t cond, res = 0;
00501 command_t command;
00502 command.instruction =( (uint64_t) bytes[0] << 56 ) |
00503 ( (uint64_t) bytes[1] << 48 ) |
00504 ( (uint64_t) bytes[2] << 40 ) |
00505 ( (uint64_t) bytes[3] << 32 ) |
00506 ( (uint64_t) bytes[4] << 24 ) |
00507 ( (uint64_t) bytes[5] << 16 ) |
00508 ( (uint64_t) bytes[6] << 8 ) |
00509 (uint64_t) bytes[7] ;
00510 command.examined = 0;
00511 command.registers = registers;
00512 memset(return_values, 0, sizeof(link_t));
00513
00514 switch(vm_getbits(&command, 63, 3)) {
00515 case 0:
00516 cond = eval_if_version_1(&command);
00517 res = eval_special_instruction(&command, cond);
00518 if(res == -1) {
00519 fprintf(MSG_OUT, "libdvdnav: Unknown Instruction!\n");
00520 abort();
00521 }
00522 break;
00523 case 1:
00524 if(vm_getbits(&command, 60, 1)) {
00525 cond = eval_if_version_2(&command);
00526 res = eval_jump_instruction(&command, cond, return_values);
00527 } else {
00528 cond = eval_if_version_1(&command);
00529 res = eval_link_instruction(&command, cond, return_values);
00530 }
00531 if(res)
00532 res = -1;
00533 break;
00534 case 2:
00535 cond = eval_if_version_2(&command);
00536 res = eval_system_set(&command, cond, return_values);
00537 if(res)
00538 res = -1;
00539 break;
00540 case 3:
00541 cond = eval_if_version_3(&command);
00542 eval_set_version_1(&command, cond);
00543 if(vm_getbits(&command, 51, 4)) {
00544 res = eval_link_instruction(&command, cond, return_values);
00545 }
00546 if(res)
00547 res = -1;
00548 break;
00549 case 4:
00550 eval_set_version_2(&command, 1);
00551 cond = eval_if_version_4(&command);
00552 res = eval_link_subins(&command, cond, return_values);
00553 if(res)
00554 res = -1;
00555 break;
00556 case 5:
00557
00558 cond = eval_if_version_4(&command);
00559 eval_set_version_2(&command, cond);
00560 res = eval_link_subins(&command, cond, return_values);
00561 if(res)
00562 res = -1;
00563 break;
00564 case 6:
00565
00566 cond = eval_if_version_4(&command);
00567 eval_set_version_2(&command, cond);
00568 res = eval_link_subins(&command, 1, return_values);
00569 if(res)
00570 res = -1;
00571 break;
00572 default:
00573 fprintf(MSG_OUT, "libdvdnav: WARNING: Unknown Command=%x\n", vm_getbits(&command, 63, 3));
00574 abort();
00575 }
00576
00577
00578 if(command.instruction & ~ command.examined) {
00579 fprintf(MSG_OUT, "libdvdnav: decoder.c: [WARNING, unknown bits:");
00580 fprintf(MSG_OUT, " %08"PRIx64, (command.instruction & ~ command.examined) );
00581 fprintf(MSG_OUT, "]\n");
00582 }
00583
00584 return res;
00585 }
00586
00587
00588 int32_t vmEval_CMD(vm_cmd_t commands[], int32_t num_commands,
00589 registers_t *registers, link_t *return_values) {
00590 int32_t i = 0;
00591 int32_t total = 0;
00592
00593 #ifdef TRACE
00594
00595 fprintf(MSG_OUT, "libdvdnav: Registers before transaction\n");
00596 vm_print_registers( registers );
00597 fprintf(MSG_OUT, "libdvdnav: Full list of commands to execute\n");
00598 for(i = 0; i < num_commands; i++)
00599 vm_print_cmd(i, &commands[i]);
00600 fprintf(MSG_OUT, "libdvdnav: --------------------------------------------\n");
00601 fprintf(MSG_OUT, "libdvdnav: Single stepping commands\n");
00602 #endif
00603
00604 i = 0;
00605 while(i < num_commands && total < 100000) {
00606 int32_t line;
00607
00608 #ifdef TRACE
00609 vm_print_cmd(i, &commands[i]);
00610 #endif
00611
00612 line = eval_command(&commands[i].bytes[0], registers, return_values);
00613
00614 if (line < 0) {
00615 #ifdef TRACE
00616 fprintf(MSG_OUT, "libdvdnav: Registers after transaction\n");
00617 vm_print_registers( registers );
00618 fprintf(MSG_OUT, "libdvdnav: eval: Doing Link/Jump/Call\n");
00619 #endif
00620 return 1;
00621 }
00622
00623 if (line > 0)
00624 i = line - 1;
00625 else
00626 i++;
00627
00628 total++;
00629 }
00630
00631 memset(return_values, 0, sizeof(link_t));
00632 #ifdef TRACE
00633 fprintf(MSG_OUT, "libdvdnav: Registers after transaction\n");
00634 vm_print_registers( registers );
00635 #endif
00636 return 0;
00637 }
00638
00639 #ifdef TRACE
00640
00641 static char *linkcmd2str(link_cmd_t cmd) {
00642 switch(cmd) {
00643 case LinkNoLink:
00644 return "LinkNoLink";
00645 case LinkTopC:
00646 return "LinkTopC";
00647 case LinkNextC:
00648 return "LinkNextC";
00649 case LinkPrevC:
00650 return "LinkPrevC";
00651 case LinkTopPG:
00652 return "LinkTopPG";
00653 case LinkNextPG:
00654 return "LinkNextPG";
00655 case LinkPrevPG:
00656 return "LinkPrevPG";
00657 case LinkTopPGC:
00658 return "LinkTopPGC";
00659 case LinkNextPGC:
00660 return "LinkNextPGC";
00661 case LinkPrevPGC:
00662 return "LinkPrevPGC";
00663 case LinkGoUpPGC:
00664 return "LinkGoUpPGC";
00665 case LinkTailPGC:
00666 return "LinkTailPGC";
00667 case LinkRSM:
00668 return "LinkRSM";
00669 case LinkPGCN:
00670 return "LinkPGCN";
00671 case LinkPTTN:
00672 return "LinkPTTN";
00673 case LinkPGN:
00674 return "LinkPGN";
00675 case LinkCN:
00676 return "LinkCN";
00677 case Exit:
00678 return "Exit";
00679 case JumpTT:
00680 return "JumpTT";
00681 case JumpVTS_TT:
00682 return "JumpVTS_TT";
00683 case JumpVTS_PTT:
00684 return "JumpVTS_PTT";
00685 case JumpSS_FP:
00686 return "JumpSS_FP";
00687 case JumpSS_VMGM_MENU:
00688 return "JumpSS_VMGM_MENU";
00689 case JumpSS_VTSM:
00690 return "JumpSS_VTSM";
00691 case JumpSS_VMGM_PGC:
00692 return "JumpSS_VMGM_PGC";
00693 case CallSS_FP:
00694 return "CallSS_FP";
00695 case CallSS_VMGM_MENU:
00696 return "CallSS_VMGM_MENU";
00697 case CallSS_VTSM:
00698 return "CallSS_VTSM";
00699 case CallSS_VMGM_PGC:
00700 return "CallSS_VMGM_PGC";
00701 case PlayThis:
00702 return "PlayThis";
00703 }
00704 return "*** (bug)";
00705 }
00706
00707 void vm_print_link(link_t value) {
00708 char *cmd = linkcmd2str(value.command);
00709
00710 switch(value.command) {
00711 case LinkNoLink:
00712 case LinkTopC:
00713 case LinkNextC:
00714 case LinkPrevC:
00715 case LinkTopPG:
00716 case LinkNextPG:
00717 case LinkPrevPG:
00718 case LinkTopPGC:
00719 case LinkNextPGC:
00720 case LinkPrevPGC:
00721 case LinkGoUpPGC:
00722 case LinkTailPGC:
00723 case LinkRSM:
00724 fprintf(MSG_OUT, "libdvdnav: %s (button %d)\n", cmd, value.data1);
00725 break;
00726 case LinkPGCN:
00727 case JumpTT:
00728 case JumpVTS_TT:
00729 case JumpSS_VMGM_MENU:
00730 case JumpSS_VMGM_PGC:
00731 fprintf(MSG_OUT, "libdvdnav: %s %d\n", cmd, value.data1);
00732 break;
00733 case LinkPTTN:
00734 case LinkPGN:
00735 case LinkCN:
00736 fprintf(MSG_OUT, "libdvdnav: %s %d (button %d)\n", cmd, value.data1, value.data2);
00737 break;
00738 case Exit:
00739 case JumpSS_FP:
00740 case PlayThis:
00741 fprintf(MSG_OUT, "libdvdnav: %s\n", cmd);
00742 break;
00743 case JumpVTS_PTT:
00744 fprintf(MSG_OUT, "libdvdnav: %s %d:%d\n", cmd, value.data1, value.data2);
00745 break;
00746 case JumpSS_VTSM:
00747 fprintf(MSG_OUT, "libdvdnav: %s vts %d title %d menu %d\n",
00748 cmd, value.data1, value.data2, value.data3);
00749 break;
00750 case CallSS_FP:
00751 fprintf(MSG_OUT, "libdvdnav: %s resume cell %d\n", cmd, value.data1);
00752 break;
00753 case CallSS_VMGM_MENU:
00754 case CallSS_VTSM:
00755 fprintf(MSG_OUT, "libdvdnav: %s %d resume cell %d\n", cmd, value.data1, value.data2);
00756 break;
00757 case CallSS_VMGM_PGC:
00758 fprintf(MSG_OUT, "libdvdnav: %s %d resume cell %d\n", cmd, value.data1, value.data2);
00759 break;
00760 }
00761 }
00762
00763 void vm_print_registers( registers_t *registers ) {
00764 int32_t i;
00765 fprintf(MSG_OUT, "libdvdnav: # ");
00766 for(i = 0; i < 24; i++)
00767 fprintf(MSG_OUT, " %2d |", i);
00768 fprintf(MSG_OUT, "\nlibdvdnav: SRPMS: ");
00769 for(i = 0; i < 24; i++)
00770 fprintf(MSG_OUT, "%04x|", registers->SPRM[i]);
00771 fprintf(MSG_OUT, "\nlibdvdnav: GRPMS: ");
00772 for(i = 0; i < 16; i++)
00773 fprintf(MSG_OUT, "%04x|", get_GPRM(registers, i) );
00774 fprintf(MSG_OUT, "\nlibdvdnav: Gmode: ");
00775 for(i = 0; i < 16; i++)
00776 fprintf(MSG_OUT, "%04x|", registers->GPRM_mode[i]);
00777 fprintf(MSG_OUT, "\nlibdvdnav: Gtime: ");
00778 for(i = 0; i < 16; i++)
00779 fprintf(MSG_OUT, "%04lx|", registers->GPRM_time[i].tv_sec & 0xffff);
00780 fprintf(MSG_OUT, "\n");
00781 }
00782
00783 #endif
00784