Advertisement
TerusTheBird

data loader, example commands

Jan 27th, 2020
132
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. uint32_t command = 0;
  16. uint32_t command_last = 1; // so that we can detect when commands change
  17.  
  18. uint8_t* data_pointer = NULL;
  19. void (*func_pointer)(void);
  20.  
  21. read_pad( ) {
  22.     uint16_t temp;
  23.     uint8_t lowlevel_command, out_bytes[ 11 ];
  24.    
  25.     // for all of the controller bytes that are full bytes, load them directly
  26.     out_bytes[ 0 ] = pad_bytes[  0 ];
  27.     out_bytes[ 1 ] = pad_bytes[  2 ];
  28.     out_bytes[ 2 ] = pad_bytes[  3 ];
  29.     out_bytes[ 3 ] = pad_bytes[  4 ];
  30.     out_bytes[ 4 ] = pad_bytes[  6 ];
  31.     out_bytes[ 5 ] = pad_bytes[  7 ];
  32.     out_bytes[ 6 ] = pad_bytes[  8 ];
  33.     out_bytes[ 7 ] = pad_bytes[ 10 ];
  34.     out_bytes[ 8 ] = pad_bytes[ 11 ];
  35.    
  36.     // pad_bytes[ 1 ], pad_bytes[ 5 ], pad_bytes[ 9 ] only have 6 bits of useful data
  37.     // we'll have to do some bitwise operations to compose them into bytes
  38.    
  39.     // mask off garbage bits, can skip if this isn't needed
  40.     pad_bytes[ 1 ] &= 63;
  41.     pad_bytes[ 5 ] &= 63;
  42.     pad_bytes[ 9 ] &= 63;
  43.    
  44.    
  45.     // --- Read extra bytes ---
  46.    
  47.     // step by step bit twiddling
  48.     temp = pad_bytes[ 5 ];  // read pad byte 5 into a register
  49.     temp &= 3;              // mask off everything except the first two bits
  50.     temp <<= 6;             // shift it up 6 bits, so that the first two bits are at the top of the byte
  51.     temp |= pad_bytes[ 1 ]; // merge it with the entirety of pad byte 1
  52.    
  53.     // write it out
  54.     out_bytes[ 9 ] = temp;
  55.    
  56.     // read the next byte
  57.     temp = pad_bytes[ 5 ];  // load pad byte 5 into a register
  58.     temp &= 60;             // mask off the lowest two bits (which were part of the old byte)
  59.     temp <<= 4;             // shift everything up 4 bits, so that there's 6 bits free at the bottom
  60.     temp |= pad_bytes[ 9 ]; // merge pad byte 9 into the lower 6 bits
  61.     temp >>= 2;             // shift everything down two bits, discarding the first two bits of pad byte 9
  62.    
  63.     // write it out
  64.     out_bytes[ 10 ] = temp;
  65.    
  66.     // there should now be 11 (!) bytes in our buffer
  67.    
  68.    
  69.     // --- Read command ---
  70.    
  71.     lowlevel_command = pad_bytes[ 9 ] & 3;
  72.     // bitwise operations end here
  73.    
  74.    
  75.     // --- Execute command ---
  76.    
  77.     if( lowlevel_command == 0 ) { // execute meta command
  78.         switch( command ) {
  79.            
  80.             case 0: { // set data pointer
  81.                 data_pointer = *((uint8_t**)out_bytes);
  82.             } break;
  83.            
  84.             case 1: { // write 11 bytes to memory (always 11 bytes)
  85.                 uint8_t i;
  86.                 for( i = 0; i < 11; ++i ) {
  87.                     *data_pointer = out_bytes[ i ];
  88.                     ++data_pointer;
  89.                 }
  90.             } break;
  91.            
  92.             case 2: { // write up to 10 bytes to memory
  93.                 uint8_t i;
  94.                 for( i = 0; i < out_bytes[ 10 ] && i < 10; ++i ) {
  95.                     *data_pointer = out_bytes[ i ];
  96.                     ++data_pointer;
  97.                 }
  98.             } break;
  99.            
  100.             case 3: { // set function pointer
  101.                 func_pointer = *( (void (*)(void))out_bytes );
  102.             } break;
  103.            
  104.             case 4: { // execute function ptr
  105.                 func_pointer();
  106.             } break;
  107.            
  108.             default: break;
  109.         }
  110.     }
  111.     if( lowlevel_command == 1 ) { // load a new meta command
  112.         command_last = command; // set the previous command to the current command
  113.         command = *( (uint32_t*)out_bytes ); // set the current command to the new command
  114.     }
  115.     // if lowlevel_command == 2 then do something else
  116.     // if lowlevel_command == 3 then NOP
  117.    
  118. }
Advertisement
RAW Paste Data Copied
Advertisement