Advertisement
TerusTheBird

slightly more complicated but more efficient

Jan 27th, 2020
163
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Same deal with this
  2. // we only do bitwise operations at the beginning, and there's not too many
  3. // (I also intentionally wrote them to be (hopefully) easier to convert to assembly)
  4.  
  5. // however, the change with this is that instead of having 10 bits for signalling, we only have 2
  6. // so one of the 4 commands is to load a "meta" command
  7. // this shouldn't make things much more complicated
  8.  
  9. // the benefit is that we get 11 bytes per frame, nearly as much as the old bitwise version
  10. // but without the mountain of complications
  11.  
  12. // let the following be an array that magically contains the bytes for 3 controllers
  13. uint8_t pad_bytes[ 12 ];
  14.  
  15. uint16_t command = 0;
  16. uint16_t command_last = 1;
  17.  
  18. read_pad( ) {
  19.     uint16_t temp;
  20.     uint8_t lowlevel_command, out_bytes[ 11 ];
  21.    
  22.     // for all of the controller bytes that are full bytes, load them directly
  23.     out_bytes[ 0 ] = pad_bytes[  0 ];
  24.     out_bytes[ 1 ] = pad_bytes[  2 ];
  25.     out_bytes[ 2 ] = pad_bytes[  3 ];
  26.     out_bytes[ 3 ] = pad_bytes[  4 ];
  27.     out_bytes[ 4 ] = pad_bytes[  6 ];
  28.     out_bytes[ 5 ] = pad_bytes[  7 ];
  29.     out_bytes[ 6 ] = pad_bytes[  8 ];
  30.     out_bytes[ 7 ] = pad_bytes[ 10 ];
  31.     out_bytes[ 8 ] = pad_bytes[ 11 ];
  32.    
  33.     // pad_bytes[ 1 ], pad_bytes[ 5 ], pad_bytes[ 9 ] only have 6 bits of useful data
  34.     // we'll have to do some bitwise operations to compose them into bytes
  35.    
  36.     // mask off garbage bits, can skip if this isn't needed
  37.     pad_bytes[ 1 ] &= 63;
  38.     pad_bytes[ 5 ] &= 63;
  39.     pad_bytes[ 9 ] &= 63;
  40.    
  41.    
  42.     // --- Read extra bytes ---
  43.    
  44.     // step by step bit twiddling
  45.     temp = pad_bytes[ 5 ];  // read pad byte 5 into a register
  46.     temp &= 3;              // mask off everything except the first two bits
  47.     temp <<= 6;             // shift it up 6 bits, so that the first two bits are at the top of the byte
  48.     temp |= pad_bytes[ 1 ]; // merge it with the entirety of pad byte 1
  49.    
  50.     // write it out
  51.     out_bytes[ 9 ] = temp;
  52.    
  53.     // read the next byte
  54.     temp = pad_bytes[ 5 ];  // load pad byte 5 into a register
  55.     temp &= 60;             // mask off the lowest two bits (which were part of the old byte)
  56.     temp <<= 4;             // shift everything up 4 bits, so that there's 6 bits free at the bottom
  57.     temp |= pad_bytes[ 9 ]; // merge pad byte 9 into the lower 6 bits
  58.     temp >>= 2;             // shift everything down two bits, discarding the first two bits of pad byte 9
  59.    
  60.     // write it out
  61.     out_bytes[ 10 ] = temp;
  62.    
  63.     // there should now be 11 (!) bytes in our buffer
  64.    
  65.    
  66.     // --- Read command ---
  67.    
  68.     lowlevel_command = pad_bytes[ 9 ] & 3;
  69.    
  70.    
  71.     // --- Execute command ---
  72.    
  73.     if( lowlevel_command == 0 ) { // execute meta command
  74.         switch( command ) {
  75.             // ...
  76.             default: break;
  77.         }
  78.     }
  79.     if( lowlevel_command == 1 ) { // load a new meta command
  80.         uint16_t* out_bytes16;
  81.         out_bytes16 = (uint16_t*)out_bytes; // type punning
  82.        
  83.         command_last = command; // set the previous command to the current command
  84.         command = *out_bytes16; // set the current command to the new command
  85.     }
  86.     // if lowlevel_command == 2 then do something else
  87.     // if lowlevel_command == 3 then NOP
  88.    
  89. }
Advertisement
RAW Paste Data Copied
Advertisement