Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Same deal with this
- // we only do bitwise operations at the beginning, and there's not too many
- // (I also intentionally wrote them to be (hopefully) easier to convert to assembly)
- // however, the change with this is that instead of having 10 bits for signalling, we only have 2
- // so one of the 4 commands is to load a "meta" command
- // this shouldn't make things much more complicated
- // the benefit is that we get 11 bytes per frame, nearly as much as the old bitwise version
- // but without the mountain of complications
- // let the following be an array that magically contains the bytes for 3 controllers
- uint8_t pad_bytes[ 12 ];
- uint32_t command = 0;
- uint32_t command_last = 1; // so that we can detect when commands change
- uint8_t* data_pointer = NULL;
- void (*func_pointer)(void);
- read_pad( ) {
- uint16_t temp;
- uint8_t lowlevel_command, out_bytes[ 11 ];
- // for all of the controller bytes that are full bytes, load them directly
- out_bytes[ 0 ] = pad_bytes[ 0 ];
- out_bytes[ 1 ] = pad_bytes[ 2 ];
- out_bytes[ 2 ] = pad_bytes[ 3 ];
- out_bytes[ 3 ] = pad_bytes[ 4 ];
- out_bytes[ 4 ] = pad_bytes[ 6 ];
- out_bytes[ 5 ] = pad_bytes[ 7 ];
- out_bytes[ 6 ] = pad_bytes[ 8 ];
- out_bytes[ 7 ] = pad_bytes[ 10 ];
- out_bytes[ 8 ] = pad_bytes[ 11 ];
- // pad_bytes[ 1 ], pad_bytes[ 5 ], pad_bytes[ 9 ] only have 6 bits of useful data
- // we'll have to do some bitwise operations to compose them into bytes
- // mask off garbage bits, can skip if this isn't needed
- pad_bytes[ 1 ] &= 63;
- pad_bytes[ 5 ] &= 63;
- pad_bytes[ 9 ] &= 63;
- // --- Read extra bytes ---
- // step by step bit twiddling
- temp = pad_bytes[ 5 ]; // read pad byte 5 into a register
- temp &= 3; // mask off everything except the first two bits
- temp <<= 6; // shift it up 6 bits, so that the first two bits are at the top of the byte
- temp |= pad_bytes[ 1 ]; // merge it with the entirety of pad byte 1
- // write it out
- out_bytes[ 9 ] = temp;
- // read the next byte
- temp = pad_bytes[ 5 ]; // load pad byte 5 into a register
- temp &= 60; // mask off the lowest two bits (which were part of the old byte)
- temp <<= 4; // shift everything up 4 bits, so that there's 6 bits free at the bottom
- temp |= pad_bytes[ 9 ]; // merge pad byte 9 into the lower 6 bits
- temp >>= 2; // shift everything down two bits, discarding the first two bits of pad byte 9
- // write it out
- out_bytes[ 10 ] = temp;
- // there should now be 11 (!) bytes in our buffer
- // --- Read command ---
- lowlevel_command = pad_bytes[ 9 ] & 3;
- // bitwise operations end here
- // --- Execute command ---
- if( lowlevel_command == 0 ) { // execute meta command
- switch( command ) {
- case 0: { // set data pointer
- data_pointer = *((uint8_t**)out_bytes);
- } break;
- case 1: { // write 11 bytes to memory (always 11 bytes)
- uint8_t i;
- for( i = 0; i < 11; ++i ) {
- *data_pointer = out_bytes[ i ];
- ++data_pointer;
- }
- } break;
- case 2: { // write up to 10 bytes to memory
- uint8_t i;
- for( i = 0; i < out_bytes[ 10 ] && i < 10; ++i ) {
- *data_pointer = out_bytes[ i ];
- ++data_pointer;
- }
- } break;
- case 3: { // set function pointer
- func_pointer = *( (void (*)(void))out_bytes );
- } break;
- case 4: { // execute function ptr
- func_pointer();
- } break;
- default: break;
- }
- }
- if( lowlevel_command == 1 ) { // load a new meta command
- command_last = command; // set the previous command to the current command
- command = *( (uint32_t*)out_bytes ); // set the current command to the new command
- }
- // if lowlevel_command == 2 then do something else
- // if lowlevel_command == 3 then NOP
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement