filename | src/bootstrap.c |
changeset | 1099:566cdeb157ec |
prev | 1095:a8b798030464 |
author | nkeynes |
date | Sat Aug 04 08:46:28 2012 +1000 (11 years ago) |
permissions | -rw-r--r-- |
last change | Handle corner case in pvr2_run_slice when we've previously slightly overrun the end of the time slice |
file | annotate | diff | log | raw |
1.1 --- a/src/bootstrap.c Sun Jan 31 18:28:24 2010 +10001.2 +++ b/src/bootstrap.c Sat Aug 04 08:46:28 2012 +10001.3 @@ -135,3 +135,71 @@1.4 INFO( buf, NULL );1.5 }1.6 }1.7 +1.8 +/* Scramble/unscramble, based on Marcus Comstedt's algorithm. */1.9 +1.10 +typedef uint16_t randseed;1.11 +1.12 +#define MAXBLOCK (2048*1024)1.13 +#define CHUNKSIZE 321.14 +#define NEXT(seed) (((seed = (seed*2109+9273)&0x7fff) + 0xC000) & 0xFFFF)1.15 +1.16 +void bootprogram_scramble( unsigned char *dest, unsigned char *src, size_t length )1.17 +{1.18 + randseed seed = length & 0xFFFF;1.19 + unsigned table[MAXBLOCK/32];1.20 + unsigned char *s = src;1.21 + unsigned char *d = dest;1.22 +1.23 + for( unsigned blocksize = MAXBLOCK; blocksize >= CHUNKSIZE; blocksize >>= 1 ) {1.24 + while( length >= blocksize ) {1.25 + unsigned nchunks = blocksize/CHUNKSIZE;1.26 + for( unsigned i=0; i<nchunks; i++ ) {1.27 + table[i] = i; // Identity1.28 + }1.29 + for( unsigned i = nchunks-1; i != (unsigned)-1; --i ) {1.30 + unsigned j = (NEXT(seed) * i)>>16;1.31 + unsigned tmp = table[i];1.32 + table[i] = table[j];1.33 + table[j] = tmp;1.34 + memcpy( d, s + CHUNKSIZE*table[i], CHUNKSIZE );1.35 + d+= CHUNKSIZE;1.36 + }1.37 + length -= blocksize;1.38 + s += blocksize;1.39 + }1.40 + }1.41 + if( length ) {1.42 + memcpy( d, s, length );1.43 + }1.44 +}1.45 +1.46 +void bootprogram_unscramble( unsigned char *dest, unsigned char *src, size_t length )1.47 +{1.48 + randseed seed = length & 0xFFFF;1.49 + unsigned table[MAXBLOCK/32];1.50 + unsigned char *s = src;1.51 + unsigned char *d = dest;1.52 +1.53 + for( unsigned blocksize = MAXBLOCK; blocksize >= CHUNKSIZE; blocksize >>= 1 ) {1.54 + while( length >= blocksize ) {1.55 + unsigned nchunks = blocksize/CHUNKSIZE;1.56 + for( unsigned i=0; i<nchunks; i++ ) {1.57 + table[i] = i; // Identity1.58 + }1.59 + for( unsigned i = nchunks-1; i != (unsigned)-1; --i ) {1.60 + unsigned j = (NEXT(seed) * i)>>16;1.61 + unsigned tmp = table[i];1.62 + table[i] = table[j];1.63 + table[j] = tmp;1.64 + memcpy( d + CHUNKSIZE*table[i], s, CHUNKSIZE );1.65 + s+= CHUNKSIZE;1.66 + }1.67 + length -= blocksize;1.68 + d += blocksize;1.69 + }1.70 + }1.71 + if( length ) {1.72 + memcpy( d, s, length );1.73 + }1.74 +}
.