Files
Shawn Quick dfcaae62dd Add qlink, the disk tools, and a bootable ProDOS 8 image.
Move the assembler to src/qasm. qlink links OMF 1.0 and 2.0 from a script. makeBin flattens a load file, qomf dumps OMF, and qpro builds ProDOS volumes. APW and MPW assemble through the ORCA front end. Relocatable modules emit OMF objects. Listings stay off unless -l is set.

make boot assembles the GS/OS 6.0.1 ProDOS 8 kernel and BASIC.SYSTEM into an 800K volume. BASIC.SYSTEM accepts ls and pfx, and its splash reports PRODOS BASIC 2.0, copyright 1983-2026. IIGS.601.SRC is the source and the BASIC.SYSTEM oracle that image is built from.
2026-10-16 14:41:55 -07:00

1 line
3.5 KiB
C

/*
Make Image
This program will create the image file used to boot GS/OS.
The file consists of a header block followed by several "files."
The header block starts with the text 'GSOSBOOT'. 256 bytes
into the header is a list of "file headers" with the following
structure:
word size in bytes
word block number of first block
word size in blocks
long start address
word maximum ROM version to load under
word tells which boot os(es) to load file for
0 = all, 1 = GS/OS only, 2 = ProDOS 8 only
word hardware type
0 = all, 1 = Built-in LocalTalk only, 2 = EtherTalk only
Parameters to the tool consist of name,address,version,os,harware 5-tuples.
Address may be in hex (preceded by a "$"). Missing addresses,
versions, os, or hardware are assumed to be 0.
The first parameter is the name of the output file.
*/
#include <fcntl.h>
#include <stdio.h>
#include <cursorctl.h>
int curblk;
main(argc,argv)
int argc;
char *argv[];
{
int i,version,bytes,blocks,output,firstblk,os,hardware;
long address;
char *p,*name,*h,*format;
char header[512];
void onefile(int fd,char *s,int *byte,int *first,int *block);
char *onehead(char *p,long addr,int byte,int firstblk,int block,int ver,int os,int hardware);
InitCursorCtl(NULL);
if (argc<2) {
fprintf(stderr,"# No output file given\n");
exit(1);
}
output = open(argv[1],O_WRONLY|O_CREAT|O_TRUNC);
if (output == -1) {
fprintf(stderr,"# Could not open output file: %s\n",argv[1]);
exit(1);
}
write(output,header,512);
curblk = 1;
h = header+256;
for (i=0; i<512; i++)
header[i]='\0';
strcpy(header,"GSOSBOOT");
for (i=2; i<argc; i++) {
p = name = argv[i];
while (*p && *p!=',')
p++;
if (*p == ',')
*(p++) = '\0';
if (*p == '$') {
p++;
format = "%x";
} else
format = "%d";
if (sscanf(p,format,&address) != 1)
address = 0;
while (*p && *p!=',')
p++;
if (*p == ',')
p++;
if (sscanf(p,"%d",&version) != 1)
version = 0;
while (*p && *p!=',')
p++;
if (*p == ',')
p++;
if (sscanf(p,"%d",&os) != 1)
os = 0;
while (*p && *p!=',')
p++;
if (*p == ',')
p++;
if (sscanf(p,"%d",&hardware) != 1)
hardware = 0;
/*
At this point the name, address, and version variables are all set for
the next file to put in the image. I could pass most of the work off
to a function that did the compression as necessary.
*/
onefile(output,name,&bytes,&firstblk,&blocks);
h=onehead(h,address,bytes,firstblk,blocks,version,os,hardware);
}
h=onehead(h,0,0,curblk,0,0,0,0);
lseek(output,0L,0);
write(output,header,512);
close(output);
}
void onefile(fd,s,byte,first,block)
int fd;
char *s;
int *byte,*first,*block;
{
int input,i;
char blockbuf[512];
input = open(s,O_RDONLY);
if (input == -1) {
fprintf(stderr,"# Could not open input file: %s\n",s);
exit(1);
}
*block = 0;
*byte = 0;
*first = curblk;
i = read(input,blockbuf,512);
while (i>0) {
*byte += i;
(*block)++;
write(fd,blockbuf,512);
curblk++;
SpinCursor(32);
i = read(input,blockbuf,512);
}
close(input);
}
char *onehead(p,addr,byte,firstblk,block,ver,os,hardware)
char *p;
long addr;
int byte,block,ver,os,hardware;
{
*(p++) = byte & 0xFF;
*(p++) = byte >> 8;
*(p++) = firstblk & 0xFF;
*(p++) = firstblk >> 8;
*(p++) = block & 0xFF;
*(p++) = block >> 8;
addr &= 0xFFFFFF;
*(p++) = addr & 0xFF;
addr >>= 8;
*(p++) = addr & 0xFF;
*(p++) = addr >> 8;
*(p++) = 0;
*(p++) = ver & 0xFF;
*(p++) = ver >> 8;
*(p++) = os & 0xFF;
*(p++) = os >> 8;
*(p++) = hardware & 0xFF;
*(p++) = hardware >> 8;
return(p);
}