.H Copyright (c) 1988-2002, Gary D. Campbell NAME=MAIN PASS1 CODE=0600 DATA=0152 ------------- LINK: MAIN --------------------- 0152 MAX.DATE (14) 0160 OBJECT (4) First 64K above .OBJ files (Build .COM may overwrite) 0164 XPATCH (4) 4-byte OBJECT fixups (appended to SYMTAB for AUX). 0168 SYMTAB (8) Final 64K: Rebuild in .OBJ area as AUX .OBJ file. 0600 NEXT 0600 MAIN ENTRY 0600 SI=081 at 081 0603 HL=@OBJ.EXT+1 force .OBJ file extension 0606 CALL SCAN.SRC Returns $7B = \,0 0609 SI=@USAGE 060C IF CY,GOTO DSPLY 0610 BP=@PARMS (SS=CS, and BP=0100 access to Parm Data) 0613 CALL INIT.MEM 0616 HL=01000 HL=#paragraphs(64K) above current CS 0619 CALL LOAD.FILE $7C = 061C CALL GET.DATE HL=Handle (saves file Date-Time) 061F SI,DS=%(BP+FB) 0622 CALL LOAD.OBJ (Abort on Bad File; May issue Warnings) 0625 CALL LOAD.AUX (Abort on Bad File; May issue Warnings) 0628 CALL PASS.1 Define CBSE for each module & initial DBSE 062B CALL PASS.2 Define SYMTAB 062E CALL PASS.3 Define XPATCH & OBJECT (.COM) 0631 CALL CK.ERRORS 0634 IF ZR, 0636 CALL WIPE.COM Name the .COM file and delete it. 0639 CALL WRITE.COM If there were NO ERRORS, finalize 063C SI=@DONEOK and create/write the .COM file. 063F CALL DSPLY Created O.K. 0642 CALL FILE.POINT 0645 SI=6D 0648* $SI:" " 064B IF NE,CALL WRITE.AUX Write .OBJ file. 0650 AA=4C00 0653 INT 021 (Program Exit) .PAD=10 0660*INIT.MEM AA=0 0662 %OBJECT=AA NOTE: This sequence of memory insures 0665 %XPATCH=AA against overruns and overflows. 0668 %SYMTAB=AA 066B AA=%A2 Next Available Paragraph 066E* AA:9F00 0671 IF GT, 0673 AA=9F00 Next Paragraph beyond end of memory 0676* AA=AA-01000 0679 %SYMTAB+2=AA SYMTAB(4) = 64K segment 067C %A2=AA (reset Next Available Paragraph) 067F* AA=AA-01000 0682 %XPATCH+2=AA XPATCH(4) = 64K segment 0685* AA=AA-01000 0688 %OBJECT+2=AA OBJECT(4) = 64K segment 068B BC=@OBJECT-PARMS 068E DI=BP Zero the GOTO MAIN, & Copyright area. 0690* AA=0 0692 DO UNTIL BC=0 NOTE: Data above copyright is $DI+=A already initialized or set to zero. BC=BC-1 LOOP (BC>0) 0694 CALL FILE.POINT gets SI,DS = . 0697 DI,ES=%(BP+SYM) Now: %(DI,ES) = Symtab 1st entry 069A ADD.FILE A=0F0 069C PUSH DI Need Init Symtab = Signature Entry: 069D $DI+=A [parm:skip],0 069E DO $DI+=$SI+ 069F* $SI:"." 06A2 LOOP UNTIL EQ 06A4 POP BC 06A5 PUSH DI 06A6 SWAP BC,DI 06A8* BC=BC-DI 06AA* ES: $DI=$DI OR C 06AD POP DI 06AE %(BP+SYM)=DI 06B1 ES: $DI=0 SymTab starts at 0-byte terminator 06B5 RETURN 06B6 FILE.POINT DS=CS 06B8 ES=CS 06BA SI=7C Source (preceded by "\") 06BD DO A=$SI+ Scan to 0-byte 06BE* A:0 06C0 LOOP UNTIL EQ 06C2+ DO SI=SI-1 Scan back to "\" 06C3 A=$SI 06C5* A:"\" 06C7 LOOP UNTIL EQ 06C9+ SI=SI+1 SI,DS = . 06CA DI=SI DI,ES = . 06CC RETURN .PAD=10 06D0 WIPE.COM CALL FILE.POINT 06D3 DS=%(BP+SYM+2) 06D6* SI=0 06D8 CALL FILE.NAME 06DB DO UNTIL BC=0 $DI+=$SI+ BC=BC-1 LOOP (BC>0) Suffix to 06DD SI=@COM.EXT 06E0 CALL COPY.EXT 06E3 GOTO WIPE.FILE finally, delete the file & return. 06E6 WRITE.COM SI=@MAX.DATE-0100 06E9 AA=%(BP+SI) Fetch MAX.DATE(4) 06EB %(BP+SI-4)=AA 06EE AA=%(BP+SI+2) Store DATE(2),TIME(2) 06F1 %(BP+SI-2)=AA 06F4 DS=CS File Pointers are set by PASS.3 06F6 GOTO WRITE.OBJ Write the .COM file (path at 07C). 06F9 FILE.NAME A=$SI+ 06FA C=A (Symtab prefix byte) 06FC* BC=BC AND 0F Here is length of Symtab 1st entry 0700+ BC=BC-1 get BC = actual symbol length 0701* A:0FB 0703 IF EQ, Old "0FB" Format requires 0705+ SI=SI+2 Pointer Fixup 0707+ BC=BC-1 Decrement count by 2 0708 SWAP BC,HL or more, and by any 070A+ DO HL=HL-1 trailing " " bytes. 070B* $(HL+SI-1):" " 070F LOOP UNTIL NE 0711 SWAP HL,BC 0713 RETURN 0714 COPY.EXT DS=CS .EXT comes from Code Segment. 0716 $DI+=$SI+ So, copy the "." ,0 0717 %DI+=%SI+ 0718 %DI+=%SI+ 0719 RETURN 071A DF3 ENTRY DSPLY FUNCTION: Display 2-byte BCD 071A A=$SI+ 071B PUSH AA 071C* LSR A,4 071F IF NZ,CALL DIGIT 0724 POP AA 0725* A=A AND 0F 0727*DIGIT A=A OR "0" 0729 $DI+=A 072A $DI=0 072D RETURN .PAD=10 0730 LOAD.NXT PUSH DS Pointer to next LOAD= entry in .OBJ file. 0731 PUSH SI 0732 CALL FILE.POINT 0735 CALL NO.DUPS (accesses above Pointer on TOS) 0738 POP SI (HL,DE returned as Pointer to ) 0739 POP DS 073A IF EQ,RTN 073D PUSH ES 073E PUSH DI 073F CALL FILE.NAME 0742 DO UNTIL BC=0 $DI+=$SI+ BC=BC-1 LOOP (BC>0) Suffix to , 0744 SI=@OBJ.EXT and add .,0 to complete it. 0747 CALL COPY.EXT 074A ES=DE Saved by NO.DUPS 074C DI=HL =Pointer to to be Loaded. 074E POP SI 074F POP DS 0750 CALL ADD.FILE Add .OBJ filename to SYMTAB 0753 SI,DS=%(BP+EOF) 0756 CALL MIN.SI 0759 PUSH DS 075A PUSH SI 075B DS=CS 075D CALL LOAD.2ND 0760 CALL GET.DATE 0763 AA=3E00 Close the File 0766 INT 021 (HL=FileHandle) 0768 POP SI 0769 POP DS 076A LOAD.OBJ CALL CK.ROOT Be sure .OBJ is compatible w/Root, 076D PUSH DS and is NOT an "Aux" type .OBJ file. 076E PUSH SI (issue Format Warning if necessary) 076F CALL VERIFY Be sure .OBJ is not corrupt. 0772 POP SI 0773 POP DS 0774 DO A=$SI Loop through all 0776* AA=AA AND 0F the files in the 0779* SI=SI+AA Load List. 077B A=$SI 077D* A=A AND 0F0 077F* A:0F0 0781 * IF NE,EXIT 0783 PUSH DS 0784 PUSH SI 0785 CALL LOAD.NXT 0788 POP SI 0789 POP DS 078A LOOP 078C RETURN .PAD=10 0790 BAD.1: SI=@E.1 ABORT: "Corrupt .OBJ File" 0793 GOTO DSPLY 0796 VERIFY CALL SET.PARMS 0799 IF NE,GOTO BAD.1 Undefined Format 079B HL=0F 079E CALL CK.PART Follow 4-bit skips to End-of-Part 07A1 HL=3F Follow 6-bit skips to End-of-Part 07A4 CK.PART DO A=$SI 07A6* A=A AND L 07A8 * IF ZR,EXIT 07AA AA=A 07AB* SI=SI+AA 07AD+ H=H+1 07AF LOOP 07B1* $SI:0 Bad file if any 0-skip not a 0-byte. 07B4 IF NE,GOTO BAD.1 07B6+ SI=SI+1 07B7* $SI:H Also bad if Count byte is incorrect. 07B9 IF NE,GOTO BAD.1 07BB+ SI=SI+1 Return Pointer to End-of-Part. 07BC RETURN 07BD NEED.AUX A=$SI 07BF* A:0F2 Here, we DO want an 07C1 IF GE, "Aux" type .OBJ File. 07C3* A:0FB (Signature = 0F2-0FA) 07C5 * IF LT,EXIT 07C7 BAD.TYPE: ELSE SI=@E.4 Signature = 0FB is "Old" type .OBJ 07CA GOTO DSPLY Issue an Error, & abort. 07CD RETURN 07CE CK.ROOT A=$SI Verify not "Aux" type, and that the 07D0* A:0F2 .OBJ is compatible with the Root. 07D2 IF GE, 07D4* A:0FB 07D6 IF LT,GOTO BAD.TYPE ("Aux" type .OBJ) 07D8 PUSH DS 07D9 PUSH SI Pointer to Base of latest .OBJ 07DA SI,DS=%(BP+FB) Pointer to Root File 07DD* A=A XOR $SI Compare Signature with 07DF* A::030 Endian & WordSize should match. 07E1 IF NZ, (Signature Mismatch) 07E3 SI=@W.1 07E6 CALL DSPLY 07E9 DS=CS 07EB SI=@DATE 07EE AA=%SI 07F0 BC=%(SI+2) 07F3* AA:%(SI+4) 07F6 IF EQ, 07F8* BC:%(SI+6) 07FB IF GT, 07FD %(SI+4)=AA Save the MAX Date-Time 0800 %(SI+6)=BC 0803 POP SI 0804 POP DS Pointer to Base of latest .OBJ 0805 RETURN .PAD=10 0810 LOAD.AUX CALL FILE.POINT An "Aux" type .OBJ file is a special 0813 SI=6D (17th) format to allow generation of 0816* $SI:" " cross reference listings and LINKing 0819 IF NE,CALL READ.AUX .OBJ files independently from their 081E SI,DS=%(BP+EOF) group. 0821 $SI=0 0824 SI,DS=%(BP+FB) 0827 CALL SET.PARMS Get HL=@ParmList for root .OBJ 082A CS: AA=%HL Set the default Code Base. 082D %(BP+CBSE)=AA 0830 RETURN 0831 NO.DUPS PUSH BP 0832 BP=SP TOS = [BP][RETURN][seg:index of FileName] 0834 PUSH ES 0835 PUSH DI ES:DI = CS:7C+ (target for FileName) 0836 SI,DS=%(BP+4) 0839 CALL FILE.NAME Get Match Parameters for Load Filename 083C HL=BC (length of name) 083E ES=DS 0840 DI=SI 0842 CS: DS=%SYMTAB+2 Pointer to SymTab's list 0847* SI=0 of files already loaded. 0849 DO CALL FILE.NAME Get Match Parameters 084C* C:L (BC = Byte Count) 084E IF EQ, 0850 PUSH DI 0851 DO UNTIL BC=0 * $SI+:$DI+ BC=BC-1 LOOP EQ (BC>0) 0853 POP DI 0854 * IF EQ,EXIT 0856* SI=SI+BC 0858* $SI:1 085B LOOP UNTIL LT 085D HL=SI Save Pointer to End-of-SymTab 085F DE=DS (if filename not found) 0861 POP DI (so it can be entered later) 0862 POP ES 0863 POP BP 0864 RETURN .PAD=10 0870 READ.AUX BC=8 0873 DO UNTIL BC=0 $DI+=$SI+ Here, we load the .OBJ file BC=BC-1 named as the 2nd parameter. LOOP (BC>0) 0875+ DO DI=DI-1 It will reside above the 0876* $DI:" " last loaded normal .OBJ 0879 LOOP WHILE EQ 087B+ DI=DI+1 Then, its SymTab portion 087C SI=@OBJ.EXT will be apended to the 087F CALL COPY.EXT file list that already 0882 DE=07C begins the current SymTab. 0885 AA=04300 [new file list][old SymTab] 0888 INT 021 088A IF NC, 088C PUSH %(BP+EOF+2) 088F PUSH %(BP+EOF) 0892 CALL LOAD.2ND 0895 AA=3E00 0898 INT 021 Close the "Aux" file. 089A POP %(BP+EOF) 089D POP %(BP+EOF+2) When the "Aux" file is later 08A0 SI,DS=%(BP+EOF) written out, it will have a 08A3 CALL MIN.SI single fixup record giving a 08A6 PUSH DS count of XPATCH entries that 08A7 PUSH SI are appended to the file. 08A8 CALL VERIFY On input, this portion of 08AB POP SI "Aux" is ignored. 08AC POP DS 08AD CALL NEED.AUX CY-->Good "Aux" 08B0 * IF NC,EXIT Warning DSPLY-->ZR 08B2 A=$SI 08B4* DO AA=AA AND 0F 08B7* SI=SI+AA 08B9 A=$SI Skip the Aux's "Load List" 08BB* A:0F0 08BD LOOP UNTIL LT 08BF DI,ES=%(BP+SYM) 08C2 DO A=$SI 08C4* AA=AA AND 0F 08C7 * IF ZR,EXIT 08C9 SWAP AA,BC 08CA DO UNTIL BC=0 Append the Aux's $DI+=$SI+ SymTab to the current BC=BC-1 SymTab's Load LIst. LOOP (BC>0) 08CC LOOP 08CE $DI+=A 08CF RETURN .PAD=10 08E0 WRITE.AUX BC=8 08E3 DO A=$SI+ 08E4* A:" " 08E6 IF NE, 08E8 $DI+=A 08E9 BC=BC-1 LOOP NE (BC>0) 08EB SI=@OBJ.EXT 08EE CALL COPY.EXT 08F1 ES=%(BP+FB+2) 08F4 DS=%(BP+SYM+2) 08F7* SI=0 08F9* DI=0 08FB* HL=0 08FD %(BP+FB)=DI 0900 DO BC=%SI 0902* BC=BC AND 0F 0906 * IF ZR,EXIT 0908 A=$SI 090A* A=A XOR C 090C* A:030 Is TYPE = New Def ? 090E IF EQ, If so, 0910* $SI=$SI AND 02F Make TYPE = "Old Def" 0913+ HL=HL+1 0914 DO UNTIL BC=0 $DI+=$SI+ BC=BC-1 LOOP (BC>0) 0916 LOOP 0918* AA=0 091A SWAP A',L 091C %DI+=AA 091D DE,DS=%(BP+XPT) 0920* SI=0 0922 A=3 0924 $DI+=A 0925 SWAP AA,DE 0926 %DI+=AA 0927 BC='0001' 092A SWAP AA,BC 092B %DI+=AA 092C CALL MIN.DI 092F DO UNTIL BC=0 $DI+=$SI+ BC=BC-1 LOOP (BC>0) 0931 %(BP+EOF)=DI 0934 %(BP+EOF+2)=ES 0937 CALL WRITE.COM 093A SI=@DONEOK 093D CALL DSPLY 0940 RETURN .PAD=10 0950 CK.ERRORS DE,DS=%(BP+XPT) 0953* SI=0 0955* BC=0 0957* DO $(SI+3):0 095B IF NEG, 095D PUSH DS 095E PUSH SI 095F AA=%SI 0961 CALL WRITE.HEX 0964 SWAP AA,BC 0965* A::0F 0967 IF ZR, 0969 SI=@E.2 096C* A:0 096E IF NZ, 0970 SI=@CR.LF 0973 CALL DSPLY 0976 A=1 0978 PUSH AA 0979 SI=@E.3 097C CALL DSPLY 097F POP BC 0980+ BC=BC+1 0981 POP SI 0982 POP DS 0983 SI=(SI+4) 0986* SI:DE 0988 LOOP UNTIL GE 098A* C:0 098C RETURN 098D NEXT . 0603 OBJ.EXT 0606 SCAN.SRC 0609 USAGE 060C DSPLY 0610 PARMS 0619 LOAD.FILE 061C GET.DATE 061F FB 0628 PASS.1 062B PASS.2 062E PASS.3 063C DONEOK 066B A2 0697 SYM 06DD COM.EXT 06E3 WIPE.FILE 06F6 WRITE.OBJ 0753 EOF 0756 MIN.SI 075D LOAD.2ND 0790 E.1 0796 SET.PARMS 07C7 E.4 07E3 W.1 07EB DATE 082D CBSE 091D XPT 092C MIN.DI 0961 WRITE.HEX 0969 E.2 0970 CR.LF 0979 E.3