|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 3468 (0xd8c) Types: TextFile Notes: UNIX file Names: »prom.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code └─⟦926b8033d⟧ UNIX Filesystem └─ ⟦this⟧ »prom.c«
/* * Split up a binary file (e.g. Z8002 .boot file) * for the ProLog. Adjust the base addresses * and handle H and L roms. Send the data down the * of the hex records. Send the data down the * serial line, using Intel format #10 (hex * with ACK/NAK. */ #include <stdio.h> #include <sgtty.h> #define NDAT 32 /* Maximum data in a record */ struct rec { int r_size; unsigned r_addr; int r_type; char r_data[NDAT]; } rec; char eflag; char oflag; long addr; /* Start address */ unsigned llimit; unsigned hlimit; int sentdata; struct sgttyb sgttyb; FILE *ifp; long atol(); main(argc, argv) char *argv[]; { register int size; if (argc>1 && *argv[1]=='-') { switch (argv[1][1]) { case 'e': case 'h': eflag++; break; case 'o': case 'l': oflag++; break; default: usage(); } argc--; argv++; } if (argc < 4) usage(); if ((size=promsize(argv[1])) == 0) { fprintf(stderr, "prom: %s: bad prom type\n", argv[1]); exit(1); } llimit = size*atoi(argv[2]); hlimit = llimit+size; addr = llimit; if (eflag | oflag) addr <<= 1; if (argc > 4) addr = atol(argv[4]); if ((ifp=fopen(argv[3], "r")) == NULL) { fprintf(stderr, "prom: %s: cannot open\n", argv[3]); exit(1); } gtty(1, &sgttyb); { sgttyb.sg_ispeed = B2400; sgttyb.sg_ospeed = B2400;} sgttyb.sg_ispeed = B9600; sgttyb.sg_ospeed = B9600; stty(1, &sgttyb); copydata(); printf(":00000001FF\n"); /* Write end-of-file record */ if (sentdata == 0) fprintf(stderr, "Empty!\n"); } copydata() { register unsigned int whlimit; register unsigned int wllimit; register int checksum; register int length; register unsigned int address; register int data; register int i; fseek(ifp, addr, 0); while (getrec()) { if (rec.r_type != 0x00) continue; wllimit = max(llimit, rec.r_addr); whlimit = min(hlimit, rec.r_addr+rec.r_size); if (wllimit >= whlimit) continue; sentdata = 1; printf(":"); length = whlimit-wllimit; checksum = length; printf("%02x", checksum); address = wllimit-llimit; checksum += address; checksum += address>>8; printf("%04x", address); printf("00"); i = wllimit-rec.r_addr; while (length--) { data = rec.r_data[i++]&0xFF; printf("%02x", data); checksum += data; } printf("%02x\n", (-checksum)&0xFF); } } max(a, b) unsigned int a; unsigned int b; { if (a > b) return (a); else return (b); } min(a, b) unsigned int a; unsigned int b; { if (a < b) return (a); else return (b); } /* * Read a binary file. The format is the * Commodore `.boot' format which is just * the code first, and rounding up to next * 512 bytes, then the data. However, this * file is just binary bits really. */ getrec() { register char *cp; register int c; rec.r_addr = addr; rec.r_type = 0; for (cp = &rec.r_data[0]; cp < &rec.r_data[NDAT]; cp++) { if ((c = getb()) == EOF) break; *cp = c; } rec.r_size = cp - rec.r_data; } getb() { register int eb, ob; addr++; eb = getc(ifp); if ((eflag|oflag) == 0) return (eb); ob = getc(ifp); if (eflag) return (eb); else return (ob); } promsize(s) char *s; { if (strcmp(s, "2708") == 0) return (1024); if (strcmp(s, "2716") == 0) return (2048); if (strcmp(s, "2732") == 0) return (4096); if (strcmp(s, "2764") == 0) return (8192); if (strcmp(s, "27128") == 0) return (16384); return (0); } usage() { fprintf(stderr, "Usage: prom [-eohl] type sequence file [addr]\n"); exit(1); }