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