mirror of
https://github.com/marketideas/qasm.git
synced 2026-10-25 13:02:45 +00:00
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.
1 line
3.5 KiB
C
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);
|
|
}
|