.TITLE LGETLN Aleda Get Line .PSECT Aleda,Gbl,Con .Dsabl GBL ;;********************************************************************** ;; Fortran callable subroutine to access the specified Alvin unit # ;; for transfer of characters to the user specified buffer. ;; ;; Supports calls of the form: ;; Ierror = LGetLN ( Unit #, Line, Line Size, Return Count, ;; c Control Word, Terminator Array ) ;;********************************************************************** ;; Last Modified: 8-May-84 DVJensen ;; 19-Aug-85 DVJ - Always return the error code if an error occurs. ;; Add the CARRY BIT convention used by RT: C-set = error. ;; 25-Nov-85 DJ - A call to AlvIdle occurs if insufficient characters ;; are available to satisfy the current request. AlvIdle ;; will do a timed wait, call AlvUpdate, (possibly do other ;; busy work), then return. This allows the GET processes ;; to run at full speed if in fact Input is keeping up, but ;; will relinquish control (for a short while) to other jobs. ;;********************************************************************** ;; .Mcall $Alv51 .Globl AlvUpdate,GetByte,GetParm,GetDDA,AlvIdle ;External Globals $Alv51 ;; Control Word Bits - If set they indicate: DoTerms=1 ; 0 : Process terminator array for end of line. Parity =2 ; 1 : Include parity bit in characters moved to Line. DoTime =4 ; 2 : Return to user if next character is not available ; within "TimOut" length of time (in tenths of secs). ;;********************************************************************** LGetLn:: MOV R5,-(SP) ;SAVE REGISTERS USED MOV R4,-(SP) MOV R3,-(SP) MOV R2,-(SP) MOV R1,-(SP) Jsr Pc,AlvUpdate ; Let Alvin move characters. Therefore, as ; long as we are busily calling Lget.., we ; will avoid the system buffer overrunning ; if the device does not Xoff. Clr Count ;Initialize Variables Clr Return ;Fortran Calling Convention: Clr R0 ;Set for counting the parameters MOV (R5)+,R1 ;Get number of parameters passed. BIC #177400,R1 ;Clear possible high order junk Jsr PC,GetParm ;Get Parm # 1: Alvin Unit number. Bcs GetlError ;Required Parm - Abort if not provided. Mov (R4),R3 ;Get the actual unit number Mov R3,Unit ;Save it Jsr PC,GetParm ;Get Parm # 2: Line Buffer. Bcs GetlError ;Required Parm - Abort if not provided. Mov R4,LnBuf ;Save pointer to the buffer region. Jsr PC,GetParm ;Get Parm # 3: Line Buffer Size. Bcs GetlError ;Required Parm - Abort if not provided. Mov (R4),LnSize ;Save the SIZE. Ble GetLError ;Return an error if Negative or Zero. Jsr PC,GetParm ;Get Parm # 4: Return Code Location. Bcs Getp5 ;Continue if not available (defaulted above) Mov R4,Return ;Save the address to return the code to. Getp5: Clr Control ;Default Control Word to zero (optional). Jsr PC,GetParm ;Get Parm # 5: Control Word. Bcs Getp6 ;Continue if not available Mov (R4),Control ;Save the Control Word value. Getp6: Clr Terms ;Default Terminator Array (optional) to zero. Jsr PC,GetParm ;Get Parm # 6: String of Terminator Chars. Bcc Getp6T ;Branch if specified to save it Bit #Doterm,Control ;Did the user say to look for terminators? Bne GetNoTerm ;Yes, and non was provided - error branch. Br Getp7 Getp6T: Mov R4,Terms ;Save the base adr of the terminator array. Getp7: Clr Timout ;Default Time-out value (optional) to zero. Jsr PC,GetParm ;Get Parm # 7: Maximum time to complete transfer. Bcs Getp8 ;Continue if not available. Mov (R4),Timout ;Save the Time-out Value. Getp8: Br GetLGO ;;**************************** GetLError: ;ERROR occurred - Code is in R0: Neg R0 ; All error returned values are negative. Mov R0,Count ; Return (negative) error code not count. Sec ; RT convention - force carry set on error. Jmp GetLRtn ;and Return ;;**************************** ;; GetLGO: Jsr R5,GetDDA ;Get the Device Descriptor Address .Word -1 ;Requested unit is already in Register 3. Tst R0 ;Check if this was a valid unit number Bne GetLBD ;Proceed if non-zero. GetL1Err: Mov #20.,R0 ;Error in parameter #1 - No Descriptor. Br GetlError ;Return error code. GetNoTerm: Mov #33.,R0 ;Error - No terminators provided, but Br GetLError ; terminator processing specified. GetEnaErr: Mov #21.,R0 ;Error code #21 - Device not enabled. Br GetLError ;Return error code. GetOutDev: Mov #25.,R0 ;Error code #25 - Device not an input device. Br GetLError ;Return error code. GetNoBuf: Mov #37.,R0 ;Error code #37 - No buffer descriptor. Br GetLError ;Return error code. GetlBD: Mov R0,R2 ;Save the Device Desc Address. Bit #Disabled,(R2) ;Is this device currently enabled? Bne GetEnaErr ;No, invalid device. Bit #Output,Lctl(R2) ;Is this an Output device? Bne GetOutDev ;Yes, branch - Cannot input from it. Mov BDAdr(R2),R4 ;Get the buffer Descriptor Address Beq GetNoBuf ;If zero, it does not exist. Mov LnBuf,R1 ;Get the User Line Buffer address GetLbyte: Jsr R5,GetByte ;Get a byte .Word 0 ; from the buffer in Reg 4. Br GetLwait ;No byte available - wait... Bit #Parity,Control ;Should the parity bit be included? Beq GetLPC ;No, branch to clear it Bic #177400,R0 ;Clear only the high byte. Br GetLUB GetLPC: Bic #177600,R0 ;Clear high-order & parity bits. GetLUB: MovB R0,(R1)+ ;Move the character to the user buffer Inc Count ;Count it. Bit #DoTerm,Control ;Should terminators be looked for? Beq GetLContinue ;No, branch Mov Terms,R5 ;Yes, get the array base address MovB (R5)+,R3 ;Get the number of bytes to look for Beq GetLContinue ;If zero, then no terminators provided Bic #177400,R3 ;Clear high byte TermLP: Cmpb R0,(R5)+ ;Is this a terminator? Beq GetLDone ;Yes, then done with this line. Dec R3 ;Count down number of term chars. Bne TermLP ;Loop until all terminators checked. GetLCont: Cmp Count,LnSize ;Has the maximum number of chars been xfer'd? Blo GetLbyte ;No, go look for another Bit #DoTerm,Control ;Were terminators being looked for? Beq GetLdone ;No, then complete normally. Mov #34.,R0 ;Yes, return error code #34. Br GetLError GetLdone: Bit #Error,(R2) ;Were any input errors discovered? Beq GetLOK ;No, Bic #Error,(R2) ;Clear the error indication Mov #35.,R0 ;Return error code #35. Br GetLerror GetLOK: ;Successful completion: Clr R0 ; Aleda convention - Return code Zero; Clc ; RT convention - Carry clear = no error. Br GetLRtn GetLwait: Bit #Bufull,(R2) ;Did a buffer overrun occur? Beq GetLtime ;No, branch Bic #Bufull,(R2) ;Clear the flag to allow input to continue. Mov #32.,R0 ;Return error #32 - Buffer overrun. Br GetLError GetLtime: ; Note: a timed wait will only occur if output catches up with input. Jsr Pc,AlvIdle ; Let Alvin do a timed wait, after which ; AlvIdle will call AlvUpdate. Br GetLbyte ; Go see if now there is more to be processed. ;;**************************** GetLRtn: Mov Return,R1 ; Did the user provide a return code location? Beq GetLExit ; No, exit. Mov Count,(R1) ;Move the return code/count to user. GetLexit: MOV (SP)+,R1 MOV (SP)+,R2 MOV (SP)+,R3 MOV (SP)+,R4 MOV (SP)+,R5 RTS PC ;AND RETURN ;;**************************** Unit: .Word 0 ;Unit number to transfer from. LnBuf: .Word 0 ;Address of User's Line Buffer. LnSize: .Word 0 ;Size of the User's Line Buffer. Count: .Word 0 ;Count of characters transmitted to user. Return: .Word 0 ;Address of User's Location for Return Code. Control: .Word 0 ;User specified control word. Terms: .Word 0 ;Address of User's Terminator Array. Timout: .Word 0 ;Maximum time to complete the Get Line. ;;**************************************************************************** .END