home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GEMini Atari
/
GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso
/
zip
/
language
/
f68k.zoo
/
os9
/
os9lader.c
< prev
Wrap
C/C++ Source or Header
|
1992-03-25
|
12KB
|
462 lines
/********************************************************************
Loader program for a F68K image file
This loader tries to open a file F68K.CFG which
holds information about the F68K system to be loaded.
It is possible to use another CFG-File by invoking its name
in command line: os9lader [ xxx.CFG ].
Works only correct if FORTH-Kernel lays address of FORTH-Paras
down on stack before calling I/O (see CHANGES.TXT 14.11.91) 26FEB92 TB
********************************************************************/
#define DEBUG
#include <stdio.h>
#define CODESIZE 0x20000L
#define DATASIZE 0x20000L
#define TIBSIZE 2048
#define MAX_DEVICES 10
#define BPB 2048 /* Bytes Per Block */
#define FILENAME_MAX 64
#define FALSE (0)
#define TRUE (-1)
long key_quest();
long key();
void emit();
long r_w();
long writesys();
long readsys();
void read_paras();
void read_segments();
void keymode();
void linemode();
char devicename[MAX_DEVICES][FILENAME_MAX];
FILE* device[MAX_DEVICES];
FILE* infile;
long roottable[MAX_DEVICES * 2 + 1];
long codesz = CODESIZE;
long datasz = DATASIZE;
char imagename[FILENAME_MAX] = "F68K.IMG";
char outfilename[FILENAME_MAX] = "F68K.OUT";
char cfgname[FILENAME_MAX] = "F68K.CFG";
char key_buffer;
handle_signal(signum)
int signum;
{
linemode();
exit(0);
}
void main(argc,argv)
int argc;
char *argv[];
{
char *codeseg,*dataseg;
void (*f68k)();
static long _keytable[] = {1, key};
static long _keyqtable[] = {1, key_quest};
static long _emittable[] = {1, emit};
static long _r_wtable[] = {1, r_w};
static long _readsystable[] = {1, readsys};
static long _writesystable[] = {1, writesys};
struct _forthparas
{
long registers[16]; /* to be filled by F68K */
/* void *forthregs[4]; */ /* A3,A5,A6,A7 for F68K */
void *data; /* A3 */
void *code; /* A5 */
void *datastack; /* A6 */
void *retstack; /* A7 */
void *TIBptr;
long codelen;
long datalen;
void *emittable;
void *keytable;
long *keyqtable;
long *r_wtable;
long *readsystable;
long *writesystable;
long *roottable;
} forthparas;
forthparas.emittable = _emittable;
forthparas.keytable = _keytable;
forthparas.keyqtable = _keyqtable;
forthparas.r_wtable = _r_wtable;
forthparas.readsystable = _readsystable;
forthparas.writesystable= _writesystable;
forthparas.roottable = roottable;
if(argc==2) strcpy(cfgname,argv[1]);
read_paras(roottable);
forthparas.codelen = codesz;
forthparas.datalen = datasz;
read_segments(&codeseg,&dataseg);
forthparas.code = codeseg;
forthparas.data = dataseg;
forthparas.datastack = (void*)((long)dataseg+datasz-TIBSIZE);
forthparas.retstack = (void*)((long)dataseg+datasz);
forthparas.TIBptr = (void*)((long)dataseg+datasz-TIBSIZE);
keymode();
intercept(handle_signal);
f68k=(void*)codeseg;
(*f68k)(0,0,&forthparas);
#asm
movea.l 56(a7),a6
#endasm
linemode();
exit(0);
}
/************************************************************************
* *
* the F68K I/O-functions *
* *
************************************************************************/
long key_quest()
{
#asm
movea.l 20(a7),a6
movea.l 56(a6),a6
#endasm
return (_gs_rdy(fileno(stdin)) != -1) ? TRUE : FALSE ;
}
long key()
{
#asm
movea.l 20(a7),a6
movea.l 56(a6),a6
#endasm
read(fileno(stdin),&key_buffer,1);
return (key_buffer);
}
void emit(chars)
char chars;
{
#asm
move.l 20(a7),(a7)
movea.l 24(a7),a6
movea.l 56(a6),a6
#endasm
chars &= 0x7f;
write(1,&chars,1);
}
#include <sgstat.h>
struct sgbuf ttys, ttysnew; /* for terminal mode setting */
static lmode = 0;
#define M_KEY 1
#define M_LINE 2
void initline()
{
if (lmode)
return;
if (_gs_opt(0, &ttys) < 0)
return;
_strass(&ttysnew, &ttys, sizeof(struct sgbuf));
ttysnew.sg_echo = 0; /* set for no echoing */
ttysnew.sg_case = 0; /* allow either case */
ttysnew.sg_delete = 0; /* no crt line erasing */
ttysnew.sg_pause = 0; /* no page mode */
ttysnew.sg_bspch = 0; /* no backspace editing */
ttysnew.sg_dlnch = 0; /* no delete line */
ttysnew.sg_eorch = 20; /* end of record character ^T in case of bomb */
ttysnew.sg_eofch = 0; /* no end of file character */
ttysnew.sg_rlnch = 0; /* no repeat line character */
ttysnew.sg_dulnch = 0; /* no duplicate line character */
ttysnew.sg_psch = 0; /* no pause character */
ttysnew.sg_kbich = 3; /* ^C keyboard interrupt character */
ttysnew.sg_kbach = 0; /* no keyboard abort character */
ttysnew.sg_xon = 0; /* no XON character */
ttysnew.sg_xoff = 0; /* no XOFF character */
ttysnew.sg_tabcr = 0; /* no tab character */
}
void linemode()
{
initline();
if (lmode != M_LINE)
{
_ss_opt(0, &ttys);
lmode = M_LINE;
}
}
void keymode()
{
initline();
if (lmode != M_KEY)
{
_ss_opt(0, &ttysnew);
lmode = M_KEY;
}
}
long r_w(buffer,block,flg)
long buffer,block,flg;
{
int i, dev;
long rootblk=0L, maxblock=0L;
#asm
move.l 20(a7),(a7)
move.l 24(a7),4(a7)
move.l 28(a7),20(a7)
movea.l 32(a7),a6
movea.l 56(a6),a6
#endasm
for(i=0; i<roottable[0]; i++) /* find device */
if( (roottable[2*i+1] >= rootblk) && (block >= roottable[2*i+1]))
{
maxblock += roottable[2*i+2];
rootblk = roottable[2*i+1];
dev = i;
}
if(block >= maxblock) /* block in range? */
{
goto bad;
}
if( fseek(device[dev],(block-rootblk)*BPB,0))
{
goto bad;
}
if(flg!=0L)
{
if( !fwrite(buffer,BPB,1,device[dev]))
{
goto bad;
}
}
else
{
if( !fread(buffer,BPB,1,device[dev]))
{
goto bad;
}
}
return TRUE;
bad:
#ifdef DEBUG
printf("%ld\n*** F68K loader warning: tried to reach physical block: ",block," ***\n");
#endif
return FALSE;
}
long readsys(buffer,count)
unsigned long buffer, count;
{
#asm
move.l 20(a7),(a7)
move.l 24(a7),4(a7)
movea.l 28(a7),a6
movea.l 56(a6),a6
#endasm
if ( fread(buffer,count,1,infile) != 1)
{
return FALSE;
}
return TRUE;
}
long writesys(buffer,count)
unsigned long buffer, count;
{
static FILE *out = NULL;
#asm
move.l 20(a7),(a7)
move.l 24(a7),4(a7)
movea.l 28(a7),a6
movea.l 56(a6),a6
#endasm
if(!out)
if( (out = fopen(outfilename,"w"))== NULL)
{
return FALSE;
}
if ( fwrite(buffer,count,1,out) != 1)
{
return FALSE;
}
fflush(out);
return TRUE;
}
/************************************************************************
* end of I/O functions *
************************************************************************/
void read_paras(roottable)
long *roottable;
{
FILE *paras;
int devices, dev;
long devicesize[MAX_DEVICES];
char infilename[FILENAME_MAX];
int i;
long startblock = 0;
if( (paras=fopen(cfgname,"r"))==NULL)
{
fprintf(stderr,"*** F68K loader warning: configuration file F68K.CFG not found\n");
return;
}
if( !fscanf(paras,"image: %s%*d\n",imagename))
fprintf(stderr,"*** F68K loader warning: no imagefile given in F68K.CFG, suppose F68K.IMG\n");
if( !fscanf(paras,"code: 0x%lx%*d\n",&codesz))
fprintf(stderr,"*** F68K loader warning: no codesize given in F68K.CFG, suppose %ld\n",CODESIZE);
if( !fscanf(paras,"data: 0x%lx%*d\n",&datasz))
fprintf(stderr,"*** F68K loader warning: no datasize given in F68K.CFG, suppose %ld\n",DATASIZE);
if( !fscanf(paras,"input: %s%*d\n", infilename))
{
fprintf(stderr,"*** F68K loader warning: no input file given in F68K.CFG, suppose F68K.IN\n");
strcpy(infilename,"F68K.IN");
}
if( (infile = fopen(infilename,"r"))==NULL)
fprintf(stderr,"*** F68K loader warning: cannot open input file, READSYS not available\n");
if( !fscanf(paras,"output: %s%*d\n", outfilename))
fprintf(stderr,"*** F68K loader warning: no output file given in F68K.CFG, suppose F68K.OUT\n");
if( !fscanf(paras,"devices: %d%*d\n",&devices))
fprintf(stderr,"*** F68K loader warning: no number of devices given in F68K.CFG\n");
if( devices == 0)
fprintf(stderr,"*** F68K loader warning: no block storage device available\n");
if( devices > MAX_DEVICES )
{
fprintf(stderr,"*** F68K loader error: too much devices (max. %d devices available)\n");
exit(0);
}
for(i=0; i<devices; i++)
{
if( fscanf(paras,"d%d: ",&dev) && (dev>=0) && (dev<MAX_DEVICES))
fscanf(paras,"%s%*d\n",devicename[dev]);
else
{
fprintf(stderr,"*** F68K loader error: invalid device specification\n");
exit(0);
}
if( (devicesize[dev]=fsize(devicename[dev])) != -1L)
{
device[dev] = fopen(devicename[dev],"r+");
roottable[2*dev+1] = startblock;
roottable[2*(dev+1)] = devicesize[dev]/BPB;
startblock += devicesize[dev]/BPB;
}
else
{
fprintf(stderr,"*** F68K loader warning: device D%d: cannot be accessed\n",dev);
roottable[2*dev+1] = -1;
roottable[2*(dev+1)] = 0;
}
}
roottable[0] = devices;
}
long fsize(filename)
char *filename;
{
FILE *fnr;
long size;
if((fnr=fopen(filename,"r")) == 0) return(-1L);
size=lseek(fileno(fnr),0,2);
fclose(fnr);
return(size);
}
void read_segments(codeseg,dataseg)
char **codeseg, **dataseg;
{
FILE *image;
struct header
{
short magic;
unsigned long codesize;
unsigned long datasize;
short dont_care[9];
} header;
if( ((*codeseg = malloc(codesz)) == NULL) |
((*dataseg = malloc(datasz)) == NULL))
{
fprintf(stderr,"*** F68K loader error: segments allocation fault\n");
exit(-1);
}
if( (image=fopen(imagename,"r")) == NULL )
{
fprintf(stderr,"*** F68K loader error: image file not found\n");
exit(-1);
}
if( fread(&header,(long)sizeof(header),1,image) != 1)
{
fprintf(stderr,"*** F68K loader error: image file read error (header)\n");
exit(-1);
}
if(header.magic != (256*'J'+'P'))
{
fprintf(stderr,"*** F68K loader error: this is not an F68K image\n");
exit(-1);
}
if( fread(*codeseg,header.codesize,1,image) != 1)
{
fprintf(stderr,"*** F68K loader error: image file read error (code)\n");
exit(-1);
}
if( fread(*dataseg,header.datasize,1,image) != 1)
{
fprintf(stderr,"*** F68K loader error: image file read error (data)\n");
exit(-1);
}
}