; > SerTest  tests serial lines using loopback
;            Sends char to SLU, waits for return on same SLU
;            Loops through 00 to FF, once polling, once under IRQ
;            Halts when done or on failure
;
        ORG     512
        BR      TEST
BASE:   DEF     O176500         ; SLU base address
VEC:    DEF     O300            ; SLU base vector
CON:    EQU     O177560         ; Console address
TEST:   MOV     #512,R6         ; stack
        JSR     R7,@#CRLF
        JSR     R7,@#CRLF
        JSR     R7,@#ADDR
        MOV     @#VEC,R5
        MOV     #GET,(R5)+      ; set vector to receive chars
        MOV     #O340,(R5)+     ; set PSW to ignore IRQ during GET
        MOV     #SND,(R5)+      ; set vector to send chars
        MOV     #O340,(R5)      ; no IRQ during SND either
        MOV     @#BASE,R5
        CLR     R2              ; pass 0
        CLR     R0              ; first char
        MOV     #O100,(R5)      ; enable IRQ on rcvr
        BIS     #6,R5           ; BASE+6=TxBuff
        MOV     R0,(R5)         ; set it going
IRQ:    WAIT                    ; for IRQ
        TSTB    R0              ; what char ?
        BNE     IRQ             ; if back to 0, all done
        CLR     @BASE-$         ; disable IRQ on RxCSR
        JSR     R7,@#PASS
        BIS     #6,R5
        MOVB    R0,(R5)         ; send first char, pass 1
RCV:    MOV     @#BASE,R5       ; =BASE again
        TSTB    (R5)
        BPL     RCV
        BIS     #2,R5           ; BASE+2=RxBuff
        MOV     (R5),R1         ; get char
        BIT     R1,#&8000       ; test for error
        BEQ     NOERR
PARITY: HALT                    ; parity/overrun/framing error
NOERR:  CMPB    R0,R1
        BEQ     XMIT
CHAR:   HALT                    ; mismatch
XMIT:   INCB    R0
        BEQ     DONE
        BIS     #6,R5           ; BASE+6=TxBuff
        MOVB    R0,(R5)
        BR      RCV
DONE:   JSR     R7,@#PASS
        JSR     R7,@#CRLF
        HALT
;
GET:    MOV     R5,-(R6)        ; push R5 in case!
        MOV     @#BASE,R5
        BIS     #2,R5           ; RxBuff
        MOV     (R5)+,R1        ; get char; RxBuff+2=TxCSR
        BIT     R1,#&8000       ; test for error
        BNE     PARITY
        CMPB    R1,R0           ; test for right char
        BNE     CHAR
        INCB    R0              ; next char
        BEQ     HOME
        MOV     #O100,(R5)      ; enable xmit IRQ
HOME:   MOV     (R6)+,R5        ; pop R5
        RTI
;
SND:    MOV     R5,-(R6)        ; push R5 in case!
        MOV     @#BASE,R5
        BIS     #4,R5           ; BASE+4=TxCSR
        CLR     (R5)+           ; prevent further IRQ until char got
        MOV     R0,(R5)
        MOV     (R6)+,R5        ; pop R5
        RTI
;
CRLF:   MOV     #13,R4
        JSR     R7,@#PRTN
        MOV     #10,R4
PRTN:   TSTB    @#CON+4         ; console RDY
        BPL     PRTN
        MOVB    R4,@#CON+6
        RTS     R7
;
PASS:   INC     R2
        JSR     R5,@#PRTTXT
        DEFS    " Pass"
        DEFB    &A0             ; space with top bit set
        ALIGN
        MOV     R2,R4
        BIS     #ASC"0",R4
        JSR     R7,@#PRTN
        JSR     R5,@#PRTTXT
        DEFS    "  OK "
        DEFB    &A0
        ALIGN
        RTS     R7
;
ADDR:   MOV     @#BASE,R5
        MOV     #O30,R4         ; after shifts, 3x will be 6x
        ROL     R5              ; rotate 1 bit from R5 to R4
        ROL     R4
        JSR     R7,@#PRTN       ; print as ASCII digit
        MOV     #5,R3
CLOOP:  MOV     #6,R4           ; 6>>3 becomes 6x
        ROL     R5
        ROL     R4
        ROL     R5
        ROL     R4
        ROL     R5
        ROL     R4
        JSR     R7,@#PRTN
        DEC     R3
        BNE     CLOOP
        RTS     R7
;
PRTTXT: MOVB    (R5),R4         ; get char just past where we were
        JSR     R7,@#PRTN
        TSTB    (R5)+
        BPL     PRTTXT
        INC     R5              ; in case it's an odd number
        BIC     R5,#1           ; in case it just became an odd one!
        RTS     R5
