README.md: fix typo
[32620_extract] / extract.c
1 /* Extractor for Geraet 32620 ROM files
2 *
3 * Copyright (c) 2020 Michael Gernoth <michael@gernoth.net>
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to
7 * deal in the Software without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23 #include <errno.h>
24 #include <inttypes.h>
25 #include <fcntl.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <unistd.h>
32
33 int main(int argc, char **argv)
34 {
35 uint8_t header[64];
36 uint32_t adrs[(64/3)+1] = { 0 };
37 uint8_t cs2 = 0;
38 int fd;
39 int r;
40 int i;
41 int count = 0;
42
43 if (argc != 3) {
44 fprintf(stderr, "Syntax: %s in.bin prefix\n", argv[0]);
45 exit(EXIT_FAILURE);
46 }
47
48 fd = open(argv[1], O_RDONLY);
49 if (fd == -1) {
50 perror("Can't open ROM");
51 exit(EXIT_FAILURE);
52 }
53
54 r = read(fd, header, sizeof(header));
55 if (r != sizeof(header)) {
56 perror("Can't read header");
57 exit(EXIT_FAILURE);
58 }
59
60 /*
61 * From: https://blog.ardy.io/2020/8/geraet-32620/
62 *
63 * 00000000 01000000 01000011 10110111 01001010 01000011 11000011 01011000
64 * ^^^^^^^^ ^^^^^^^^ ^^^^^^^^| |
65 * LIIIIIII LIILIIII LIIIILII
66 * I I I | +-- Amplification (Default: 3)
67 * I I I +----- Chip/Module Select lines/EOF?
68 * I I +----------- Address (HI Byte)
69 * I +---------------- Chip Select lines A15, A14, A13
70 * +-------------------- Address (LO Byte)
71 */
72 for (i = 0; i < 62; i+=3) {
73 uint8_t hi, lo, amp, cs;
74 uint32_t adr;
75
76 lo = header[i];
77 hi = header[i+1] & 0x1f;
78
79 // !EOF ?!
80 if ((header[i+2] & 0xf8) != 0xf8)
81 cs2 = (header[i+2] & 0xf8) >> 3;
82
83 cs = ((header[i+1] & 0xe0) >> 5) - 2;
84
85 // second module?
86 if ((cs2 & 0x08) == 0x00)
87 cs += 6; // 6 ROMs per module
88
89 amp = header[i+2] & 0x3;
90
91 adr = ((hi << 8) | lo) + (cs * 8192);
92 if (adr == 0)
93 adr += sizeof(header);
94
95 printf("%02d. hi: 0x%02x, lo: 0x%02x, cs: 0x%02x, cs2: 0x%02x -> chip: 0x%02x, adr: 0x%04x; amp: 0x%02x\n",
96 i/3, hi, lo,
97 ((header[i+1] & 0xe0) >> 5),
98 ((header[i+2] & 0xf8) >> 3),
99 cs, adr, amp);
100
101 adrs[i/3] = adr;
102 if ((header[i+2] & 0xf8) == 0xf8)
103 break;
104
105 count++;
106 }
107
108 for (i = 0; i < count; i++) {
109 uint8_t buf[65536];
110 uint32_t len;
111 char file[32];
112 int fd_out;
113
114 lseek(fd, adrs[i], SEEK_SET);
115
116 len = adrs[i+1] - adrs[i];
117
118 if (!len)
119 break;
120
121 printf("%02d. Length: %d\n", i, len);
122 memset(file, 0, sizeof(file));
123 snprintf(file, sizeof(file)-1, "%s-%02d.raw", argv[2], i);
124
125 fd_out = open(file, O_WRONLY|O_CREAT|O_TRUNC, 0644);
126 if (fd_out == -1) {
127 perror("Can't open out");
128 exit(EXIT_FAILURE);
129 }
130
131 r = read(fd, buf, len);
132 if (r != len) {
133 perror("Can't read content");
134 exit(EXIT_FAILURE);
135 }
136
137 r = write(fd_out, buf, len);
138 if (r != len) {
139 perror("Can't write content");
140 exit(EXIT_FAILURE);
141 }
142
143 close(fd_out);
144
145 }
146
147 close(fd);
148
149 return EXIT_SUCCESS;
150 }
Impressum, Datenschutz