.TITLE LODOVR .IDENT \V02.03\ ;++ ; FUNCTIONAL DESCRIPTION: ; This Overlay is used to bring in a previously ; Workspace. It actually does all the work for LOAD. ; ; INPUTS: ; R2 - This points to the (open) channel that will ; be used to read in the Workspace ;-- .PSECT CODE LODOVR:: .IF GE RSTS ; ; Handle RSX and RT-11 )LOAD Commands ; POP R4 ;Get the return address ; ; Read SP Stack, 1K of variables ; MOV #CPOUTL,C.BUFF(R2) ;SP Stack work area MOV #OBUFLN,C.BUFL(R2) ;Length is std default CALL READB ;Read in the block MOV #SYSTAT,C.BUFF(R2) ;BUFFER CALL READB ;READ THE BUFFER CMP SPINIT,SPHOLD ;STACK POINTER OK? BLO 6$ ;BAD - PROBLEM CMP #,VERNUM ;Does the WS ver = processor ver? BNE 6$ ;No, Then can't load it. ;+ ; Read rest of free core ;- MOV ENDCOR,R3 ;POINT TO END OF CORE .IF EQ RSX MOV R3,R0 ;Indicate Minimum Space Required .SETTOP ;I Want! CMP R3,R0 ;Is it enough? .IF GT RSTS BLOS 20$ ;Yes, there is enough SUB R3,R0 ;Compute NEG R0 ; the space we need ADD #3777,R0 ;Round up to nearest K ASH #-11.,R0 ;Shift to # of Kwords .STAT ;Get Current Amount of Space ADD XRB,R0 ;Plus extra we need .GETCOR ;Get the space MOV R3,R0 ;Get minimum space (again) .SETTOP ;Ask for it CMP R3,R0 ;Is it enough? .ENDC BHI 6$ ;Nope, error .IFTF 20$: TST (R3)+ ;Fudge pointer to one beyond top SUB #,R3 ;MINUS LOW CORE MOV #,R1 ;BUFFER POINTER MOV R1,C.BUFF(R2) ;POINTER TO LOCATION 1$: CALL READB ;READ FREE STORAGE ADD C.BUFL(R2),C.BUFF(R2) ;Increment buffer pointer SUB C.BUFL(R2),R3 ;Decrease count CMP R3,#OBUFLN ;Any whole blocks left? BHI 1$ ;Yes, Then loop some more TST R3 ;No, Any bytes left? BGT 10$ ;Yes SYSERR ;No, There should be, SYSTEM Error 10$: .IFF ADD R3,C.BUFL(R2) ;INCREMENT THE COUNT .ENDC CALL READB ;GET FINAL BLOCK 2$: CALL RESCHN ;Finished with the channel ; ; Move stack from buffer to low core ; MOVB OMODE,TMODE ;Restore terminal mode BIT #F$EXEC,FLAGS ;In Execute frame? BEQ 3$ ;Nope, assumptions are all QX CLRB TMODE ;Apparently within execute 3$: MOV SPINIT,R1 ;HIGH END OF STACK SUB SPHOLD,R1 ;LENGTH OF STACK BMI 6$ ;OOPS! MOV R1,R3 ;COPY LENGTH ADD #CPOUTL,R3 ;POINT PAST END OF STACK IN BUFFER MOV SPINIT,SP ;POINT TO HIGH END OF STACK ; ASR R1 ;WORD LENGTH OF STACK ROR R1 ;WORD LENGTH OF STACK 4$: MOV -(R3),-(SP) ;RESTORE STACK SOB R1,4$ BIT #^C<1>,ORIGIN ;CHECK A CONSTANT BNE 6$ ;WRONG, MUST DIE CMP #2,LENTAB+4 ;MUST ALSO MATCH BNE 6$ ;WRONG, MUST DIE MOV (SP),SI ;RESTORE SI POINTER MOV R4,(SP) ;Save return Address BIS #SY.SVL,SYSTAT ;No longer in SAVE/LOAD .IF NE RSX GTSK$S R3 ;Get task parameters MOV G.TSTS(R3),R3 ;The region size is ... .IFF PUSH ;Parameters for call MOV SP,R0 ;Point to parameter list .GTJB ;Get Job Parameters CMP (SP)+,(SP)+ ;Skip Garbage MOV 2.(R3),R3 ;Get High Memory Limit .ENDC BIC #1.,R3 ;Drop the garbage bit TST -(R3) ;Back up for safty MOV ENDCOR,R0 ;Get a pointer to core end MOV R0,R4 ;Current top of core CMP R3,R4 ;Is there enough space? BLO 6$ ;No, Then give'm a Clear workspace SUB R3,R4 ;Minus top of task ; ASR R4 ;Get # of words ROR R4 ;Get # of words CMP R4,#-4. ;Must have at least 4 BGT 5$ ;Don't, so ignore extra space MOV R3,ENDCOR ;New ENDCOR value for top MOV #-1.,(R3) ;Flag for top of memory MOV R4,(R0)+ ;Start of last block - allocated MOV R4,-(R3) ;Move it to top also CALL RETCOR ;"Return" it to APL 5$: RETURN ;Finished 6$: JMP CLEAR ;Clear Core, start again .ENDC