display a warning when the rom image is >512KB. use "len" to set the size/checksum...
[AROS.git] / arch / m68k-amiga / boot / romcheck.c
blob51be18de8b701bb381d4d885b6564ec6a2df0c59
1 /*
2 Copyright © 1995-2010, 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 old 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;
60 void *rom;
61 uint8_t *p;
62 uint32_t size = 512 * 1024;
63 off_t len;
65 fd = open(argv[1], O_RDWR | O_CREAT, 0666);
66 if (fd < 0) {
67 perror(argv[1]);
68 return EXIT_FAILURE;
71 /* Pad with 0xff */
72 for (len = lseek(fd, 0, SEEK_END); len < size; len++) {
73 unsigned char ff = 0xff;
74 write(fd, &ff, 1);
76 if (len > size)
77 printf("Warning: ROM Size > 512KB\n");
79 rom = mmap(NULL, len, PROT_READ | PROT_WRITE,
80 MAP_SHARED, fd, 0);
81 if (rom == MAP_FAILED) {
82 perror(argv[1]);
83 close(fd);
84 return EXIT_FAILURE;
87 /* add interrupt vector offsets, needed by 68000 and 68010 */
88 p = (uint8_t*)rom + len - 16;
89 for (i = 0; i < 7; i++) {
90 p[i * 2 + 1] = i + 0x18;
91 p[i * 2 + 0] = 0;
94 /* set rom size */
95 p = (uint8_t*)rom + len - 20;
96 p[0] = len >> 24;
97 p[1] = len >> 16;
98 p[2] = len >> 8;
99 p[3] = len >> 0;
101 err = amiga_checksum(rom, len, len - 24, 0);
102 err = amiga_checksum(rom, len, len - 24, 1);
104 munmap(rom, len);
106 close(fd);
108 return EXIT_SUCCESS;