.TITLE PUTC0 RT11 support output routine .ident /000002/ .ENABL LC .LIST MEB .NLIST BEX ; ; PUTC0 writes one byte to a specified output file. ; FLUSH Flushes the current (physical) record to the file. ; ; PUTC0 calling sequence: ; ; MOV BYTE,R0 ;Byte to output ; MOV FDB,R1 ;R1 -> file data block ; MOV SP,R5 ;Caller SP for error return ; JSR PC,PUTC0 ;And do it ; ; On return: ; All registers are preserved (even R0) ; Note, on an error, the stack will be cut back to the R5 ; value and the original caller returned to with the C-bit ; set and the RT11 error code in $ERROR. ; ; ; The FDB has the following format: ; ; .WORD Address of the CSI block for this file ; FDB: .WORD Channel number ; .WORD Number of bytes left in the buffer ; .WORD Address of the first free byte in the buffer ; .WORD Current block number ; .BLKB 512. The buffer itself ; ; ; Edit history ; 000001 28-Jul-79 MM Original edit ; 000002 14-Jul-80 MM Removed BPT on error, also SAVREG global ; .GLOBL $ERROR ;Error code (byte) ; PUTC0:: MOV R1,-(SP) ;Save FDB pointer TST (R1)+ ;Skip over channel number DEC (R1)+ ;Count the byte as in BGE 10$ ;Branch if there's room JSR PC,$PUTC0 ;No room, write the buffer out DEC (R1)+ ;Now, really count the byte 10$: MOVB R0,@(R1)+ ;Output the byte INC -(R1) ;Step the buffer pointer MOV (SP)+,R1 ;Restore the original FDB RTS PC ;and exit ; ; Actually do the flush. ; On entry: R1 -> FDB+4 (free byte pointer) ; On return: R1 -> FDB+2 (number of bytes unused) ; ; Other registers are unchanged. ; Note that the original caller will be returned to on an error. ; This routine is called by PUTC0 and by FLUSH. ; $PUTC0:: MOV R0,-(SP) ;Get a working register MOV (R1)+,R0 ;R0 := free byte pointer BEQ 30$ ;Branch if the buffer is unused CLR -(SP) ;Start making an RT11 argument block TST (R1)+ ;R1 := buffer address SUB R1,R0 ;R0 has byte count INC R0 ;Round up to get ASR R0 ;The word count BCS 10$ ;Branch if byte count was even CLRB @-4(R1) ;Mash the leftover byte 10$: MOV R0,-(SP) ;Output the word count MOV R1,-(SP) ;And the buffer address MOV -(R1),-(SP) ;Now the block number MOV -6(R1),-(SP) ;and the channel number BIS #<11*400>,(SP) ;Set function .WRITEW MOV SP,R0 ;R0 -> argument block EMT 375 ;Go for it BCC 20$ ;Branch if successful MOVB @#52,$ERROR ;Save the error code MOV R5,SP ;Cut the stack RTS PC ;For an error return ; 20$: INC (R1) ;Up the block number ADD #<5*2>,SP ;Cut the stack 30$: MOV R1,R0 ;R0 -> FDB block number MOV R0,-(R1) ;FDB free byte pointer ADD #2,(R1) ; -> buffer start MOV #512.,-(R1) ;FDB free byte count setup MOV (SP)+,R0 ;Restore temp register RTS PC ;Take normal return .END