/******************************************************************** 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. ********************************************************************/ #define DEBUG #include #include #include #include #define CODESIZE 0x20000L #define DATASIZE 0x20000L #define TIBSIZE 2048 #define MAX_DEVICES 10 #define BPB 2048 /* Bytes Per Block */ #define FALSE (0) #define TRUE (-1) #define CONSOLE 2 #define fsize(x) Fseek(0L,fileno(x),2) long cdecl key_quest(); long cdecl key(); void cdecl emit(); long cdecl r_w(); long cdecl writesys(); long cdecl readsys(); void read_paras(long*); void read_segments(void**,void**); 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"; void main(int argc, const char *argv[]) { void *codeseg,*dataseg; long keytable[] = {1, (long)key}; long keyqtable[] = {1, (long)key_quest}; long emittable[] = {1, (long)emit}; long r_wtable[] = {1, (long)r_w}; long readsystable[] = {1, (long)readsys}; long writesystable[] = {1, (long)writesys}; struct forthparas { long registers[16]; /* to be filled by F68K */ void *data; /* A3 */ void *code; /* A5 */ void *datastack; /* A6 */ void *retstack; /* A7 */ void *TIBptr; long codelen; long datalen; void *emittable; void *keytable; void *keyqtable; void *r_wtable; void *readsystable; void *writesystable; void *roottable; } forthparas; typedef void cdecl FUNC(struct 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); Super(0); (*(FUNC*)codeseg)(&forthparas); } /************************************************************************ * * * the F68K I/O-functions * * * ************************************************************************/ long cdecl key_quest() { return (long)Bconstat(CONSOLE); } long cdecl key() { return (long)Bconin(CONSOLE); } void cdecl emit(ch) long ch; { Bconout(CONSOLE,(int)ch); } long cdecl r_w(buffer,block,flag) void *buffer; long block,flag; { int i, dev; long rootblk=0L, maxblock=0L; char buf[10]; /* buffer for number conversion */ int handle; #ifdef DEBUG char message[100]; /* this is for the errormessage */ #endif 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(Mediach(0) != 0) /* Disk A only!! */ { rewind(device[dev]); fclose(device[dev]); device[dev]=fopen(devicename[dev],"rb+"); } handle = fileno(device[dev]); /* never trust standard functions! */ if( Fseek((block-rootblk)*BPB,handle,0)!=(block-rootblk)*BPB) { goto bad; } if(flag!=0L) { if( Fwrite(handle,BPB,buffer)!=BPB) { goto bad; } } else { if( Fread(handle,BPB,buffer)!=BPB) { goto bad; } } return TRUE; bad: #ifdef DEBUG message[0]=0; strcpy(message,"\n*** F68K loader warning:\ tried to reach physical block: "); printf(strcat(message,strcat(ultoa(block,buf,10)," ***\n"))); #endif return FALSE; } long cdecl readsys(buffer,count) unsigned long *buffer, count; { if ( fread(buffer,count,1,infile) != 1) { return FALSE; } return TRUE; } long cdecl writesys(buffer,count) unsigned long *buffer, count; { static FILE *out = NULL; if(!out) if( (out = fopen(outfilename,"wb"))== NULL) { return FALSE; } if ( fwrite(buffer,count,1,out) != 1) { return FALSE; } 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,"rb"))==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