.MCALL .MODULE .MODULE DRVUTL,RELEASE=V00,VERSION=30,COMMENT= .MCALL .TTYOU, .WRITW .PSECT U$$COD,RW,D,LCL,CON ;************************************************************************ ;* The following subroutines operate on buffer headers that are presumed* ;* to have the following structure (offsets): * ;* * BUFBEG = 0 ; Pointer to the start of the buffer. * BUFEND = 2 ; Pointer to the end of the buffer. * BUFCUR = 4 ; Pointer to the next available location. * BUFCHN = 6 ; I/O channel to be used * BUFBLN = 10 ; Block number to write to. ;* * ;************************************************************************ .PAGE .SBTTL Copy a character string to the output buffer. $UTLPR:: MOV 2(R5),R1 ; Pointer to the string. MOV 4(R5),R2 ; Pointer to the buffer control block. 10$: MOV BUFCUR(R2),R3 ; Current data pointer. 20$: CMP R3,BUFEND(R2) ; Check for end-of-buffer. BGE 40$ ; Branch if buffer is full. CMPB (R1),#200 ; End-of-String? BEQ 50$ CMPB (R1),#0 ; End-of-String? BEQ 50$ CMP #-2,BUFCHN(R2) ; Terminal I/O? BNE 30$ ; Branch if not. .TTYOUT (R1)+ ; Output the character if it is. BR 20$ ; Keep going. 30$: MOVB (R1)+,(R3)+ ; Buffer the character. BR 20$ 40$: MOV BUFEND(R2),R3 ; Calculate the number of words to write. SUB (R2),R3 ASR R3 ; Convert bytes to words. .WRITW #AREA,BUFCHN(R2),(R2),R3,BUFBLN(R2) INC BUFBLN(R2) MOV (R2),BUFCUR(R2) ; Reset the current pointer. BR 10$ 50$: MOV R3,BUFCUR(R2) ; Save the current pointer. RTS PC ; Return. .PAGE .SBTTL Copy a character to the output buffer. $UTLCH:: MOV 2(R5),R1 ; Pointer to the character. MOV 4(R5),R2 ; Pointer to the buffer control block. 10$: MOV BUFCUR(R2),R3 ; Current data pointer. 20$: CMP R3,BUFEND(R2) ; Check for end-of-buffer. BGE 40$ ; Branch if buffer is full. CMP #-2,BUFCHN(R2) ; Terminal I/O? BNE 30$ ; Branch if not. .TTYOUT (R1)+ ; Output the character if it is. BR 50$ ; Keep going. 30$: MOVB (R1)+,(R3)+ ; Buffer the character. BR 50$ 40$: MOV BUFEND(R2),R3 ; Calculate the number of words to write. SUB (R2),R3 ASR R3 ; Convert bytes to words. .WRITW #AREA,BUFCHN(R2),(R2),R3,BUFBLN(R2) INC BUFBLN(R2) MOV (R2),BUFCUR(R2) ; Reset the current pointer. BR 10$ 50$: MOV R3,BUFCUR(R2) ; Save the current pointer. RTS PC ; Return. .PAGE .SBTTL Flush the buffer. $UTLFL:: MOV 2(R5),R2 ; Pointer to the buffer control block. CMP #-2,BUFCHN(R2) ; Terminal I/O? BEQ 20$ ; Branch if not. 10$: MOV BUFCUR(R2),R1 ; Calculate the number of characters. MOVB #0,(R1)+ ; NULL byte for termination. SUB (R2),R1 ; Subtract the start address. ASR R1 ; Convert bytes to words. .WRITW #AREA,BUFCHN(R2),(R2),R1,BUFBLN(R2) INC BUFBLN(R2) ; Increment the block number. 20$: MOV (R2),BUFCUR(R2) ; Reset the current pointer. RTS PC ; Return. .PAGE .SBTTL Utility Buffers and Data Area. .PSECT U$$DAT,RW,D,LCL,CON AREA: .BLKW 10 ; Setup area for EMT's .END