--- /dev/null
+TITLE LOADGC MODULE TO LOAD THE GARBAGE COLLECTOR
+
+RELOCA
+
+.INSRT MUDDLE >
+SYSQ
+IFE ITS,[
+.INSRT STENEX >
+XJRST==JRST 5,
+]
+IFN ITS, PGSZ==10.
+IFE ITS, PGSZ==9.
+
+; ROUTINES TO GET THE GC DO PDL OVERFLOWS IN GC AND ALLOCATE SPECIAL
+; BUFFERS.
+
+; IMPORTANT VARAIBLES
+
+.GLOBAL PAGEGC ; STARTING PAGE OF GARBAGE COLLECTOR (PAGES)
+.GLOBAL LENGC ; LENGTH OF GARBAGE COLLECTOR (PAGES)
+.GLOBAL SLENGC ; LENGTH OF MARK/SWEEP GARBAGE COLLECTOR
+.GLOBAL MRKPDL ; STARTING LOCATION OF MARK PDL (WORDS)
+.GLOBAL STRBUF ; START OF BUFFER LOCATIONS (WORDS)
+.GLOBAL SWAPGC ; WHICH GARBAGE COLLECTOR TO LOAD
+
+.GLOBAL MARK2G ; GENERAL MARKING ROUTINE FOR TEMPLATE STUFF
+.GLOBAL MARK2A,MARK2S ; SPECIFIC MARKERS IN SGC/AGC
+.GLOBAL SECLEN ; LENGTH OF SECTION GC GUY
+.GLOBAL MULTSG
+.GLOBAL SECBLK,DECBLK,GCDEBU,DEBUGC,NDEBUG
+.GLOBAL FRETOP,PURBOT,PURTOP,GCPDL,LPUR,STRPAG,CKPUR,INPLOD,GETPAG,CURPLN,SGCLBK,PGCNT
+.GLOBAL LODGC,CKFILE,SLEEPR,KILGC,GETBUF,KILBUF,GPDLOV,GCDIR,INTDIR,GCLDBK
+.GLOBAL OPBLK,SJFNS,IJFNS,OPSYS,IJFNS1,RBLDM,ILDBLK,TILDBL
+.GLOBAL TMTNXS,C%1
+
+IFN ITS,[
+IMAPCH==0 ; INTERNAL MAPPING CHANNEL
+MAPCHN==1000,,IMAPCH ; CORBLK CHANNEL
+FME==1000,,-1 ; BITS FOR CURRENT JOB
+FLS==1000,,0 ; BITS TO FLUSH A PAGE
+RDTP==1000,,200000 ; BITS TO MAP IN IN READ-ONLY
+WRTP==1000,,100000
+CRJB==1000,,400001 ; BITS TO ALLOCATE CORE
+CWRITE==1000,,4000
+]
+IFE ITS,[
+MFORK==400000
+CTREAD==100000 ; READ BIT
+CTEXEC==20000 ; EXECUTE BIT
+CTWRIT==40000 ; WRITE BIT
+CTCW==400 ; COPY ON WRITE
+SGJF==1 ; USE SHORT JFN (LH FLAG)
+OLDF==100000 ; REQUIRE OLD (EXISTING FILE) (LH FLAG)
+FREAD==200000 ; READ BIT FOR OPENF
+FEXEC==40000 ; EXEC BIT FOR OPENF
+FTHAW==2000
+]
+; GENERAL MARK ROUTINE FOR TEMPLATE STUFF. GOES TO RIGHT PLACE IN
+; WHICHEVER GC'ER WE'RE USING AT THE MOMENT
+MARK2G: SKIPN SWAPGC
+ JRST MARK2A ; INTO AGC
+ JRST MARK2S ; INTO SGC
+
+; ROUTINE TO LOAD THE GARBAGE COLLECTOR
+
+LODGC:
+IFN ITS,[
+ MOVEI 0,GCLDBK
+ SKIPE SWAPGC ; SKIP IF SWAPPED GARBAGE COLLECTOR
+ MOVEI 0,SGCLBK
+ MOVEM 0,OPBLK
+
+
+ .SUSET [.RSNAM,,SAVSNM] ; SAVE OLD SNAME
+ .SUSET [.SSNAM,,GCDIR] ; SET SNAME TO APP DIR
+ .OPEN IMAPCH,@OPBLK ; OPEN CHANNEL TO FILE
+ PUSHJ P,CKFILE ; SEE IF REALLY LOSING
+ HRLZI A,-LENGC+3
+ SKIPE SWAPGC
+ HRLZI A,-SLENGC
+ MOVE B,A ; B WILL CONTAIN PTR TO CORE
+ HRRI B,PAGEGC
+ DOTCAL CORBLK,[[RDTP],[FME],B,[MAPCHN],A]
+ PUSHJ P,SLEEPR
+ HRLI B,-1
+ SKIPN SWAPGC ; IF SWAP 1 PAGE FOR CORBLK ELSE 3
+ HRLI B,-3
+GETIT: DOTCAL CORBLK,[[WRTP],[FME],B,[CRJB]]
+ PUSHJ P,SLEEPR
+ .CLOSE IMAPCH,
+ MOVEI A,LENGC ; SMASH PAGECOUNT
+ SKIPE SWAPGC
+ MOVEI A,SLENGC+1 ; PSTACK
+ MOVEM A,PGCNT
+ POPJ P,
+
+; SEE WHY OPEN FAILED
+
+CKFILE: .STATUS IMAPCH,0 ; GET STATUS BITS INTO 0
+ HRLZS 0
+ ANDI 0,77 ; AND OF EXTRANEOUS BITS
+ CAIN 0,4 ; SKIP IF NOT FNF
+ FATAL CANT OPEN AGC FILE
+
+SLEEPR: MOVEI 0,1 ; SLEEP FOR A WHILE
+ .SLEEP
+ SOS (P) ; TRY AGAIN
+ SOS (P)
+ POPJ P, ; BYE
+]
+
+IFE ITS,[
+ HRRZ A,IJFNS1
+ SKIPN MULTSG
+ HLRZ A,IJFNS
+ SKIPE SWAPGC
+ HLRZ A,IJFNS1
+ JUMPN A,GOTJFN
+
+; HERE TO GET GC JFNS
+; GET STRING NAME OF MDL INTERPRETER FILE
+ HRRZ A,IJFNS ; INTERPRETER JFN
+ MOVE B,A ; SET UP FOR JFNS
+ PUSHJ P,TMTNXS ; MAKES A STRING ON P STACK
+ MOVE D,E ; SAVED VALUE OF P STACK
+ HRROI A,1(E) ; STRING FOR RESULT
+ MOVE C,[211000,,1] ; GET "DEV:<DIR>NM1" FROM JFNS
+ JFNS
+ MOVE C,A ; SAVE TO REUSE FOR ".SGC"
+; GET JFN TO AGC FILE
+ MOVEI B,[ASCIZ /.AGC/]
+ SKIPN MULTSG
+ JRST .+4
+ MOVEI B,[ASCIZ /.DEC/]
+ SKIPN GCDEBU
+ MOVEI B,[ASCIZ /.SEC/]
+ SKIPE SWAPGC
+ MOVEI B,[ASCIZ /.SGC/]
+ HRLI B,440700
+ ILDB B
+ IDPB A
+ JUMPN .-2 ; COPY ".AGC" INTO STRING
+ HRROI B,1(E) ; GTJFN STRING
+ MOVSI A,SGJF+OLDF ; GTJFN CONTROL BITSS
+ GTJFN
+ FATAL AGC GARBAGE COLLECTOR IS MISSING
+ SKIPN SWAPGC
+ JRST .+3
+ HRLM A,IJFNS1
+ JRST JFNIN
+ SKIPE MULTSG
+ HRRM A,IJFNS1
+ SKIPN MULTSG
+ HRLM A,IJFNS
+JFNIN: MOVE B,[440000,,FREAD+FEXEC]
+ OPENF
+ FATAL CANT OPEN AGC FILE
+ MOVE P,E
+GOTJFN:
+ MOVEI D,SECLEN+SECLEN-2
+ SKIPN MULTSG
+ MOVEI D,LENGC+LENGC-6 ; # OF TENEX PAGES TO GET IT
+ SKIPE SWAPGC
+ MOVEI D,SLENGC+SLENGC
+ MOVSI A,(A) ; JFN TO LH
+ MOVE B,[MFORK,,PAGEGC+PAGEGC]
+ MOVSI C,CTREAD+CTEXEC
+
+LDLP: PMAP
+ ADDI A,1
+ ADDI B,1
+ SOJG D,LDLP
+
+ MOVEI C,0
+ MOVEI D,6 ; THESE PAGES WILL BE THE GC PDL
+ SKIPN MULTSG
+ SKIPE SWAPGC
+ MOVEI D,2 ; PDL BUT NO FRONT OR WINDOW
+ MOVNI A,1
+
+LDLP1: PMAP
+ ADDI B,1
+ SOJG D,LDLP1
+
+ MOVEI A,SECLEN+1
+ SKIPN MULTSG
+ MOVEI A,LENGC ; SMASH PAGECOUNT
+ SKIPE SWAPGC
+ MOVEI A,SLENGC+1
+ MOVEM A,PGCNT
+ POPJ P,
+
+;ROUTINE TO "SLEEP" FOR A WHILE ON 10X/20X HA HA
+SLEEPR: SOS (P)
+ POPJ P,
+]
+
+; ROUTINE TO LOAD THE INTERPRETER
+; C=>LENGTH OF PAGES
+; D=>START OF PAGES
+
+LODINT:
+IFN ITS,[
+ .SUSET [.RSNAME,,SAVSNM]
+LODIN1: .IOPUS IMAPCH,
+ .SUSET [.SSNAM,,INTDIR]
+ .OPEN IMAPCH,ILDBLK ; OPEN FILE TO INTERPRETER BLOCK
+ PUSHJ P,CKFILE
+ HLRE B,TP ; MAKE SURE BIG ENOUGJ
+ MOVNS B ; SEE IF WE WIN
+ CAIGE B,400 ; SKIP IF WINNING
+ FATAL NO ROOM FOR PAGE MAP
+ MOVSI A,-400
+ HRRI A,1(TP)
+ .ACCES IMAPCH,C%1
+ .IOT IMAPCH,A ; GET IN PAGE MAP
+ MOVEI A,1 ; INITIALIZE FILE PAGE COUNT
+ MOVEI B,0 ; CORE PAGE COUNT
+ MOVEI E,1(TP)
+LOPFND: HRRZ 0,(E)
+ JUMPE 0,NOPAG ; IF 0 FORGET IT
+ ADDI A,1 ; AOS FILE MAP
+NOPAG: ADDI B,1 ; AOS PAGE MAP
+ CAIE B,(D) ; SKIP IF DONE
+ AOJA E,LOPFND
+ MOVNI 0,(C) ; GET PAGE-COUNT
+ HRL A,0 ; BUILD FILE PAGE POINTER
+ HRL B,0 ; BUILD CORE PAGE POINTER
+ DOTCAL CORBLK,[[RDTP],[FME],B,[MAPCHN],A]
+ PUSHJ P,SLEEPR ; GO TO SLEEP FOR A WHILE
+ .CLOSE IMAPCH,
+ .IOPOP IMAPCH,
+ .SUSET [.SSNAM,,SAVSNM]
+ POPJ P, ; DONE
+]
+IFE ITS,[
+ HRRZ E,IJFNS
+ MOVEI A,(E) ; FIND OUT LENGTH OF MAP
+ MOVEI B,0
+ SFPTR
+ FATAL CANNOT RESET FILE POINTER
+ MOVEI A,(E)
+ BIN ; GET LENGTH WORD
+ MOVEI A,(B) ; ISOLATE SIZE OF MAP
+ HLRZ 0,B
+ HLRE B,TP ; MUST BE SPACE FOR CRUFT
+ MOVNS B
+ CAIGE B,(A) ; ROOM?
+ FATAL NO ROOM FOR PAGE MAP (GULP)
+ PUSH P,C ; SAVE # PAGES WANTED
+ MOVN C,A
+ MOVEI A,(E) ; READY TO READ IN MAP
+ MOVEI B,1(TP) ; ONTO TP STACK
+ HRLI B,444400
+ SIN ; SNARF IT IN
+
+ MOVEI A,1(TP)
+ CAIE 0,1000 ; CHECK FOR TENEX
+ JRST TOPS20
+ LDB 0,[221100,,(A)] ; GET FORK PAGE
+ CAIE 0,(D) ; GOT IT?
+ AOJA A,.-2
+ HRRZ A,(A)
+ JRST GOTPG
+
+TOPS21: ADDI A,2
+TOPS20: HRRZ 0,1(A) ; GET PAGE IN PROCESS
+ LDB B,[331100,,1(A)] ; GET REPT COUNT
+ ADD B,0 ; LAST PAGE IN BLOCK
+ CAIG 0,(D)
+ CAIGE B,(D) ; WITHIN RANGE?
+ JRST TOPS21
+ SUBM D,0
+ HRRZ A,(A)
+ ADD A,0
+
+GOTPG: HRLI A,(E)
+ MOVEI B,(D)
+ HRLI B,MFORK
+ MOVSI C,CTREAD+CTEXEC ; BITS
+ POP P,D ; PAGES
+ ASH D,1 ; FOR TENEX
+
+MPLP: PMAP
+ ADDI A,1
+ ADDI B,1
+ SOJG D,MPLP ; MAP-EM IN
+
+ POPJ P,
+]
+
+; ROUTINE TO MAP IN OVER GARBAGE COLLECTOR EXPLICITLY
+
+KILGC:
+IFN ITS,[
+ MOVEI D,PAGEGC
+ MOVE C,PGCNT
+ JRST LODIN1
+]
+IFE ITS,[
+ MOVEI D,PAGEGC+PAGEGC
+ MOVE C,PGCNT
+ JRST LODINT
+]
+
+; ROUTINE TO TRY TO ALLOCATE A BUFFER
+; 1) IT FIRSTS LOOKS BETWEEN FRETOP AND PURBOT
+; 2) LOOKS AT THE INTERPRETER
+; A=>NUMBER OF BUFFER PAGES (CURRENTLY ALWAYS 1)
+; B=>BUFFER
+; BUFFER SAVED IN BUFPTR
+
+GETBUF: ASH A,10. ; CONVERT TO WORDS
+ MOVE B,PURBOT ; LOOK FOR ROOM IN GCS
+ SUB B,FRETOP
+ CAMGE B,A ; SKIP IF WINNING
+ JRST NOBUF1
+ MOVE B,FRETOP ; BUFFER IN B
+ MOVEM B,BUFPTR ; SAVE BUFFER
+ ASH A,-10. ; TO PAGES
+ MOVEM A,BUFLT ; LENGTH OF BUFFER
+ POPJ P,
+NOBUF1: ASH A,-10. ; BACK TO WORDS
+ SKIPE INPLOD ; SKIP IF NOT IN MAPPUR
+ JRST INTBUF
+ PUSH P,A
+ PUSH P,E
+ JSP E,CKPUR
+ POP P,E
+ POP P,A
+ MOVE B,PURTOP
+ SUB B,PURBOT
+ SUB B,CURPLN
+ ASH B,-10. ; CALCULATE AVAILABLE ROOM
+ CAIGE B,(A) ; SEE IF ENOUGH
+ JRST INTBUF ; LOSE LOSE GET BUFFER FROM INTERPRETER
+IFE ITS, ASH A,1 ; TENEX PAGES
+ PUSH P,C
+ PUSH P,D
+ PUSH P,E
+ PUSHJ P,GETPAG ; GET THOSE PAGES
+ FATAL GETPAG FAILED
+ POP P,E
+ POP P,D
+ POP P,C
+IFE ITS, ASH A,-1
+ JRST GETBUF ; TRY AGAIN
+INTBUF: MOVEM A,BUFLT
+IFN ITS,[
+ MOVNS A ; NEGATE
+ HRLZS A ; SWAP
+ HRRI A,STRPAG ; AOBJN TO PAGE
+ MOVE B,A
+ DOTCAL CORBLK,[[FLS],[FME],A]
+ FATAL CANT FLUSH PAGE
+ DOTCAL CORBLK,[[WRTP],[FME],B,[CRJB]]
+ PUSHJ P,SLEEPR
+]
+
+IFE ITS,[
+ PUSH P,C
+ MOVEI C,(A) ; PAGES TO FLUSH
+ ASH C,1
+ MOVNI A,1 ; FLUSH PAGES
+ MOVE B,[MFORK,,STRPAG+STRPAG] ; WHICH ONES
+FLSLP: PMAP
+ ADDI B,1
+ SOJG C,FLSLP
+ POP P,C
+]
+ MOVEI B,STRBUF ; START OF BUFFER
+ MOVEM B,BUFPTR ; SAVE IN BUFPTR
+ PUSHJ P,RBLDM
+ POPJ P,
+
+; ROUTINE TO FLUSH A BUFFER WHEN DONE WITH IT
+
+KILBUF: SKIPN B,BUFPTR ; SEE IF BUFPTR EXISTS
+ POPJ P,
+IFE ITS, JRST @[.+1] ; RUN IN SECTION 0
+ CAIL B,HIBOT ; SKIP IF NOT PART OF INTERPRETER
+ JRST HIBUF ; INTERPRETER
+IFN ITS,[
+ ASH B,-10.
+ MOVN A,BUFLT ; GET LENGTH
+ HRLI B,(A) ; BUILD PAGE AOBJN
+ DOTCAL CORBLK,[[FLS],[FME],B]
+ FATAL CANT FLUSH PAGES
+]
+IFE ITS,[
+ ASH B,-9. ; TO PAGES
+ HRLI B,MFORK
+ MOVNI A,1
+ MOVE D,BUFLT
+ LSH D,1 ; TO TENEX PAGES
+ PUSH P,C ; SAVE C
+ MOVEI C,0 ; C CONTAINS SOME FLAGS
+
+FLSLP1: PMAP
+ ADDI B,1
+ SOJG D,FLSLP1
+
+ POP P,C ; RESTORE C
+]
+
+FLEXIT: SETZM BUFPTR
+ SETZM BUFLT
+IFE ITS,[
+ PUSH P,A
+ HLRZ A,SJFNS
+ JUMPE A,.+3
+ CLOSF
+ JFCL
+ SETZM SJFNS
+ POP P,A
+ SKIPN MULTSG
+ POPJ P,
+ POP P,21
+ SETZM 20
+ XJRST 20
+]
+IFN ITS,[
+ POPJ P,
+]
+HIBUF: MOVE C,BUFLT
+ MOVE D,BUFPTR
+IFN ITS, ASH D,-10.
+IFE ITS, ASH D,-9.
+ PUSHJ P,LODINT
+ JRST FLEXIT
+
+; HERE TO HANDLE GC PDL OVERFLOW. ROUTINE USES A,B AND ASSUMES GCPDL IS THE PDL
+
+GPDLOV: HRRZ A,PGCNT ; # OF PAGES TO A
+ ADDI A,PAGEGC ; SEE IF ROOM
+ ASH A,10. ; TO WORDS
+ CAIL A,LPUR ; HAVE WE LOST
+ FATAL NO ROOM FOR GCPDL
+IFN ITS,[
+ ASH A,-10. ; GET PAGE NUMBER
+ AOS PGCNT ; AOS
+ DOTCAL CORBLK,[[FLS],[FME],A]
+ FATAL CANT FLUSH PAGE
+ DOTCAL CORBLK,[[WRTP],[FME],A,[CRJB]]
+ PUSHJ P,SLEEPR
+]
+IFE ITS,[
+ ASH A,-9.
+ AOS PGCNT
+ MOVE B,A
+ MOVNI A,1
+ HRLI B,MFORK
+ PUSH P,C ; BETTER HAVE A PDL HERE
+ MOVEI C,0
+ PMAP
+ ADDI B,1
+ PMAP
+ POP P,C
+
+]
+ HRRI A,-2000 ; SMASH PDL
+ HRLM A,GCPDL
+ POPJ P, ; EXIT
+
+IFN ITS,[
+
+
+GCDIR: SIXBIT /MUDSAV/
+INTDIR: SIXBIT /MUDSAV/
+GCLDBK: SIXBIT / &DSK/
+ SIXBIT /AGC/
+ 0 ; FILLED IN BY INITM
+
+SGCLBK: SIXBIT / &DSK/
+ SIXBIT /SGC/
+ 0
+
+ILDBLK: SIXBIT / &DSK/
+ SIXBIT /TS/
+ 0 ; FILLED IN BY INITM
+]
+
+
+NDEBUG: SETZM GCDEBU
+ CAIA
+DEBUGC: SETOM GCDEBU
+ HRRZ A,IJFNS1 ; GET GC JFN
+ SKIPE A
+ CLOSF
+ JFCL
+ POPJ P,
+
+IMPURE
+GCDEBU: 0
+BUFPTR: 0 ; POINTER TO CURRENTLY ACTIVE BUFFER (WORD)
+BUFLT: 0 ; LENGTH OF CURRENTLY ACTIVE BUFFER (PAGES)
+PGCNT: 0 ; # OF PAGES OF MAPPED OUT INTERPRETER
+SAVSNM: 0
+OPBLK: 0 ; BLOCK USED FOR OPEN
+
+PURE
+
+END
+\f
\ No newline at end of file