# HG changeset patch # User jcdutton # Date 1018642001 0 # Node ID 7e8628911b4f90fed6204e8c4f88fc22dd138a78 # Parent e6ac0a8d9c14e84133ca6e1554f3e4c684baabc6 Implement General Register Counters or GPRM counters. Navigation timers are not supported yet. SPRM[9] and SPRM[10]. diff -r e6ac0a8d9c14 -r 7e8628911b4f decoder.c --- a/decoder.c Fri Apr 12 12:43:36 2002 +0000 +++ b/decoder.c Fri Apr 12 20:06:41 2002 +0000 @@ -58,6 +58,42 @@ return (uint32_t) result; } +static uint16_t get_GPRM(registers_t* registers, uint8_t reg) { + if (registers->GPRM_mode[reg] & 0x01) { + struct timeval current_time, time_offset; + uint16_t result; + /* Counter mode */ + /* fprintf(stderr, "Getting counter %d\n",reg);*/ + gettimeofday(¤t_time, NULL); + time_offset.tv_sec = current_time.tv_sec - registers->GPRM_time[reg].tv_sec; + time_offset.tv_usec = current_time.tv_usec - registers->GPRM_time[reg].tv_usec; + if (time_offset.tv_usec < 0) { + time_offset.tv_sec--; + time_offset.tv_usec += 1000000; + } + result = (uint16_t) (time_offset.tv_sec & 0xffff); + registers->GPRM[reg]=result; + return result; + + } else { + /* Register mode */ + return registers->GPRM[reg]; + } + +} + +static void set_GPRM(registers_t* registers, uint8_t reg, uint16_t value) { + if (registers->GPRM_mode[reg] & 0x01) { + struct timeval current_time; + /* Counter mode */ + /* fprintf(stderr, "Setting counter %d\n",reg); */ + gettimeofday(¤t_time, NULL); + registers->GPRM_time[reg] = current_time; + registers->GPRM_time[reg].tv_sec -= value; + } + registers->GPRM[reg] = value; +} + /* Eval register code, can either be system or general register. SXXX_XXXX, where S is 1 if it is system register. */ static uint16_t eval_reg(command_t* command, uint8_t reg) { @@ -67,7 +103,7 @@ } return command->registers->SPRM[reg & 0x1f]; /* FIXME max 24 not 32 */ } else { - return command->registers->GPRM[reg & 0x0f]; + return get_GPRM(command->registers, reg & 0x0f) ; } } @@ -90,7 +126,7 @@ if(imm) /* immediate */ return vm_getbits(command, ((byte*8)+1), 7); else - return command->registers->GPRM[vm_getbits(command, ((byte*8)+4), 4)]; + return get_GPRM(command->registers, (vm_getbits(command, ((byte*8)+4), 4)) ); } @@ -341,14 +377,12 @@ data = eval_reg_or_data(command, vm_getbits(command, 3, 1), 2); data2 = vm_getbits(command, 44, 4); if(vm_getbits(command, 40, 1)) { - fprintf(stderr, "Detected SetGPRMMD Counter!! This is unsupported.\n"); command->registers->GPRM_mode[data2] |= 1; /* Set bit 0 */ } else { - fprintf(stderr, "Detected ResetGPRMMD Counter!! This is unsupported.\n"); command->registers->GPRM_mode[data2] &= ~ 0x01; /* Reset bit 0 */ } if(cond) { - command->registers->GPRM[data2] = data; + set_GPRM(command->registers, data2, data); } break; case 6: /* Set system reg 8 (Highlighted button) */ @@ -374,48 +408,48 @@ int32_t tmp; switch(op) { case 1: - command->registers->GPRM[reg] = data; + set_GPRM(command->registers, reg, data); break; case 2: /* SPECIAL CASE - SWAP! */ - command->registers->GPRM[reg2] = command->registers->GPRM[reg]; - command->registers->GPRM[reg] = data; + set_GPRM(command->registers, reg2, get_GPRM(command->registers, reg)); + set_GPRM(command->registers, reg, data); break; case 3: - tmp = command->registers->GPRM[reg] + data; + tmp = get_GPRM(command->registers, reg) + data; if(tmp > shortmax) tmp = shortmax; - command->registers->GPRM[reg] = (uint16_t)tmp; + set_GPRM(command->registers, reg, (uint16_t)tmp); break; case 4: - tmp = command->registers->GPRM[reg] - data; + tmp = get_GPRM(command->registers, reg) - data; if(tmp < 0) tmp = 0; - command->registers->GPRM[reg] = (uint16_t)tmp; + set_GPRM(command->registers, reg, (uint16_t)tmp); break; case 5: - tmp = command->registers->GPRM[reg] * data; + tmp = get_GPRM(command->registers, reg) * data; if(tmp >= shortmax) tmp = shortmax; - command->registers->GPRM[reg] = (uint16_t)tmp; + set_GPRM(command->registers, reg, (uint16_t)tmp); break; case 6: if (data != 0) { - command->registers->GPRM[reg] /= data; + set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) / data) ); } else { - command->registers->GPRM[reg] = 0; /* Avoid that divide by zero! */ + set_GPRM(command->registers, reg, 0); /* Avoid that divide by zero! */ } break; case 7: - command->registers->GPRM[reg] %= data; + set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) % data) ); break; case 8: /* SPECIAL CASE - RND! */ - command->registers->GPRM[reg] = (uint16_t) ((float) data * rand()/(RAND_MAX+1.0)); + set_GPRM(command->registers, reg, ((uint16_t) ((float) data * rand()/(RAND_MAX+1.0))) ); break; case 9: - command->registers->GPRM[reg] &= data; + set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) & data) ); break; case 10: - command->registers->GPRM[reg] |= data; + set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) | data) ); break; case 11: - command->registers->GPRM[reg] ^= data; + set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) ^ data) ); break; } } @@ -722,9 +756,12 @@ fprintf(stderr, "%04x|", registers->SPRM[i]); fprintf(stderr, "\nGRPMS: "); for(i = 0; i < 16; i++) - fprintf(stderr, "%04x|", registers->GPRM[i]); + fprintf(stderr, "%04x|", get_GPRM(registers, i) ); fprintf(stderr, "\nGmode: "); for(i = 0; i < 16; i++) fprintf(stderr, "%04x|", registers->GPRM_mode[i]); + fprintf(stderr, "\nGtime: "); + for(i = 0; i < 16; i++) + fprintf(stderr, "%04lx|", registers->GPRM_time[i].tv_sec & 0xffff); fprintf(stderr, "\n"); } diff -r e6ac0a8d9c14 -r 7e8628911b4f decoder.h --- a/decoder.h Fri Apr 12 12:43:36 2002 +0000 +++ b/decoder.h Fri Apr 12 20:06:41 2002 +0000 @@ -27,6 +27,8 @@ #include "config.h" #include +#include + #include /* vm_cmd_t */ /* Uncomment for tracing */ @@ -86,6 +88,7 @@ uint16_t SPRM[24]; uint16_t GPRM[16]; uint8_t GPRM_mode[16]; /* Need to have some thing to indicate normal/counter mode for every GPRM */ + struct timeval GPRM_time[16]; /* For counter mode */ } registers_t; typedef struct diff -r e6ac0a8d9c14 -r 7e8628911b4f vm.c --- a/vm.c Fri Apr 12 12:43:36 2002 +0000 +++ b/vm.c Fri Apr 12 20:06:41 2002 +0000 @@ -167,6 +167,8 @@ memset((vm->state).registers.SPRM, 0, sizeof(uint16_t)*24); memset((vm->state).registers.GPRM, 0, sizeof((vm->state).registers.GPRM)); memset((vm->state).registers.GPRM_mode, 0, sizeof((vm->state).registers.GPRM_mode)); + memset((vm->state).registers.GPRM_mode, 0, sizeof((vm->state).registers.GPRM_mode)); + memset((vm->state).registers.GPRM_time, 0, sizeof((vm->state).registers.GPRM_time)); (vm->state).registers.SPRM[0] = ('e'<<8)|'n'; /* Player Menu Languange code */ (vm->state).AST_REG = 15; /* 15 why? */ (vm->state).SPST_REG = 62; /* 62 why? */ @@ -1572,6 +1574,10 @@ /* * $Log$ + * Revision 1.11 2002/04/12 20:06:41 jcdutton + * Implement General Register Counters or GPRM counters. + * Navigation timers are not supported yet. SPRM[9] and SPRM[10]. + * * Revision 1.10 2002/04/12 12:43:36 jcdutton * Display DVD disk region setting. * Display possible RCE region protection message.