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.