/******************************************************************** 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 #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 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= 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=0) && (dev