DataMuseum.dk

Presents historical artifacts from the history of:

Commodore CBM-900

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Commodore CBM-900

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦d1a5022e0⟧ TextFile

    Length: 3468 (0xd8c)
    Types: TextFile
    Notes: UNIX file
    Names: »prom.c«

Derivation

└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
    └─⟦926b8033d⟧ UNIX V7 Filesystem
        └─ ⟦this⟧ »prom.c« 

TextFile

/*
 * 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);
}