Split up files.
[pdp10-muddle.git] / sumex / nfree.mcr032
diff --git a/sumex/nfree.mcr032 b/sumex/nfree.mcr032
new file mode 100644 (file)
index 0000000..0dad0f6
--- /dev/null
@@ -0,0 +1,251 @@
+TITLE MODIFIED AFREE FOR MUDDLE\r
+\r
+RELOCATABLE\r
+\r
+.INSRT MUDDLE >\r
+\r
+.GLOBAL CAFREE,CAFRET,PARNEW,AGC,PARBOT,CODTOP,CAFRE1\r
+.GLOBAL STOGC,STOSTR,CAFRE,ISTOST,STOLST,SAT,ICONS,BYTDOP\r
+.GLOBAL FLIST,STORIC\r
+MFUNCTION FREEZE,SUBR\r
+\r
+       ENTRY   1\r
+\r
+       GETYP   A,(AB)          ; get type of it\r
+       PUSH    TP,(AB)         ; save a copy\r
+       PUSH    TP,1(AB)\r
+       PUSH    P,[0]           ; flag for tupel freeze\r
+       PUSHJ   P,SAT           ; to SAT\r
+       MOVEI   B,0             ; final type\r
+       CAIN    A,SNWORD        ; check valid types\r
+       MOVSI   B,TUVEC         ; use UVECTOR\r
+       CAIN    A,S2NWOR\r
+       MOVSI   B,TVEC\r
+       CAIN    A,SARGS\r
+       MOVSI   B,TVEC\r
+       CAIN    A,SCHSTR\r
+       MOVSI   B,TCHSTR\r
+       JUMPE   B,WTYP1\r
+       PUSH    P,B             ; save final type\r
+       CAME    B,$TCHSTR       ; special chars hack\r
+       JRST    OK.FR\r
+       HRR     B,(AB)          ; fixup count\r
+       MOVEM   B,(P)\r
+\r
+       MOVEI   C,(TB)          ; point to it\r
+       PUSHJ   P,BYTDOP        ; A==> points to dope word\r
+       HRRO    B,1(TB)\r
+       SUBI    A,1(B)          ; A==> length of block\r
+       TLC     B,-1(A)\r
+       MOVEM   B,1(TB)         ; and save\r
+       MOVSI   0,TUVEC\r
+       MOVEM   0,(TB)\r
+\r
+OK.FR: HLRE    A,1(TB)         ; get length\r
+       MOVNS   A\r
+       PUSH    P,A\r
+       ADDI    A,2\r
+       PUSHJ   P,CAFREE        ; get storage\r
+       HRLZ    B,1(TB)         ; set up to BLT\r
+       HRRI    B,(A)\r
+       POP     P,C\r
+       ADDI    C,(A)           ; compute end\r
+       BLT     B,(C)\r
+       MOVEI   B,(A)\r
+       HLL     B,1(AB)\r
+       POP     P,A\r
+       JRST    FINIS\r
+\r
+               \r
+CAFRE: PUSH    P,A\r
+       HRRZ    E,STOLST+1(TVP)\r
+       SETZB   C,D\r
+       PUSHJ   P,ICONS         ; get list element\r
+       PUSH    TP,$TLIST       ; and save\r
+       PUSH    TP,B\r
+       MOVE    A,(P)           ; restore length\r
+       ADDI    A,2             ; 2 more for dope words\r
+       PUSHJ   P,CAFREE        ; get the core and dope words\r
+       POP     P,B             ; restore count\r
+       MOVNS   B               ; build AOBJN pointer\r
+       MOVSI   B,(B)\r
+       HRRI    B,(A)\r
+       MOVE    C,(TP)\r
+       MOVEM   B,1(C)          ; save on list\r
+       MOVSI   0,TSTORA        ; and type\r
+       HLLM    0,(C)\r
+       HRRZM   C,STOLST+1(TVP) ; and save as new list\r
+       SUB     TP,[2,,2]\r
+       POPJ    P,\r
+       \r
+CAFRE1:        PUSH    P,A\r
+       ADDI    A,2\r
+       PUSHJ   P,CAFREE\r
+       HRROI   B,(A)           ; pointer to B\r
+       POP     P,A             ; length back\r
+       TLC     B,-1(A)\r
+       POPJ    P,\r
+\r
+CAFREE:        IRP     AC,,[B,C,D,E]\r
+       PUSH    P,AC\r
+       TERMIN\r
+       SKIPG   A               ; make sure arg is a winner\r
+       FATAL BAD CALL TO CAFREE\r
+       MOVSI   A,(A)           ; count to left half for search\r
+       MOVEI   B,FLIST         ; get first pointer\r
+       HRRZ    C,(B)           ; c points to next block\r
+CLOOP: CAMG    A,(C)           ; skip if not big enough\r
+       JRST    CONLIS          ; found one\r
+       MOVEI   D,(B)           ; save in case fall out\r
+       MOVEI   B,(C)           ; point to new previous\r
+       HRRZ    C,(C)           ; next block\r
+       JUMPN   C,CLOOP         ; go on through loop\r
+       HLRZ    E,A             ; count to E\r
+       CAMGE   E,STORIC        ; skip if a area or more\r
+       MOVE    E,STORIC        ; else use a whole area\r
+       MOVE    C,PARBOT        ; foun out if any funny space\r
+       SUB     C,CODTOP        ; amount around to C\r
+       CAMLE   C,E             ; skip if must GC\r
+       JRST    CHAVIT          ; already have it\r
+       SUBI    E,-1(C)         ; get needed from agc\r
+       MOVEM   E,PARNEW        ; funny arg to AGC\r
+       PUSH    P,A\r
+       MOVE    C,[7,,6]        ; SET UP AGC INDICATORS\r
+       PUSHJ   P,AGC           ; collect that garbage\r
+       SETZM   PARNEW          ; dont do it again\r
+       AOJL    A,GCLOS         ; couldn't get core\r
+       POP     P,A\r
+\r
+; Make sure pointers still good after GC\r
+\r
+       MOVEI   D,FLIST\r
+       HRRZ    B,(D)\r
+\r
+       HRRZ    E,(B)           ; next pointer\r
+       JUMPE   E,.+4           ; end of list ok\r
+       MOVEI   D,(B)\r
+       MOVEI   B,(E)\r
+       JRST    .-4             ; look at next\r
+\r
+CHAVIT:        MOVE    E,PARBOT        ; find amount obtained\r
+       SUBI    E,1             ; dont use a real pair\r
+       MOVEI   C,(E)           ; for reset of CODTOP\r
+       SUB     E,CODTOP\r
+       EXCH    C,CODTOP        ; store it back\r
+       CAIE    B,(C)           ; did we simply grow the last block?\r
+       JRST    CSPLIC          ; no, splice it in\r
+       HLRZ    C,(B)           ; length of old guy\r
+       ADDI    C,(E)           ; total length\r
+       ADDI    B,(E)           ; point to new last dope word\r
+       HRLZM   C,(B)           ; clobber final length in\r
+       HRRM    B,(D)           ; and splice into free list\r
+       MOVEI   C,(B)           ; reset acs for reentry into loop\r
+       MOVEI   B,(D)\r
+       JRST    CLOOP\r
+\r
+; Here to splice new core onto end of list.\r
+\r
+CSPLIC:        MOVE    C,CODTOP        ; point to end of new block\r
+       HRLZM   E,(C)           ; store length of new block in dope words\r
+       HRRM    C,(D)           ; D is old previous, link it up\r
+       MOVEI   B,(D)           ; and reset B for reentry into loop\r
+       JRST    CLOOP\r
+\r
+; here if an appropriate block is on the list\r
+\r
+CONLIS:        HLRZS   A               ; count back to a rh\r
+       HLRZ    D,(C)           ; length of proposed block to D\r
+       CAIN    A,(D)           ; skip if they are different\r
+       JRST    CEASY           ; just splice it out\r
+       MOVEI   B,(C)           ; point to block to be chopped up\r
+       SUBI    B,-1(D)         ; point to beginning of same\r
+       SUBI    D,(A)           ; amount of block to be left to D\r
+       HRLM    D,(C)           ; and fix up dope words\r
+       ADDI    B,-1(A)         ; point to end of same\r
+       HRLZM   A,(B)\r
+       HRRM    B,(B)           ; for GC benefit\r
+\r
+CFREET:        CAIE    A,1             ; if more than 1\r
+       SETZM   -1(B)           ; make tasteful dope worda\r
+       SUBI    B,-1(A)\r
+       MOVEI   A,(B)\r
+       IRP     AC,,[E,D,C,B]\r
+       POP     P,AC\r
+       TERMIN\r
+       POPJ    P,\r
+\r
+CEASY: MOVEI   D,(C)           ; point to block to return\r
+       HRRZ    C,(C)           ; point to next of same\r
+       HRRM    C,(B)           ; smash its previous\r
+       MOVEI   B,(D)           ; point to block with B\r
+       HRRM    B,(B)           ; for GC benefit\r
+       JRST    CFREET\r
+\r
+GCLOS: PUSH    TP,$TATOM\r
+       PUSH    TP,EQUOTE NO-MORE-STORAGE\r
+       JRST    CALER1\r
+\r
+CAFRET:        HRROI   B,(B)           ; prepare to search list\r
+       TLC     B,-1(A)         ; by making an AOBJN pointer\r
+       HRRZ    C,STOLST+1(TVP) ; start of list\r
+       MOVEI   D,STOLST+1(TVP)\r
+\r
+CAFRTL:        JUMPE   C,CPOPJ         ; not founc\r
+       CAME    B,1(C)          ; this it?\r
+       JRST    CAFRT1\r
+       HRRZ    C,(C)           ; yes splice it out\r
+       HRRM    C,(D)           ; smash it\r
+CPOPJ: POPJ    P,              ; dont do anything now\r
+\r
+CAFRT1:        MOVEI   D,(C)\r
+       HRRZ    C,(C)\r
+       JRST    CAFRTL\r
+\r
+; Here from GC to collect all unused blocks into free list\r
+\r
+STOGC: SETZB   C,E             ; zero current length and pointer\r
+       MOVE    A,CODTOP        ; get high end of free space\r
+\r
+STOGCL:        CAIG    A,STOSTR        ; end?\r
+       JRST    STOGCE          ; yes, cleanup and leave\r
+\r
+       HLRZ    0,(A)           ; get length\r
+       ANDI    0,377777\r
+       SKIPGE  (A)             ; skip if a not used block\r
+       JRST    STOGC1          ; jump if marked\r
+\r
+       JUMPE   C,STOGC3        ; jump if no block under construction\r
+       ADD     C,0             ; else add this length to current\r
+       JRST    STOGC4\r
+\r
+STOGC3:        MOVEI   B,(A)           ; save pointer\r
+       MOVE    C,0             ; init length\r
+\r
+STOGC4:        SUB     A,0             ; point to next block\r
+       JRST    STOGCL\r
+\r
+STOGC1:        ANDCAM  D,(A)           ; kill mark bit\r
+       JUMPE   C,STOGC4        ; if no block under cons, dont fix\r
+       HRLM    C,(B)           ; store total block length\r
+       HRRM    E,(B)           ; next pointer hooked in\r
+       MOVEI   E,(B)           ; new next pointer\r
+       MOVEI   C,0\r
+       JRST    STOGC4\r
+\r
+STOGCE:        JUMPE   C,STGCE1        ; jump if no current block\r
+       HRLM    C,(B)           ; smash in count\r
+       HRRM    E,(B)           ; smash in next pointer\r
+       MOVEI   E,(B)           ; and setup E\r
+\r
+STGCE1:        HRRZM   E,FLIST+1       ; final link up\r
+       POPJ    P,\r
+\r
+IMPURE\r
+\r
+FLIST: .+1\r
+       ISTOST\r
+\r
+PURE\r
+\r
+END\r
+\f\r