1 TITLE PURE-PAGE LOADER
\r
5 MAPCH==0 ; channel for MAPing
\r
6 ELN==3 ; Length of table entry
\r
8 .GLOBAL PURVEC,PURTOP,PURBOT,P.TOP,MUDSTR,STRTO6,PLOAD,AGC,GCDOWN
\r
9 .GLOBAL SQUTOA,IGVAL,IBLOCK,PURCLN,MOVPUR,GETPAG,GCFLG,NOSHUF
\r
16 IF1, .INSRT STENEX >
\r
20 PURDIR==SIXBIT /MUD50/ ; directory containing pure pages
\r
21 OPURDI==SIXBIT /MHILIB/
\r
22 OFIXDI==SIXBIT /MHILIB/
\r
23 FIXDIR==SIXBIT /MUD50/
\r
24 ARC==1 ; flag saying fixups on archive
\r
35 ; This routine taskes a slot offset in register A and
\r
36 ; maps in the associated file. It clobbers all ACs
\r
37 ; It skip returns if it wins.
\r
39 PLOAD: PUSH P,A ; save slot offset
\r
40 ADD A,PURVEC+1(TVP) ; point into pure vector
\r
41 MOVE B,(A) ; get sixbit of name
\r
43 MOVE C,MUDSTR+2 ; get version number
\r
44 PUSHJ P,CSIXBT ; vers # to six bit
\r
45 HRRI C,(SIXBIT /SAV/)
\r
47 .SUSET [.RSNAM,,0] ; GET CURRENT SNAME TO 0
\r
48 .SUSET [.SSNAM,,[PURDIR]] ; get sname for it
\r
49 MOVE A,[SIXBIT / &DSK/] ; build open block
\r
50 .OPEN MAPCH,A ; try to open file
\r
51 JRST FIXITU ; no current version, fix one up
\r
52 PUSH P,0 ; for compat wit tenex and save old sname
\r
53 DOTCAL FILLEN,[[1000,,MAPCH],[2000,,A]]
\r
55 ADDI A,PGMSK ; in case not even # of pages
\r
56 ASH A,-PGSHFT ; to pages
\r
57 PUSH P,A ; save the length
\r
60 MOVE E,P ; save pdl base
\r
61 PUSH P,[0] ; slots for building strings
\r
63 MOVE A,[440700,,1(E)]
\r
67 JUMPE 0,.+4 ; violate cardinal ".+ rule"
\r
68 ADDI 0,40 ; to ASCII
\r
72 PUSH P,[ASCII / SAV/]
\r
73 MOVE C,MUDSTR+2 ; get ascii of vers no.
\r
74 IORI C,1 ; hair to change r.o. to space
\r
77 ANDCM C,0 ; C has 1st 1
\r
79 MOVEI 0,0 ; use zer name
\r
83 AND 0,MSKS(C) ; get rid of r.o.s
\r
85 MOVEI B,-1(P) ; point to it
\r
87 HRROI D,1(E) ; point to name
\r
91 PUSH P,[377777,,377777]
\r
92 PUSH P,[-1,,[ASCIZ /DSK/]]
\r
93 PUSH P,[-1,,[ASCIZ /MUDLIB/]]
\r
100 MOVE D,4(E) ; save final version string
\r
104 MOVE B,[440000,,240000]
\r
107 MOVE P,E ; flush crap
\r
111 PUSH P,C ; save # of pages
\r
114 PUSHJ P,ALOPAG ; get the necessary pages
\r
116 PUSH P,B ; save page number
\r
118 MOVN A,-1(P) ; get neg count
\r
119 MOVSI A,(A) ; build aobjn pointer
\r
120 HRR A,(P) ; get page to start
\r
121 MOVE B,A ; save for later
\r
122 HLLZ 0,A ; page pointer for file
\r
123 DOTCAL CORBLK,[[1000,,200000],[1000,,-1],A,[1000,,MAPCH],0]
\r
124 JRST MAPLS3 ; total wipe out
\r
125 .CLOSE MAPCH, ; no need to have file open anymore
\r
128 MOVE D,-1(P) ; # of pages to D
\r
129 HRLI B,400000 ; specify this fork
\r
130 HRROI E,(B) ; build page aobjn for later
\r
131 TLC E,-1(D) ; sexy way of doing lh
\r
132 HRLZ A,-2(P) ; JFN to lh of A
\r
133 MOVSI C,120000 ; bits for read/execute
\r
138 SOJG D,.-3 ; map 'em all
\r
140 CLOSF ; try to close file
\r
141 JFCL ; ignore failure
\r
145 ; now try to smash slot in PURVEC
\r
147 PLOAD1: MOVE A,PURVEC+1(TVP) ; get pointer to it
\r
148 ASH B,PGSHFT ; convert to aobjn pointer to words
\r
149 MOVE C,-3(P) ; get slot offset
\r
150 ADDI C,(A) ; point to slot
\r
151 MOVEM B,1(C) ; clobber it in
\r
152 ANDI B,-1 ; isolate address of page
\r
153 HRRZ D,PURVEC(TVP) ; get offset into vector for start of chain
\r
154 TRNE D,400000 ; skip if not end marker
\r
156 HRLI D,A ; set up indexed pointer
\r
158 HRRZ 0,@D ; get its address
\r
159 JUMPE 0,SCHAIN ; no chain exists, start one
\r
160 CAILE 0,(B) ; skip if new one should be first
\r
161 AOJA D,INLOOP ; jump into the loop
\r
163 SUBI D,1 ; undo ADDI
\r
164 FCLOB: MOVE E,-3(P) ; get offset for this guy
\r
165 HRRM D,2(C) ; link up
\r
166 HRRM E,PURVEC(TVP) ; store him away
\r
169 SCHAIN: MOVEI D,400000 ; get end of chain indicator
\r
170 JRST FCLOB ; and clobber it in
\r
172 INLOOP: MOVE E,D ; save in case of later link up
\r
173 HRR D,@D ; point to next table entry
\r
174 TRNE D,400000 ; 400000 is the end of chain bit
\r
175 JRST SLFOUN ; found a slot, leave loop
\r
176 ADDI D,1 ; point to address of progs
\r
177 HRRZ 0,@D ; get address of block
\r
178 CAILE 0,(B) ; skip if still haven't fit it in
\r
179 AOJA D,INLOOP ; back to loop start and point to chain link
\r
180 SUBI D,1 ; point back to start of slot
\r
182 SLFOUN: MOVE 0,-3(P) ; get offset into vector of this guy
\r
183 HRRM 0,@E ; make previous point to us
\r
184 HRRM D,2(C) ; link it in
\r
187 PLOADD: AOS -4(P) ; skip return
\r
189 MAPLS3: SUB P,[1,,1] ; flush stack crap
\r
190 MAPLS1: SUB P,[1,,1]
\r
194 .SUSET [.SSNAM,,0] ; restore SNAME
\r
199 ; Here if no current version exists
\r
201 FIXITU: PUSH TP,$TFIX
\r
202 PUSH TP,0 ; maybe save sname
\r
205 PUSH P,C ; save final name
\r
206 MOVE C,[SIXBIT /FIXUP/] ; name of fixup file
\r
207 IFN <PURDIR-OFIXDI>,.SUSET [.SSNAM,,[OFIXDI]]
\r
208 IFN ARC, HRRI A,(SIXBIT /ARC/)
\r
210 IFE ARC, JRST MAPLOS
\r
211 IFN ARC, PUSHJ P,ARCLOS
\r
212 MOVE 0,[-2,,A] ; prepare to read version and length
\r
213 PUSH P,B ; save program name
\r
216 FATAL BAD FIXUP FILE
\r
217 PUSH P,B ; save version number of fixup file
\r
218 MOVEI A,-2(A) ; length -2 (for vers and length)
\r
219 PUSHJ P,IBLOCK ; get a UVECTOR for the fixups
\r
220 PUSH TP,$TUVEC ; and save
\r
224 MOVEM 0,ASTO(PVP) ; prepare for moby iot (interruptable)
\r
226 .IOT MAPCH,A ; get fixups
\r
230 POP P,A ; restore version number
\r
231 IDIVI A,100. ; get 100s digit in a rest in B
\r
232 ADDI A,20 ; convert to sixbit
\r
233 IDIVI B,10. ; B tens digit C 1s digit
\r
237 MOVSI D,(SIXBIT /SAV/)
\r
243 MOVE B,[SIXBIT / &DSK/]
\r
244 MOVE C,(P) ; program name
\r
245 IFN <OPURDI-OFIXDI>,.SUSET [.SSNAM,,[OPURDI]]
\r
246 .OPEN MAPCH,B ; try for this one
\r
248 DOTCAL FILLEN,[[1000,,MAPCH],[2000,,A]]
\r
250 ADDI A,PGMSK ; in case not exact pages
\r
251 ASH A,-PGSHFT ; to pages
\r
253 PUSHJ P,ALOPAG ; find some pages
\r
255 MOVN A,(P) ; build aobjn pointer
\r
260 DOTCAL CORBLK,[[1000,,104000],[1000,,-1],A,[1000,,MAPCH],0]
\r
266 PUSH TP,$TPDL ; save stack pointer
\r
268 PUSH P,D ; save vers string
\r
269 HRROI A,[ASCIZ /FIXUP/]
\r
270 MOVEM A,10.(E) ; into name slot
\r
271 MOVEI A,5(E) ; point to arg block
\r
275 MOVEI C,(A) ; save JFN in case OPNEF loses
\r
276 MOVE B,[440000,,200000]
\r
279 BIN ; length of fixups to B
\r
280 PUSH P,A ; save JFN
\r
281 MOVEI A,-2(B) ; length of uvextor to get
\r
285 POP P,A ; restore JFN
\r
286 BIN ; read in vers #
\r
287 MOVE D,B ; save vers #
\r
291 SIN ; read in entire fixups
\r
292 CLOSF ; and close file of same
\r
293 JFCL ; ignore cailure to close
\r
294 HRROI C,1(E) ; point to name
\r
300 MOVEM 0,4(E) ; all spaces
\r
302 IDIVI A,100. ; to ascii
\r
307 MOVE 0,[440700,,4(E)]
\r
314 MOVEI A,5(E) ; ready for 'nother GTJFN
\r
317 MOVEI C,(A) ; save JFN in case OPENF loses
\r
318 MOVE B,[440000,,240000]
\r
326 PUSHJ P,ALOPAG ; get the pages
\r
328 MOVEI D,(B) ; save pointer
\r
329 MOVN A,(P) ; build page aobjn pntr
\r
331 EXCH D,(P) ; get length
\r
334 HRLZ A,-1(P) ; JFN for PMAP
\r
335 MOVSI C,120400 ; bits for read/execute/copy-on-write
\r
345 POP P,B ; restore page #
\r
350 MOVE A,(TP) ; pointer to them
\r
351 ASH B,PGSHFT ; aobjn to program
\r
353 FIX1: SKIPL E,(A) ; read one hopefully squoze
\r
354 FATAL ATTEMPT TO TYPE FIX PURE
\r
356 PUSHJ P,SQUTOA ; look it up
\r
360 HLRZ D,(A) ; get old value
\r
361 SUBM E,D ; D is diff between old and new
\r
362 HRLM E,(A) ; fixup the fixups
\r
363 MOVEI 0,0 ; flag for which half
\r
364 FIX4: JUMPE 0,FIXRH ; jump if getting rh
\r
365 MOVEI 0,0 ; next time will get rh
\r
366 AOBJP A,FIX2 ; done?
\r
367 HLRZ C,(A) ; get lh
\r
368 JUMPE C,FIX3 ; 0 terminates
\r
369 FIX5: ADDI C,(B) ; access the code
\r
370 ADDM D,-1(C) ; and fix it up
\r
373 FIXRH: MOVEI 0,1 ; change flag
\r
374 HRRZ C,(A) ; get it and
\r
377 FIX3: AOBJN A,FIX1 ; do next one
\r
381 IFN <PURDIR-OPURDI> .SUSET [.SSNAM,,[PURDIR]]
\r
382 .OPEN MAPCH,[SIXBIT / 'DSK_PURE_>/]
\r
384 MOVE E,B ; save pointer
\r
385 ASH E,-PGSHFT ; to page AOBJN
\r
386 .IOT MAPCH,B ; write out the goodie
\r
391 .FDELE 0 ; attempt to rename to right thing
\r
394 MOVE B,[SIXBIT / &DSK/]
\r
396 FATAL WHERE DID THE FILE GO?
\r
397 HLLZ 0,E ; pointer to file pages
\r
398 PUSH P,E ; SAVE FOR END
\r
399 DOTCAL CORBLK,[[1000,,200000],[1000,,-1],E,[1000,,MAPCH],0]
\r
400 FATAL LOSSAGE LOSSAGE PAGES LOST
\r
403 SKIPGE MUDSTR+2 ; skip if not experimental
\r
405 PUSHJ P,GENVN ; get version number as a number
\r
407 IFN <PURDIR-FIXDIR>,.SUSET [.SSNAM,,[FIXDIR]]
\r
408 IFE ARC, .OPEN MAPCH,[SIXBIT / 'DSK_FIXU_>/]
\r
409 IFN ARC, .OPEN MAPCH,[SIXBIT / 'ARC_FIXU_>/]
\r
410 IFE ARC, FATAL CANT WRITE FIXUPS
\r
411 IFN ARC, PUSHJ P,ARCFAT
\r
412 HLRE A,E ; get length
\r
414 ADDI A,2 ; account for these 2 words
\r
415 MOVE 0,[-2,,A] ; write version and length
\r
417 .IOT MAPCH,E ; out go the fixups
\r
421 MOVE D,[SIXBIT /FIXUP/]
\r
423 FATAL FIXUP WRITE OUT FAILED
\r
428 MOVE E,-2(TP) ; restore P-stack base
\r
429 MOVEI 0,600000 ; fixup args to GTJFN
\r
431 MOVE D,B ; save page number
\r
432 POP P,4(E) ; current version name in
\r
433 MOVEI A,5(E) ; pointer ro arg block
\r
436 FATAL MAP FIXUP LOSSAGE
\r
437 MOVE B,[440000,,100000]
\r
439 FATAL MAP FIXUP LOSSAGE
\r
440 MOVEI B,(D) ; ready to write it out
\r
444 TLO A,400000 ; dont recycle the JFN
\r
447 ANDI A,-1 ; kill sign bit
\r
448 MOVE B,[440000,,240000]
\r
450 FATAL MAP FIXUP LOSSAGE
\r
452 ASH B,-PGSHFT ; aobjn to pages
\r
468 HRROI 0,[ASCIZ /FIXUP/] ; now write out new fixup file
\r
474 JRST NOFIXO ; exp vers, dont write out
\r
477 MOVEI D,(B) ; save vers in D
\r
479 FATAL MAP FIXUP LOSSAGE
\r
480 MOVE B,[440000,,100000]
\r
482 FATAL MAP FIXUP LOSSAGE
\r
483 HLRE B,(TP) ; length of fixup vector
\r
485 ADDI B,2 ; for length and version words
\r
487 MOVE B,D ; and vers #
\r
489 MOVSI B,444400 ; byte pointer to fixups
\r
495 NOFIXO: MOVE A,(P) ; save aobjn to pages
\r
500 HRRZ A,(P) ; get page #
\r
501 HLRE C,(P) ; and # of same
\r
502 MOVE B,(P) ; set B up for return
\r
506 MOVE 0,-2(TP) ; saved sname
\r
515 MAPLS4: .CLOSE MAPCH,
\r
520 MAPLS4: SKIPA A,[4,,4]
\r
521 MAPLS5: MOVE A,[6,,6]
\r
532 ARCLOS: PUSHJ P,CKLOCK
\r
539 ARCFAT: PUSHJ P,CKLOCK
\r
540 FATAL CANT WRITE FIXUP FILE
\r
546 CAIN 0,23 ; file locked?
\r
547 JRST WAIT ; wait and retry
\r
559 ; Here to try to get a free page block for new thing
\r
560 ; A/ # of pages to get
\r
562 ALOPAG: PUSHJ P,GETPAG ; try to get enough pages
\r
564 AOS (P) ; won skip return
\r
565 MOVEI 0,(B) ; update PURBOT/PURTOP to reflect current state
\r
570 GETPAG: MOVE C,P.TOP ; top of GC space
\r
571 ASH C,-PGSHFT ; to page number
\r
572 MOVE B,PURBOT ; current bottom of pure space
\r
573 ASH B,-PGSHFT ; also to pages
\r
574 SUBM B,C ; pages available ==> C
\r
575 CAIGE C,(A) ; skip if have enough already
\r
576 JRST GETPG1 ; no, try to shuffle around
\r
577 SUBI B,(A) ; B/ first new page
\r
579 POPJ P, ; return with new free page in B
\r
581 ; Here if shuffle must occur or gc must be done to make room
\r
584 SKIPE NOSHUF ; if can't shuffle, then ask gc
\r
586 MOVE 0,PURTOP ; get top of mapped pure area
\r
587 SUB 0,P.TOP ; total free words to 0
\r
588 ASH 0,-PGSHFT ; to pages
\r
589 CAIGE 0,(A) ; skip if winnage possible
\r
590 JRST ASKAGC ; please AGC give me some room!!
\r
591 SUBM A,C ; C/ amount we must flush to make room
\r
593 ; Here to find pages for flush using LRU algorithm
\r
595 GL1: MOVE B,PURVEC+1(TVP) ; get pointer to pure sr vector
\r
596 MOVEI 0,-1 ; get very large age
\r
598 GL2: SKIPN 1(B) ; skip if not already flushed
\r
600 HLRZ D,2(B) ; get this ones age
\r
601 CAMLE D,0 ; skip if this is a candidate
\r
603 MOVE E,B ; point to table entry with E
\r
604 MOVEI 0,(D) ; and use as current best
\r
605 GL3: ADD B,[ELN,,ELN] ; look at next
\r
608 HLRE B,1(E) ; get length of flushee
\r
609 ASH B,-PGSHFT ; to negative # of pages
\r
610 ADD C,B ; update amount needed
\r
611 SETZM 1(E) ; indicate it will be gone
\r
612 JUMPG C,GL1 ; jump if more to get
\r
614 ; Now compact pure space
\r
616 PUSH P,A ; need all acs
\r
618 HRRZ D,PURVEC(TVP) ; point to first in core addr order
\r
619 HRRZ C,PURTOP ; get destination page
\r
620 ASH C,-PGSHFT ; to page number
\r
622 CL1: ADD D,PURVEC+1(TVP) ; to real pointer
\r
623 SKIPE 1(D) ; skip if this one is a flushee
\r
626 HRRZ D,2(D) ; point to next one in chain
\r
627 JUMPN E,CL3 ; jump if not first one
\r
628 HRRM D,PURVEC(TVP) ; and use its next as first
\r
631 CL3: HRRM D,2(E) ; link up
\r
634 ; Found a stayer, move it if necessary
\r
636 CL2: MOVEI E,(D) ; another pointer to slot
\r
637 HLRE B,1(D) ; - length of block
\r
638 HRRZ D,1(D) ; pointer to block
\r
639 SUB D,B ; point to top of block
\r
640 ASH D,-PGSHFT ; to page number
\r
641 CAIN D,(C) ; if not moving, jump
\r
644 ASH B,-PGSHFT ; to pages
\r
646 CL5: SUBI C,1 ; move to pointer and from pointer
\r
648 DOTCAL CORBLK,[[1000,,200000],[1000,,-1],C,[1000,,-1],D]
\r
649 FATAL PURE SHUFFLE LOSSAGE
\r
650 AOJL B,CL5 ; count down
\r
653 PUSH P,B ; save # of pages
\r
654 MOVEI A,-1(D) ; copy from pointer
\r
655 HRLI A,400000 ; get this fork code
\r
656 RMAP ; get a JFN (hopefully)
\r
657 EXCH D,(P) ; D # of pages (save from)
\r
658 ADDM D,(P) ; update from
\r
659 MOVEI B,-1(C) ; to pointer in B
\r
661 MOVSI C,120000 ; read/execute modes
\r
666 AOJL D,.-3 ; move them all
\r
672 ; Update the table address for this loser
\r
674 SUBM C,D ; compute offset (in pages)
\r
675 ASH D,PGSHFT ; to words
\r
676 ADDM D,1(E) ; update it
\r
677 CL7: HRRZ D,2(E) ; chain on
\r
678 CL4: TRNN D,400000 ; skip if end of chain
\r
681 ASH C,PGSHFT ; to words
\r
682 MOVEM C,PURBOT ; reset pur bottom
\r
686 CL6: HRRZ C,1(E) ; get new top of world
\r
687 ASH C,-PGSHFT ; to page #
\r
690 ; SUBR to create an entry in the vector for one of these guys
\r
692 MFUNCTION PCODE,SUBR
\r
696 GETYP 0,(AB) ; check 1st arg is string
\r
699 GETYP 0,2(AB) ; second must be fix
\r
703 MOVE A,(AB) ; convert name of program to sixbit
\r
706 PCODE4: MOVE C,(P) ; get name in sixbit
\r
708 ; Now look for either this one or an empty slot
\r
711 MOVE B,PURVEC+1(TVP)
\r
713 PCODE2: CAMN C,(B) ; skip if this is not it
\r
714 JRST PCODE1 ; found it, drop out of loop
\r
715 JUMPN E,.+3 ; dont record another empty if have one
\r
716 SKIPN (B) ; skip if slot filled
\r
717 MOVE E,B ; remember pointer
\r
719 JUMPL B,PCODE2 ; jump if more to look at
\r
721 JUMPE E,PCODE3 ; if E=0, error no room
\r
722 MOVEM C,(E) ; else stash away name and zero rest
\r
727 PCODE1: MOVE E,B ; build <slot #>,,<offset>
\r
728 MOVEI 0,0 ; flag whether new slot
\r
729 SKIPE 1(E) ; skip if mapped already
\r
733 HLRE E,PURVEC+1(TVP)
\r
737 SKIPN NOSHUF ; skip if not shuffling
\r
739 JUMPN 0,FINIS ; jump if winner
\r
749 PCOERR: PUSH TP,$TATOM
\r
750 PUSH TP,EQUOTE PURE-LOAD-FAILURE
\r
754 PCODE3: HLRE A,PURVEC+1(TVP) ; get current length
\r
756 ADDI A,10*ELN ; add 10(8) more entry slots
\r
758 EXCH B,PURVEC+1(TVP) ; store new one and get old
\r
759 HLRE A,B ; -old length to A
\r
760 MOVSI B,(B) ; start making BLT pointer
\r
761 HRR B,PURVEC+1(TVP)
\r
762 SUBM B,A ; final dest to A
\r
766 ; Here if must try to GC for some more core
\r
768 ASKAGC: SKIPE GCFLG ; if already in GC, lose
\r
770 SUBM A,0 ; amount required to 0
\r
771 ASH 0,PGSHFT ; TO WORDS
\r
772 MOVEM 0,GCDOWN ; pass as funny arg to AGC
\r
773 EXCH A,C ; save A from gc's destruction
\r
774 IFN ITS, .IOPUSH MAPCH, ; gc uses same channel
\r
776 MOVE C,[8,,9.] ; SET UP INDICATORS FOR GC
\r
779 IFN ITS, .IOPOP MAPCH,
\r
783 PUSH TP,EQUOTE NO-MORE-PAGES
\r
786 ; Here to clean up pure space by flushing all shared stuff
\r
788 PURCLN: SKIPE NOSHUF
\r
791 HRRM B,PURVEC(TVP) ; flush chain pointer
\r
792 MOVE B,PURVEC+1(TVP) ; get pointer to table
\r
793 SETZM 1(B) ; zero pointer entry
\r
794 SETZM 2(B) ; zero link and age slots
\r
795 ADD B,[ELN,,ELN] ; go to next slot
\r
796 JUMPL B,.-3 ; do til exhausted
\r
797 MOVE B,PURBOT ; now return pages
\r
798 SUB B,PURTOP ; compute page AOBJN pointer
\r
799 JUMPE B,CPOPJ ; no pure pages?
\r
804 DOTCAL CORBLK,[[1000,,0],[1000,,-1],B]
\r
805 FATAL SYSTEM WONT TAKE CORE BACK?
\r
808 HLRE D,B ; - # of pges to flush
\r
809 HRLI B,400000 ; specify hacking hom fork
\r
816 MOVE B,PURTOP ; now fix up pointers
\r
817 MOVEM B,PURBOT ; to indicate no pure
\r
820 ; Here to move the entire pure space.
\r
821 ; A/ # and direction of pages to move (+ ==> up)
\r
823 MOVPUR: SKIPE NOSHUF
\r
824 FATAL CANT MOVE PURE SPACE AROUND
\r
826 SKIPN B,A ; zero movement, ignore call
\r
829 ASH B,PGSHFT ; convert to words for pointer update
\r
830 MOVE C,PURVEC+1(TVP) ; loop through updating non-zero entries
\r
836 MOVE C,PURTOP ; found pages at top and bottom of pure
\r
840 ADDM B,PURTOP ; update to new boundaries
\r
842 CAIN C,(D) ; differ?
\r
844 JUMPG A,PUP ; if moving up, go do separate CORBLKs
\r
847 SUBM D,C ; -size of area to C (in pages)
\r
848 MOVEI E,(D) ; build pointer to bottom of destination
\r
852 DOTCAL CORBLK,[[1000,,200000],[1000,,-1],E,[1000,,-1],D]
\r
853 FATAL CANT MOVE PURE
\r
856 PUP: SUBM C,D ; pages to move to D
\r
857 ADDI A,(C) ; point to new top
\r
861 DOTCAL CORBLK,[[1000,,200000],[1000,,-1],A,[1000,,-1],C]
\r
862 FATAL CANT MOVE PURE
\r
867 SUBM D,C ; pages to move to D
\r
868 MOVSI E,(C) ; build aobjn pointer
\r
869 HRRI E,(D) ; point to lowest
\r
870 ADD D,A ; D==> new lowest page
\r
871 PURCL1: MOVSI A,400000 ; specify here
\r
872 HRRI A,(E) ; get a page
\r
873 RMAP ; get a real handle on it
\r
874 MOVE B,D ; where to go
\r
882 PUP: SUB D,C ; - count to D
\r
883 MOVSI E,(D) ; start building AOBJN
\r
884 HRRI E,(C) ; aobjn to top
\r
885 ADD C,A ; C==> new top
\r
888 PUPL: MOVSI A,400000
\r
890 RMAP ; get real handle
\r
906 CSXB2: ILDB E,-1(P)
\r
912 CSXB1: SUB P,[2,,2]
\r
916 GENVN: MOVE C,[440700,,MUDSTR+2]
\r