Twenex Muddle.
[pdp10-muddle.git] / <mdl.int> / mappur.mid.162
1
2 TITLE MAPURE-PAGE LOADER
3
4 RELOCATABLE
5
6 MAPCH==0                        ; channel for MAPing
7 XJRST==JRST 5,
8
9 .GLOBAL PURVEC,PURTOP,PURBOT,P.TOP,GCSTOP,FRETOP,MUDSTR,STRTO6,PLOAD,AGC,GCDOWN
10 .GLOBAL SQUTOA,IGVAL,IBLOCK,PURCLN,MOVPUR,GETPAG,GCFLG,NOSHUF,DIR,NDIRS,SQUPNT
11 .GLOBAL PLODR,SQUKIL,GETBUF,KILBUF,INPLOD,SQKIL,PVSTOR,TVSTOR,DSTOREM,SLEEPR
12 .GLOBAL OPSYS,SJFNS,MULTSG,PURBTB,SFIX,NSEGS
13 .GLOBAL C%11,C%22,C%33,C%44,C%55,C%66,C%0,C%1,C%2,C%3,C%M1,C%M2,C%M10
14 .GLOBAL C%M20,C%M30,C%M40,C%M60
15 .GLOBAL MAPJFN,DIRCHN
16
17 .INSRT MUDDLE >
18 SPCFXU==1
19 SYSQ
20
21 IFE ITS,[
22 IF1, .INSRT STENEX >
23 ]
24
25 F==PVP
26 G==TVP
27 H==SP
28 RDTP==1000,,200000
29 FME==1000,,-1
30
31
32 IFN ITS,[
33 PGMSK==1777
34 PGSHFT==10.
35 ]
36
37 IFE ITS,[
38 FLUSHP==0
39 PGMSK==777
40 PGSHFT==9.
41 ]
42
43 LNTBYT==340700
44 ELN==4                          ; LENGTH OF SLOT
45 FB.NAM==0                       ; NAME SLOT IN TABLE
46 FB.PTR==1                       ; Pointer to core pages
47 FB.AGE==2                       ; age,,chain
48 FB.PGS==3                       ; PTR AND LENGTH OF PAGE IN FILE
49 FB.AMK==37777777                ; extended address mask
50 FB.CNT==<-1>#<FB.AMK>           ; page count mask
51 EOC==400000                     ; END OF PURVEC CHAIN
52
53 IFE ITS,[
54 .FHSLF==400000                  ; THIS FORK
55 %GJSHT==000001                  ; SHORT FORM GTJFN
56 %GJOLD==100000
57         ;PMAP BITS
58 PM%CNT==400000                  ; PMAP WITH REPEAT COUNT
59 PM%RD==100000                   ; PMAP WITH READ ACCESS
60 PM%EX==20000                    ; PMAP WITH EXECUTE ACCESS (NO-OP ON 20X)
61 PM%CPY==400                     ; PMAP WITH COPY-ON-WRITE ACCESS
62 PM%WR==40000                    ; PMAP WITH WRITE ACCESS
63
64         ;OPENF BITS
65 OF%RD==200000                   ; OPEN IN READ MODE
66 OF%WR==100000                   ; OPEN IN WRITE MODE
67 OF%EX==040000                   ; OPEN IN EXECUTE MODE (TENEX CARES)
68 OF%THW==02000                   ; OPEN IN THAWED MODE
69 OF%DUD==00020                   ; DON'T UPDATE THAWED PAGES
70 ]
71 ; THIS ROUTINE TAKES A SLOT OFFSET IN REGISTER A AND MAPS IN THE ASSOCIATED
72 ; FILE. IT CLOBBERS ALL ACs AND SKIP RETURNS IF IT WINS.
73
74 OFF==-5                         ; OFFSET INTO PURVEC OF SLOT
75 NAM==-4                         ; SIXBIT NAME OF THING BEING LOADED
76 LASTC==-3                       ; LAST CHARACTER OF THE NAME
77 DIR==-2                         ; SAVED POINTER TO DIRECTORY
78 SPAG==-1                        ; FIRST PAGE IN FILE
79 PGNO==0                         ; FIRST PAGE IN CORE 
80 VER==-6                         ; VERSION NUMBER OF MUDDLE TO USE IN OPENING FILES
81 FLEN==-7                        ; LENGTH OF THE FILE
82 TEMP==-10                       ; GENERAL TEMPORARY SLOT
83 WRT==-11                        ; INDICATION IF OPEN IS FOR WRITING OR READING
84 CADDR==-12                      ; ADDRESS OF CORE IMAGE LOCATION OF FILE
85 NSLOTS==13
86
87 ; IT FIRST LOOKS TO SEE IF IT HAS THE PAGE NUMBER OF THE FILE
88
89 PLOAD:  ADD     P,[NSLOTS,,NSLOTS]
90         SKIPL   P
91          JRST   PDLOV
92         MOVEM   A,OFF(P)
93         PUSH    TP,C%0                  ; [0]
94         PUSH    TP,C%0          ; [0]
95 IFE ITS,[
96         SKIPN   MAPJFN
97          PUSHJ  P,OPSAV
98 ]
99
100 PLOADX: PUSHJ   P,SQKIL
101         MOVE    A,OFF(P)
102         ADD     A,PURVEC+1              ; GET TO SLOT
103         SKIPE   B,FB.PGS(A)             ; SKIP IF PAGE NUMBER
104          JRST   GETIT
105         MOVE    B,FB.NAM(A)
106         MOVEM   B,NAM(P)
107         MOVE    0,B
108         MOVEI   A,6                     ; FIND LAST CHARACTER
109         TRNE    0,77                    ; SKIP IF NOT DONE
110          JRST   .+3
111         LSH     0,-6                    ; BACK A CHAR
112         SOJG    A,.-3                   ; NOW CHAR IS BACKED OUT
113         ANDI    0,77            ; LASTCHR
114         MOVEM   0,LASTC(P)
115
116 ; NOT TO TRY TO FIND FILE IN MAIN DATA BASE.
117 ; THE GC'S WINDOW IS USED IN THIS CASE.
118
119 IFN ITS,[
120         .CALL   MNBLK           ; OPEN CHANNEL TO MAIN FILE
121          JRST   NTHERE
122         PUSHJ   P,TRAGN                 ; TRY OPENING UP CHANNEL AGAIN IF POSSIBLE
123 ]
124 IFE ITS,[
125         SKIPN   E,MAPJFN
126          JRST   NTHERE          ;who cares if no SAV.FILE?
127         MOVEM   E,DIRCHN
128 ]
129         MOVE    D,NAM(P)
130         MOVE    0,LASTC(P)
131         PUSHJ   P,GETDIR
132         MOVEM   E,DIR(P)
133         PUSHJ   P,GENVN                 ; GET VERSION # AS FIX
134         MOVE    E,DIR(P)
135         MOVE    D,NAM(P)
136         MOVE    A,B
137         PUSHJ   P,DIRSRC                ; SEARCH DIRECTORY
138          JRST   NTHERE                  ; GO TRY FIXING UP ITS NOT THERE
139         ANDI    A,-1                    ; WIN IN MULT SEG CASE
140         MOVE    B,OFF(P)                ; GET SLOT NUMBER
141         ADD     B,PURVEC+1              ; POINT TO SLOT
142         HRRZ    C,1(A)                  ; GET BLOCK NUMBER
143         HRRM    C,FB.PGS(B)             ; SMASH INTO SLOT
144         LDB     C,[LNTBYT,,1(A)]        ; SMASH IN LENGTH
145         HRLM    C,FB.PGS(B)             ; SMASH IN LENGTH
146         JRST    PLOADX
147
148 ; NOW TRY TO FIND FILE IN WORKING DIRECTORY
149
150 NTHERE: PUSHJ   P,KILBUF
151         MOVE    A,OFF(P)                        ; GET POINTER TO PURVEC SLOT
152         ADD     A,PURVEC+1
153         PUSHJ   P,GENVN                 ; GET VERSION NUMBER
154         HRRZM   B,VER(P)
155         PUSHJ   P,OPMFIL                ; OPEN FILE
156          JRST   FIXITU
157         
158 ; NUMBER OF PAGES ARE IN A
159 ; STARTING PAGE NUMBER IN SPAG(P)
160
161 PLOD1:  PUSHJ   P,ALOPAG        ; get the necessary pages
162          JRST    MAPLS2
163         MOVE    E,SPAG(P)       ; E starting page in file
164         MOVEM   B,PGNO(P)
165 IFN ITS,[
166         MOVN    A,FLEN(P)       ; get neg count
167         MOVSI   A,(A)           ; build aobjn pointer
168         HRR     A,PGNO(P)       ; get page to start
169         MOVE    B,A             ; save for later
170         HRRI    0,(E)           ; page pointer for file
171         DOTCAL  CORBLK,[[1000,,200000],[1000,,-1],A,[1000,,MAPCH],0]
172          .LOSE  %LSSYS
173         .CLOSE  MAPCH,          ; no need to have file open anymore
174 ]
175 IFE ITS,[
176         MOVEI   A,(E)           ; First page on rh of A
177         HRL     A,DIRCHN        ; JFN to lh of A
178         HRLI    B,.FHSLF        ; specify this fork
179         MOVSI   C,PM%RD+PM%EX   ; bits for read/execute
180         MOVE    D,FLEN(P)       ; # of pages to D
181         HRROI   E,(B)           ; build page aobjn for later
182         TLC     E,-1(D)         ; sexy way of doing lh
183
184         SKIPN   OPSYS
185          JRST   BLMAP           ; if tops-20 can block PMAP
186         PMAP
187         ADDI    A,1
188         ADDI    B,1
189         SOJG    D,.-3           ; map 'em all
190         MOVE    B,E
191         JRST    PLOAD1
192
193 BLMAP:  HRRI    C,(D)
194         TLO     C,PM%CNT        ; say it is counted
195         PMAP                    ; one PMAP does the trick
196         MOVE    B,E
197 ]
198 ; now try to smash slot in PURVEC
199
200 PLOAD1: MOVE    A,PURVEC+1 ; get pointer to it
201         ASH     B,PGSHFT        ; convert to aobjn pointer to words
202         MOVE    C,OFF(P)        ; get slot offset
203         ADDI    C,(A)           ; point to slot
204         MOVEM   B,FB.PTR(C)     ; clobber it in
205         TLZ     B,(FB.CNT)      ; isolate address of page
206         HRRZ    D,PURVEC        ; get offset into vector for start of chain
207         TRNE    D,EOC           ; skip if not end marker
208          JRST   SCHAIN
209         HRLI    D,400000+A      ; set up indexed pointer
210         ADDI    D,1
211 IFN ITS,        HRRZ    0,@D            ; get its address
212 IFE ITS,[
213         MOVE    0,@D
214         TLZ     0,(FB.CNT)
215 ]
216         JUMPE   0,SCHAIN        ; no chain exists, start one
217         CAMLE   0,B             ; skip if new one should be first
218          AOJA   D,INLOOP        ; jump into the loop
219
220         SUBI    D,1             ; undo ADDI
221 FCLOB:  MOVE    E,OFF(P)        ; get offset for this guy
222         HRRM    D,FB.AGE(C)             ; link up
223         HRRM    E,PURVEC        ; store him away
224         JRST    PLOADD
225
226 SCHAIN: MOVEI   D,EOC           ; get end of chain indicator
227         JRST    FCLOB           ; and clobber it in
228
229 INLOOP: MOVE    E,D             ; save in case of later link up
230         HRR     D,@D            ; point to next table entry
231         TRNE    D,EOC           ; 400000 is the end of chain bit
232          JRST   SLFOUN          ; found a slot, leave loop
233         ADDI    D,1             ; point to address of progs
234 IFN ITS,        HRRZ    0,@D    ; get address of block
235 IFE ITS,[
236         MOVE    0,@D
237         TLZ     0,(FB.CNT)
238 ]
239         CAMLE   0,B             ; skip if still haven't fit it in
240          AOJA   D,INLOOP        ; back to loop start and point to chain link
241         SUBI    D,1             ; point back to start of slot
242
243 SLFOUN: MOVE    0,OFF(P)                ; get offset into vector of this guy
244         HRRM    0,@E            ; make previous point to us
245         HRRM    D,FB.AGE(C)             ; link it in
246
247
248 PLOADD: AOS     -NSLOTS(P)              ; skip return
249         MOVE    B,FB.PTR(C)
250
251 MAPLOS: SUB     P,[NSLOTS,,NSLOTS]      ; flush stack crap
252         SUB     TP,C%22
253         POPJ    P,
254
255
256 MAPLS0: ERRUUO  EQUOTE NO-SAV-FILE
257         JRST    MAPLOS
258
259 MAPLS1: ERRUUO  EQUOTE NO-FIXUP-FILE
260         JRST    MAPLOS
261
262 MAPLS2: ERRUUO  EQUOTE NO-ROOM-AVAILABLE
263         JRST    MAPLOS
264
265 FIXITU:
266
267 ;OPEN FIXUP FILE ON MUDSAV
268
269 IFN ITS,[
270         .CALL   FIXBLK          ; OPEN UP FIXUP FILE
271         PUSHJ   P,TRAGN                 ; SEE IF TOTALLY LOSING
272 ]
273 IFE ITS,[
274         MOVSI   A,%GJSHT                ; GTJFN BITS
275         HRROI   B,FXSTR
276         SKIPE   OPSYS
277          HRROI  B,TFXSTR
278         GTJFN
279          FATAL  FIXUP FILE NOT FOUND
280         MOVEM   A,DIRCHN
281         MOVE    B,[440000,,OF%RD+OF%EX]
282         OPENF
283          FATAL  FIXUP FILE CANT BE OPENED
284 ]
285
286         MOVE    0,LASTC(P)              ; GET DIRECTORY
287         PUSHJ   P,GETDIR
288         MOVE    D,NAM(P)
289         PUSHJ   P,DIRSR1                ; SEARCH DIRECTORY FOR FIXUP
290          JRST   NOFXUP                  ; NO FIXUP IN MAIN DIRECTORY
291         ANDI    A,-1                    ; WIN IN MULTI SEGS
292         HRRZ    A,1(A)                  ; GET BLOCK NUMBER OF START
293         ASH     A,8.                    ; CONVERT TO WORDS
294 IFN ITS,[
295         .ACCES  MAPCH,A                 ; ACCESS FILE
296 ]
297
298 IFE ITS,[
299         MOVEI   B,(A)
300         MOVE    A,DIRCHN
301         SFPTR
302          JFCL
303 ]
304         PUSHJ   P,KILBUF
305 FIXT1:  PUSHJ   P,RFXUP                 ; READ IN THE FIXUP FILE
306
307 IFN ITS,[
308         .CALL   MNBLK                   ; REOPEN SAV FILE
309         PUSHJ   P,TRAGN
310 ]
311
312 IFE ITS,[
313         MOVE    A,MAPJFN                ; SET UP DIRCHAN AGAIN
314         MOVEM   A,DIRCHN
315 ]
316
317 ; NOW TRY TO LOCATE SAV FILE
318
319         MOVE    0,LASTC(P)              ; GET LASTCHR
320         PUSHJ   P,GETDIR                ; GET DIRECTORY
321         HRRZ    A,VER(P)                        ; GET VERSION #
322         MOVE    D,NAM(P)                ; GET NAME OF FILE
323         PUSHJ   P,DIRSRC                ; SEARCH DIRECTORY
324          JRST   MAPLS1                  ; NO SAV FILE THERE
325         ANDI    A,-1
326         HRRZ    E,1(A)                  ; GET STARTING BLOCK #
327         LDB     A,[LNTBYT,,1(A)]        ; GET LENGTH INTO A
328         MOVEM   A,FLEN(P)               ; SAVE LENGTH
329         MOVEM   E,SPAG(P)               ; SAVE STARTING BLOCK NUMBER
330         PUSHJ   P,KILBUF
331         PUSHJ   P,RSAV                  ; READ IN CODE
332 ; now to do fixups
333
334 FXUPGO: MOVE    A,(TP)          ; pointer to them
335         SETOM   INPLOD          ;  ABSOLUTE CLUDGE TO PREVENT BUFFER FROM
336                                 ;       SCREWING US
337 IFE ITS,[
338         SKIPN   MULTSG
339          JRST   FIXMLT
340         HRRZ    D,B             ; this codes gets us running in the correct
341                                 ;       segment
342         ASH     D,PGSHFT
343         HRRI    D,FIXMLT
344         MOVEI   C,0
345         XJRST   C               ; good bye cruel segment (will work if we fell
346                                 ;        into segment 0)
347 FIXMLT: ASH     B,PGSHFT        ; aobjn to program
348
349 FIX1:   SKIPL   E,(A)           ; read one hopefully squoze
350         FATAL   ATTEMPT TO TYPE FIX PURE
351         TLZ     E,740000
352
353 NOPV1:  PUSHJ   P,SQUTOA        ; look it up
354         FATAL   BAD FIXUPS
355
356 ; N.B. THE VALUE IN THE FIXUPS FOR AN ADDRESS CAN BE NEGATIVE. IF THIS HAPPENS
357 ; IT MEANS THAT THE LEFT HALF CONTAINS THE VALUE INSTEAD OF THE RIGHT HALF
358 NOPV2:  AOBJP   A,FIX2
359         HLRZ    D,(A)           ; get old value
360         HRRZS   E
361         SUBM    E,D             ; D is diff between old and new
362         HRLM    E,(A)           ; fixup the fixups
363 NOPV3:  MOVEI   0,0             ; flag for which half
364 FIX4:   JUMPE   0,FIXRH         ; jump if getting rh
365         MOVEI   0,0             ; next time will get rh
366         AOBJP   A,FIX2          ; done?
367         HLRE    C,(A)           ; get lh
368         JUMPE   C,FIX3          ; 0 terminates
369 FIX5:   SKIPGE  C               ; If C is negative then left half garbage
370          JRST   FIX6
371         ADDI    C,(B)           ; access the code
372
373 NOPV4:  ADDM    D,-1(C)         ; and fix it up
374         JRST    FIX4
375
376 ; FOR LEFT HALF CASE
377
378 FIX6:   MOVNS   C               ; GET TO ADRESS
379         ADDI    C,(B)           ; ACCESS TO CODE
380         HLRZ    E,-1(C)         ; GET OUT WORD
381         ADDM    D,E             ; FIX IT UP
382         HRLM    E,-1(C)
383         JRST    FIX4
384
385 FIXRH:  MOVEI   0,1             ; change flag
386         HRRE    C,(A)           ; get it and
387         JUMPN   C,FIX5
388
389 FIX3:   AOBJN   A,FIX1          ; do next one
390
391 IFN SPCFXU,[
392         MOVE    C,B
393         PUSHJ   P,SFIX
394 ]
395         PUSHJ   P,SQUKIL        ; KILL SQUOZE TABLE
396         SETZM   INPLOD
397 FIX2:
398         HRRZS   VER(P)          ; INDICATE SAV FILE
399         MOVEM   B,CADDR(P)
400         PUSHJ   P,GENVN
401         HRRM    B,VER(P)
402         PUSHJ   P,OPWFIL
403          FATAL  MAP FIXUP LOSSAGE
404 IFN ITS,[
405         MOVE    B,CADDR(P)
406         .IOT    MAPCH,B         ; write out the goodie
407         .CLOSE  MAPCH,
408         PUSHJ   P,OPMFIL
409          FATAL  WHERE DID THE FILE GO?
410         MOVE    E,CADDR(P)
411         ASH     E,-PGSHFT       ; to page AOBJN
412         DOTCAL  CORBLK,[[1000,,200000],[1000,,-1],E,[1000,,MAPCH],0]
413          .LOSE  %LSSYS
414         .CLOSE  MAPCH,
415 ]
416
417
418 IFE ITS,[
419         MOVE    A,DIRCHN        ; GET JFN
420         MOVE    B,CADDR(P)      ; ready to write it out
421         HRLI    B,444400
422         HLRE    C,CADDR(P)
423         SOUT                    ; zap it out
424         TLO     A,400000        ; dont recycle the JFN
425         CLOSF
426          JFCL
427         ANDI    A,-1            ; kill sign bit
428         MOVE    B,[440000,,240000]
429         OPENF
430          FATAL MAP FIXUP LOSSAGE
431         MOVE    B,CADDR(P)
432         ASH     B,-PGSHFT       ; aobjn to pages
433         HLRE    D,B             ; -count
434         HRLI    B,.FHSLF
435         MOVSI   A,(A)
436         MOVSI   C,PM%RD+PM%EX
437         PMAP
438         ADDI    A,1
439         ADDI    B,1
440         AOJN    D,.-3
441 ]
442
443         SKIPGE  MUDSTR+2
444          JRST   EFIX2           ; exp vers, dont write out
445 IFE ITS,[
446         HRRZ    A,SJFNS         ; get last jfn from savxxx file
447         JUMPE   A,.+4           ; oop
448          CAME   A,MAPJFN
449           CLOSF                 ; close it
450            JFCL
451         HLLZS   SJFNS           ; zero the slot
452 ]
453         MOVEI   0,1             ; INDICATE FIXUP
454         HRLM    0,VER(P)
455         PUSHJ   P,OPWFIL
456          FATAL  CANT WRITE FIXUPS
457
458 IFN ITS,[
459         MOVE    E,(TP)
460         HLRE    A,E             ; get length
461         MOVNS   A
462         ADDI    A,2             ; account for these 2 words
463         MOVE    0,[-2,,A]       ; write version and length
464         .IOT    MAPCH,0
465         .IOT    MAPCH,E         ; out go the fixups
466         SETZB   0,A
467         MOVEI   B,MAPCH
468         .CLOSE  MAPCH,
469 ]
470
471 IFE ITS,[       
472         MOVE    A,DIRCHN
473         HLRE    B,(TP)          ; length of fixup vector
474         MOVNS   B
475         ADDI    B,2             ; for length and version words
476         BOUT
477         PUSHJ   P,GENVN
478         BOUT
479         MOVSI   B,444400        ; byte pointer to fixups
480         HRR     B,(TP)
481         HLRE    C,(TP)
482         SOUT
483         CLOSF
484          JFCL
485 ]
486
487 EFIX2:  MOVE    B,CADDR(P)
488         ASH     B,-PGSHFT
489         JRST    PLOAD1
490
491 ; Here to try to get a free page block for new thing
492 ;       A/      # of pages to get
493
494 ALOPAG: MOVE    C,GCSTOP        ; FOOL GETPAG
495         ADDI    C,3777
496         ASH     C,-PGSHFT
497         MOVE    B,PURBOT
498 IFE ITS,[
499         SKIPN   MULTSG          ; skip if multi-segments
500          JRST   ALOPA1
501 ; Compute the "highest" PURBOT (i.e. find the least busy segment)
502
503         PUSH    P,E
504         PUSH    P,A
505         MOVN    A,NSEGS         ; aobjn pntr to table
506         HRLZS   A
507         MOVEI   B,0
508 ALOPA3: CAML    B,PURBTB(A)     ; if this one is larger
509          JRST   ALOPA2
510         MOVE    B,PURBTB(A)     ; use it
511         MOVEI   E,FSEG(A)       ; and the segment #
512 ALOPA2: AOBJN   A,ALOPA3
513         POP     P,A
514 ]
515
516 ALOPA1: ASH     B,-PGSHFT
517         SUBM    B,C             ; SEE IF ROOM
518         CAIL    C,(A)
519          JRST   ALOPGW
520         PUSHJ   P,GETPAX        ; try to get enough pages
521 IFE ITS,         JRST   EPOPJ
522 IFN ITS,         POPJ   P,
523
524 ALOPGW:
525 IFN ITS,        AOS     (P)             ; won skip return
526 IFE ITS,[
527         SKIPE   MULTSG
528          AOS    -1(P)                   ; ret addr
529         SKIPN   MULTSG
530          AOS    (P)
531 ]
532         MOVE    0,PURBOT
533 IFE ITS,[
534         SKIPE   MULTSG
535          MOVE   0,PURBTB-FSEG(E)
536 ]
537         ASH     0,-PGSHFT
538         SUBI    0,(A)
539         MOVE    B,0
540 IFE ITS,[
541         SKIPN   MULTSG
542          JRST   ALOPW1
543         ASH     0,PGSHFT
544         HRRZM   0,PURBTB-FSEG(E)
545         ASH     E,PGSHFT                ; INTO POSITION
546         IORI    B,(E)           ; include segment in address
547         POP     P,E
548         JRST    ALOPW2
549 ]
550 ALOPW1: ASH     0,PGSHFT
551 ALOPW2: CAMGE   0,PURBOT
552          MOVEM  0,PURBOT
553         CAML    0,P.TOP
554          POPJ   P,
555 IFE ITS,[
556         SUBI    0,1777
557         ANDCMI  0,1777
558 ]
559         MOVEM   0,P.TOP
560         POPJ    P,
561
562 EPOPJ:  SKIPE   MULTSG
563          POP    P,E
564         POPJ    P,
565 IFE ITS,[
566 GETPAX: TDZA    B,B             ; here if other segs ok
567 GETPAG: MOVEI   B,1             ; here for only main segment
568         JRST    @[.+1]          ; run in sect 0
569         MOVNI   E,1
570 ]
571 IFN ITS,[
572 GETPAX:
573 GETPAG:
574 ]
575         MOVE    C,P.TOP         ; top of GC space
576         ASH     C,-PGSHFT       ; to page number
577 IFE ITS,[
578         SKIPN   MULTSG
579          JRST   GETPA9
580         JUMPN   B,GETPA9        ; if really wan all segments,
581                                 ;       must force all to be  free
582         PUSH    P,A
583         MOVN    A,NSEGS         ; aobjn pntr to table
584         HRLZS   A
585         MOVE    B,P.TOP
586 GETPA8: CAMLE   B,PURBTB(A)     ; if this one is larger (or the same)
587          JRST   GETPA7
588         MOVE    B,PURBTB(A)     ; use it
589         MOVEI   E,FSEG(A)       ; and the segment #
590 GETPA7: AOBJN   A,GETPA8
591         POP     P,A
592         JRST    .+2
593 ]
594 GETPA9: MOVE    B,PURBOT
595         ASH     B,-PGSHFT       ; also to pages
596         SUBM    B,C             ; pages available ==> C
597         CAMGE   C,A             ; skip if have enough already
598          JRST   GETPG1          ; no, try to shuffle around
599         SUBI    B,(A)           ; B/  first new page
600 CPOPJ1: AOS     (P)
601 IFN ITS,        POPJ    P,
602 IFE ITS,[
603 SPOPJ:  SKIPN   MULTSG
604          POPJ   P,              ; return with new free page in B
605                                 ;       (and seg# in E?)
606         POP     P,21
607         SETZM   20
608         XJRST   20
609 ]
610 ; Here if shuffle must occur or gc must be done to make room
611
612 GETPG1: MOVEI   0,0
613         SKIPE   NOSHUF          ; if can't shuffle, then ask gc
614          JRST   ASKAGC
615         MOVE    0,PURTOP        ; get top of mapped pure area
616         SUB     0,P.TOP
617         ASH     0,-PGSHFT       ; to pages
618         CAMGE   0,A             ; skip if winnage possible
619          JRST   ASKAGC          ; please AGC give me some room!!
620         SUBM    A,C             ; C/ amount we must flush to make room
621
622 IFE ITS,[
623         SKIPE   MULTSG          ; if  multi and getting in all segs
624          JUMPL  E,LPGL1         ; check out each and every segment
625
626         PUSHJ   P,GL1
627
628         SKIPE   MULTSG
629          PUSHJ  P,PURTBU        ; update PURBOT in multi case
630
631         JRST    GETPAX
632
633 LPGL1:  PUSH    P,A
634         PUSH    P,[FSEG-1]
635
636 LPGL2:  AOS     E,(P)           ; count segments
637         MOVE    B,NSEGS
638         ADDI    B,FSEG
639         CAML    E,B
640          JRST   LPGL3
641         PUSH    P,C
642         MOVE    C,PURBOT        ; fudge so look for appropriate amt
643         SUB     C,PURBTB-FSEG(E)
644         ASH     C,-PGSHFT       ; to pages
645         ADD     C,(P)
646         SKIPLE  C               ; none to flush
647         PUSHJ   P,GL1
648         HRRZ    E,-1(P)         ; fet section again
649         HRRZ    B,PURBOT
650         HRRZ    C,PURBTB-FSEG(E)        ; lets share with 0 again
651         SUB     C,B
652         HRL     B,E             ; get segment
653         MOVEI   A,(B)
654         ASH     B,-PGSHFT
655         ASH     A,-PGSHFT
656         HRLI    A,.FHSLF
657         HRLI    B,.FHSLF
658         ASH     C,-PGSHFT
659         HRLI    C,PM%CNT+PM%RD+PM%WR+PM%EX
660         PMAP
661 LPGL4:  POP     P,C
662         JRST    LPGL2
663
664 LPGL3:  SUB     P,C%11
665         POP     P,A
666
667         SKIPE   MULTSG
668          PUSHJ  P,PURTBU        ; update PURBOT in multi case
669
670         JRST    GETPAG
671 ]
672 ; Here to find pages for flush using LRU algorithm (in multi seg mode, only
673 ;               care about the segment in E)
674
675 GL1:    MOVE    B,PURVEC+1      ; get pointer to pure sr vector
676         MOVEI   0,-1            ; get very large age
677
678 GL2:    SKIPL   FB.PTR(B)       ; skip if not already flushed
679          JRST   GL3
680 IFE ITS,[
681         SKIPN   MULTSG
682          JRST   GLX
683         LDB     D,[220500,,FB.PTR(B)]   ; get segment #
684         CAIE    D,(E)
685          JRST   GL3             ; wrong swegment, ignore
686 ]
687 GLX:    HLRZ    D,FB.AGE(B)     ; get this ones age
688         CAMLE   D,0             ; skip if this is a candidate
689          JRST   GL3
690         MOVE    F,B             ; point to table entry with E
691         MOVEI   0,(D)           ; and use as current best
692 GL3:    ADD     B,[ELN,,ELN]    ; look at next
693         JUMPL   B,GL2
694
695         HLRE    B,FB.PTR(F)     ; get length of flushee
696         ASH     B,-PGSHFT       ; to negative # of pages
697         ADD     C,B             ; update amount needed
698 IFN ITS,SETZM   FB.PTR(F)       ; indicate it will be gone
699 IFE ITS,MOVNS   FB.PTR(F)       ; save page info for flushing pages
700         JUMPG   C,GL1           ; jump if more to get
701
702 ; Now compact pure space
703
704         PUSH    P,A             ; need all acs
705         HRRZ    D,PURVEC        ; point to first in core addr order
706         HRRZ    C,PURTOP        
707 IFE ITS,[
708         SKIPE   MULTSG
709          HRLI   C,(E)           ; adjust for segment
710 ]
711         ASH     C,-PGSHFT       ; to page number
712         SETZB   F,A
713
714 CL1:    ADD     D,PURVEC+1      ; to real pointer
715         SKIPGE  FB.PTR(D)       ; skip if this one is a flushee
716          JRST   CL2             ; this one stays
717
718 IFE ITS,[
719         PUSH    P,C
720         PUSH    P,D
721         HRRZ    C,FB.PGS(D)     ; is this from SAV FILE?
722         JUMPN   C,CLFOUT        ; yes.  don't bother flushing pages
723         MOVN    C,FB.PTR(D)     ; get aobjn pointer to code in C
724         SETZM   FB.PTR(D)       ; and flush this because it works (sorry)
725         ASH     C,-PGSHFT       ; pages speak louder than words
726         HLRE    D,C             ; # of pages saved here for unmap
727         HRLI    C,.FHSLF        ; C now contains myfork,,lowpage
728         MOVE    A,C             ; put that in A for RMAP
729         RMAP                    ; A now contains JFN in left half
730         MOVE    B,C             ; ac roulette: get fork,,page into B for PMAP
731         HLRZ    C,A             ; hold JFN in C for future CLOSF
732         MOVNI   A,1             ; say this page to be unmapped
733 CLFLP:  PMAP                    ; do the unmapping
734         ADDI    B,1             ; next page
735         AOJL    D,CLFLP         ; continue for all pages
736         MOVE    A,C             ; restore JFN
737         CLOSF                   ; and close it, throwing away the JFN
738          JFCL                   ; should work in 95/100 cases
739 CLFOU1: POP     P,D             ; fatal error if can't close
740         POP     P,C
741 ]
742         HRRZ    D,FB.AGE(D)     ; point to next one in chain
743         JUMPN   F,CL3           ; jump if not first one
744         HRRM    D,PURVEC        ; and use its next as first
745         JRST    CL4
746
747 IFE ITS,[
748 CLFOUT: SETZM   FB.PTR(D)       ; zero the code pointer
749         JRST    CLFOU1
750 ]
751
752 CL3:    HRRM    D,FB.AGE(F)     ; link up
753         JRST    CL4
754
755 ; Found a stayer, move it if necessary
756
757 CL2:
758 IFE ITS,[
759         SKIPN   MULTSG
760          JRST   CL9
761         LDB     F,[220500,,FB.PTR(D)]   ; check segment
762         CAIE    E,(F)
763          JRST   CL6X            ; no other segs move at all
764 ]
765 CL9:    MOVEI   F,(D)           ; another pointer to slot
766         HLRE    B,FB.PTR(D)     ; - length of block
767 IFE ITS,[
768         TRZ     B,<-1>#<(FB.CNT)>
769         MOVE    D,FB.PTR(D)     ; pointer to block
770         TLZ     D,(FB.CNT)      ; kill count bits
771 ]
772 IFN ITS,        HRRZ    D,FB.PTR(D)     
773         SUB     D,B             ; point to top of block
774         ASH     D,-PGSHFT       ; to page number
775         CAMN    D,C             ; if not moving, jump
776          JRST   CL6
777
778         ASH     B,-PGSHFT       ; to pages
779 IFN ITS,[
780 CL5:    SUBI    C,1             ; move to pointer and from pointer
781         SUBI    D,1
782         DOTCAL  CORBLK,[[1000,,200000],[1000,,-1],C,[1000,,-1],D]
783          .LOSE  %LSSYS
784         AOJL    B,CL5           ; count down
785 ]
786 IFE ITS,[
787         PUSH    P,B             ; save # of pages
788         MOVEI   A,-1(D)         ; copy from pointer
789         HRLI    A,.FHSLF        ; get this fork code
790         RMAP                    ; get a JFN (hopefully)
791         EXCH    D,(P)           ; D # of pages (save from)
792         ADDM    D,(P)           ; update from
793         MOVEI   B,-1(C)         ; to pointer in B
794         HRLI    B,.FHSLF
795         MOVSI   C,PM%RD+PM%EX   ; read/execute modes
796
797         SKIPN   OPSYS
798          JRST   CCL1
799         PMAP                    ; move a page
800         SUBI    A,1
801         SUBI    B,1
802         AOJL    D,.-3           ; move them all
803         AOJA    B,CCL2
804
805 CCL1:   TLO     C,PM%CNT
806         MOVNS   D
807         SUBI    B,-1(D)
808         SUBI    A,-1(D)
809         HRRI    C,(D)
810         PMAP
811
812 CCL2:   MOVEI   C,(B)
813         POP     P,D
814 ]
815 ; Update the table address for this loser
816
817         SUBM    C,D             ; compute offset (in pages)
818         ASH     D,PGSHFT        ; to words
819         ADDM    D,FB.PTR(F)     ; update it
820 CL7:    HRRZ    D,FB.AGE(F)     ; chain on
821 CL4:    TRNN    D,EOC           ; skip if end of chain
822          JRST   CL1
823
824         ASH     C,PGSHFT        ; to words
825 IFN ITS,        MOVEM   C,PURBOT        ; reset pur bottom
826 IFE ITS,[
827         SKIPN   MULTSG
828          JRST   CLXX
829
830         HRRZM   C,PURBTB-FSEG(E)
831         CAIA
832 CLXX:   MOVEM   C,PURBOT        ; reset pur bottom
833 ]
834         POP     P,A
835         POPJ    P,
836
837 IFE ITS,[
838 CL6X:   MOVEI   F,(D)           ; chain on
839         JRST    CL7
840 ]
841 CL6:    
842 IFN ITS,        HRRZ    C,FB.PTR(F)     ; get new top of world
843 IFE ITS,[
844         MOVE    C,FB.PTR(F)
845         TLZ     C,(FB.CNT)
846 ]
847         ASH     C,-PGSHFT       ; to page #
848         JRST    CL7
849
850 IFE ITS,[
851 PURTBU: PUSH    P,A
852         PUSH    P,B
853
854         MOVN    B,NSEGS
855         HRLZS   B
856         MOVE    A,PURTOP
857
858 PURTB2: CAMGE   A,PURBTB(B)
859          JRST   PURTB1
860         MOVE    A,PURBTB(B)
861         MOVEM   A,PURBOT
862 PURTB1: AOBJN   B,PURTB2
863
864         POP     P,B
865         POP     P,A
866         POPJ    P,
867 ]
868
869 \f; SUBR to create an entry in the vector for one of these guys
870
871 MFUNCTION PCODE,SUBR
872
873         ENTRY   2
874
875         GETYP   0,(AB)          ; check 1st arg is string
876         CAIE    0,TCHSTR
877          JRST   WTYP1
878         GETYP   0,2(AB)         ; second must be fix
879         CAIE    0,TFIX
880          JRST   WTYP2
881
882         MOVE    A,(AB)          ; convert name of program to sixbit
883         MOVE    B,1(AB)
884         PUSHJ   P,STRTO6
885 PCODE4: MOVE    C,(P)           ; get name in sixbit
886
887 ; Now look for either this one or an empty slot
888
889         MOVEI   E,0
890         MOVE    B,PURVEC+1
891
892 PCODE2: CAMN    C,FB.NAM(B)     ; skip if this is not it
893          JRST   PCODE1          ; found it, drop out of loop
894         JUMPN   E,.+3           ; dont record another empty if have one
895         SKIPN   FB.NAM(B)               ; skip if slot filled
896          MOVE   E,B             ; remember pointer
897         ADD     B,[ELN,,ELN]
898         JUMPL   B,PCODE2        ; jump if more to look at
899
900         JUMPE   E,PCODE3        ; if E=0, error no room
901         MOVEM   C,FB.NAM(E)     ; else stash away name and zero rest
902         SETZM   FB.PTR(E)
903         SETZM   FB.AGE(E)
904         CAIA
905 PCODE1:  MOVE   E,B             ; build <slot #>,,<offset>
906         MOVEI   0,0             ; flag whether new slot
907         SKIPE   FB.PTR(E)       ; skip if mapped already
908          MOVEI  0,1
909         MOVE    B,3(AB)
910         HLRE    D,E
911         HLRE    E,PURVEC+1
912         SUB     D,E
913         HRLI    B,(D)
914         MOVSI   A,TPCODE
915         SKIPN   NOSHUF          ; skip if not shuffling
916          JRST   FINIS
917         JUMPN   0,FINIS         ; jump if winner
918         PUSH    TP,A
919         PUSH    TP,B
920         HLRZ    A,B
921         PUSHJ   P,PLOAD
922          JRST   PCOERR
923         POP     TP,B
924         POP     TP,A
925         JRST    FINIS
926
927 PCOERR: ERRUUO  EQUOTE PURE-LOAD-FAILURE
928
929 PCODE3: HLRE    A,PURVEC+1      ; get current length
930         MOVNS   A
931         ADDI    A,10*ELN        ; add 10(8) more entry slots
932         PUSHJ   P,IBLOCK
933         EXCH    B,PURVEC+1      ; store new one and get old
934         HLRE    A,B             ; -old length to A
935         MOVSI   B,(B)           ; start making BLT pointer
936         HRR     B,PURVEC+1
937         SUBM    B,A             ; final dest to A
938 IFE ITS,        HRLI    A,-1            ; force local index
939         BLT     B,-1(A)
940         JRST    PCODE4
941
942 ; Here if must try to GC for some more core
943
944 ASKAGC: SKIPE   GCFLG           ; if already in GC, lose
945 IFN ITS,         POPJ   P,
946 IFE ITS,         JRST   SPOPJ
947         MOVEM   A,0             ; amount required to 0
948         ASH     0,PGSHFT        ; TO WORDS
949         MOVEM   0,GCDOWN        ; pass as funny arg to AGC
950         EXCH    A,C             ; save A from gc's destruction
951 IFN ITS,.IOPUSH MAPCH,          ; gc uses same channel
952         PUSH    P,C
953         SETOM   PLODR
954         MOVE    C,[8,,9.]       ; SET UP INDICATORS FOR GC
955         PUSHJ   P,AGC
956         SETZM   PLODR
957         POP     P,C
958 IFN ITS,.IOPOP  MAPCH,
959         EXCH    C,A
960 IFE ITS,[
961         JUMPL   C,.+3
962         JUMPL   E,GETPAG
963         JRST    GETPAX
964 ]
965 IFN ITS,        JUMPGE  C,GETPAG
966          ERRUUO EQUOTE NO-MORE-PAGES
967
968 ; Here to clean up pure space by flushing all shared stuff
969
970 PURCLN: SKIPE   NOSHUF
971          POPJ   P,
972         MOVEI   B,EOC
973         HRRM    B,PURVEC        ; flush chain pointer
974         MOVE    D,PURVEC+1      ; get pointer to table
975 CLN1:
976 IFE ITS,[
977         SKIPN   A,FB.PTR(D)
978          JRST   NOCL
979         ASH     A,-PGSHFT
980         HRLI    A,.FHSLF
981         RMAP
982         HLRZS   A
983         CLOSF
984         JFCL
985 ]
986 NOCL:   SETZM   FB.PTR(D)       ; zero pointer entry
987         SETZM   FB.AGE(D)       ; zero link and age slots
988         SETZM   FB.PGS(D)
989         ADD     D,[ELN,,ELN]    ; go to next slot
990         JUMPL   D,CLN1          ; do til exhausted
991         MOVE    B,PURBOT        ; now return pages
992         SUB     B,PURTOP        ; compute page AOBJN pointer
993 IFE ITS,        SETZM   MAPJFN          ; make sure zero mapjfn
994         JUMPE   B,CPOPJ         ; no pure pages?
995         MOVSI   B,(B)
996         HRR     B,PURBOT
997         ASH     B,-PGSHFT
998 IFN ITS,[
999         DOTCAL  CORBLK,[[1000,,0],[1000,,-1],B]
1000          .LOSE  %LSSYS
1001 ]
1002 IFE ITS,[
1003
1004         SKIPE   MULTSG
1005          JRST   CLN2
1006         HLRE    D,B             ; - # of pges to flush
1007         HRLI    B,.FHSLF        ; specify hacking hom fork
1008         MOVNI   A,1
1009         MOVEI   C,0
1010
1011         PMAP
1012         ADDI    B,1
1013         AOJL    D,.-2
1014 ]
1015
1016         MOVE    B,PURTOP        ; now fix up pointers
1017         MOVEM   B,PURBOT        ;   to indicate no pure
1018 CPOPJ:  POPJ    P,
1019
1020 IFE ITS,[
1021 CLN2:   HLRE    C,B             ; compute pos no. pages
1022         HRLI    B,.FHSLF
1023         MOVNS   C
1024         MOVNI   A,1             ; flushing pages
1025         HRLI    C,PM%CNT
1026         MOVE    D,NSEGS
1027         MOVE    E,PURTOP        ; for munging table
1028         ADDI    B,<FSEG>_9.     ; do it to the correct segment
1029         PMAP
1030         ADDI    B,1_9.          ; cycle through segments
1031         HRRZM   E,PURBTB(D)     ; mung table
1032         SOJG    D,.-3
1033
1034         MOVEM   E,PURBOT
1035         POPJ    P,
1036 ]
1037
1038 ; Here to move the entire pure space.
1039 ;       A/      # and direction of pages to move (+ ==> up)
1040
1041 MOVPUR: SKIPE   NOSHUF
1042          FATAL  CANT MOVE PURE SPACE AROUND
1043 IFE ITS,ASH     A,1
1044         SKIPN   B,A             ; zero movement, ignore call
1045          POPJ   P,
1046
1047         ASH     B,PGSHFT        ; convert to words for pointer update
1048         MOVE    C,PURVEC+1      ; loop through updating non-zero entries
1049         SKIPE   1(C)
1050          ADDM   B,1(C)
1051         ADD     C,[ELN,,ELN]
1052         JUMPL   C,.-3
1053
1054         MOVE    C,PURTOP        ; found pages at top and bottom of pure
1055         ASH     C,-PGSHFT
1056         MOVE    D,PURBOT
1057         ASH     D,-PGSHFT
1058         ADDM    B,PURTOP        ; update to new boundaries
1059         ADDM    B,PURBOT
1060 IFE ITS,[
1061         SKIPN   MULTSG          ; in multi-seg mode, must mung whole table
1062          JRST   MOVPU1
1063         MOVN    E,NSEGS
1064         HRLZS   E
1065         ADDM    PURBTB(E)
1066         AOBJN   E,.-1
1067 ]
1068 MOVPU1: CAIN    C,(D)           ; differ?
1069          POPJ   P,
1070         JUMPG   A,PUP           ; if moving up, go do separate CORBLKs
1071
1072 IFN ITS,[
1073         SUBM    D,C             ; -size of area to C (in pages)
1074         MOVEI   E,(D)           ; build pointer to bottom of destination
1075         ADD     E,A
1076         HRLI    E,(C)
1077         HRLI    D,(C)
1078         DOTCAL  CORBLK,[[1000,,200000],[1000,,-1],E,[1000,,-1],D]
1079          .LOSE  %LSSYS
1080         POPJ    P,
1081
1082 PUP:    SUBM    C,D             ; pages to move to D
1083         ADDI    A,(C)           ; point to new top
1084
1085 PUPL:   SUBI    C,1
1086         SUBI    A,1
1087         DOTCAL  CORBLK,[[1000,,200000],[1000,,-1],A,[1000,,-1],C]
1088          .LOSE  %LSSYS
1089         SOJG    D,PUPL
1090         POPJ    P,
1091 ]
1092 IFE ITS,[
1093         SUBM    D,C             ; pages to move to D
1094         MOVSI   E,(C)           ; build aobjn pointer
1095         HRRI    E,(D)           ; point to lowest
1096         ADD     D,A             ; D==> new lowest page
1097         MOVEI   F,0             ; seg info 
1098         SKIPN   MULTSG
1099          JRST   XPLS3
1100         MOVEI   F,FSEG-1
1101         ADD     F,NSEGS
1102         ASH     F,9.
1103 XPLS3:  MOVE    G,E
1104         MOVE    H,D             ; save for outer loop
1105
1106 PURCL1: MOVSI   A,.FHSLF                ; specify here
1107         HRRI    A,(E)           ; get a page
1108         IORI    A,(F)           ; hack seg i
1109         RMAP                    ; get a real handle on it
1110         MOVE    B,D             ; where to go
1111         HRLI    B,.FHSLF
1112         MOVSI   C,PM%RD+PM%EX
1113         IORI    A,(F)
1114         PMAP
1115         ADDI    D,1
1116         AOBJN   E,PURCL1
1117         SKIPN   MULTSG
1118          POPJ   P,
1119         SUBI    F,1_9.
1120         CAIGE   F,FSEG_9.
1121          POPJ   P,
1122         MOVE    E,G
1123         MOVE    D,H
1124         JRST    PURCL1
1125
1126 PUP:    SUB     D,C             ; - count to D
1127         MOVSI   E,(D)           ; start building AOBJN
1128         HRRI    E,(C)           ; aobjn to top
1129         ADD     C,A             ; C==> new top
1130         MOVE    D,C
1131         MOVEI   F,0             ; seg info 
1132         SKIPN   MULTSG
1133          JRST   XPLS31
1134         MOVEI   F,FSEG
1135         ADD     F,NSEGS
1136         ASH     F,9.
1137 XPLS31: MOVE    G,E
1138         MOVE    H,D             ; save for outer loop
1139
1140 PUPL:   MOVSI   A,.FHSLF
1141         HRRI    A,(E)
1142         IORI    A,(F)           ; segment
1143         RMAP                    ; get real handle
1144         MOVE    B,D
1145         HRLI    B,.FHSLF
1146         IORI    B,(F)
1147         MOVSI   C,PM%RD+PM%EX
1148         PMAP
1149         SUBI    E,2
1150         SUBI    D,1
1151         AOBJN   E,PUPL
1152         SKIPN   MULTSG
1153          POPJ   P,
1154         SUBI    F,1_9.
1155         CAIGE   F,FSEG_9.
1156          POPJ   P,
1157         MOVE    E,G
1158         MOVE    D,H
1159         JRST    PUPL
1160
1161         POPJ    P,
1162 ]
1163 IFN ITS,[
1164 .GLOBAL CSIXBT
1165 CSIXBT: MOVEI   0,5
1166         PUSH    P,[440700,,C]
1167         PUSH    P,[440600,,D]
1168         MOVEI   D,0
1169 CSXB2:  ILDB    E,-1(P)
1170         CAIN    E,177
1171         JRST    CSXB1
1172         SUBI    E,40
1173         IDPB    E,(P)
1174         SOJG    0,CSXB2
1175 CSXB1:  SUB     P,C%22
1176         MOVE    C,D
1177         POPJ    P,
1178 ]
1179 GENVN:  MOVE    C,[440700,,MUDSTR+2]
1180         MOVEI   D,5
1181         MOVEI   B,0
1182 VNGEN:  ILDB    0,C
1183         CAIN    0,177
1184          POPJ   P,
1185         IMULI   B,10.
1186         SUBI    0,60
1187         ADD     B,0
1188         SOJG    D,VNGEN
1189         POPJ    P,
1190
1191 IFE ITS,[
1192 MSKS:   774000,,0
1193         777760,,0
1194         777777,,700000
1195         777777,,777400
1196         777777,,777776
1197 ]
1198
1199 \f; THESE ARE DIRECTORY SEARCH ROUTINES
1200
1201
1202 ; THIS ROUTINE DOES A BINARY SEARCH ON A DIRECTORY AND RETURNS A POINTER
1203 ; RESTED DOWN TO THE APPROPRIATE SLOT IN THE DIRECTORY.
1204 ; ARGS: E==DIR POINTER D==FILE-NAME 1 A==VERSION #
1205 ; RETS: A==RESTED DOWN DIRECTORY
1206
1207 DIRSR1: TLOA    0,400000                ; INDICATION OF ONE ARGUMENT SEARCH
1208 DIRSRC:  TLZ    0,400000                ; INDICATOR OF 2 ARGUMENT SEARCH
1209         PUSH    P,A                     ; SAVE VERSION #
1210         HLRE    B,E                     ; GET LENGTH INTO B
1211         MOVNS   B
1212         MOVE    A,E
1213         HRLS    B                       ; GET BOTH SIDES
1214 UP:     ASH     B,-1                    ; HALVE TABLE
1215         AND     B,[-2,,-2]              ; FORCE DIVIS BY 2
1216         MOVE    C,A                     ; COPY POINTER
1217         JUMPLE  B,LSTHLV                ; CANT GET SMALLER
1218         ADD     C,B
1219 IFE ITS,        HRRZ    F,C             ; avoid lossage in multi-sections
1220 IFN ITS,        CAMLE   D,(C)           ; SKIP IF EITHER FOUND OR IN TOP
1221 IFE ITS,        CAMLE   D,(F)           ; SKIP IF EITHER FOUND OR IN TOP
1222          MOVE    A,C                    ; POINT TO SECOND HALF
1223 IFN ITS,        CAMN    D,(C)           ; SKIP IF NOT FOUND
1224 IFE ITS,        CAMN    D,(F)           ; SKIP IF NOT FOUND
1225          JRST    WON
1226 IFN ITS,        CAML    D,(C)           ; SKIP IF IN TOP HALF
1227 IFE ITS,        CAML    D,(F)           ; SKIP IF IN TOP HALF
1228          JRST    UP
1229         HLLZS   C                       ; FIX UP POINTER
1230         SUB     A,C
1231         JRST    UP
1232
1233 WON:    JUMPL   0,SUPWIN
1234         MOVEI   0,0                     ; DOWN FLAG
1235 WON1:   LDB     A,[221200,,1(C)]        ; GET VERSION NUMBER
1236         CAMN    A,(P)                   ; SKIP IF NOT EQUAL
1237          JRST   SUPWIN
1238         CAMG    A,(P)                   ; SKIP IF LT
1239          JRST   SUBIT
1240         SETO    0,
1241         SUB     C,C%22                  ; GET NEW C
1242         JRST    SUBIT1
1243
1244 SUBIT:  ADD     C,C%22                  ; SUBTRACT
1245         JUMPN   0,C1POPJ
1246 SUBIT1:
1247 IFN ITS,        CAMN    D,(C)           ; SEE WHETHER WERE STILL WINNING
1248 IFE ITS,[
1249         HRRZ    F,C
1250         CAMN    D,(F)
1251 ]
1252          JRST   WON1
1253 C1POPJ: SUB     P,C%11                  ; GET RID OF VERSION #
1254         POPJ    P,                      ; LOSE LOSE LOSE
1255 SUPWIN: MOVE    A,C                     ; RETURN ARGUMENT IN A  
1256         AOS     -1(P)                   ; SKIP RETURN INDICATES IT WAS FOUND
1257         JRST    C1POPJ
1258
1259 LSTHLV:
1260 IFN ITS,        CAMN    D,(C)           ; LINEAR SEARCH REST
1261 IFE ITS,[
1262         HRRZ    F,C
1263         CAMN    D,(F)           ; LINEAR SEARCH REST
1264 ]
1265          JRST    WON
1266         ADD     C,C%22
1267         JUMPL   C,LSTHLV
1268         JRST    C1POPJ
1269
1270 \f; ROUTINE TO GET A DIRECTORY. ASSUMES MAPCH IS OPEN TO FIXUP OR SAV FILE AND 0 IS THE
1271 ; LAST CHAR TO BE HASHED. RETURNS POINTER TO DIRECTORY IN E
1272
1273 IFN ITS,[
1274 GETDIR: PUSH    P,C
1275         PUSH    P,0
1276         PUSHJ   P,SQKIL
1277         MOVEI   A,1                     ; GET A BUFFER
1278         PUSHJ   P,GETBUF
1279         MOVEI   C,(B)
1280         ASH     C,-10.
1281         DOTCAL  CORBLK,[[RDTP],[FME],C,[1000,,MAPCH],[1000,,0]]
1282         PUSHJ   P,SLEEPR
1283         POP     P,0
1284         IDIV    0,(B)                   ; A NOW CONTAINS THE DIRECTORY NUMBER
1285         ADDI    A,1(B)
1286         DOTCAL  CORBLK,[[RDTP],[FME],C,[1000,,MAPCH],(A)]
1287         PUSHJ   P,SLEEPR
1288         MOVN    E,(B)                   ; GET -LENGTH OF DIRECTORY
1289         HRLZS   E                       ; BUILD AOBJN PTR TO DIR
1290         HRRI    E,1(B)
1291         POP     P,C
1292         POPJ    P,
1293 ]
1294 ; IN WONDERFUL TOPS20 VERSION DIRCHN CONTAINS THE JFN
1295
1296 IFE ITS,[
1297 GETDIR: JRST    @[.+1]
1298         PUSH    P,C
1299         PUSH    P,0
1300         PUSHJ   P,SQKIL
1301         MOVEI   A,1                     ; GET A BUFFER
1302         PUSHJ   P,GETBUF
1303         HRROI   E,(B)
1304         ASH     B,-9.
1305         HRLI    B,.FHSLF                        ; SET UP DESTINATION (CORE)
1306         MOVS    A,DIRCHN                ; SET UP SOURCE (FILE)
1307         MOVSI   C,PM%RD+PM%EX           ; READ+EXEC ACCESS
1308         PMAP
1309         POP     P,0
1310         IDIV    0,(E)                   ; A NOW CONTAINS THE DIRECTORY NUMBER
1311         ADDI    A,1(E)                  ; POINT TO THE DIRECTORY ENTRY
1312         MOVE    A,(A)                   ; GET THE PAGE NUMBER
1313         HRL     A,DIRCHN                ; SET UP SOURCE (FILE)
1314         PMAP                            ; AGAIN READ IN DIRECTORY
1315         MOVEI   A,(E)
1316         MOVN    E,(E)                   ; GET -LENGTH OF DIRECTORY
1317         HRLZS   E                       ; BUILD AOBJN PTR TO DIR
1318         HRRI    E,1(A)
1319         POP     P,C
1320         SKIPN   MULTSG
1321          POPJ   P,
1322         POP     P,21
1323         SETZM   20
1324         XJRST   20
1325 ]
1326 ; HERE IF CAN'T FIND FIXUP FILE IN MAIN DIRECTORY
1327
1328 NOFXUP: 
1329 IFE ITS,[
1330         MOVE    A,DIRCHN                ; JFN FOR FIXUP FILE
1331         CLOSF                           ; CLOSE IT
1332          JFCL
1333 ]
1334         MOVE    A,FXTBL                 ; GET AOBJN POINTER TO FIXUP TABLE
1335 NOFXU1: HRRZ    B,(A)                   ; GET VERSION TO TRY
1336         HRRM    B,VER(P)                ; STUFF IN VERSION
1337         MOVEI   B,1                     ; DUMP IN FIXUP INDICATOR
1338         HRLM    B,VER(P)
1339         MOVEM   A,TEMP(P)               ; SAVE POINTER TO FXTBL
1340         PUSHJ   P,OPXFIL                ; LOOK FOR FIXUP FILE   
1341          JRST   NOFXU2
1342         PUSHJ   P,RFXUP                 ; READ IN THE FIXUP FILE
1343         HRRZS   VER(P)                  ; INDICATE SAV FILE
1344         PUSHJ   P,OPXFIL                ; TRY OPENING IT
1345          JRST   MAPLS0                  ; GIVE UP NO SAV FILE TO BE HAD
1346         PUSHJ   P,RSAV
1347         JRST    FXUPGO                  ; GO FIXUP THE WORLD
1348 NOFXU2: MOVE    A,TEMP(P)               ; GET BACK POINTER
1349         AOBJN   A,NOFXU1                ; TRY NEXT
1350         JRST    MAPLS1                  ; NO FILE TO BE HAD
1351
1352 GETIT:  HRRZM   B,SPAG(P)               ; GET BLOCK OF START
1353         HLRZM   B,FLEN(P)               ; DAMMIT SAVE THIS!
1354         HLRZ    A,B                     ; GET LENGTH\r
1355 IFN ITS,[
1356         .CALL   MNBLK
1357         PUSHJ   P,TRAGN
1358 ]
1359 IFE ITS,[
1360         MOVE    E,MAPJFN
1361         MOVEM   E,DIRCHN
1362 ]
1363
1364         JRST    PLOD1
1365
1366 ; ROUTINE TO SEE IF FILE IS NOT OPEN BECAUSE OF FNF AND FATAL IF SO
1367
1368 IFN ITS,[
1369 TRAGN:  PUSH    P,0             ; SAVE 0
1370         .STATUS MAPCH,0         ; GET STATUS BITS
1371         LDB     0,[220600,,0]
1372         CAIN    0,4             ; SKIP IF NOT FNF
1373          FATAL  MAJOR FILE NOT FOUND
1374         POP     P,0
1375         SOS     (P)
1376         SOS     (P)             ; RETRY OPEN
1377         POPJ    P,
1378 ]
1379 IFE ITS,[
1380 OPSAV:  MOVSI   A,%GJSHT+%GJOLD ; BITS FOR GTJFN
1381         HRROI   B,SAVSTR        ; STRING POINTER
1382         SKIPE   OPSYS
1383          HRROI  B,TSAVST
1384         GTJFN
1385          FATAL  CANT FIND SAV FILE
1386         MOVEM   A,MAPJFN        ; STORE THE JFN
1387         MOVE    B,[440000,,OF%RD+OF%EX+OF%THW+OF%DUD]
1388         OPENF
1389          FATAL  CANT OPEN SAV FILE
1390         POPJ    P,
1391 ]
1392
1393 ; OPMFIL IS USED TO OPEN A FILE ON MUDTMP.  IT CAN OPEN EITHER A SAV OR FIXUP FILE
1394 ; AND THE VERSION NUMBER IS SPECIFIED.  THE ARGUMENTS ARE
1395 ; NAM-1(P) HAS SIXBIT OF FILE NAME
1396 ; VER-1(P) HAS 0,,VERSION # FOR SAV FILE AND 1,,VERSION# FOR FIXUP FILE
1397 ; RETURNS LENGTH OF FILE IN SLEN AND 
1398
1399 ; OPXFIL IS A KLUDGE FOR GETTING SAV AND FIXUP FILES OFF OF THE MDLLIB
1400 ; DIRECTORY DURING THE CHANGEOVER TO PRE- AND POST- MUDSAV WORLDS
1401
1402 OPXFIL: MOVEI   0,1
1403         MOVEM   0,WRT-1(P)
1404         JRST    OPMFIL+1
1405
1406 OPWFIL: SETOM   WRT-1(P)
1407         SKIPA
1408 OPMFIL:  SETZM  WRT-1(P)
1409
1410 IFN ITS,[
1411         HRRZ    C,VER-1(P)              ; GET VERSION NUMBER
1412         PUSHJ   P,NTOSIX                ; CONVERT TO SIXBIT
1413         HRLI    C,(SIXBIT /SAV/)        ; BUILD SECOND FILE NAME
1414         HLRZ    0,VER-1(P)
1415         SKIPE   0                       ; SKIP IF SAV
1416          HRLI   C,(SIXBIT/FIX/)
1417         MOVE    B,NAM-1(P)              ; GET NAME
1418         MOVSI   A,7                     ; WRITE MODE
1419         SKIPL   WRT-1(P)
1420          MOVSI  A,6                     ; READ MODE
1421 RETOPN: .CALL   FOPBLK
1422          JRST   OPCHK                   ; SEE IF FIXUP IS NECESSARY OR JUST REOPENING
1423         DOTCAL  FILLEN,[[1000,,MAPCH],[2000,,A]]
1424          .LOSE  1000
1425         ADDI    A,PGMSK                 ; ROUND
1426         ASH     A,-PGSHFT               ; TO PAGES
1427         MOVEM   A,FLEN-1(P)
1428         SETZM   SPAG-1(P)
1429         AOS     (P)                     ; SKIP RETURN TO SHOW SUCCESS
1430         POPJ    P,
1431
1432 OPCHK: .STATUS  MAPCH,0                 ; GET STATUS BITS
1433         LDB     0,[220600,,0]
1434         CAIE    0,4                     ; SKIP IF FNF
1435          JRST   OPCHK1                  ; RETRY
1436         POPJ    P,
1437
1438 OPCHK1: MOVEI   0,1                     ; SLEEP FOR A WHILE
1439         .SLEEP
1440         JRST    OPCHK
1441
1442 ; NTOSIX GETS NUMBER IN C AND CONVERTS IT TO SIXBIT AND RETURNS RESULT IN C
1443  
1444 NTOSIX: PUSH    P,A                     ; SAVE A AND B
1445         PUSH    P,B
1446         PUSH    P,D
1447         MOVE    D,[220600,,C]
1448         MOVEI   A,(C)                   ; GET NUMBER
1449         MOVEI   C,0
1450         IDIVI   A,100.                  ; GET RESULT OF DIVISION
1451         SKIPN   A
1452          JRST   ALADD
1453         ADDI    A,20                    ; CONVERT TO DIGIT
1454         IDPB    A,D
1455 ALADD:  MOVEI   A,(B)
1456         IDIVI   A,10.                   ; GET TENS DIGIT
1457         SKIPN   C
1458          SKIPE  A                       ; IF BOTH 0 BLANK DIGIT
1459           ADDI  A,20
1460         IDPB    A,D
1461         SKIPN   C
1462          SKIPE  B
1463           ADDI  B,20
1464         IDPB    B,D
1465         POP     P,D
1466         POP     P,B
1467         POP     P,A
1468         POPJ    P,
1469
1470 ]
1471
1472 IFE ITS,[
1473         MOVE    E,P             ; save pdl base
1474         MOVE    B,NAM-1(E)              ; GET FIRST NAME
1475         PUSH    P,C%0           ; [0]; slots for building strings
1476         PUSH    P,C%0           ; [0]
1477         MOVE    A,[440700,,1(E)]
1478         MOVE    C,[440600,,B]
1479         
1480 ; DUMP OUT SIXBIT NAME
1481
1482         MOVEI   D,6
1483         ILDB    0,C
1484         JUMPE   0,.+4           ; violate cardinal ".+ rule"
1485         ADDI    0,40            ; to ASCII
1486         IDPB    0,A
1487         SOJG    D,.-4
1488
1489         MOVE    0,[ASCII /  SAV/]
1490         HLRZ    C,VER-1(E)              ; GET SAV/FIXUP FLAG
1491         SKIPE   C
1492          MOVE   0,[ASCII /  FIX/]
1493         PUSH    P,0 
1494         HRRZ    C,VER-1(E)              ; get ascii of vers no.
1495         PUSHJ   P,NTOSEV        ; CONVERT TO STRING LEFT JUSTIFIED
1496         PUSH    P,C
1497         MOVEI   B,-1(P)         ; point to it
1498         HRLI    B,260700
1499         HRROI   D,1(E)          ; point to name
1500         MOVEI   A,1(P)
1501         MOVSI   0,100000        ; INPUT FILE (GJ%OLD)
1502         SKIPGE  WRT-1(E)
1503          MOVSI  0,400000        ; OUTPUT FILE (GJ%FOU)
1504         PUSH    P,0
1505         PUSH    P,[377777,,377777]
1506         MOVE    0,[-1,,[ASCIZ /DSK/]]
1507         SKIPN   OPSYS
1508          MOVE   0,[-1,,[ASCIZ /PS/]]
1509         PUSH    P,0
1510         HRROI   0,[ASCIZ /MDL/]
1511         SKIPLE  WRT-1(E)                
1512          HRROI  0,[ASCIZ /MDLLIB/]      ; USE MDLLIB FOR SPECIAL CASE
1513         PUSH    P,0
1514         PUSH    P,D
1515         PUSH    P,B
1516         PUSH    P,C%0           ; [0]
1517         PUSH    P,C%0           ; [0]
1518         PUSH    P,C%0           ; [0]
1519         MOVEI   B,0
1520         MOVE    D,4(E)          ; save final version string
1521         GTJFN
1522          JRST   OPMLOS          ; FAILURE
1523         MOVEM   A,DIRCHN
1524         MOVE    B,[440000,,OF%RD+OF%EX]
1525         SKIPGE  WRT-1(E)
1526          MOVE   B,[440000,,OF%RD+OF%WR]
1527         OPENF
1528          FATAL  OPENF FAILED
1529         MOVE    P,E             ; flush crap
1530         PUSH    P,A
1531         SIZEF                   ; get length
1532          JRST   MAPLOS
1533         SKIPL   WRT-1(E)
1534          MOVEM  C,FLEN-1(E)     ; ONLY SAVE LENGTH FOR READ JFNS
1535         SETZM   SPAG-1(E)
1536
1537 ; RESTORE STACK AND LEAVE
1538
1539         MOVE    P,E
1540         MOVE    A,C             ; NUMBER OF PAGES IN A, DAMN!
1541         AOS     (P)
1542         POPJ    P,
1543
1544 OPMLOS: MOVE    P,E
1545         POPJ    P,
1546
1547 ; CONVERT A NUMBER IN C TO AN ASCII STRING LEFT JUSTIFIED IN C
1548
1549 NTOSEV: PUSH    P,A                     ; SAVE A AND B
1550         PUSH    P,B
1551         PUSH    P,D
1552         MOVE    D,[440700,,C]
1553         MOVEI   A,(C)                   ; GET NUMBER
1554         MOVEI   C,0
1555         IDIVI   A,100.                  ; GET RESULT OF DIVISION
1556         JUMPE   A,ALADD
1557         ADDI    A,60                    ; CONVERT TO DIGIT
1558         IDPB    A,D
1559 ALADD:  MOVEI   A,(B)
1560         IDIVI   A,10.                   ; GET TENS DIGIT
1561         ADDI    A,60
1562         IDPB    A,D
1563 ALADD1: ADDI    B,60
1564         IDPB    B,D
1565         POP     P,D
1566         POP     P,B
1567         POP     P,A
1568         POPJ    P,
1569
1570 ]
1571
1572 ; ROUTINE TO READ IN THE FIXUPS FROM DIRCHN OR MAPCH WORKS
1573 ; FOR FIXUP FILE OR FIXUPS IN A SEPERATE FILE AS LONG AS THE
1574 ; CHANNEL IS OPENED AND ACCESSED TO THE RIGHT PLACE
1575
1576 RFXUP:
1577 IFN ITS,[
1578         MOVE    0,[-2,,A]               ; PREPARE TO READ VERSION AND LENGTH
1579         .IOT    MAPCH,0                 ; READ IT IN
1580         SKIPGE  0                       ; SKIP IF NOT HIT EOF
1581         FATAL   BAD FIXUP FILE
1582         MOVEI   A,-2(A)                 ; COUNT FOR FIRST 2 WORDS
1583         HRRM    B,VER-1(P)              ; SAVE VERSION #
1584         .IOPUS  MAPCH,                  ; PUSH THE MAPPING CHANNEL
1585         SETOM   PLODR
1586         PUSHJ   P,IBLOCK                ; GET A UVECTOR OF APPROPRIATE SIZE
1587         SETZM   PLODR
1588         .IOPOP  MAPCH,
1589         MOVE    0,$TUVEC
1590         MOVEM   0,-1(TP)                ; SAVE UVECTOR
1591         MOVEM   B,(TP)
1592         MOVE    A,B                     ; GET AOBJN POINTER TO UVECTOR FOR IOT
1593         .IOT    MAPCH,A                 ; GET FIXUPS
1594         .CLOSE  MAPCH,
1595         POPJ    P,
1596 ]
1597
1598 IFE ITS,[
1599         MOVE    A,DIRCHN
1600         BIN                             ; GET LENGTH OF FIXUP
1601         MOVE    C,B
1602         MOVE    A,DIRCHN
1603         BIN                             ; GET VERSION NUMBER
1604         HRRM    B,VER-1(P)
1605         SETOM   PLODR
1606         MOVEI   A,-2(C)
1607         PUSHJ   P,IBLOCK
1608         SETZM   PLODR
1609         MOVSI   0,$TUVEC
1610         MOVEM   0,-1(TP)
1611         MOVEM   B,(TP)
1612         MOVE    A,DIRCHN
1613         HLRE    C,B
1614 ;       SKIPE   OPSYS           ; SKIP IF TOPS20 SINCE C MUST BE NEGETIVE
1615 ;        MOVNS  C               ; C IS POSITIVE FOR TENEX ?????
1616         HRLI    B,444400
1617         SIN
1618         MOVE    A,DIRCHN
1619         CLOSF
1620          FATAL  CANT CLOSE FIXUP FILE
1621         RLJFN
1622          JFCL
1623         POPJ    P,
1624 ]
1625
1626 ; ROUTINE TO READ IN THE CODE
1627
1628 RSAV:   MOVE    A,FLEN-1(P)
1629         PUSHJ   P,ALOPAG                ; GET PAGES
1630         JRST    MAPLS2
1631         MOVE    E,SPAG-1(P)
1632
1633 IFN ITS,[
1634         MOVN    A,FLEN-1(P)     ; build aobjn pointer
1635         MOVSI   A,(A)
1636         HRRI    A,(B)
1637         MOVE    B,A
1638         HRRI    0,(E)
1639         DOTCAL  CORBLK,[[1000,,104000],[1000,,-1],A,[1000,,MAPCH],0]
1640          .LOSE  %LSSYS
1641         .CLOSE  MAPCH,
1642         POPJ    P,
1643 ]
1644 IFE ITS,[
1645         PUSH    P,B             ; SAVE PAGE #
1646         MOVS    A,DIRCHN        ; SOURCE (MUDSAV)
1647         HLRM    A,SJFNS         ; SAVE POINTER FOR FUTURE CLOSING
1648         HRR     A,E
1649         HRLI    B,.FHSLF        ; DESTINATION (FORK)
1650         MOVSI   C,PM%RD+PM%CPY  ; MAKE COPY ON WRITE
1651         SKIPE   OPSYS
1652          JRST   RSAV1           ; HANDLE TENEX
1653         TLO     C,PM%CNT        ; REPEAT COUNT BIT FOR TOPS20
1654         HRR     C,FLEN-2(P)     ; PAGE (FOR PUSHJ AND PUSHED B)
1655         PMAP
1656 RSAVDN: POP     P,B
1657         MOVN    0,FLEN-1(P)
1658         HRL     B,0
1659         POPJ    P,
1660
1661 RSAV1:  HRRZ    D,FLEN-2(P)     ; GET IN PAGE COUNT
1662 RSAV2:  PMAP
1663         ADDI    A,1             ; NEXT PAGE
1664         ADDI    B,1     
1665         SOJN    D,RSAV2         ; LOOP
1666         JRST    RSAVDN
1667 ]
1668
1669 PDLOV:  SUB     P,[NSLOTS,,NSLOTS]
1670         PUSH    P,C%0           ; [0]; CAUSE A PDL OVERFLOW
1671         JRST    .-1
1672
1673 ; CONSTANTS RELATED TO DATA BASE
1674 DEV:    SIXBIT /DSK/
1675 MODE:   6,,0
1676 MNDIR:  SIXBIT /MUDSAV/                         ; DIR OF MAIN DATA BASE FILES
1677 WRKDIR: SIXBIT /MUDTMP/                         ; DIRECTORY OF UPDATE FILES
1678
1679 IFN ITS,[
1680 MNBLK:  SETZ
1681         SIXBIT /OPEN/
1682         MODE
1683         DEV
1684         [SIXBIT /SAV/]
1685         [SIXBIT /FILE/]
1686         SETZ MNDIR
1687
1688
1689 FIXBLK: SETZ
1690         SIXBIT /OPEN/
1691         MODE
1692         DEV
1693         [SIXBIT /FIXUP/]
1694         [SIXBIT /FILE/]
1695         SETZ MNDIR
1696
1697 FOPBLK: SETZ
1698         SIXBIT /OPEN/
1699         A
1700         DEV
1701         B
1702         C
1703         SETZ WRKDIR
1704
1705 FXTBL:  -2,,.+1
1706         55.
1707         54.
1708 ]
1709 IFE ITS,[
1710
1711 FXSTR:  ASCIZ /PS:<MDL>FIXUP.FILE/
1712 SAVSTR: ASCIZ /PS:<MDL>SAV.FILE/
1713 TFXSTR: ASCIZ /DSK:<MDL>FIXUP.FILE/
1714 TSAVST: ASCIZ /DSK:<MDL>SAV.FILE/
1715
1716 FXTBL:  -3,,.+1
1717         55.
1718         54.
1719         104.
1720 ]
1721 IFN SPCFXU,[
1722
1723 ;This code does two things to code for FBIN;
1724 ;       1)      Makes dispatches win in multi seg mode
1725 ;       2)      Makes OBLIST? work with "new" atom format
1726 ;       3)      Makes LENGTH win in multi seg mode
1727 ;       4)      Gets AOBJN pointer to code vector in C
1728
1729 SFIX:   PUSH    P,A
1730         PUSH    P,B
1731         PUSH    P,C             ; for referring back
1732
1733 SFIX1:  MOVSI   B,-MLNT         ; for looping through tables    
1734
1735 SFIX2:  MOVE    A,(C)           ; get code word
1736
1737         AND     A,SMSKS(B)
1738         CAMN    A,SPECS(B)      ; do we match
1739          JRST   @SFIXR(B)
1740
1741         AOBJN   B,SFIX2
1742
1743 SFIX3:  AOBJN   C,SFIX1         ; do all of code
1744 SFIX4:  POP     P,C
1745         POP     P,B
1746         POP     P,A
1747         POPJ    P,
1748
1749 SMSKS:  -1
1750         777000,,-1
1751         -1,,0
1752         777037,,0
1753 MLNT==.-SMSKS
1754
1755 SPECS:  HLRES   A               ; begin of arg diaptch table
1756         SKIPN   2               ; old compiled OBLIST?
1757         JRST    (M)             ; compiled LENGTH
1758         ADDI    (M)             ; begin a case dispatch
1759
1760 SFIXR:  SETZ    DFIX
1761         SETZ    OBLFIX
1762         SETZ    LFIX
1763         SETZ    CFIX
1764
1765 DFIX:   AOBJP   C,SFIX4         ; make sure dont run out
1766         MOVE    A,(C)           ; next ins
1767         CAME    A,[ASH A,-1]    ; still winning?
1768          JRST   SFIX3           ; false alarm
1769         AOBJP   C,SFIX4         ; make sure dont run out
1770         HLRZ    A,(C)           ; next ins
1771         CAIE    A,(ADDI A,(M))  ; still winning?
1772          JRST   SFIX3           ; false alarm
1773         AOBJP   C,SFIX4
1774         HLRZ    A,(C)
1775         CAIE    A,(PUSHJ P,@(A))        ; last one to check
1776          JRST   SFIX3
1777         AOBJP   C,SFIX4
1778         MOVE    A,(C)
1779         CAME    A,[JRST FINIS]          ; extra check
1780          JRST   SFIX3
1781
1782         MOVSI   B,(SETZ)
1783 SFIX5:  AOBJP   C,SFIX4
1784         HLRZ    A,(C)
1785         CAIN    A,(SUBM M,(P))
1786          JRST   SFIX3
1787         CAIE    A,M                     ; dispatch entry?
1788          JRST   SFIX3           ; maybe already fixed
1789         IORM    B,(C)           ; fix it
1790         JRST    SFIX5
1791
1792 OBLFIX: PUSH    P,[-TLN,,TPTR]
1793         PUSH    P,C
1794         MOVE    B,-1(P)
1795
1796 OBLFXY: PUSH    P,1(B)
1797         PUSH    P,(B)
1798
1799 OBLFI1: AOBJP   C,OBLFXX
1800         MOVE    A,(C)
1801         AOS     B,(P)
1802         AND     A,(B)
1803         MOVE    B,-1(P)
1804         CAME    A,(B)
1805          JRST   OBLFXX
1806         AOBJP   B,DOOBFX
1807         MOVEM   B,-1(P)
1808         JRST    OBLFI1
1809
1810 OBLFXX: SUB     P,C%22          ; for checking more ins
1811         MOVE    B,-1(P)
1812         ADD     B,C%22
1813         JUMPGE  B,OBLFX1
1814         MOVEM   B,-1(P)
1815         MOVE    C,(P)
1816         JRST    OBLFXY
1817
1818
1819 INSBP==331100                   ; byte pointer for ins field
1820 ACBP==270400                    ; also for ac
1821 INDXBP==220400
1822
1823 DOOBFX: MOVE    C,-2(P)
1824         SUB     P,C%44
1825         MOVEI   B,<<(HRRZ)>_<-9>>       ; change em
1826         DPB     B,[INSBP,,(C)]  ; SKIPN==>HRRZ
1827         LDB     A,[ACBP,,(C)]   ; get AC field
1828         MOVEI   B,<<(JUMPE)>_<-9>>
1829         DPB     B,[INSBP,,1(C)]
1830         DPB     A,[ACBP,,1(C)]
1831         AOS     1(C)            ; JRST FOO==>JUMPE ac,FOO+1
1832         MOVE    B,[CAMG VECBOT]
1833         DPB     A,[ACBP,,B]
1834         MOVEM   B,2(C)          ; JUMPL ==> CAMG ac,VECBOT
1835         HRRZ    A,3(C)          ; get indicator of existence of ADD AC,TVP
1836         CAIE    A,TVP           ; skip if extra ins exists
1837          JRST   NOATVP
1838         MOVSI   A,(JFCL)
1839         EXCH    A,4(C)
1840         MOVEM   A,3(C)
1841         ADD     C,C%11
1842 NOATVP: TLC     B,(CAMG#HRLI)   ; change CAMG to HRLI (preserving AC)
1843         HRRZ    A,4(C)          ; see if moves in type
1844         CAIE    A,$TOBLS
1845          SUB    C,[1,,1]        ; fudge it
1846         HLLOM   B,5(C)          ; in goes HRLI -1
1847         CAIE    A,$TOBLS        ; do we need a skip?
1848          JRST   NOOB$
1849         MOVSI   B,(CAIA)        ;  skipper
1850         EXCH    B,6(C)
1851         MOVEM   B,7(C)
1852         ADD     C,[7,,7]
1853         JRST    SFIX3
1854
1855 NOOB$:  MOVSI   B,(JFCL)
1856         MOVEM   B,6(C)
1857         ADD     C,C%66
1858         JRST    SFIX3
1859
1860 OBLFX1: MOVE    C,(P)
1861         SUB     P,C%22
1862         JRST    SFIX3
1863
1864 ; Here to fixup compiled LENGTH
1865
1866 LFIX:   MOVSI   B,-LLN          ; for checking other LENGTH ins
1867         PUSH    P,C
1868
1869 LFIX1:  AOBJP   C,LFIXY
1870         MOVE    A,(C)
1871         AND     A,LMSK(B)
1872         CAME    A,LINS(B)
1873          JRST   LFIXY
1874         AOBJN   B,LFIX1
1875
1876         POP     P,C             ; restore code pointer
1877         MOVE    A,(C)           ; save jump for its addr
1878         MOVE    B,[MOVSI 400000]
1879         MOVEM   B,(C)           ; JRST .+2 ==> MOVSI 0,400000
1880         LDB     B,[ACBP,,1(C)]  ; B==> AC of interest
1881         ADDI    A,2
1882         DPB     B,[ACBP,,A]
1883         MOVEI   B,<<(JUMPE)>_<-9.>>
1884         DPB     B,[INSBP,,A]
1885         EXCH    A,1(C)
1886         TLC     A,(HRR#HRRZ)    ; HRR==>HRRZ
1887         HLLZM   A,2(C)          ; TRNN AC,-1 ==> HRRZ AC,(AC)
1888         MOVEI   B,(AOBJN (M))
1889         HRLM    B,3(C)          ; AOBJP AC,.-2 ==> AOBJN 0,.-2
1890         MOVE    B,2(C)          ; get HRRZ AC,(AC)
1891         TLZ     B,17            ; kill (AC) part
1892         MOVEM   B,4(C)          ; HLRZS AC ==> HRRZ AC,0
1893         ADD     C,C%44
1894         JRST    SFIX3
1895
1896 LFIXY:  POP     P,C
1897         JRST    SFIX3
1898
1899 ; Fixup a CASE dispatch
1900
1901  CFIX:  LDB     A,[ACBP,,(C)]
1902         AOBJP   C,SFIX4
1903         HLRZ    B,(C)           ; Next ins
1904         ANDI    B,777760
1905         CAIE    B,(JRST @)
1906          JRST   SFIX3
1907         LDB     B,[INDXBP,,(C)]
1908         CAIE    A,(B)
1909          JRST   SFIX3
1910         MOVE    A,(C)           ; ok, fix it up
1911         TLZ     A,20            ; kill indirection
1912         MOVEM   A,(C)
1913         HRRZ    B,-1(C)         ; point to table
1914         ADD     B,(P)           ; point to code to change
1915
1916 CFIXLP: HLRZ    A,(B)           ; check one out
1917         TRZ     A,400000        ; kill bit
1918         CAIE    A,M             ; check for just index (or index with SETZ)
1919          JRST   SFIX3
1920         MOVEI   A,(JRST (M))
1921         HRLM    A,(B)
1922         AOJA    B,CFIXLP
1923
1924 DEFINE FOO LBL,LNT,LBL2,L
1925 LBL:
1926         IRP A,,[L]
1927                 IRP B,C,[A]
1928                         B
1929                         .ISTOP
1930                 TERMIN
1931         TERMIN
1932 LNT==.-LBL
1933 LBL2:
1934         IRP A,,[L]
1935                 IRP B,C,[A]
1936                         C
1937                         .ISTOP
1938                 TERMIN
1939         TERMIN
1940 TERMIN
1941
1942 IMSK==777017,,0
1943 AIMSK==777000,,-1
1944
1945 FOO OINS,OLN,OMSK,[[<JRST (M)>,IMSK],[<JUMPL (M)>,IMSK],[MOVE,AIMSK]
1946                    [<MOVE $TOBLS>,AIMSK],[<JRST (M)>,IMSK]
1947                    [<MOVE $TFALSE>,AIMSK],[MOVEI,AIMSK]]
1948
1949 FOO OINS3,OLN3,OMSK3,[[<JRST (M)>,IMSK],[<JUMPL (M)>,IMSK],[MOVE,AIMSK]
1950                       [<JRST (M)>,IMSK],[MOVEI,AIMSK]]
1951
1952 FOO OINS2,OLN2,OMSK2,[[<JRST (M)>,IMSK],[<JUMPL (M)>,IMSK],[<ADD TVP>,AIMSK]
1953                       [MOVE,AIMSK],[<MOVE $TOBLS>,AIMSK],[<JRST (M)>,IMSK]
1954                       [<MOVE $TFALSE>,AIMSK],[MOVEI,AIMSK]]
1955
1956 FOO OINS4,OLN4,OMSK4,[[<JRST (M)>,IMSK],[<JUMPL (M)>,IMSK],[<ADD TVP>,AIMSK]
1957                       [MOVE,AIMSK],[<JRST (M)>,IMSK],[MOVEI,AIMSK]]
1958
1959 TPTR:   -OLN,,OINS
1960         OMSK-1
1961         -OLN2,,OINS2
1962         OMSK2-1
1963         -OLN3,,OINS3
1964         OMSK3-1
1965         -OLN4,,OINS4
1966         OMSK4-1
1967 TLN==.-TPTR
1968
1969 FOO LINS,LLN,LMSK,[[<HRR -1>,AIMSK],[<TRNE -1>,AIMSK],[<AOBJP (M)>,IMSK]
1970                    [<HLRZS>,<-1,,777760>]]
1971
1972 ]
1973 IMPURE
1974
1975 SAVSNM: 0                                       ; SAVED SNAME
1976 INPLOD: 0                                       ; FLAG SAYING WE ARE IN MAPPUR
1977
1978 IFE ITS,[
1979 MAPJFN: 0                                       ; JFN OF <MDL>SAV FILE
1980 DIRCHN: 0                                       ; JFN USED BY GETDIR
1981 ]
1982
1983 PURE
1984
1985 END
1986