Initial revision
This commit is contained in:
		
							parent
							
								
									1519576e82
								
							
						
					
					
						commit
						5140441585
					
				
					 5 changed files with 367 additions and 0 deletions
				
			
		
							
								
								
									
										3
									
								
								mach/minixST/.distr
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								mach/minixST/.distr
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | ||||||
|  | Action | ||||||
|  | cv | ||||||
|  | libsys | ||||||
							
								
								
									
										6
									
								
								mach/minixST/Action
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								mach/minixST/Action
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | ||||||
|  | name "Atari ST Minix systemcall library" | ||||||
|  | dir libsys | ||||||
|  | end | ||||||
|  | name "Atari ST Minix conversion program from ack.out --> Minix ST a.out" | ||||||
|  | dir cv | ||||||
|  | end | ||||||
							
								
								
									
										2
									
								
								mach/minixST/cv/.distr
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								mach/minixST/cv/.distr
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | ||||||
|  | Makefile | ||||||
|  | cv.c | ||||||
							
								
								
									
										25
									
								
								mach/minixST/cv/Makefile
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								mach/minixST/cv/Makefile
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,25 @@ | ||||||
|  | EMHOME =	../../.. | ||||||
|  | LIBOBJ =	$(EMHOME)/modules/lib/libobject.a | ||||||
|  | INCLUDE =	$(EMHOME)/h | ||||||
|  | CFLAGS =	-I. -I$(INCLUDE) -O | ||||||
|  | TARGETS =	cv | ||||||
|  | 
 | ||||||
|  | all:		$(TARGETS) | ||||||
|  | 
 | ||||||
|  | install:	all | ||||||
|  | 		../../install cv | ||||||
|  | 
 | ||||||
|  | cmp:		all | ||||||
|  | 		../../compare cv | ||||||
|  | 
 | ||||||
|  | cv:	cv.o | ||||||
|  | 		$(CC) $(LDFLAGS) -o cv cv.o $(LIBOBJ) | ||||||
|  | 
 | ||||||
|  | clean: | ||||||
|  | 		rm -f $(TARGETS) *.o nohup.out Out | ||||||
|  | 
 | ||||||
|  | pr: | ||||||
|  | 		@pr Makefile cv.c | ||||||
|  | 
 | ||||||
|  | opr: | ||||||
|  | 		make pr | opr | ||||||
							
								
								
									
										331
									
								
								mach/minixST/cv/cv.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										331
									
								
								mach/minixST/cv/cv.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,331 @@ | ||||||
|  | /* $Header$ */ | ||||||
|  | /*
 | ||||||
|  |  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||||
|  |  * See the copyright notice in the ACK home directory, in the file "Copyright". | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Convert ACK a.out file to ST-Minix object format. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <out.h> | ||||||
|  | #include <assert.h> | ||||||
|  | 
 | ||||||
|  | struct outhead	outhead; | ||||||
|  | struct outsect	outsect[S_MAX]; | ||||||
|  | 
 | ||||||
|  | #define TEXTSG	0 | ||||||
|  | #define ROMSG	1 | ||||||
|  | #define DATASG	2 | ||||||
|  | #define BSSSG	3 | ||||||
|  | #define LSECT	BSSSG+1 | ||||||
|  | #define NSECT	LSECT+1 | ||||||
|  | 
 | ||||||
|  | char	*output_file; | ||||||
|  | int	outputfile_created; | ||||||
|  | 
 | ||||||
|  | char *program ; | ||||||
|  | 
 | ||||||
|  | /* Output file definitions and such */ | ||||||
|  | 
 | ||||||
|  | int		output; | ||||||
|  | 
 | ||||||
|  | int unresolved; | ||||||
|  | long	textsize ;  | ||||||
|  | long	datasize ; | ||||||
|  | long	bsssize; | ||||||
|  | 
 | ||||||
|  | char *chmemstr; | ||||||
|  | 
 | ||||||
