$TITLE('==> M R K O B J <== MRKOBJ') MRKOBJ: DO; /************************************************************************/ /* */ /* 'Copyright 1981,1983 Intel Corporation'. All rights reserved. */ /* No part of this program or publication may be reproduced, */ /* transmitted, transcribed, stored in a retrievel system, or */ /* translated into any language or computer language, in any */ /* form or by any means, electronic, mechanical, magnetic, */ /* optical, chemical, manual or otherwise, without the prior */ /* written permission of Intel Corporation, 3065 Bowers */ /* Avenue, Santa Clara, California, 95051, Attn: Software */ /* License Administration. */ /* */ /************************************************************************/ $IF XVERSION DECLARE PROPRIETARY(*) BYTE DATA ('INTEL PROPRIETARY SOFTWARE'); DECLARE PROGRAM$VERSION$NUMBER$STRING (*) BYTE DATA ('program_version_number=X103',0); $ELSE DECLARE COPYRIGHT (*) BYTE DATA ('COPYRIGHT 1981,1983 INTEL '); DECLARE PROGRAM$VERSION$NUMBER$STRING (*) BYTE DATA ('program_version_number=V1.1',0); $ENDIF /******* EXTERNALS *******/ /* SYS.LIB */ DECLARE actual ADDRESS EXTERNAL; ex: PROCEDURE EXTERNAL; END; readu: PROCEDURE (dst,count) EXTERNAL; DECLARE (dst,count) ADDRESS; END; sbyteu: PROCEDURE (distance) EXTERNAL; DECLARE distance ADDRESS; END; writeu: PROCEDURE (src,count) EXTERNAL; DECLARE (src,count) ADDRESS; END; /* UTIL.LIB */ DECLARE scan$p ADDRESS EXTERNAL; DECLARE obuf$p ADDRESS EXTERNAL; error$message: PROCEDURE (ptr) EXTERNAL; DECLARE ptr ADDRESS; END; file$ch: PROCEDURE BYTE EXTERNAL; END; out$scan$byte: PROCEDURE EXTERNAL; END; /* MINVOK.P80 */ process$invocation$line: PROCEDURE EXTERNAL; END; DECLARE source$file$name$ptr ADDRESS EXTERNAL; DECLARE object$file$name$ptr ADDRESS EXTERNAL; DECLARE nopurge BYTE EXTERNAL; /* MFILER.P80 */ file$error$msg: PROCEDURE (msg$ptr, file$name$ptr) EXTERNAL; DECLARE (msg$ptr, file$name$ptr) ADDRESS; END; movem: PROCEDURE (count) EXTERNAL; DECLARE count ADDRESS; END; /******* END OF EXTERNALS *******/ DECLARE scan$byte BASED scan$p BYTE, scan$word BASED scan$p ADDRESS, obuf$byte BASED obuf$p BYTE; DECLARE end$of$filled$buffer ADDRESS, mod$end$rec$type BYTE, mod$end$record$ptr ADDRESS, record$length ADDRESS, bytes$to$rewrite ADDRESS, crec$begin ADDRESS, crec$length$ptr ADDRESS, crec$length BASED crec$length$ptr ADDRESS, check$sum BYTE INITIAL (0), first$buffer$byte BYTE AT (.memory) INITIAL (0); DECLARE segid$8080$record STRUCTURE ( type BYTE, r$length ADDRESS, segid BYTE, offset ADDRESS, line$no ADDRESS, checksum BYTE ) INITIAL (008H,6,0,0,0,0F2H); DECLARE crec$8080 (31) BYTE INITIAL (10H,0,0,0,'SOURCE_FILE= ',0), crec$8086 (32) BYTE INITIAL (88H,0,0,0FFH,0,'SOURCE_FILE= ',0); DECLARE crec$8080$name$length BYTE AT (.crec$8080(3)); DECLARE library$msg (*) BYTE INITIAL ('IS AN 808X LIBRARY',0), library$msg$type BYTE AT (.library$msg(9)); DECLARE not$obj$msg (*) BYTE INITIAL ('IS NOT AN OBJECT MODULE',0); its$a$library: PROCEDURE (type); DECLARE type BYTE; library$msg$type = type; CALL file$error$msg (.library$msg, object$file$name$ptr); CALL ex; END its$a$library; its$not$an$object$module: PROCEDURE; CALL file$error$msg (.not$obj$msg, object$file$name$ptr); CALL ex; END its$not$an$object$module; scan$whole$file: PROCEDURE; DECLARE new$scan$p ADDRESS; /* the whole file is in the buffer, just scan until modend record found */ DO WHILE scan$byte <> mod$end$rec$type; scan$p = scan$p + 1; record$length = scan$word; /* check for possibility of missing modend record! */ new$scan$p = scan$p + record$length + 2; IF (new$scan$p >= end$of$filled$buffer) /* but still less than 64K */ OR (new$scan$p < scan$p) THEN /* wrapped around 64K */ CALL error$message (.('MISSING MODEND RECORD?!',0)); scan$p = new$scan$p; END; END scan$whole$file; scan$and$buffer$file: PROCEDURE; DECLARE three$bytes$left$ptr ADDRESS, bytes$to$move ADDRESS, bytes$left$in$buffer ADDRESS, too$much$file ADDRESS; /* can't fit whole object file into buffer, must handle scanning to end of buffer, etc. */ three$bytes$left$ptr = end$of$filled$buffer - 3; DO WHILE scan$byte <> mod$end$rec$type; IF scan$p >= three$bytes$left$ptr THEN /* length field may not be here */ DO; IF scan$p >= end$of$filled$buffer THEN /* went too far, abort */ DO; CALL error$message (.('UNABLE TO SCAN OBJECT FILE',0)); CALL ex; END; /* OK here, move unscanned bytes to beginning and read again */ bytes$to$move = end$of$filled$buffer - scan$p; CALL movem (bytes$to$move); CALL readu (.memory + bytes$to$move, 7000H); scan$p = .memory; end$of$filled$buffer = .memory + bytes$to$move + actual; IF actual < 7000H THEN /* all the rest of the file is in the buffer */ DO; CALL scan$whole$file; /* do it the easy way */ RETURN; END; three$bytes$left$ptr = end$of$filled$buffer - 3; END; /* now OK to look at the record length */ scan$p = scan$p + 1; record$length = scan$word; scan$p = scan$p + 2; /* bump past record field */ /* record$length bytes may not have been read yet */ bytes$left$in$buffer = end$of$filled$buffer - scan$p; DO WHILE bytes$left$in$buffer <= record$length; CALL readu (.memory, 7000H); scan$p = .memory; end$of$filled$buffer = .memory + actual; record$length = record$length - bytes$left$in$buffer; IF actual < 7000H THEN DO; scan$p = scan$p + record$length; CALL scan$whole$file; RETURN; END; bytes$left$in$buffer = actual; three$bytes$left$ptr = end$of$filled$buffer - 3; END; /* whatever's left of this record is in the buffer now */ scan$p = scan$p + record$length; /* now pointing at next record type byte */ END; /* WHILE scan$byte <> mod$end$rec$type */ /* now we've found the modend record, but there's still more to read */ bytes$to$move = end$of$filled$buffer - scan$p; CALL movem (bytes$to$move); /* this is the last read, if it doesn't all fit, give up */ too$much$file = 7000H - bytes$to$move + 1; CALL readu (.memory + bytes$to$move, too$much$file); IF actual = too$much$file THEN CALL error$message (.('CANNOT MARK OBJECT MODULE SEQUENCE',0)); scan$p = .memory; end$of$filled$buffer = .memory + bytes$to$move + actual; END scan$and$buffer$file; /*************** MAINLINE CODE ***************/ CALL process$invocation$line; /* now object file has been opened for update */ /* read the first byte to check for valid file */ CALL readu (.memory, 1); IF first$buffer$byte = 002H THEN /* 8080 module */ mod$end$rec$type = 004H; ELSE IF first$buffer$byte = 080H THEN /* 8086 translator module */ mod$end$rec$type = 08AH; ELSE IF first$buffer$byte = 082H THEN /* 8086 linker module */ mod$end$rec$type = 08AH; ELSE IF first$buffer$byte = 06EH THEN /* 8086 locater module */ mod$end$rec$type = 08AH; ELSE IF first$buffer$byte = 02CH THEN /* 8080 library */ CALL its$a$library('0'); ELSE IF first$buffer$byte = 0A4H THEN /* 8086 library */ CALL its$a$library('6'); ELSE CALL its$not$an$object$module; /* OK to mark this object file, read it in */ CALL readu (.memory + 1, 7000H); /* 28K read */ scan$p = .memory; end$of$filled$buffer = .memory + actual + 1; /* points after last byte */ IF actual < 7000H THEN /* the whole file fit into the buffer */ CALL scan$whole$file; ELSE /* there's still more to read */ CALL scan$and$buffer$file; /* now pointing at modend record */ bytes$to$rewrite = end$of$filled$buffer - scan$p; mod$end$record$ptr = scan$p; /* seek backwards */ CALL sbyteu (-bytes$to$rewrite); /* build comment record */ IF nopurge THEN /* make 8086 comment record unpurgeable */ crec$8086(4)=080H; IF mod$end$rec$type = 004H THEN /* 8080 */ DO; crec$length$ptr = (crec$begin := .crec$8080) + 1; obuf$p = .crec$8080(16); /* source file name area */ END; ELSE /* 8086 */ DO; crec$length$ptr = (crec$begin := .crec$8086) + 1; obuf$p = .crec$8086(17); END; scan$p = source$file$name$ptr; DO WHILE file$ch; CALL out$scan$byte; /* put source file name into comment record */ END; crec$length = obuf$p - crec$length$ptr - 1; /* set record length */ IF mod$end$rec$type = 004H THEN /* set name length byte in 8080 record */ crec$8080$name$length = crec$length - 2; /* now calculate checksum */ scan$p = crec$begin; DO WHILE scan$p < obuf$p; check$sum = check$sum + scan$byte; scan$p = scan$p + 1; END; obuf$byte = 256 - check$sum; /* write the comment record and the rest of the object file */ CALL writeu (crec$begin, crec$length + 3); IF mod$end$rec$type = 004H THEN /* write dummy segid record for 8080 */ CALL writeu (.segid$8080$record, 9); CALL writeu (mod$end$record$ptr, bytes$to$rewrite); CALL ex; END;