typo.
[AROS.git] / arch / m68k-amiga / boot / romcheck.c
blob24be467f9cebf17b713c45f7abc78e8aabe98410
1 /*
2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: m68k-amiga ROM checksum generator
6 Lang: english
7 */
9 #include <stdint.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13 #include <fcntl.h>
14 #include <errno.h>
16 #include <sys/mman.h>
18 static int amiga_checksum(uint8_t *mem, int size, uint32_t chkoff, int update)
20 uint32_t oldcksum = 0, cksum = 0, prevck = 0;
21 int i;
23 for (i = 0; i < size; i+=4) {
24 uint32_t val = (mem[i+0] << 24) +
25 (mem[i+1] << 16) +
26 (mem[i+2] << 8) +
27 (mem[i+3] << 0);
29 /* Clear existing checksum */
30 if (update && i == chkoff) {
31 oldcksum = val;
32 val = 0;
35 cksum += val;
36 if (cksum < prevck)
37 cksum++;
38 prevck = cksum;
41 cksum = ~cksum;
43 if (update && cksum != oldcksum) {
44 printf("Updating checksum from 0x%08x to 0x%08x\n", oldcksum, cksum);
46 mem[chkoff + 0] = (cksum >> 24) & 0xff;
47 mem[chkoff + 1] = (cksum >> 16) & 0xff;
48 mem[chkoff + 2] = (cksum >> 8) & 0xff;
49 mem[chkoff + 3] = (cksum >> 0) & 0xff;
51 return 1;
54 return 0;
57 int main(int argc, char **argv)
59 int err, fd, i, retval = EXIT_FAILURE;
60 void *rom;
61 uint8_t *p;
62 uint32_t size = 0;
63 off_t origlen, len;
65 fd = open(argv[1], O_RDWR | O_CREAT, 0666);
66 if (fd < 0) {
67 perror(argv[1]);
68 return retval;
71 origlen = lseek(fd, 0, SEEK_END);
73 /* Make sure we have a valid ROM ID */
74 rom = mmap(NULL, origlen, PROT_READ | PROT_WRITE,
75 MAP_SHARED, fd, 0);
76 if (rom == MAP_FAILED)
78 perror(argv[1]);
79 close(fd);
80 return retval;
82 p = (uint8_t*)rom;
83 if (p[0] == 0x11 && (p[1] >= 0x11 || p[1] <= 0x14))
85 if (p[1] == 0x11)
87 size = 256 * 1024;
88 if (origlen > size)
90 printf("Warning: ROM ID is for a 256K ROM, but the image is larger -> promoting to 512KB ROM.\n");
91 p[1] = 0x14;
94 if (p[1] == 0x14)
95 size = 512 * 1024;
97 if (size == 0)
98 printf("Error: Invalid ROM ID (%02x%02x).\n", p[0], p[1]);
99 munmap(rom, origlen);
100 if (size == 0)
102 close(fd);
103 return retval;
106 len = origlen;
108 if (len > size)
110 printf("Error: ROM Size > %uKB", size/1024);
111 if ((len - size) >= 1024)
112 printf(" (+%luKB).\n", (len - size)/1024);
113 else
114 printf(" (+%luB).\n", (len - size));
115 return retval;
118 /* Pad with 0xff */
119 for (; len < size; len++) {
120 unsigned char padb;
122 #if (0)
123 /* Earlier kickstarts used 0x00 as the pad byte.. */
124 padb = 0x0;
125 #else
126 padb = 0xff;
127 #endif
128 write(fd, &padb, 1);
131 rom = mmap(NULL, len, PROT_READ | PROT_WRITE,
132 MAP_SHARED, fd, 0);
134 if (rom != MAP_FAILED)
136 p = (uint8_t*)rom + len - 20;
137 if ((origlen <= (size - 24)) ||
138 ((p[0] == (len >> 24) & 0xFF) &&
139 (p[1] == (len >> 16) & 0xFF) &&
140 (p[2] == (len >> 8) & 0xFF) &&
141 (p[3] == (len >> 0) & 0xFF)))
143 /* Make sure the rom size is set*/
144 p[0] = len >> 24;
145 p[1] = len >> 16;
146 p[2] = len >> 8;
147 p[3] = len >> 0;
149 /* Add the interrupt vector offsets,
150 * needed by 68000 and 68010 */
151 p = (uint8_t*)rom + len - 16;
152 for (i = 0; i < 8; i++) {
153 p[i * 2 + 1] = i + 0x18;
154 p[i * 2 + 0] = 0;
157 err = amiga_checksum(rom, len, len - 24, 0);
158 err = amiga_checksum(rom, len, len - 24, 1);
160 retval = EXIT_SUCCESS;
162 else
164 printf("Error: Rom Data Size exceeds available space (%lu bytes remaining).\n", size - origlen);
167 munmap(rom, len);
169 else
170 perror(argv[1]);
172 close(fd);
174 return retval;