Twenex Muddle.
[pdp10-muddle.git] / <mdl.int> / mappur.mid.161
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    B,PURVEC+1      ; get pointer to table
975 CLN1:   SETZM   FB.PTR(B)       ; zero pointer entry
976         SETZM   FB.AGE(B)       ; zero link and age slots
977         SETZM   FB.PGS(B)
978         ADD     B,[ELN,,ELN]    ; go to next slot
979         JUMPL   B,CLN1          ; do til exhausted
980         MOVE    B,PURBOT        ; now return pages
981         SUB     B,PURTOP        ; compute page AOBJN pointer
982 IFE ITS,        SETZM   MAPJFN          ; make sure zero mapjfn
983         JUMPE   B,CPOPJ         ; no pure pages?
984         MOVSI   B,(B)
985         HRR     B,PURBOT
986         ASH     B,-PGSHFT
987 IFN ITS,[
988         DOTCAL  CORBLK,[[1000,,0],[1000,,-1],B]
989          .LOSE  %LSSYS
990 ]
991 IFE ITS,[
992
993         SKIPE   MULTSG
994          JRST   CLN2
995         HLRE    D,B             ; - # of pges to flush
996         HRLI    B,.FHSLF        ; specify hacking hom fork
997         MOVNI   A,1
998         MOVEI   C,0
999
1000         PMAP
1001         ADDI    B,1
1002         AOJL    D,.-2
1003 ]
1004
1005         MOVE    B,PURTOP        ; now fix up pointers
1006         MOVEM   B,PURBOT        ;   to indicate no pure
1007 CPOPJ:  POPJ    P,
1008
1009 IFE ITS,[
1010 CLN2:   HLRE    C,B             ; compute pos no. pages
1011         HRLI    B,.FHSLF
1012         MOVNS   C
1013         MOVNI   A,1             ; flushing pages
1014         HRLI    C,PM%CNT
1015         MOVE    D,NSEGS
1016         MOVE    E,PURTOP        ; for munging table
1017         ADDI    B,<FSEG>_9.     ; do it to the correct segment
1018         PMAP
1019         ADDI    B,1_9.          ; cycle through segments
1020         HRRZM   E,PURBTB(D)     ; mung table
1021         SOJG    D,.-3
1022
1023         MOVEM   E,PURBOT
1024         POPJ    P,
1025 ]
1026
1027 ; Here to move the entire pure space.
1028 ;       A/      # and direction of pages to move (+ ==> up)
1029
1030 MOVPUR: SKIPE   NOSHUF
1031          FATAL  CANT MOVE PURE SPACE AROUND
1032 IFE ITS,ASH     A,1
1033         SKIPN   B,A             ; zero movement, ignore call
1034          POPJ   P,
1035
1036         ASH     B,PGSHFT        ; convert to words for pointer update
1037         MOVE    C,PURVEC+1      ; loop through updating non-zero entries
1038         SKIPE   1(C)
1039          ADDM   B,1(C)
1040         ADD     C,[ELN,,ELN]
1041         JUMPL   C,.-3
1042
1043         MOVE    C,PURTOP        ; found pages at top and bottom of pure
1044         ASH     C,-PGSHFT
1045         MOVE    D,PURBOT
1046         ASH     D,-PGSHFT
1047         ADDM    B,PURTOP        ; update to new boundaries
1048         ADDM    B,PURBOT
1049 IFE ITS,[
1050         SKIPN   MULTSG          ; in multi-seg mode, must mung whole table
1051          JRST   MOVPU1
1052         MOVN    E,NSEGS
1053         HRLZS   E
1054         ADDM    PURBTB(E)
1055         AOBJN   E,.-1
1056 ]
1057 MOVPU1: CAIN    C,(D)           ; differ?
1058          POPJ   P,
1059         JUMPG   A,PUP           ; if moving up, go do separate CORBLKs
1060
1061 IFN ITS,[
1062         SUBM    D,C             ; -size of area to C (in pages)
1063         MOVEI   E,(D)           ; build pointer to bottom of destination
1064         ADD     E,A
1065         HRLI    E,(C)
1066         HRLI    D,(C)
1067         DOTCAL  CORBLK,[[1000,,200000],[1000,,-1],E,[1000,,-1],D]
1068          .LOSE  %LSSYS
1069         POPJ    P,
1070
1071 PUP:    SUBM    C,D             ; pages to move to D
1072         ADDI    A,(C)           ; point to new top
1073
1074 PUPL:   SUBI    C,1
1075         SUBI    A,1
1076         DOTCAL  CORBLK,[[1000,,200000],[1000,,-1],A,[1000,,-1],C]
1077          .LOSE  %LSSYS
1078         SOJG    D,PUPL
1079         POPJ    P,
1080 ]
1081 IFE ITS,[
1082         SUBM    D,C             ; pages to move to D
1083         MOVSI   E,(C)           ; build aobjn pointer
1084         HRRI    E,(D)           ; point to lowest
1085         ADD     D,A             ; D==> new lowest page
1086         MOVEI   F,0             ; seg info 
1087         SKIPN   MULTSG
1088          JRST   XPLS3
1089         MOVEI   F,FSEG-1
1090         ADD     F,NSEGS
1091         ASH     F,9.
1092 XPLS3:  MOVE    G,E
1093         MOVE    H,D             ; save for outer loop
1094
1095 PURCL1: MOVSI   A,.FHSLF                ; specify here
1096         HRRI    A,(E)           ; get a page
1097         IORI    A,(F)           ; hack seg i
1098         RMAP                    ; get a real handle on it
1099         MOVE    B,D             ; where to go
1100         HRLI    B,.FHSLF
1101         MOVSI   C,PM%RD+PM%EX
1102         IORI    A,(F)
1103         PMAP
1104         ADDI    D,1
1105         AOBJN   E,PURCL1
1106         SKIPN   MULTSG
1107          POPJ   P,
1108         SUBI    F,1_9.
1109         CAIGE   F,FSEG_9.
1110          POPJ   P,
1111         MOVE    E,G
1112         MOVE    D,H
1113         JRST    PURCL1
1114
1115 PUP:    SUB     D,C             ; - count to D
1116         MOVSI   E,(D)           ; start building AOBJN
1117         HRRI    E,(C)           ; aobjn to top
1118         ADD     C,A             ; C==> new top
1119         MOVE    D,C
1120         MOVEI   F,0             ; seg info 
1121         SKIPN   MULTSG
1122          JRST   XPLS31
1123         MOVEI   F,FSEG
1124         ADD     F,NSEGS
1125         ASH     F,9.
1126 XPLS31: MOVE    G,E
1127         MOVE    H,D             ; save for outer loop
1128
1129 PUPL:   MOVSI   A,.FHSLF
1130         HRRI    A,(E)
1131         IORI    A,(F)           ; segment
1132         RMAP                    ; get real handle
1133         MOVE    B,D
1134         HRLI    B,.FHSLF
1135         IORI    B,(F)
1136         MOVSI   C,PM%RD+PM%EX
1137         PMAP
1138         SUBI    E,2
1139         SUBI    D,1
1140         AOBJN   E,PUPL
1141         SKIPN   MULTSG
1142          POPJ   P,
1143         SUBI    F,1_9.
1144         CAIGE   F,FSEG_9.
1145          POPJ   P,
1146         MOVE    E,G
1147         MOVE    D,H
1148         JRST    PUPL
1149
1150         POPJ    P,
1151 ]
1152 IFN ITS,[
1153 .GLOBAL CSIXBT
1154 CSIXBT: MOVEI   0,5
1155         PUSH    P,[440700,,C]
1156         PUSH    P,[440600,,D]
1157         MOVEI   D,0
1158 CSXB2:  ILDB    E,-1(P)
1159         CAIN    E,177
1160         JRST    CSXB1
1161         SUBI    E,40
1162         IDPB    E,(P)
1163         SOJG    0,CSXB2
1164 CSXB1:  SUB     P,C%22
1165         MOVE    C,D
1166         POPJ    P,
1167 ]
1168 GENVN:  MOVE    C,[440700,,MUDSTR+2]
1169         MOVEI   D,5
1170         MOVEI   B,0
1171 VNGEN:  ILDB    0,C
1172         CAIN    0,177
1173          POPJ   P,
1174         IMULI   B,10.
1175         SUBI    0,60
1176         ADD     B,0
1177         SOJG    D,VNGEN
1178         POPJ    P,
1179
1180 IFE ITS,[
1181 MSKS:   774000,,0
1182         777760,,0
1183         777777,,700000
1184         777777,,777400
1185         777777,,777776
1186 ]
1187
1188 \f; THESE ARE DIRECTORY SEARCH ROUTINES
1189
1190
1191 ; THIS ROUTINE DOES A BINARY SEARCH ON A DIRECTORY AND RETURNS A POINTER
1192 ; RESTED DOWN TO THE APPROPRIATE SLOT IN THE DIRECTORY.
1193 ; ARGS: E==DIR POINTER D==FILE-NAME 1 A==VERSION #
1194 ; RETS: A==RESTED DOWN DIRECTORY
1195
1196 DIRSR1: TLOA    0,400000                ; INDICATION OF ONE ARGUMENT SEARCH
1197 DIRSRC:  TLZ    0,400000                ; INDICATOR OF 2 ARGUMENT SEARCH
1198         PUSH    P,A                     ; SAVE VERSION #
1199         HLRE    B,E                     ; GET LENGTH INTO B
1200         MOVNS   B
1201         MOVE    A,E
1202         HRLS    B                       ; GET BOTH SIDES
1203 UP:     ASH     B,-1                    ; HALVE TABLE
1204         AND     B,[-2,,-2]              ; FORCE DIVIS BY 2
1205         MOVE    C,A                     ; COPY POINTER
1206         JUMPLE  B,LSTHLV                ; CANT GET SMALLER
1207         ADD     C,B
1208 IFE ITS,        HRRZ    F,C             ; avoid lossage in multi-sections
1209 IFN ITS,        CAMLE   D,(C)           ; SKIP IF EITHER FOUND OR IN TOP
1210 IFE ITS,        CAMLE   D,(F)           ; SKIP IF EITHER FOUND OR IN TOP
1211          MOVE    A,C                    ; POINT TO SECOND HALF
1212 IFN ITS,        CAMN    D,(C)           ; SKIP IF NOT FOUND
1213 IFE ITS,        CAMN    D,(F)           ; SKIP IF NOT FOUND
1214          JRST    WON
1215 IFN ITS,        CAML    D,(C)           ; SKIP IF IN TOP HALF
1216 IFE ITS,        CAML    D,(F)           ; SKIP IF IN TOP HALF
1217          JRST    UP
1218         HLLZS   C                       ; FIX UP POINTER
1219         SUB     A,C
1220         JRST    UP
1221
1222 WON:    JUMPL   0,SUPWIN
1223         MOVEI   0,0                     ; DOWN FLAG
1224 WON1:   LDB     A,[221200,,1(C)]        ; GET VERSION NUMBER
1225         CAMN    A,(P)                   ; SKIP IF NOT EQUAL
1226          JRST   SUPWIN
1227         CAMG    A,(P)                   ; SKIP IF LT
1228          JRST   SUBIT
1229         SETO    0,
1230         SUB     C,C%22                  ; GET NEW C
1231         JRST    SUBIT1
1232
1233 SUBIT:  ADD     C,C%22                  ; SUBTRACT
1234         JUMPN   0,C1POPJ
1235 SUBIT1:
1236 IFN ITS,        CAMN    D,(C)           ; SEE WHETHER WERE STILL WINNING
1237 IFE ITS,[
1238         HRRZ    F,C
1239         CAMN    D,(F)
1240 ]
1241          JRST   WON1
1242 C1POPJ: SUB     P,C%11                  ; GET RID OF VERSION #
1243         POPJ    P,                      ; LOSE LOSE LOSE
1244 SUPWIN: MOVE    A,C                     ; RETURN ARGUMENT IN A  
1245         AOS     -1(P)                   ; SKIP RETURN INDICATES IT WAS FOUND
1246         JRST    C1POPJ
1247
1248 LSTHLV:
1249 IFN ITS,        CAMN    D,(C)           ; LINEAR SEARCH REST
1250 IFE ITS,[
1251         HRRZ    F,C
1252         CAMN    D,(F)           ; LINEAR SEARCH REST
1253 ]
1254          JRST    WON
1255         ADD     C,C%22
1256         JUMPL   C,LSTHLV
1257         JRST    C1POPJ
1258
1259 \f; ROUTINE TO GET A DIRECTORY. ASSUMES MAPCH IS OPEN TO FIXUP OR SAV FILE AND 0 IS THE
1260 ; LAST CHAR TO BE HASHED. RETURNS POINTER TO DIRECTORY IN E
1261
1262 IFN ITS,[
1263 GETDIR: PUSH    P,C
1264         PUSH    P,0
1265         PUSHJ   P,SQKIL
1266         MOVEI   A,1                     ; GET A BUFFER
1267         PUSHJ   P,GETBUF
1268         MOVEI   C,(B)
1269         ASH     C,-10.
1270         DOTCAL  CORBLK,[[RDTP],[FME],C,[1000,,MAPCH],[1000,,0]]
1271         PUSHJ   P,SLEEPR
1272         POP     P,0
1273         IDIV    0,(B)                   ; A NOW CONTAINS THE DIRECTORY NUMBER
1274         ADDI    A,1(B)
1275         DOTCAL  CORBLK,[[RDTP],[FME],C,[1000,,MAPCH],(A)]
1276         PUSHJ   P,SLEEPR
1277         MOVN    E,(B)                   ; GET -LENGTH OF DIRECTORY
1278         HRLZS   E                       ; BUILD AOBJN PTR TO DIR
1279         HRRI    E,1(B)
1280         POP     P,C
1281         POPJ    P,
1282 ]
1283 ; IN WONDERFUL TOPS20 VERSION DIRCHN CONTAINS THE JFN
1284
1285 IFE ITS,[
1286 GETDIR: JRST    @[.+1]
1287         PUSH    P,C
1288         PUSH    P,0
1289         PUSHJ   P,SQKIL
1290         MOVEI   A,1                     ; GET A BUFFER
1291         PUSHJ   P,GETBUF
1292         HRROI   E,(B)
1293         ASH     B,-9.
1294         HRLI    B,.FHSLF                        ; SET UP DESTINATION (CORE)
1295         MOVS    A,DIRCHN                ; SET UP SOURCE (FILE)
1296         MOVSI   C,PM%RD+PM%EX           ; READ+EXEC ACCESS
1297         PMAP
1298         POP     P,0
1299         IDIV    0,(E)                   ; A NOW CONTAINS THE DIRECTORY NUMBER
1300         ADDI    A,1(E)                  ; POINT TO THE DIRECTORY ENTRY
1301         MOVE    A,(A)                   ; GET THE PAGE NUMBER
1302         HRL     A,DIRCHN                ; SET UP SOURCE (FILE)
1303         PMAP                            ; AGAIN READ IN DIRECTORY
1304         MOVEI   A,(E)
1305         MOVN    E,(E)                   ; GET -LENGTH OF DIRECTORY
1306         HRLZS   E                       ; BUILD AOBJN PTR TO DIR
1307         HRRI    E,1(A)
1308         POP     P,C
1309         SKIPN   MULTSG
1310          POPJ   P,
1311         POP     P,21
1312         SETZM   20
1313         XJRST   20
1314 ]
1315 ; HERE IF CAN'T FIND FIXUP FILE IN MAIN DIRECTORY
1316
1317 NOFXUP: 
1318 IFE ITS,[
1319         MOVE    A,DIRCHN                ; JFN FOR FIXUP FILE
1320         CLOSF                           ; CLOSE IT
1321          JFCL
1322 ]
1323         MOVE    A,FXTBL                 ; GET AOBJN POINTER TO FIXUP TABLE
1324 NOFXU1: HRRZ    B,(A)                   ; GET VERSION TO TRY
1325         HRRM    B,VER(P)                ; STUFF IN VERSION
1326         MOVEI   B,1                     ; DUMP IN FIXUP INDICATOR
1327         HRLM    B,VER(P)
1328         MOVEM   A,TEMP(P)               ; SAVE POINTER TO FXTBL
1329         PUSHJ   P,OPXFIL                ; LOOK FOR FIXUP FILE   
1330          JRST   NOFXU2
1331         PUSHJ   P,RFXUP                 ; READ IN THE FIXUP FILE
1332         HRRZS   VER(P)                  ; INDICATE SAV FILE
1333         PUSHJ   P,OPXFIL                ; TRY OPENING IT
1334          JRST   MAPLS0                  ; GIVE UP NO SAV FILE TO BE HAD
1335         PUSHJ   P,RSAV
1336         JRST    FXUPGO                  ; GO FIXUP THE WORLD
1337 NOFXU2: MOVE    A,TEMP(P)               ; GET BACK POINTER
1338         AOBJN   A,NOFXU1                ; TRY NEXT
1339         JRST    MAPLS1                  ; NO FILE TO BE HAD
1340
1341 GETIT:  HRRZM   B,SPAG(P)               ; GET BLOCK OF START
1342         HLRZM   B,FLEN(P)               ; DAMMIT SAVE THIS!
1343         HLRZ    A,B                     ; GET LENGTH\r
1344 IFN ITS,[
1345         .CALL   MNBLK
1346         PUSHJ   P,TRAGN
1347 ]
1348 IFE ITS,[
1349         MOVE    E,MAPJFN
1350         MOVEM   E,DIRCHN
1351 ]
1352
1353         JRST    PLOD1
1354
1355 ; ROUTINE TO SEE IF FILE IS NOT OPEN BECAUSE OF FNF AND FATAL IF SO
1356
1357 IFN ITS,[
1358 TRAGN:  PUSH    P,0             ; SAVE 0
1359         .STATUS MAPCH,0         ; GET STATUS BITS
1360         LDB     0,[220600,,0]
1361         CAIN    0,4             ; SKIP IF NOT FNF
1362          FATAL  MAJOR FILE NOT FOUND
1363         POP     P,0
1364         SOS     (P)
1365         SOS     (P)             ; RETRY OPEN
1366         POPJ    P,
1367 ]
1368 IFE ITS,[
1369 OPSAV:  MOVSI   A,%GJSHT+%GJOLD ; BITS FOR GTJFN
1370         HRROI   B,SAVSTR        ; STRING POINTER
1371         SKIPE   OPSYS
1372          HRROI  B,TSAVST
1373         GTJFN
1374          FATAL  CANT FIND SAV FILE
1375         MOVEM   A,MAPJFN        ; STORE THE JFN
1376         MOVE    B,[440000,,OF%RD+OF%EX+OF%THW+OF%DUD]
1377         OPENF
1378          FATAL  CANT OPEN SAV FILE
1379         POPJ    P,
1380 ]
1381
1382 ; OPMFIL IS USED TO OPEN A FILE ON MUDTMP.  IT CAN OPEN EITHER A SAV OR FIXUP FILE
1383 ; AND THE VERSION NUMBER IS SPECIFIED.  THE ARGUMENTS ARE
1384 ; NAM-1(P) HAS SIXBIT OF FILE NAME
1385 ; VER-1(P) HAS 0,,VERSION # FOR SAV FILE AND 1,,VERSION# FOR FIXUP FILE
1386 ; RETURNS LENGTH OF FILE IN SLEN AND 
1387
1388 ; OPXFIL IS A KLUDGE FOR GETTING SAV AND FIXUP FILES OFF OF THE MDLLIB
1389 ; DIRECTORY DURING THE CHANGEOVER TO PRE- AND POST- MUDSAV WORLDS
1390
1391 OPXFIL: MOVEI   0,1
1392         MOVEM   0,WRT-1(P)
1393         JRST    OPMFIL+1
1394
1395 OPWFIL: SETOM   WRT-1(P)
1396         SKIPA
1397 OPMFIL:  SETZM  WRT-1(P)
1398
1399 IFN ITS,[
1400         HRRZ    C,VER-1(P)              ; GET VERSION NUMBER
1401         PUSHJ   P,NTOSIX                ; CONVERT TO SIXBIT
1402         HRLI    C,(SIXBIT /SAV/)        ; BUILD SECOND FILE NAME
1403         HLRZ    0,VER-1(P)
1404         SKIPE   0                       ; SKIP IF SAV
1405          HRLI   C,(SIXBIT/FIX/)
1406         MOVE    B,NAM-1(P)              ; GET NAME
1407         MOVSI   A,7                     ; WRITE MODE
1408         SKIPL   WRT-1(P)
1409          MOVSI  A,6                     ; READ MODE
1410 RETOPN: .CALL   FOPBLK
1411          JRST   OPCHK                   ; SEE IF FIXUP IS NECESSARY OR JUST REOPENING
1412         DOTCAL  FILLEN,[[1000,,MAPCH],[2000,,A]]
1413          .LOSE  1000
1414         ADDI    A,PGMSK                 ; ROUND
1415         ASH     A,-PGSHFT               ; TO PAGES
1416         MOVEM   A,FLEN-1(P)
1417         SETZM   SPAG-1(P)
1418         AOS     (P)                     ; SKIP RETURN TO SHOW SUCCESS
1419         POPJ    P,
1420
1421 OPCHK: .STATUS  MAPCH,0                 ; GET STATUS BITS
1422         LDB     0,[220600,,0]
1423         CAIE    0,4                     ; SKIP IF FNF
1424          JRST   OPCHK1                  ; RETRY
1425         POPJ    P,
1426
1427 OPCHK1: MOVEI   0,1                     ; SLEEP FOR A WHILE
1428         .SLEEP
1429         JRST    OPCHK
1430
1431 ; NTOSIX GETS NUMBER IN C AND CONVERTS IT TO SIXBIT AND RETURNS RESULT IN C
1432  
1433 NTOSIX: PUSH    P,A                     ; SAVE A AND B
1434         PUSH    P,B
1435         PUSH    P,D
1436         MOVE    D,[220600,,C]
1437         MOVEI   A,(C)                   ; GET NUMBER
1438         MOVEI   C,0
1439         IDIVI   A,100.                  ; GET RESULT OF DIVISION
1440         SKIPN   A
1441          JRST   ALADD
1442         ADDI    A,20                    ; CONVERT TO DIGIT
1443         IDPB    A,D
1444 ALADD:  MOVEI   A,(B)
1445         IDIVI   A,10.                   ; GET TENS DIGIT
1446         SKIPN   C
1447          SKIPE  A                       ; IF BOTH 0 BLANK DIGIT
1448           ADDI  A,20
1449         IDPB    A,D
1450         SKIPN   C
1451          SKIPE  B
1452           ADDI  B,20
1453         IDPB    B,D
1454         POP     P,D
1455         POP     P,B
1456         POP     P,A
1457         POPJ    P,
1458
1459 ]
1460
1461 IFE ITS,[
1462         MOVE    E,P             ; save pdl base
1463         MOVE    B,NAM-1(E)              ; GET FIRST NAME
1464         PUSH    P,C%0           ; [0]; slots for building strings
1465         PUSH    P,C%0           ; [0]
1466         MOVE    A,[440700,,1(E)]
1467         MOVE    C,[440600,,B]
1468         
1469 ; DUMP OUT SIXBIT NAME
1470
1471         MOVEI   D,6
1472         ILDB    0,C
1473         JUMPE   0,.+4           ; violate cardinal ".+ rule"
1474         ADDI    0,40            ; to ASCII
1475         IDPB    0,A
1476         SOJG    D,.-4
1477
1478         MOVE    0,[ASCII /  SAV/]
1479         HLRZ    C,VER-1(E)              ; GET SAV/FIXUP FLAG
1480         SKIPE   C
1481          MOVE   0,[ASCII /  FIX/]
1482         PUSH    P,0 
1483         HRRZ    C,VER-1(E)              ; get ascii of vers no.
1484         PUSHJ   P,NTOSEV        ; CONVERT TO STRING LEFT JUSTIFIED
1485         PUSH    P,C
1486         MOVEI   B,-1(P)         ; point to it
1487         HRLI    B,260700
1488         HRROI   D,1(E)          ; point to name
1489         MOVEI   A,1(P)
1490         MOVSI   0,100000        ; INPUT FILE (GJ%OLD)
1491         SKIPGE  WRT-1(E)
1492          MOVSI  0,400000        ; OUTPUT FILE (GJ%FOU)
1493         PUSH    P,0
1494         PUSH    P,[377777,,377777]
1495         MOVE    0,[-1,,[ASCIZ /DSK/]]
1496         SKIPN   OPSYS
1497          MOVE   0,[-1,,[ASCIZ /PS/]]
1498         PUSH    P,0
1499         HRROI   0,[ASCIZ /MDL/]
1500         SKIPLE  WRT-1(E)                
1501          HRROI  0,[ASCIZ /MDLLIB/]      ; USE MDLLIB FOR SPECIAL CASE
1502         PUSH    P,0
1503         PUSH    P,D
1504         PUSH    P,B
1505         PUSH    P,C%0           ; [0]
1506         PUSH    P,C%0           ; [0]
1507         PUSH    P,C%0           ; [0]
1508         MOVEI   B,0
1509         MOVE    D,4(E)          ; save final version string
1510         GTJFN
1511          JRST   OPMLOS          ; FAILURE
1512         MOVEM   A,DIRCHN
1513         MOVE    B,[440000,,OF%RD+OF%EX]
1514         SKIPGE  WRT-1(E)
1515          MOVE   B,[440000,,OF%RD+OF%WR]
1516         OPENF
1517          FATAL  OPENF FAILED
1518         MOVE    P,E             ; flush crap
1519         PUSH    P,A
1520         SIZEF                   ; get length
1521          JRST   MAPLOS
1522         SKIPL   WRT-1(E)
1523          MOVEM  C,FLEN-1(E)     ; ONLY SAVE LENGTH FOR READ JFNS
1524         SETZM   SPAG-1(E)
1525
1526 ; RESTORE STACK AND LEAVE
1527
1528         MOVE    P,E
1529         MOVE    A,C             ; NUMBER OF PAGES IN A, DAMN!
1530         AOS     (P)
1531         POPJ    P,
1532
1533 OPMLOS: MOVE    P,E
1534         POPJ    P,
1535
1536 ; CONVERT A NUMBER IN C TO AN ASCII STRING LEFT JUSTIFIED IN C
1537
1538 NTOSEV: PUSH    P,A                     ; SAVE A AND B
1539         PUSH    P,B
1540         PUSH    P,D
1541         MOVE    D,[440700,,C]
1542         MOVEI   A,(C)                   ; GET NUMBER
1543         MOVEI   C,0
1544         IDIVI   A,100.                  ; GET RESULT OF DIVISION
1545         JUMPE   A,ALADD
1546         ADDI    A,60                    ; CONVERT TO DIGIT
1547         IDPB    A,D
1548 ALADD:  MOVEI   A,(B)
1549         IDIVI   A,10.                   ; GET TENS DIGIT
1550         ADDI    A,60
1551         IDPB    A,D
1552 ALADD1: ADDI    B,60
1553         IDPB    B,D
1554         POP     P,D
1555         POP     P,B
1556         POP     P,A
1557         POPJ    P,
1558
1559 ]
1560
1561 ; ROUTINE TO READ IN THE FIXUPS FROM DIRCHN OR MAPCH WORKS
1562 ; FOR FIXUP FILE OR FIXUPS IN A SEPERATE FILE AS LONG AS THE
1563 ; CHANNEL IS OPENED AND ACCESSED TO THE RIGHT PLACE
1564
1565 RFXUP:
1566 IFN ITS,[
1567         MOVE    0,[-2,,A]               ; PREPARE TO READ VERSION AND LENGTH
1568         .IOT    MAPCH,0                 ; READ IT IN
1569         SKIPGE  0                       ; SKIP IF NOT HIT EOF
1570         FATAL   BAD FIXUP FILE
1571         MOVEI   A,-2(A)                 ; COUNT FOR FIRST 2 WORDS
1572         HRRM    B,VER-1(P)              ; SAVE VERSION #
1573         .IOPUS  MAPCH,                  ; PUSH THE MAPPING CHANNEL
1574         SETOM   PLODR
1575         PUSHJ   P,IBLOCK                ; GET A UVECTOR OF APPROPRIATE SIZE
1576         SETZM   PLODR
1577         .IOPOP  MAPCH,
1578         MOVE    0,$TUVEC
1579         MOVEM   0,-1(TP)                ; SAVE UVECTOR
1580         MOVEM   B,(TP)
1581         MOVE    A,B                     ; GET AOBJN POINTER TO UVECTOR FOR IOT
1582         .IOT    MAPCH,A                 ; GET FIXUPS
1583         .CLOSE  MAPCH,
1584         POPJ    P,
1585 ]
1586
1587 IFE ITS,[
1588         MOVE    A,DIRCHN
1589         BIN                             ; GET LENGTH OF FIXUP
1590         MOVE    C,B
1591         MOVE    A,DIRCHN
1592         BIN                             ; GET VERSION NUMBER
1593         HRRM    B,VER-1(P)
1594         SETOM   PLODR
1595         MOVEI   A,-2(C)
1596         PUSHJ   P,IBLOCK
1597         SETZM   PLODR
1598         MOVSI   0,$TUVEC
1599         MOVEM   0,-1(TP)
1600         MOVEM   B,(TP)
1601         MOVE    A,DIRCHN
1602         HLRE    C,B
1603 ;       SKIPE   OPSYS           ; SKIP IF TOPS20 SINCE C MUST BE NEGETIVE
1604 ;        MOVNS  C               ; C IS POSITIVE FOR TENEX ?????
1605         HRLI    B,444400
1606         SIN
1607         MOVE    A,DIRCHN
1608         CLOSF
1609          FATAL  CANT CLOSE FIXUP FILE
1610         RLJFN
1611          JFCL
1612         POPJ    P,
1613 ]
1614
1615 ; ROUTINE TO READ IN THE CODE
1616
1617 RSAV:   MOVE    A,FLEN-1(P)
1618         PUSHJ   P,ALOPAG                ; GET PAGES
1619         JRST    MAPLS2
1620         MOVE    E,SPAG-1(P)
1621
1622 IFN ITS,[
1623         MOVN    A,FLEN-1(P)     ; build aobjn pointer
1624         MOVSI   A,(A)
1625         HRRI    A,(B)
1626         MOVE    B,A
1627         HRRI    0,(E)
1628         DOTCAL  CORBLK,[[1000,,104000],[1000,,-1],A,[1000,,MAPCH],0]
1629          .LOSE  %LSSYS
1630         .CLOSE  MAPCH,
1631         POPJ    P,
1632 ]
1633 IFE ITS,[
1634         PUSH    P,B             ; SAVE PAGE #
1635         MOVS    A,DIRCHN        ; SOURCE (MUDSAV)
1636         HLRM    A,SJFNS         ; SAVE POINTER FOR FUTURE CLOSING
1637         HRR     A,E
1638         HRLI    B,.FHSLF        ; DESTINATION (FORK)
1639         MOVSI   C,PM%RD+PM%CPY  ; MAKE COPY ON WRITE
1640         SKIPE   OPSYS
1641          JRST   RSAV1           ; HANDLE TENEX
1642         TLO     C,PM%CNT        ; REPEAT COUNT BIT FOR TOPS20
1643         HRR     C,FLEN-2(P)     ; PAGE (FOR PUSHJ AND PUSHED B)
1644         PMAP
1645 RSAVDN: POP     P,B
1646         MOVN    0,FLEN-1(P)
1647         HRL     B,0
1648         POPJ    P,
1649
1650 RSAV1:  HRRZ    D,FLEN-2(P)     ; GET IN PAGE COUNT
1651 RSAV2:  PMAP
1652         ADDI    A,1             ; NEXT PAGE
1653         ADDI    B,1     
1654         SOJN    D,RSAV2         ; LOOP
1655         JRST    RSAVDN
1656 ]
1657
1658 PDLOV:  SUB     P,[NSLOTS,,NSLOTS]
1659         PUSH    P,C%0           ; [0]; CAUSE A PDL OVERFLOW
1660         JRST    .-1
1661
1662 ; CONSTANTS RELATED TO DATA BASE
1663 DEV:    SIXBIT /DSK/
1664 MODE:   6,,0
1665 MNDIR:  SIXBIT /MUDSAV/                         ; DIR OF MAIN DATA BASE FILES
1666 WRKDIR: SIXBIT /MUDTMP/                         ; DIRECTORY OF UPDATE FILES
1667
1668 IFN ITS,[
1669 MNBLK:  SETZ
1670         SIXBIT /OPEN/
1671         MODE
1672         DEV
1673         [SIXBIT /SAV/]
1674         [SIXBIT /FILE/]
1675         SETZ MNDIR
1676
1677
1678 FIXBLK: SETZ
1679         SIXBIT /OPEN/
1680         MODE
1681         DEV
1682         [SIXBIT /FIXUP/]
1683         [SIXBIT /FILE/]
1684         SETZ MNDIR
1685
1686 FOPBLK: SETZ
1687         SIXBIT /OPEN/
1688         A
1689         DEV
1690         B
1691         C
1692         SETZ WRKDIR
1693
1694 FXTBL:  -2,,.+1
1695         55.
1696         54.
1697 ]
1698 IFE ITS,[
1699
1700 FXSTR:  ASCIZ /PS:<MDL>FIXUP.FILE/
1701 SAVSTR: ASCIZ /PS:<MDL>SAV.FILE/
1702 TFXSTR: ASCIZ /DSK:<MDL>FIXUP.FILE/
1703 TSAVST: ASCIZ /DSK:<MDL>SAV.FILE/
1704
1705 FXTBL:  -3,,.+1
1706         55.
1707         54.
1708         104.
1709 ]
1710 IFN SPCFXU,[
1711
1712 ;This code does two things to code for FBIN;
1713 ;       1)      Makes dispatches win in multi seg mode
1714 ;       2)      Makes OBLIST? work with "new" atom format
1715 ;       3)      Makes LENGTH win in multi seg mode
1716 ;       4)      Gets AOBJN pointer to code vector in C
1717
1718 SFIX:   PUSH    P,A
1719         PUSH    P,B
1720         PUSH    P,C             ; for referring back
1721
1722 SFIX1:  MOVSI   B,-MLNT         ; for looping through tables    
1723
1724 SFIX2:  MOVE    A,(C)           ; get code word
1725
1726         AND     A,SMSKS(B)
1727         CAMN    A,SPECS(B)      ; do we match
1728          JRST   @SFIXR(B)
1729
1730         AOBJN   B,SFIX2
1731
1732 SFIX3:  AOBJN   C,SFIX1         ; do all of code
1733 SFIX4:  POP     P,C
1734         POP     P,B
1735         POP     P,A
1736         POPJ    P,
1737
1738 SMSKS:  -1
1739         777000,,-1
1740         -1,,0
1741         777037,,0
1742 MLNT==.-SMSKS
1743
1744 SPECS:  HLRES   A               ; begin of arg diaptch table
1745         SKIPN   2               ; old compiled OBLIST?
1746         JRST    (M)             ; compiled LENGTH
1747         ADDI    (M)             ; begin a case dispatch
1748
1749 SFIXR:  SETZ    DFIX
1750         SETZ    OBLFIX
1751         SETZ    LFIX
1752         SETZ    CFIX
1753
1754 DFIX:   AOBJP   C,SFIX4         ; make sure dont run out
1755         MOVE    A,(C)           ; next ins
1756         CAME    A,[ASH A,-1]    ; still winning?
1757          JRST   SFIX3           ; false alarm
1758         AOBJP   C,SFIX4         ; make sure dont run out
1759         HLRZ    A,(C)           ; next ins
1760         CAIE    A,(ADDI A,(M))  ; still winning?
1761          JRST   SFIX3           ; false alarm
1762         AOBJP   C,SFIX4
1763         HLRZ    A,(C)
1764         CAIE    A,(PUSHJ P,@(A))        ; last one to check
1765          JRST   SFIX3
1766         AOBJP   C,SFIX4
1767         MOVE    A,(C)
1768         CAME    A,[JRST FINIS]          ; extra check
1769          JRST   SFIX3
1770
1771         MOVSI   B,(SETZ)
1772 SFIX5:  AOBJP   C,SFIX4
1773         HLRZ    A,(C)
1774         CAIN    A,(SUBM M,(P))
1775          JRST   SFIX3
1776         CAIE    A,M                     ; dispatch entry?
1777          JRST   SFIX3           ; maybe already fixed
1778         IORM    B,(C)           ; fix it
1779         JRST    SFIX5
1780
1781 OBLFIX: PUSH    P,[-TLN,,TPTR]
1782         PUSH    P,C
1783         MOVE    B,-1(P)
1784
1785 OBLFXY: PUSH    P,1(B)
1786         PUSH    P,(B)
1787
1788 OBLFI1: AOBJP   C,OBLFXX
1789         MOVE    A,(C)
1790         AOS     B,(P)
1791         AND     A,(B)
1792         MOVE    B,-1(P)
1793         CAME    A,(B)
1794          JRST   OBLFXX
1795         AOBJP   B,DOOBFX
1796         MOVEM   B,-1(P)
1797         JRST    OBLFI1
1798
1799 OBLFXX: SUB     P,C%22          ; for checking more ins
1800         MOVE    B,-1(P)
1801         ADD     B,C%22
1802         JUMPGE  B,OBLFX1
1803         MOVEM   B,-1(P)
1804         MOVE    C,(P)
1805         JRST    OBLFXY
1806
1807
1808 INSBP==331100                   ; byte pointer for ins field
1809 ACBP==270400                    ; also for ac
1810 INDXBP==220400
1811
1812 DOOBFX: MOVE    C,-2(P)
1813         SUB     P,C%44
1814         MOVEI   B,<<(HRRZ)>_<-9>>       ; change em
1815         DPB     B,[INSBP,,(C)]  ; SKIPN==>HRRZ
1816         LDB     A,[ACBP,,(C)]   ; get AC field
1817         MOVEI   B,<<(JUMPE)>_<-9>>
1818         DPB     B,[INSBP,,1(C)]
1819         DPB     A,[ACBP,,1(C)]
1820         AOS     1(C)            ; JRST FOO==>JUMPE ac,FOO+1
1821         MOVE    B,[CAMG VECBOT]
1822         DPB     A,[ACBP,,B]
1823         MOVEM   B,2(C)          ; JUMPL ==> CAMG ac,VECBOT
1824         HRRZ    A,3(C)          ; get indicator of existence of ADD AC,TVP
1825         CAIE    A,TVP           ; skip if extra ins exists
1826          JRST   NOATVP
1827         MOVSI   A,(JFCL)
1828         EXCH    A,4(C)
1829         MOVEM   A,3(C)
1830         ADD     C,C%11
1831 NOATVP: TLC     B,(CAMG#HRLI)   ; change CAMG to HRLI (preserving AC)
1832         HRRZ    A,4(C)          ; see if moves in type
1833         CAIE    A,$TOBLS
1834          SUB    C,[1,,1]        ; fudge it
1835         HLLOM   B,5(C)          ; in goes HRLI -1
1836         CAIE    A,$TOBLS        ; do we need a skip?
1837          JRST   NOOB$
1838         MOVSI   B,(CAIA)        ;  skipper
1839         EXCH    B,6(C)
1840         MOVEM   B,7(C)
1841         ADD     C,[7,,7]
1842         JRST    SFIX3
1843
1844 NOOB$:  MOVSI   B,(JFCL)
1845         MOVEM   B,6(C)
1846         ADD     C,C%66
1847         JRST    SFIX3
1848
1849 OBLFX1: MOVE    C,(P)
1850         SUB     P,C%22
1851         JRST    SFIX3
1852
1853 ; Here to fixup compiled LENGTH
1854
1855 LFIX:   MOVSI   B,-LLN          ; for checking other LENGTH ins
1856         PUSH    P,C
1857
1858 LFIX1:  AOBJP   C,LFIXY
1859         MOVE    A,(C)
1860         AND     A,LMSK(B)
1861         CAME    A,LINS(B)
1862          JRST   LFIXY
1863         AOBJN   B,LFIX1
1864
1865         POP     P,C             ; restore code pointer
1866         MOVE    A,(C)           ; save jump for its addr
1867         MOVE    B,[MOVSI 400000]
1868         MOVEM   B,(C)           ; JRST .+2 ==> MOVSI 0,400000
1869         LDB     B,[ACBP,,1(C)]  ; B==> AC of interest
1870         ADDI    A,2
1871         DPB     B,[ACBP,,A]
1872         MOVEI   B,<<(JUMPE)>_<-9.>>
1873         DPB     B,[INSBP,,A]
1874         EXCH    A,1(C)
1875         TLC     A,(HRR#HRRZ)    ; HRR==>HRRZ
1876         HLLZM   A,2(C)          ; TRNN AC,-1 ==> HRRZ AC,(AC)
1877         MOVEI   B,(AOBJN (M))
1878         HRLM    B,3(C)          ; AOBJP AC,.-2 ==> AOBJN 0,.-2
1879         MOVE    B,2(C)          ; get HRRZ AC,(AC)
1880         TLZ     B,17            ; kill (AC) part
1881         MOVEM   B,4(C)          ; HLRZS AC ==> HRRZ AC,0
1882         ADD     C,C%44
1883         JRST    SFIX3
1884
1885 LFIXY:  POP     P,C
1886         JRST    SFIX3
1887
1888 ; Fixup a CASE dispatch
1889
1890  CFIX:  LDB     A,[ACBP,,(C)]
1891         AOBJP   C,SFIX4
1892         HLRZ    B,(C)           ; Next ins
1893         ANDI    B,777760
1894         CAIE    B,(JRST @)
1895          JRST   SFIX3
1896         LDB     B,[INDXBP,,(C)]
1897         CAIE    A,(B)
1898          JRST   SFIX3
1899         MOVE    A,(C)           ; ok, fix it up
1900         TLZ     A,20            ; kill indirection
1901         MOVEM   A,(C)
1902         HRRZ    B,-1(C)         ; point to table
1903         ADD     B,(P)           ; point to code to change
1904
1905 CFIXLP: HLRZ    A,(B)           ; check one out
1906         TRZ     A,400000        ; kill bit
1907         CAIE    A,M             ; check for just index (or index with SETZ)
1908          JRST   SFIX3
1909         MOVEI   A,(JRST (M))
1910         HRLM    A,(B)
1911         AOJA    B,CFIXLP
1912
1913 DEFINE FOO LBL,LNT,LBL2,L
1914 LBL:
1915         IRP A,,[L]
1916                 IRP B,C,[A]
1917                         B
1918                         .ISTOP
1919                 TERMIN
1920         TERMIN
1921 LNT==.-LBL
1922 LBL2:
1923         IRP A,,[L]
1924                 IRP B,C,[A]
1925                         C
1926                         .ISTOP
1927                 TERMIN
1928         TERMIN
1929 TERMIN
1930
1931 IMSK==777017,,0
1932 AIMSK==777000,,-1
1933
1934 FOO OINS,OLN,OMSK,[[<JRST (M)>,IMSK],[<JUMPL (M)>,IMSK],[MOVE,AIMSK]
1935                    [<MOVE $TOBLS>,AIMSK],[<JRST (M)>,IMSK]
1936                    [<MOVE $TFALSE>,AIMSK],[MOVEI,AIMSK]]
1937
1938 FOO OINS3,OLN3,OMSK3,[[<JRST (M)>,IMSK],[<JUMPL (M)>,IMSK],[MOVE,AIMSK]
1939                       [<JRST (M)>,IMSK],[MOVEI,AIMSK]]
1940
1941 FOO OINS2,OLN2,OMSK2,[[<JRST (M)>,IMSK],[<JUMPL (M)>,IMSK],[<ADD TVP>,AIMSK]
1942                       [MOVE,AIMSK],[<MOVE $TOBLS>,AIMSK],[<JRST (M)>,IMSK]
1943                       [<MOVE $TFALSE>,AIMSK],[MOVEI,AIMSK]]
1944
1945 FOO OINS4,OLN4,OMSK4,[[<JRST (M)>,IMSK],[<JUMPL (M)>,IMSK],[<ADD TVP>,AIMSK]
1946                       [MOVE,AIMSK],[<JRST (M)>,IMSK],[MOVEI,AIMSK]]
1947
1948 TPTR:   -OLN,,OINS
1949         OMSK-1
1950         -OLN2,,OINS2
1951         OMSK2-1
1952         -OLN3,,OINS3
1953         OMSK3-1
1954         -OLN4,,OINS4
1955         OMSK4-1
1956 TLN==.-TPTR
1957
1958 FOO LINS,LLN,LMSK,[[<HRR -1>,AIMSK],[<TRNE -1>,AIMSK],[<AOBJP (M)>,IMSK]
1959                    [<HLRZS>,<-1,,777760>]]
1960
1961 ]
1962 IMPURE
1963
1964 SAVSNM: 0                                       ; SAVED SNAME
1965 INPLOD: 0                                       ; FLAG SAYING WE ARE IN MAPPUR
1966
1967 IFE ITS,[
1968 MAPJFN: 0                                       ; JFN OF <MDL>SAV FILE
1969 DIRCHN: 0                                       ; JFN USED BY GETDIR
1970 ]
1971
1972 PURE
1973
1974 END
1975