|  | minixhead() | ||||||
|  | { | ||||||
|  | 	long		mh[8]; | ||||||
|  | 	long		stack; | ||||||
|  | 	long		chmem(); | ||||||
|  | 	int		i; | ||||||
|  | 
 | ||||||
|  | 	mh[0] = 0x04100301L; | ||||||
|  | 	mh[1] = 0x00000020L; | ||||||
|  | 	mh[2] = textsize; | ||||||
|  | 	mh[3] = datasize; | ||||||
|  | 	mh[4] = bsssize; | ||||||
|  | 	mh[5] = 0; | ||||||
|  | 	stack = 0x00010000L - (mh[3] + mh[4]); | ||||||
|  | 	if ((mh[0] & 0x00200000L) == 0)		/* not SEPARATE */ | ||||||
|  | 		stack -= mh[2]; | ||||||
|  | 	while (stack < 0) | ||||||
|  | 		stack += 0x00010000L; | ||||||
|  | 	if (chmemstr) | ||||||
|  | 		stack = chmem(chmemstr, stack); | ||||||
|  | 	printf("%D bytes assigned to stack+malloc area\n", stack); | ||||||
|  | 	mh[6] = stack + (mh[3] + mh[4]); | ||||||
|  | 	if ((mh[0] & 0x00200000L) == 0)		/* not SEPARATE */ | ||||||
|  | 		mh[6] += mh[2]; | ||||||
|  | 	mh[7] = 0; | ||||||
|  | 	for (i = 0; i < 8; i++) { | ||||||
|  | 		cvlong(&mh[i]); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (write(output, (char *) mh, sizeof(mh)) != sizeof(mh)) | ||||||
|  | 		fatal("write error\n"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | long align(a,b) | ||||||
|  | 	long a,b; | ||||||
|  | { | ||||||
|  | 	if (b == 0) return a; | ||||||
|  | 	a += b - 1; | ||||||
|  | 	return a - a % b; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | follows(pa, pb) | ||||||
|  | 	register struct outsect *pa, *pb; | ||||||
|  | { | ||||||
|  | 	/* return 1 if pa follows pb */ | ||||||
|  | 
 | ||||||
|  | 	return pa->os_base == align(pb->os_base+pb->os_size, pa->os_lign); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | main(argc, argv) | ||||||
|  | 	int	argc; | ||||||
|  | 	char	*argv[]; | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | 	program= argv[0] ; | ||||||
|  | 	if (argc > 1) { | ||||||
|  | 		switch (argv[1][0]) {  | ||||||
|  | 		case '-': | ||||||
|  | 		case '+': | ||||||
|  | 		case '=': | ||||||
|  | 			chmemstr = argv[1]; | ||||||
|  | 			argc--; | ||||||
|  | 			argv++; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	switch (argc) { | ||||||
|  | 	case 3:	if ((output = creat(argv[2], 0644)) < 0) | ||||||
|  | 			fatal("Can't write %s.\n", argv[2]); | ||||||
|  | 		output_file = argv[2]; | ||||||
|  | 		outputfile_created = 1; | ||||||
|  | 		if (! rd_open(argv[1])) | ||||||
|  | 			fatal("Can't read %s.\n", argv[1]); | ||||||
|  | 		break; | ||||||
|  | 	default:fatal("Usage: %s [+-= amount] <ACK object> <ST-MINIX object>.\n", argv[0]); | ||||||
|  | 	} | ||||||
|  | 	rd_ohead(&outhead); | ||||||
|  | 	if (BADMAGIC(outhead)) | ||||||
|  | 		fatal("Not an ack object file.\n"); | ||||||
|  | 	if (outhead.oh_flags & HF_LINK) { | ||||||
|  | 		unresolved++; | ||||||
|  | 		fatal("Contains unresolved references.\n"); | ||||||
|  | 	} | ||||||
|  | 	if ( outhead.oh_nsect!=LSECT && outhead.oh_nsect!=NSECT ) | ||||||
|  | 		fatal("Input file must have %d sections, not %ld\n", | ||||||
|  | 			NSECT,outhead.oh_nsect) ; | ||||||
|  | 	rd_sect(outsect, outhead.oh_nsect); | ||||||
|  | 	/* A few checks */ | ||||||
|  | 	if ( outsect[BSSSG].os_flen != 0 ) | ||||||
|  | 		fatal("bss space contains initialized data\n") ; | ||||||
|  | 	if (! follows(&outsect[BSSSG], &outsect[DATASG])) | ||||||
|  | 		fatal("bss segment must follow data segment\n") ; | ||||||
|  | 	textsize= (outsect[DATASG].os_base - outsect[TEXTSG].os_base); | ||||||
|  | 	if (! follows(&outsect[ROMSG],&outsect[TEXTSG])) | ||||||
|  | 		fatal("rom segment must follow text\n") ; | ||||||
|  | 	if (! follows(&outsect[DATASG],&outsect[ROMSG])) | ||||||
|  | 		fatal("data segment must follow rom\n") ; | ||||||
|  | 	outsect[TEXTSG].os_size = outsect[ROMSG].os_base - outsect[TEXTSG].os_base; | ||||||
|  | 	outsect[ROMSG].os_size = outsect[DATASG].os_base - outsect[ROMSG].os_base; | ||||||
|  | 	outsect[DATASG].os_size = outsect[BSSSG].os_base - outsect[DATASG].os_base; | ||||||
|  | 	datasize= outsect[DATASG].os_size ; | ||||||
|  | 	bsssize = outsect[BSSSG].os_size; | ||||||
|  | 	if ( outhead.oh_nsect==NSECT ) { | ||||||
|  | 		if (! follows(&outsect[LSECT],&outsect[BSSSG])) | ||||||
|  | 			fatal("end segment must follow bss\n") ; | ||||||
|  | 		if ( outsect[LSECT].os_size != 0 ) | ||||||
|  | 			fatal("end segment must be empty\n") ; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	minixhead(); | ||||||
|  | 	emits(&outsect[TEXTSG]) ; | ||||||
|  | 	emits(&outsect[ROMSG]) ; | ||||||
|  | 	emits(&outsect[DATASG]) ; | ||||||
|  | 	emit_relo(); | ||||||
|  | 	if ( outputfile_created) chmod(argv[2],0755); | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Transfer the emitted byted from one file to another. | ||||||
|  |  */ | ||||||
|  | emits(section) struct outsect *section ; { | ||||||
|  | 	char		*p; | ||||||
|  | 	char		*calloc(), *malloc(); | ||||||
|  | 	long sz = section->os_flen; | ||||||
|  | 
 | ||||||
|  | 	rd_outsect(section - outsect); | ||||||
|  | 	while (sz) { | ||||||
|  | 		unsigned int i = (sz >= 0x4000 ? 0x4000 : sz); | ||||||
|  | 		if (!(p = malloc(0x4000))) { | ||||||
|  | 			fatal("No memory.\n"); | ||||||
|  | 		} | ||||||
|  | 		rd_emit(p, (long) i); | ||||||
|  | 		if (write(output, p, (int)i) < i) { | ||||||
|  | 			fatal("write error.\n"); | ||||||
|  | 		} | ||||||
|  | 		free(p); | ||||||
|  | 		sz -= i; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	sz = section->os_size - section->os_flen; | ||||||
|  | 	if (sz) { | ||||||
|  | 		if (!(p = calloc(0x4000, 1))) { | ||||||
|  | 			fatal("No memory.\n"); | ||||||
|  | 		} | ||||||
|  | 		while (sz) { | ||||||
|  | 			unsigned int i = (sz >= 0x4000 ? 0x4000 : sz); | ||||||
|  | 			if (write(output, p, (int)i) < i) { | ||||||
|  | 				fatal("write error.\n"); | ||||||
|  | 			} | ||||||
|  | 			sz -= i; | ||||||
|  | 		} | ||||||
|  | 		free(p); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | compare(a,b) | ||||||
|  | 	register struct outrelo *a, *b; | ||||||
|  | { | ||||||
|  | 	if (a->or_sect < b->or_sect) return -1; | ||||||
|  | 	if (a->or_sect > b->or_sect) return 1; | ||||||
|  | 	if (a->or_addr < b->or_addr) return -1; | ||||||
|  | 	if (a->or_addr > b->or_addr) return 1; | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | emit_relo() | ||||||
|  | { | ||||||
|  | 	struct outrelo *ACKrelo; | ||||||
|  | 	register struct outrelo *ap; | ||||||
|  | 	unsigned int cnt = outhead.oh_nrelo; | ||||||
|  | 	long last, curr, base; | ||||||
|  | 	int sect; | ||||||
|  | 	char *bp; | ||||||
|  | 	register char *b; | ||||||
|  | 
 | ||||||
|  | 	ACKrelo = ap = (struct outrelo *) calloc(cnt, sizeof(struct outrelo)); | ||||||
|  | 	bp = b = malloc(4 + cnt); | ||||||
|  | 	if (!ap || !bp) { | ||||||
|  | 		fatal("No memory.\n"); | ||||||
|  | 	} | ||||||
|  | 	rd_relo(ap, cnt); | ||||||
|  | 	qsort((char *) ap, (int) cnt, sizeof(struct outrelo), compare); | ||||||
|  | 	/*
 | ||||||
|  |          * read relocation, modify to GEMDOS format, and write. | ||||||
|  |          * Only longs can be relocated. | ||||||
|  |          * | ||||||
|  |          * The GEMDOS format starts with a long L: the offset to the | ||||||
|  |          * beginning of text for the first long to be relocated. | ||||||
|  |          * If L==0 then no relocations have to be made. | ||||||
|  |          * | ||||||
|  |          * The long is followed by zero or more bytes. Each byte B is | ||||||
|  |          * processed separately, in one of the following ways: | ||||||
|  |          * | ||||||
|  |          * B==0: | ||||||
|  |          *      end of relocation | ||||||
|  |          * B==1: | ||||||
|  |          *      no relocation, but add 254 to the current offset | ||||||
|  |          * B==0bWWWWWWW0: | ||||||
|  |          *      B is added to the current offset and the long addressed | ||||||
|  |          *      is relocated. Note that 00000010 means 1 word distance. | ||||||
|  |          * B==0bXXXXXXX1: | ||||||
|  |          *      illegal | ||||||
|  |          */ | ||||||
|  | 
 | ||||||
|  | 	last = 0; | ||||||
|  | 	curr = 0; | ||||||
|  | 	for (sect = S_MIN; sect <= S_MIN+2; sect++) { | ||||||
|  | 		base = outsect[sect-S_MIN].os_base; | ||||||
|  | 		for (;cnt > 0 && ap->or_sect == sect; ap++, cnt--) { | ||||||
|  | 			if (ap->or_type & RELPC || | ||||||
|  | 			    ap->or_nami == outhead.oh_nname) { | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 			assert(ap->or_type & RELO4); | ||||||
|  | 			curr = base + ap->or_addr; | ||||||
|  | 			if (last == 0) { | ||||||
|  | 				last = curr; | ||||||
|  | 				cvlong(&curr); | ||||||
|  | 				*((long *) b) = curr; | ||||||
|  | 				b += 4; | ||||||
|  | 			} | ||||||
|  | 			else { | ||||||
|  | 				while (curr - last > 255) { | ||||||
|  | 					*b++ = 1; | ||||||
|  | 					last += 254; | ||||||
|  | 				} | ||||||
|  | 				*b++ = curr - last; | ||||||
|  | 				last = curr; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		assert(cnt == 0 || ap->or_sect > sect); | ||||||
|  | 	} | ||||||
|  | 	assert(cnt == 0); | ||||||
|  | 	if (cnt = (b - bp)) { | ||||||
|  | 		*b++ = '\0'; | ||||||
|  | 		write(output, bp, (int) cnt+1); | ||||||
|  | 	} | ||||||
|  | 	else write(output, "\0\0\0", 4); | ||||||
|  | 	free((char *) ACKrelo); | ||||||
|  | 	free(bp); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | long | ||||||
|  | chmem(str, old) | ||||||
|  | char *str; | ||||||
|  | long old; | ||||||
|  | { | ||||||
|  |         register long num, new; | ||||||
|  |         long atol(); | ||||||
|  | 
 | ||||||
|  |         num = atol(str+1); | ||||||
|  |         if (num == 0) | ||||||
|  |                 fatal("bad chmem amount %s\n", str+1); | ||||||
|  |         switch (str[0]) { | ||||||
|  |         case '-': | ||||||
|  |                 new = old - num; break; | ||||||
|  |         case '+': | ||||||
|  |                 new = old + num; break; | ||||||
|  |         case '=': | ||||||
|  |                 new = num; break; | ||||||
|  |         } | ||||||
|  |         return(new); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | cvlong(l) | ||||||
|  | 	long *l; | ||||||
|  | { | ||||||
|  | 	long x = *l; | ||||||
|  | 	char *p = (char *) l; | ||||||
|  | 
 | ||||||
|  | 	*p++ = x >> 24; | ||||||
|  | 	*p++ = x >> 16; | ||||||
|  | 	*p++ = x >> 8; | ||||||
|  | 	*p = x; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* VARARGS1 */ | ||||||
|  | fatal(s, a1, a2) | ||||||
|  | 	char	*s; | ||||||
|  | { | ||||||
|  | 	fprintf(stderr,"%s: ",program) ; | ||||||
|  | 	fprintf(stderr, s, a1, a2); | ||||||
|  | 	if (outputfile_created) | ||||||
|  | 		unlink(output_file); | ||||||
|  | 	exit(-1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | rd_fatal() { fatal("read error.\n"); } | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue