Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* boilerplate */
- typedef unsigned char u8;
- typedef unsigned short u16;
- typedef unsigned int u32;
- typedef char s8;
- typedef short s16;
- typedef int s32;
- /* loader state */
- static u32 l_state = 0; /* 5 bits */
- static u8 l_state_load = 0;
- static u32 temp_data = 0;
- static u8 temp_data_pos = 0;
- static u8 temp_data_length = 0;
- int temp_data_update( u8 bit, u32* var ) {
- if( temp_data_length == 0 ) return 0;
- temp_data = ( temp_data << 1 ) | ( bit & 1 );
- ++temp_data_pos;
- if( temp_data_pos >= temp_data_length ) {
- if( var != NULL )
- *var = temp_data;
- temp_data = 0;
- temp_data_pos = 0;
- temp_data_length = 0;
- return 2;
- }
- return 1;
- }
- /* never call this with a length less than 2 */
- int temp_data_start( u8 bit, u32 length ) {
- temp_data = temp_data_pos = temp_data_length = 0;
- temp_data_update( bit, NULL );
- }
- /* data loader state */
- static u8 rd_state = 0; /* 0 = length begin; 1 = length; 2 = pos begin; 3 = pos; 4 = bytes begin; 5 = bytes; */
- static u32 rd_length = 0; /* 23 bits */
- static u8* rd_address = NULL; /* 32 bits */
- static u32 rd_pos = 0;
- /* this gets called every time we poll the controllers */
- void load_data( void ) {
- u32 pads[ 3 ];
- /* get pad state with magic */
- pads[ 0 ] = get_pad_voodoo( CONTROLLER_2 );
- pads[ 1 ] = get_pad_voodoo( CONTROLLER_3 );
- pads[ 2 ] = get_pad_voodoo( CONTROLLER_4 );
- for( i = 0; i < 96; ++i ) {
- u8 bit_number;
- /* get the current bit number */
- bit_number = i & 31;
- /* skip the unused bits in the N64 pad */
- if( bit_number != 8 && bit_number != 9 ) {
- u8 bit;
- /* get the next bit */
- bit = ( pads[ i >> 5 ] >> bit_number ) & 1;
- switch( l_state & 31 ) {
- case 0: { /* load a new state */
- if( l_state_load ) {
- temp_data_start( bit, 5 );
- l_state_load = 0;
- } else {
- temp_data_update( bit, &l_state ); /* I don't know if I like this */
- l_state_load = 1;
- }
- } break; /* if we just keep loading state 0 over and over its basically a NOP */
- case 1: { /* read raw bytes to memory */
- switch( rd_state ) {
- /* get the length */
- case 0: {
- rd_address = NULL;
- rd_length = 0;
- temp_data_start( bit, 23 );
- rd_state = 1;
- } break;
- case 1: {
- if( temp_data_update( bit, &rd_length ) == 2 )
- rd_state = 2;
- } break;
- /* get the pointer */
- case 2: {
- temp_data_start( bit, 32 );
- rd_state = 3;
- } break;
- case 3: {
- if( temp_data_update( bit, (u32*)(&rd_address) ) == 2 )
- rd_state = 4;
- } break;
- /* load data a byte at a time */
- case 4: { /* start loading a byte */
- temp_data_start( bit, 8 );
- rd_state = 5;
- } break;
- case 5: {
- u32 byte;
- if( temp_data_update( bit, &byte ) == 2 ) { /* if the byte read is actually finished */
- if( rd_pos < rd_length ) /* prevent corruption */
- rd_address[ rd_pos ] = byte & 255; /* actually write to the memory */
- ++rd_pos;
- if( rd_pos < rd_length ) { /* check if we're at the end of the write */
- rd_state = 4; /* if not then read another byte */
- } else {
- /* end the read and get another command */
- rd_state = 0;
- l_state_load = 1;
- l_state = 0;
- }
- }
- } break;
- default: break;
- }
- } break;
- default: break; /* this should never happen */
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement