skip header only if address is zero
[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 I????LII
66 * I I I I +-- Amplification (Default: 3)
67 * I I I +--------- Remaining chip select line? (but not quite?)
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;
82
83 if (cs2 & 0x40) {
84 cs = ((header[i+1] & 0xe0) >> 5) - 2;
85 } else {
86 cs = (((header[i+1] & 0xe0) >> 5) | (1 << 3)) - 4;
87 }
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 -> adr: 0x%04x; amp: 0x%02x\n",
96 i/3, hi, lo, cs, adr, amp);
97
98 adrs[i/3] = adr;
99 if ((header[i+2] & 0xf8) == 0xf8)
100 break;
101
102 count++;
103 }
104
105 for (i = 0; i < count; i++) {
106 uint8_t buf[65536];
107 uint32_t len;
108 char file[32];
109 int fd_out;
110
111 lseek(fd, adrs[i], SEEK_SET);
112
113 len = adrs[i+1] - adrs[i];
114
115 if (!len)
116 break;
117
118 printf("%02d. Length: %d\n", i, len);
119 memset(file, 0, sizeof(file));
120 snprintf(file, sizeof(file)-1, "%s-%02d.raw", argv[2], i);
121
122 fd_out = open(file, O_WRONLY|O_CREAT|O_TRUNC, 0644);
123 if (fd_out == -1) {
124 perror("Can't open out");
125 exit(EXIT_FAILURE);
126 }
127
128 r = read(fd, buf, len);
129 if (r != len) {
130 perror("Can't read content");
131 exit(EXIT_FAILURE);
132 }
133
134 r = write(fd_out, buf, len);
135 if (r != len) {
136 perror("Can't write content");
137 exit(EXIT_FAILURE);
138 }
139
140 close(fd_out);
141
142 }
143
144 close(fd);
145
146 return EXIT_SUCCESS;
147 }
Impressum, Datenschutz