GET "NLIBHDR"
GET "AHDR"
MANIFEST $( T.HUNK = 1000
T.END = 1002
T.ABSHUNK = 1003
T.RELOCB = 1005
T.ABSRELOCB = 1006
$)
STATIC $( CODEVEC=0
OUTCOUNT=0
RELVECC=0
CURADR=0
MYRELC=0
DUMPCNT=0
DUMPWORD=0
RELADR=0
ABASE=0
RELBASE=0
HTYPE=T.HUNK
SEGLOC=0
SEGGED=FALSE
$)
LET DUMPINIT() BE
$( CODEVEC := GETVEC(4000)
IF CODEVEC=0 DO STOP(190)
RELVECC := GETVEC(1000)
IF RELVECC=0 DO STOP(191)
HUNKINIT()
$)
AND HUNKINIT() BE
$(
UNLESS COMMONS=0 & INTERNALS=0 & EXTERNALS=0 DO
BADLINKS()
MYRELC, CURADR, DUMPCNT := 0, 0, 0
DUMPWORD, RELADR := 0, 0
$)
AND BADLINKS() BE
$( SELECTOUTPUT(FINDOUTPUT(LISTFILE))
WRITES("*NNO EXTERNALS, INTERNALS OR COMMONS ALLOWED*N")
STOP(18)
$)
AND DUMP(TYP, V0, V1, V2, V3, V4) BE
$( SWITCHON TYPﰀ INTO
$( CASE T.ABS:
TXTO(V0, V1)
ENDCASE
CASE T.REL:
TEST DUMPWORD=0 DO
$( RELADR := V1
TXTO(V0, V1)
DUMPWORD := 1
$)
OR
$( TXTO(V0, V1)
RELVECC!MYRELC := RELADR
MYRELC := MYRELC + 1
DUMPWORD := 0
$)
ENDCASE
CASE T.COMMON:
CASE T.EXT:
BADLINKS()
ENDCASE
CASE T.DIR:
SWITCHON TYPϿ INTO
$( CASE D.ORG:
TEST V0=T.ABS DO $( ABASE := V1; HTYPE := T.ABSHUNK $)
OR $( RELBASE := CURADR ; HTYPE := T.HUNK $)
ENDCASE
CASE D.RES:
FOR I = 0 TO V0-1 DO TXTO(V1, P.LOC+I)
ENDCASE
CASE D.DSEG:
UNLESS SEGGED DO
$( IF HTYPE=T.ABSHUNK DO
$( FAULT('J')
ENDCASE
$)
SEGGED := TRUE
SEGLOC := CURADR
$)
ENDCASE
CASE D.END:
WRITEHUNK(TRUE)
FREEVEC(CODEVEC)
FREEVEC(RELVECC)
$)
$)
$)
AND TXTO(X1, X2) BE
$( UNTIL CURADR=X2 DO
$( PUTBYTE(CODEVEC, CURADR, 0)
CURADR := CURADR + 1
CHECK.CURADR()
DUMPCNT := DUMPCNT + 1
$)
PUTBYTE(CODEVEC, CURADR, X1)
CURADR := CURADR + 1
CHECK.CURADR()
DUMPCNT := DUMPCNT + 1
$)
AND WRITEHUNK(ENDQ) BE
$( LET A = OUTPUT()
LET ABSRELCNT, I = 0, 1
SELECTOUTPUT(BINOUT)
UNTIL I>MYRELC DO
$( LET N = RELVECC!(I-1) // ADDRESS IN CODE VECTOR
LET T = GETBYTE(CODEVEC, N) // MS BYTE OF ITEM
LET U = GETBYTE(CODEVEC, N+1) // LS BYTE OF ITEM
LET VAL = (T<<8) | U
TEST VAL>=RELBASE DO // REFERRING TO HUNK
$( VAL := VAL - RELBASE // MAKE VAL OFFSET IN HUNK
T := VAL>>8
U := VAL&255
IF N<RELBASE DO ABSRELCNT := ABSRELCNT+1 // ABSHUNK REFERS TO HUNK
$)
OR // REFERS TO ABSHUNK SO NO RELOCATION REQ.
$( MYRELC := MYRELC-1 // REMOVE ITEM FROM LIST
FOR J = I TO MYRELC DO
RELVECC!(J-1) := RELVECC!J // BY SHIFTING DOWN ITEMS ABOVE
I := I-1
$)
PUTBYTE(CODEVEC, N, U)
PUTBYTE(CODEVEC, N+1, T) // BYTES NOW SWAPPED FOR 8086
I := I+1
$)
UNLESS HTYPE=T.ABSHUNK DO // UNLESS ONLY 1 ABSHUNK
$( WR16(T.HUNK)
$( LET RCNT = (CURADR-RELBASE+1)/2 // WORDS IN HUNK
LET DCNT = RCNT-(SEGLOC-RELBASE)/2 // DATA WORDS
WR16(RCNT)
IF SEGGED DO WR16(DCNT)
FOR I = 1 TO RCNT*2 DO
WR8(GETBYTE(CODEVEC, RELBASE+I-1))
UNLESS MYRELC=0 | MYRELC=ABSRELCNT DO // MAKE T.RELOCB LIST
$( WR16(T.RELOCB)
WR16(MYRELC-ABSRELCNT)
FOR I = 1 TO MYRELC DO
IF RELVECC!(I-1)>=RELBASE DO WR16(RELVECC!(I-1)-RELBASE)
$)
$)
$)
IF RELBASE>0 | HTYPE=T.ABSHUNK DO // IF ABSHUNK EXISTS
$( WR16(T.ABSHUNK)
WR16(ABASE/2) // WORD ADDRESS OF BASE
$( LET AAB = (ABASE/2)*2
LET ACNT = HTYPE=T.ABSHUNK -> (CURADR-AAB+1)/2,
(RELBASE-AAB+1)/2
WR16(ACNT)
FOR I = 0 TO ACNT*2 - 1 DO
WR8(GETBYTE(CODEVEC, AAB+I))
IF ABSRELCNT>0 DO // MAKE T.ABSRELOCB LIST
$( WR16(T.ABSRELOCB)
WR16(ABSRELCNT)
FOR I = 1 TO MYRELC DO
IF RELVECC!(I-1)<RELBASE DO
WR16(RELVECC!(I-1))
$)
$)
$)
IF ENDQ DO WR16(T.END)
SELECTOUTPUT(A)
$)
AND WR8(N) BE
$( IF OUTCOUNT >=32 DO
$( NEWLINE()
OUTCOUNT := 0
$)
WRITEHEX(N, 2)
OUTCOUNT := OUTCOUNT + 1
$)
AND WR16(N) BE
$( WR8(N&255)
WR8((N>>8)&255)
$)
AND CHECK.CURADR() BE
$(
IF CURADR>16000 DO
$( SELECTOUTPUT(FINDOUTPUT(LISTFILE))
WRITES("*NCODE PRODUCER HAS RUN OUT OF STORE!*N")
ENDWRITE()
STOP(19)
$)
$)
.