ITS Muddle.
[pdp10-muddle.git] / MUDDLE / readch.10
diff --git a/MUDDLE/readch.10 b/MUDDLE/readch.10
new file mode 100644 (file)
index 0000000..f4d5191
--- /dev/null
@@ -0,0 +1,240 @@
+
+TITLE READC TELETYPE DEVICE HANDLER FOR MUDDLE
+
+RELOCATABLE
+
+.INSRT MUDDLE >
+
+.GLOBAL BUFRIN,CHRCNT,SYSCHR,ECHO,BYTPTR,ERASCH,KILLCH,BRKCH,AGC
+.GLOBAL IOIN2,READC,WRONGT,WRONGD,WRONGC,CALER1,BRFCHR,ESCAP,TTYOPE,TYI,TYO
+.GLOBAL RRESET,TTICHN,TTOCHN,CHANNO,STATUS
+
+TTYOUT==1
+TTYIN==2
+
+
+; READC IS CALLED BY PUSHJ P,READC
+; B POINTS TO A TTY FLAVOR CHANNEL
+; ONE CHARACTER IS RETURNED IN  A
+; BECOMES INTERRUPTABLE IF NO CHARACTERS EXISTS
+
+READC: PUSH    P,E             ;SAVE E FROM DEATH
+       MOVE    E,BUFRIN(B)     ;GOBBLE POINTER TO BUFFER AND INFO
+       SOSGE   CHRCNT(E)       ;ANY CHARS LEFT?
+       PUSHJ   P,INCHAR        ;NO, GO READ SOME
+       ILDB    A,BYTPTR(E)     ;GOBBLE ONE
+       POP     P,E             ;RESTORE E
+       POPJ    P,
+
+; HERE TO ASK SYSTEM FOR SOME CHARACTERS
+
+INCHAR:        IRP     A,,[0,C,D]      ;SAVE ACS
+       PUSH    P,A
+       TERMIN
+       CLEARM  CHRCNT(E)       ;NO CHARS IN BUFFER
+       MOVE    D,[010700,,BYTPTR(E)]   ;MAKE A BYTE POINTER TO START OF BUFFER
+       HLRE    0,E             ;FIND END OF BUFFER
+       SUBM    E,0
+       ANDI    0,-1            ;ISOLATE RH
+
+INCHR1:        PUSHJ   P,GETCH         ;GET A CHARACTER
+       CAMN    A,ESCAP(E)              ;ESCAPE CHAR?
+       JRST    DOESCP
+       CAMN    A,BRFCHR(E)             ;BUFFER PRINT CHAR
+       JRST    CLEARQ          ;MAYBE CLEAR SCREEN
+       CAMN    A,BRKCH(E)      ;IS THIS A BREAK?
+       JRST    DONE            ;YES, DONE
+       CAMN    A,ERASCH(E)     ;ARE IS IT ERASE?
+       JRST    ERASE           ;YES, GO PROCESS
+       CAMN    A,KILLCH(E)     ;OR KILL
+       JRST    KILL
+
+INCHR2:        PUSHJ   P,PUTCHR        ;PUT ACHAR IN BUFFER
+       JRST    INCHR1
+
+DONE:  IDPB    A,D             ;STORE 
+       MOVE    D,[010700,,BYTPTR(E)]   ;RESET BYTER
+       MOVEM   D,BYTPTR(E)
+       IRP     A,,[D,C,0]
+       POP     P,A
+       TERMIN
+       POPJ    P,
+
+
+ERASE: SUBI    A,177           ;IS THE ERASE RUBOUT
+       SKIPN   CHRCNT(E)       ;ANYTHING IN BUFFER?
+       JRST    BARFCR  ;NO, MAYBE TYPE CR
+
+       SOS     CHRCNT(E)       ;DELETE FROM COUNT
+       JUMPN   A,NECHO ;DONT ECHO IF ERASE OTHER THAN RUBOUT
+       LDB     A,D             ;RE-GOBBLE LAST CHAR
+       SKIPE   C,ECHO(E)       ;DOES AN ECHO INS EXIST?
+       XCT     C               ;YES, ECHO
+
+NECHO: ADD     D,[70000,,0]    ;DECREMENT BYTE POINTER
+       JUMPGE  D,INCHR1        ;AND GO ON, UNLESS BYTE POINTER LOST
+       SUB     D,[430000,,1]   ;FIX UP BYTE POINTER
+       JRST    INCHR1
+
+; HERE TO KILL THE WHOLE BUFFER
+
+KILL:  CLEARM  CHRCNT(E)       ;NONE LEFT NOW
+       MOVE    D,[010700,,BYTPTR(E)]   ;RESET POINTER
+
+BARFCR:        MOVE    A,ERASCH(E)     ;GET THE ERASE CHAR
+       CAIE    A,177           ;IS IT RUBOUT?
+       JRST    INCHR1          ;NO, DO NOT TYPE A CR
+       MOVEI   A,15                    ;GET THE CR
+       SKIPE   C,ECHO(E)       ;ECHO INS IN C
+       XCT     C
+       JRST    INCHR1
+
+DOESCP:        PUSHJ   P,PUTCHR        ;PUT INTO BUFFER
+       PUSHJ   P,GETCH         ;GET NEXT ONE
+       JRST    INCHR2  ;INSERT IT AND GO ON
+
+CLEARQ:        MOVEI   A,0             ;INSERT A NULL CHAR
+       IDPB    A,D             ;DEPOSIT A 0 TERMINATOR
+       MOVE    A,STATUS(B)     ;CHECK CONSOLE KIND
+       ANDI    A,77
+       CAIN    A,2             ;DATAPOINT?
+       PUSHJ   P,CLR           ;YES, CLEAR SCREEN
+       MOVEI   A,15            ;C.R.
+       MOVE    C,[010700,,BYTPTR(E)]   ;POINT TO START OF BUFFER
+       SKIPN   ECHO(E)         ;ANY ECHO INS?
+       JRST    NECHO
+
+       XCT     ECHO(E) ;WRITE OUT C.R.
+
+       ILDB    A,C                     ;GOBBLE CHAR
+       JUMPE   A,NECHO
+       XCT     ECHO(E)         ;ECHO IT
+       JRST    .-3             ;DO FOR ENTIRE BUFFER
+
+CLR:   SKIPN   C,ECHO(E)       ;ONLY IF INS EXISTS
+       POPJ    P,
+       MOVEI   A,20            ;ERASE SCREEN
+       XCT     C
+       MOVEI   A,103
+       XCT     C
+       POPJ    P,
+
+PUTCHR:        AOS     CHRCNT(E)       ;COUNT THIS CHARACTER
+       IBP     D               ;BUMP BYTE POINTER
+       CAIG    0,@D            ;DONT SKIP IF BUFFER FULL
+       PUSHJ   P,BUFULL                ;GROW BUFFER
+       DPB     A,D             ;CLOBBER BYTE POINTER IN
+       POPJ    P,
+
+; BUFFER FULL, GROW THE BUFFER
+
+BUFULL:        MOVEI   E,1000          ;GET GROWTH SPECS
+       HRRM    E,@0
+       PUSH    TP,$TCHAN       ;SAVE B
+       PUSH    TP,B
+       PUSHJ   P,AGC           ;GROW THE VECTOR
+       MOVE    B,(TP)          ;RESTORE CHANNEL POINTER
+       SUB     TP,[2,,2]       ;AND REMOVE CRUFT
+       MOVE    E,BUFRIN(B)     ;GET AUX BUFFER POINTER
+       HLRE    0,E             ;RECOMPUTE 0
+       SUBM    E,0
+       ANDI    0,-1
+       POPJ    P,
+
+GETCH: SOSGE   C,SYSCHR(E)     ;ANY CHARS IN SYSTEM?
+       JRST    ENBL            ;NO, ENABLE INTERRUPTS
+       XCT     IOIN2(E)        ;YES, GOBBLE ONE
+       POPJ    P,              ;AND RETURN
+
+ENBL:  MOVSI   A,TCHAN         ;SET A'S TYPE
+       MOVEM   A,BSTO(PVP)
+       ENABLE                  ;ENABLE INTERRUPTS
+       XCT     IOIN2(E)
+       DISABLE                 ;GOT A CHARACTER, DISABLE INTERRUPTS
+       SETZM   BSTO(PVP)
+       POPJ    P,
+
+; SUBROUTINE TO FLUSH BUFFER
+
+RRESET:        MOVE    E,BUFRIN(B)             ;GET AUX BUFFER
+       SETZM   CHRCNT(E)
+       SETZM   SYSCHR(E)
+       MOVE    D,[010700,,BYTPTR(E)]   ;RESET BYTE POINTER
+       MOVEM   D,BYTPTR(E)
+       MOVE    D,CHANNO(B)     ;GOBBLE CHANNEL
+       LSH     D,23.           ;POSITION
+       IOR     D,[.RESET 0]
+       XCT     D               ;RESET ITS CHANNEL
+       POPJ    P,
+
+; SUBROUTINE TO ESTABLISH ECHO IOINS
+
+MFUNCTION ECHOPAIR,SUBR
+
+       ENTRY   2
+
+       HLRZ    A,(AB)          ;CHECK ARG TYPES
+       HLRZ    C,(AB)
+       CAIN    A,TCHAN         ;IS A CHANNEL
+       CAIE    C,TCHAN         ;IS C ALSO
+       JRST    WRONGT          ;NO, ONE OF THEM LOSES
+
+       MOVE    A,1(AB)         ;GET CHANNEL
+       MOVE    B,DIRECT(A)     ;GET DIRECTION
+       CAME    B,CHQUOTE READ
+       JRST    WRONGD
+       LDB     C,[600,,STATUS(A)]      ;GET A CODE
+       CAILE   C,2             ;MAKE SURE A TTY FLAVOR DEVICE
+       JRST    WRONGC
+       MOVE    D,3(AB)         ;GET OTHER CHANNEL
+       MOVE    E,DIRECT(D)     ;AND ITS DIRECTION
+       CAME    E,CHQUOTE PRINT
+       JRST    WRONGD
+
+       MOVE    B,BUFRIN(A)     ;GET A'S AUX BUFFER
+       MOVE    C,IOINS(D)      ;AND C'S IO INS
+       MOVEM   C,ECHO(B)               ;CLOBBER
+       MOVE    A,(AB)
+       MOVE    B,1(AB)         ;RETURN 1ST ARG
+       JRST FINIS
+
+TTYOPEN:       .OPEN   TTYIN,[SIXBIT /   TTY/]
+       .VALUE
+       .OPEN   TTYOUT,[SIXBIT /  !TTY/]        ;AND OUTPUT
+       .VALUE
+       .STATUS TTYOUT,A                ;CHECK IT OUT
+       ANDI    A,77            ;GET DEVICE
+       CAIE    A,2             ;IF 2, CAN OPEN IN DISPLAY MODE
+       JRST    SETCHN
+       .CLOSE  TTYOUT,
+       .OPEN   TTYOUT,[21,,(SIXBIT /TTY/)]
+       .VALUE
+       
+SETCHN:        MOVE    B,TTICHN+1(TVP) ;GET CHANNEL
+       MOVEI   A,TTYIN         ;GET ITS CHAN #
+       MOVEM   A,CHANNO(B)
+       .STATUS TTYIN,STATUS(B) ;CLOBBER STATUS
+
+       MOVE    B,TTOCHN+1(TVP) ;GET OUT CHAN
+       MOVEI   A,TTYOUT
+       MOVEM   A,CHANNO(B)
+       .STATUS TTYOUT,STATUS(B)
+       POPJ    P,
+
+TYI:   .IOT    TTYIN,A
+       POPJ    P,
+
+TYO:   .IOT    TTYOUT,A
+       POPJ    P,
+
+
+WRONGD:        PUSH    TP,$TATOM
+       PUSH    TP,MQUOTE WROND-DIRECTION-CHANNEL
+       JRST    CALER1
+
+WRONGC:        PUSH    TP,$TATOM
+       PUSH    TP,MQUOTE NOT-A-TTY-TYPE-CHANNEL
+       JRST    CALER1
+
+END
+\f\ 3\f
\ No newline at end of file