git.y1.nz

SameBoy

Accurate GB/GBC emulator
download: https://git.y1.nz/archives/sameboy.tar.gz
README | Files | Log | Refs | LICENSE

BootROMs/pb12.c

      1 #include <stdio.h>
      2 #include <stdint.h>
      3 #include <stdbool.h>
      4 #include <stdlib.h>
      5 #include <unistd.h>
      6 #include <assert.h>
      7 
      8 static void opts(uint8_t byte, uint8_t *options)
      9 {
     10     *(options++) = byte | ((byte << 1) & 0xff);
     11     *(options++) = byte & (byte << 1);
     12     *(options++) = byte | ((byte >> 1) & 0xff);
     13     *(options++) = byte & (byte >> 1);
     14 }
     15 
     16 static void write_all(int fd, const void *buf, size_t count) {
     17     while (count) {
     18         ssize_t written = write(fd, buf, count);
     19         if (written < 0) {
     20             fprintf(stderr, "write");
     21             exit(1);
     22         }
     23         count -= written;
     24         buf += written;
     25     }
     26 }
     27 
     28 int main(void)
     29 {
     30     static uint8_t source[0x4000];
     31     size_t size = read(STDIN_FILENO, &source, sizeof(source));
     32     unsigned pos = 0;
     33     assert(size <= 0x4000);
     34     while (size && source[size - 1] == 0) {
     35         size--;
     36     }
     37     
     38     uint8_t literals[8];
     39     size_t literals_size = 0;
     40     unsigned bits = 0;
     41     unsigned control = 0;
     42     unsigned prev[2] = {-1, -1}; // Unsigned to allow "not set" values
     43     
     44     while (true) {
     45 
     46         uint8_t byte = 0;
     47         if (pos == size){
     48             if (bits == 0) break;
     49         }
     50         else {
     51             byte = source[pos++];
     52         }
     53         
     54         if (byte == prev[0] || byte == prev[1]) {
     55             bits += 2;
     56             control <<= 1;
     57             control |= 1;
     58             control <<= 1;
     59             if (byte == prev[1]) {
     60                 control |= 1;
     61             }
     62         }
     63         else {
     64             bits += 2;
     65             control <<= 2;
     66             uint8_t options[4];
     67             opts(prev[1], options);
     68             bool found = false;
     69             for (unsigned i = 0; i < 4; i++) {
     70                 if (options[i] == byte) {
     71                     // 01 = modify
     72                     control |= 1;
     73                     
     74                     bits += 2;
     75                     control <<= 2;
     76                     control |= i;
     77                     found = true;
     78                     break;
     79                 }
     80             }
     81             if (!found) {
     82                 literals[literals_size++] = byte;
     83             }
     84         }
     85         
     86         prev[0] = prev[1];
     87         prev[1] = byte;
     88         if (bits >= 8) {
     89             uint8_t outctl = control >> (bits - 8);
     90             assert(outctl != 1); // 1 is reserved as the end byte
     91             write_all(STDOUT_FILENO, &outctl, 1);
     92             write_all(STDOUT_FILENO, literals, literals_size);
     93             bits -= 8;
     94             control &= (1 << bits) - 1;
     95             literals_size = 0;
     96         }
     97     }
     98     uint8_t end_byte = 1;
     99     write_all(STDOUT_FILENO, &end_byte, 1);
    100 
    101     return 0;
    102 }

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.