.TITLE $WRITE - ASYNCHRONOUS FCS WRITE ROUTINE .LIST TTM,MEB .IDENT "X0001" ; .MCALL WRITE$,QIO$S,ASTX$S,SETF$S ; ; DEFINITIONS OF EXTEND CONTROL BITS IN PARAMETER WORD THREE ; OF EXTEND QIO ; EX.ENA=100000 ;ENABLE EXTEND EX.AC1=400 ;ALLOCATE CONTIGUOUS EX.AC2=1000 ;ALLOCATE CONTIGUOUS BEST EFFORT EX.FCO=2000 ;MAKE FILE CONTIGUOUS EX.ADF=4000 ;ALLOCATE DEFAULT AMOUNT ;+ ; ; *** $WRITE ASYNCHRONOUS WRITE ROUTINE ; ; THIS ROUTINE ISSUES AN FCS WRITE$ CALL ON THE INDICATED FDB. ; THE FDB IS ASSUMED TO BE SET UP WITH ALL OF THE RELEVANT ; PARAMETERS (VBN,BYTE COUNT,I/O STATUS BLOCK,AST ADDRESS, ; ETC.) IF THE FILE MUST BE EXTENDED , IT IS DONE ASYNCHRONOUSLY ; WITH AN AST POSTED TO ISSUE THE WRITE$ WHEN THE EXTEND COMPLETES. ; ; THE I/O STATUS BLOCK SUPPLIES FOR THE WRITE$ CALL MUST BE FOLLOWED ; BY A FREE WORD; IT IS USED TO STORE THE ADDRESS OF THE FDB FOR ; THE AST SERVICE ROUTINE. ; ; NOTE: THIS ROUTINE SHOULD NOT BE CALLED UNTIL A PREVIOUS INVOCATION ; HAS COMPLETED; OTHERWISE, THE FILE MAY BE REDUNDANTLY EXTENDED. ; ALSO SINCE PARAMETERS IN THE FDB ARE USED IN THE AST SERVICE ; ROUTINE, THE FDB MUST NOT BE MODIFIED UNTIL THE OPERATION HAS COMPLETED. ; ; INPUTS: ; R0=FDB ADDRESS (FDB ALL SET UP) ; (NOTE THAT I/O STATUS BLOCK IS MANDATORY!) ; OUTPUTS: ; ALL REGISTERS PRESERVED. FILE MAY BE EXTENDED AFTER THE ; ROUTINE HAS RETURNED. ; THIS ROUTINE IS AN EXAMPLE OF HOW TO EXTEND A FILE ASYNCHRONOUSLY; ; VARIATIONS OF THIS METHOD MAY BE USED. ; ;- .ENABL LSB $WRITE:: JSR R5,.SAVR1 ;SAVE REGISTERS WITH LIBRARY ROUTINE MOV F.BKST(R0),R1 ;SEE IF I/O STATUS BLOCK IS PRESENT BEQ 70$ ;BRANCH IF NOT-ERROR MOV R0,4(R1) ;SAVE FDB ADDRESS MOV F.BKDS(R0),R2 ;GET BYTE COUNT OF TRANSFER DEC R2 ;SUBTRACT ONE BLOCK'S WORTH AND ROUND U CLRB R2 ;AND CONVERT TO BLOCK COUNT SWAB R2 ASR R2 MOV F.BKVD(R0),R1 ;ADD TO STARTING VBN ADD F.BKVB+2(R0),R2 ADC R1 CMP R1,F.HIBK(R0) BNE 10$ CMP R2,F.HIBK+2(R0) 10$: BLOS 60$ ;BRANCH IF EXTEND NOT NEEDED ; ; COMPUTE THE EXTEND PARAMETERS AND ISSUE THE EXTEND ; MOV #EX.ENA,R2 ;GET BASIC EXTEND CONTROL MOV F.ALOC(R0),R3 ;GET EXTEND INCREMENT BMI 30$ ;BRANCH IF NON-CONTIGUOUS BEQ 20$ ;BRANCH IF DEFAULT BIS #EX.AC1,R2 ;SET CONTIGUOUS BIT BR 40$ 20$: BIS #EX.ADF,R2 ;REQUEST DEFAULT ALLOCATION 30$: NEG R3 ;MAKE TRUE COUNT 40$: MOV R0,R1 ADD #F.FNB,R1 ;POINT TO FILE ID ;ISSUE THE EXTEND QIO. NOTE THAT ;AN AST, BUT NO EVENT FLAG IS USED. QIO$S #IO.EXT,F.LUN(R0),,,F.BKST(R0),#WRITE, BCC 50$ ;BRANCH IF OK MOV @#$DSW,F.ERR(R0) ;GET ERROR STATUS 50$: RETURN ; ; WE GET HERE IF THE FILE DOES NOT NEED TO BE EXTENDED ; 60$: WRITE$ R0 ;JUST ISSUE THE WRITE RETURN ; ; WE GET HERE IF NO I/O STATUS BLOCK WAS SUPPLIED ; 70$: MOVB #IE.ILL,F.ERR(R0) SEC RETURN ; ; AST SERVICE ROUTINE FOR THE EXTENDED OPERATION ; WRITE: MOV R0,-(SP) ;SAVE SOME REGISTERS MOV R1,-(SP) MOV 4(SP),R1 ;R1=I/O STATUS BLOCK ADDRESS MOV 4(R1),R0 ;R0=FDB ADDRESS TSTB (R1) ;CHECK I/O STATUS BMI 100$ ;BRANCH IF ERROR ADD 2(R1),F.HIBK+2(R0) ;UPDATE FILE SIZE DATA ADC F.HIBK(R0) MOV (R1),R1 ;GET SOME HIGH ORDER BLOCKS CLRB R1 ;FROM HIGH BYTE SWAB R1 ADD R1,F.HIBK(R0) WRITE$ R0 ;ISSUE THE WRITE BCS 90$ ;BRANCH ON ERROR MOV (SP)+,R1 ;RESTORE REGISTERS 80$: MOV (SP)+,R0 TST (SP)+ ;CLEAN STACK ASTX$S ; AND EXIT THE AST ; ; IF AN ERROR OCCURS DURING THE AST, COMPLETE THE I/O IMMEDIATELY ; 90$: MOV F.ERR(R0),@F.BKST(R0) ;RETURN ERROR IN IOST 100$: MOVB F.BKEF(R0),R1 ;GET EVENT FLAG NUMBER BEQ 110$ ;ZERO MEANS DEFAULT CMP R1,#64. ;CHECK RANGE BLOS 120$ ;BRANCH IF OK 110$: MOV #32.,R1 ;DEFAULT TO 32 120$: SETF$S R1 ;SET THE EVENT FLAG ; ; NOW TRANSFER TO USER'S AST SERVICE ROUTINE IF IT EXISTS ; MOV (SP)+,R1 ;RESTORE R1 MOV F.BKDN(R0),R0 ;GET AST ADDRESS, IF ANY BEQ 80$ ;BRANCH IF NONE RTS R0 ;RESTORE R0 AND GO TO USERS AST .DSABL LSB .END