/ / Get characters. / .globl getcha .globl getc .globl __getc .globl __get / / getchar(); / getc(ioptr); / FILE *ioptr; / / These routines read a character from either / the standard input (getchar) or the specified / input stream (getc). / EOF is returned on end of file or error. / getcha: jsr r0,__csav /Get a stack frame mov stdin,r4 /Get standard input IOV br 0f / getc: jsr r0,__csav /Get a stack frame mov 12(r5),r4 /Get user IOV 0: call __getc /Get the character jmp __cret / / / Get a character. / Called by above and by gets. / / r5=stack frame pointer / r4=ioptr / / Returns character (or -1) in r0 / __getc: mov V_UGET(r4),r0 /Is there an unget character bmi 0f /No mov $-1,V_UGET(r4) /Make unget character go away return / 0: bit $VF_UBF,(r4) /Is this an unbuffered stream beq 0f /No bis $VF_ERR,(r4) /Yes, set error br 2f / 0: bit $VF_EOR,(r4) /Any more stuff bne 2f /Br if not 1: dec V_R0(r4) /Get a byte from the line bmi 0f /Br if none movb *V_R1(r4),r0 /Grab it inc V_R1(r4) /Fix pointer bic $!377,r0 /Mask number to 8 bits return / 0: mov V_RBUF(r4),r0 /Address of record buffer mov r0,V_R1(r4) /Buffer address mov V_RBSZ(r4),r1 /Size of record buffer call __get /Get record bcs 2f /EOF or error mov r0,V_R0(r4) /Number of bytes in record br 1b /Try again 2: mov $-1,r0 /Return EOF return / / / Get record. / r0 = buffer address. / r1 = max record size. / / Returns c bit set on EOF or error. / Record length in r0. / __get: mov r0,-(sp) /Save registers mov r1,-(sp) / mov r2,-(sp) / mov r3,-(sp) / / / Record devices. / bit $VF_REC,(r4) /Record device? beq 2f /Br if not / / Standard input/standard output / magic on a tty. / cmp r4,stdin /Are we reading standard input? bne 0f /No bit $VF_TTY,(r4) /Yes, is it a TTY? beq 0f /No mov stdout,r0 /Is the standard output bit $VF_TTY,(r0) /Also a TTY? beq 0f /No mov r4,-(sp) /Yes, flush out the mov r0,r4 /Standard output call __flsh /This is all in the mov (sp)+,r4 /Prompting / / Read record. / 0: clr -(sp) /Issue read QIO. clr -(sp) / clr -(sp) / clr -(sp) / mov 14(sp),-(sp) /Max record size mov 20(sp),-(sp) /Address mov $IO.RVB,r0 /Always use a read virtual call __qiow / bcc 0f /Br if read all ok bis $VF_EOF,(r4) /Set EOF flag cmp r0,$IE.EOF /Was the error EOF? beq 3f /Yes bis $VF_ERR,(r4) /No, set error as well br 3f / 0: mov V_IOSB+2(r4),r0 /Get byte count read. bit $VF_NOS,(r4) /Is this a no newlines read bne 3f /Yes mov r0,r1 /Append a newline add 6(sp),r1 / movb $12,(r1) / inc r0 /Add 1 to record size br 3f / / / Block device. / If file, check for end of file. / 2: bit $VF_FIL,(r4) /File on the LUN. beq 1f /No cmp V_RBLK(r4),V_EFBK(r4) /Check high lbn bhi 0f /EOF blo 1f /Ok cmp V_RBLK+2(r4),V_EFBK+2(r4) /Check low lbn bhi 0f /EOF blo 1f /Ok cmp V_RBYT(r4),V_FFBY(r4) /Byte position blo 1f /Ok 0: bis $VF_EOF,(r4) /Set end of file flag br 3f / / / Not at end of file. / 1: bitb $R.FIX,V_RTYP(r4) /Fixed length records beq 0f /No mov V_RSIZ(r4),r2 /Pick up record size br 1f /Go use it 0: call getb /Read RCW. mov r0,r2 / call getb / swab r0 / bis r0,r2 / / / FD.BLK variable length records use / a record size of -1 to mean skip. / This is, of course, completely / undocumented. / bitb $FD.BLK,V_RATT(r4) /Can records span blocks beq 1f /Yes cmp r2,$-1 /Is this the magic size bne 1f /No call nextvb /Advance to next block br 2b / 1: cmp r2,4(sp) /Is it too large? blos 0f /No bis $VF_ERR,(r4) /Set error flag br 3f / 0: mov 6(sp),r3 /Get buffer address mov r2,-(sp) /Save record size 1: dec r2 /More? bmi 1f /No call getb /Read file from the file bit $VF_NOS,(r4) /No newlines bne 0f /Yes cmp r0,$15 /Devour carriage returns beq 1b / 0: movb r0,(r3)+ /Save byte in buffer br 1b / 1: asr (sp)+ /Odd length record bcc 0f /No call getb /Skip a byte 0: bitb $R.FIX,V_RTYP(r4) /If fixed length beq 0f /And bitb $FD.BLK,V_RATT(r4) /Not spanned beq 0f /Then call nextvb /Skip to next block 0: bit $VF_NOS,(r4) /No newlines bne 0f /Yes bitb $FD.CR,V_RATT(r4) /Do we need a newline? beq 0f /No movb $12,(r3)+ /Add one 0: mov r3,r0 /Compute record size sub 6(sp),r0 / 3: mov (sp)+,r3 /Restore registers mov (sp)+,r2 / mov (sp)+,r1 / tst (sp)+ /Caller's r0 bit $VF_EOR,(r4) /Error or EOF beq 0f /No (c bit clear from TST) clr r0 /0 byte read sec /C bit set on error 0: return / / / Skip to next block. / nextvb: add $1,V_RBLK+2(r4) /Update vbn adc V_RBLK(r4) / clr V_RBYT(r4) /Go back to byte 0 bis $VF_BAD,(r4) /Set read required return / / / Get the next byte from the file. / Return it in r0. / getb: cmp V_RBYT(r4),$512. /At end of block? blo 0f /No call nextvb /Advance to next block 0: bit $VF_BAD,(r4) /Need to read? beq 0f /No bic $VF_BAD,(r4) /Clear need to read flag call __rvb /And read a block 0: mov V_RBYT(r4),r0 /Compute byte address add V_BBUF(r4),r0 / inc V_RBYT(r4) /Next byte movb (r0),r0 /Get byte from buffer bic $!377,r0 /Mask to 8 bits return /