.PAGE
;****************** DPV 11 HANDLER *********************
;  ELEMENT DVRVP IN NSILIB
;
; DPV11 Handler derived from the correspondng DUP11 handler.
;
; THIS VERSION PUTS THE FIRST 2 BYTES OF THE FRAME IN THE BUFFER'S
;PARAMETER BLOCK.  THESE ARE NOT INCLUDED IN THE MESSAGE LENGTH.
;THE LENGTH COUNT MAY BE ZERO IF EITHER THE LENGTH REALY IS ZERO OR
;IF IT IS 256 BYTES.  IN THE LATTER CASE THE POINTERS WILL BE NON-ZERO.
;
;** REGISTER DEFINITIONS **
      DPVRCS=0
      DPVRDB=2
      DPVPSR=2
      DPVTCS=4
      DPVTDB=6
;** BIT DEFINITIONS **
         TSOM=400
         TEOM=1000
         TEOMUP=2  ; TEOM in the upper byte.
         RSOM=400
         REOM=1000
        ERCHK=100000
        RABORT=2000
      RCVOVR=4000
         DPVABT=2000
         DPVXEN=20
      DPVMTY=4
         DPVREN=20
         DPVDSR=1000
         DPVDTR=2
         DPVRES=1
         DPVRTS=4
         DPVCTS=20000
         DPVDCD=10000
         COUNT=5000
;
;** INTERFRAME FLAG COUNT **
      IFLAGS=0                          ;OK WITH DQS11E'S SILO
;
;
;** TCB USEAGE **
;     P1=INTER-FRAME FLAG COUNT (TX)
;     P1=2-BYTE SHIFT REG ON RX
;
;** INIT ROUTINE **
;RESETS DEVICE TO MAKE PARAMETER REG. ACCESSIBLE.
;SETS MODE TO SDLC PRIMARY WITH CRC.
;PERFORMS MODEM HANDSHAKING.
;ENABLES RX TO ESTABLISH SYNC.
;IDLES FLAGS ON TX.
VPINIT:  BIS   #DPVRES,DPVTCS(R0)       ;RESET DEVICE
         CLR DPVTCS(R0)     ; Set 8 bit character length.
         MOV   #COUNT,R1
         MOV   #DSRM,R2
;
; Set the DPV11 mode:
;     Bit-oriented
;     Idle ABORT character.
;     CRC as DPV11
;
         MOV   #0,DPVPSR(R0)
;CONNECT TO MODEM
         BIS   #DPVDTR,(R0)             ;SET DTR
DPVS01:  BIT   #DPVDSR,(R0)             ;DSR?
         BNE   DPVS04
         DEC   R1
         BNE   DPVS01
         JMP   RPERR
DPVS04:  MOV   #COUNT,R1
         MOV   #CTSM,R2
;SET UP TX MODEM CONTROL
         BIS   #DPVRTS,(R0)             ;SET RTS?
DPVS02:  BIT   #DPVCTS,(R0)             ;CTS?
         BNE   DPVS05
         DEC   R1
         BNE   DPVS02
         JMP   RPERR
DPVS05:  MOV   #COUNT,R1
         MOV   #CARM,R2
;SET UP RX MODEM CONTROL
DPVS03:  BIT   #DPVDCD,(R0)             ;CARRIER?
         BNE   DPVS06
         DEC   R1
         BNE   DPVS03
         JMP   RPERR
;IDLE TX TO FLAG
DPVS06:  BIS   #DPVXEN,DPVTCS(R0) ; Enable device but no TX ints.
         BIS   #TSOM,DPVTDB(R0)
         RTS   PC
;
.PAGE
;** TX MECHANISM **
;
; At initialisation, the transmitter is enabled and TSOM is set.
; Thereafter, the interface idles FLAG without interrupting .  To
; start transmission of a frame, INTENB is set and the state variable
; incremented and a test of the TBEMTY bit is made to see if
; we can set TSOM in the TDSR.  If not the start sequence is
; delayed until the first interrupt (TBEMTY becoming set) occurs.
; On the first subsequent interrupt,
; the TSOM bit is cleared and the address byte is transmitted.
;  Thereafter, interrupts are taken until the message
; is completed.  On the first interrupt after completion of the
; message, TEOM is asserted to transmit the CRC.  TSOM is then set again
; to inter-frame fill with FLAG.  Then the state variable is
; re-initialised to zero and TX interrupts are disabled
; until another message is started.
;
;
;  TX STATES
;     0 = INTER FRAME IDLE, TSOM SET
;     1 = Awaiting DPVMTY to load TSOM into TDSR
;     2 = Send address byte.
;     3 = MESSAGE TRANSMISSION, NOT LAST BYTE, TEOM CLEAR
;     4 = CRC BEING TRANSMITTED, TEOM SET
;     5 = INTERFRAME FLAGS, TEOM SET
;     6 = CLEARING AFTER DATA LATE ERROR
;     7 = CLEARING (2)
;
;** TX START SEQUENCE **
;
DPVTSS: BIS #INTENB,DPVTCS(R1) ; ENABLE TRANSMITTER INTERRUPTS
      INCB STATE(R0)  ; Set state to TSOM load.
      BIT #DPVMTY,DPVTCS(R1) ; Is the TDSR ready for TSOM?
      BEQ DPVTSX ; Wait if not.
    MOV #TSOM,DPVTDB(R1)  ; Set TSOM to start up.
      INCB STATE(R0)   ; Start up with address byte.
DPVTSX:  JMP   DSPNXT
;
;** TX INTERRUPT SEQUENCE **
;
DPVTIS:  ADD   OFFTAB,R0                ;POINT AT TCB
         MOVB  STATE(R0),R2             ;GET STATE
         TSTB DPVTDB+1(R1)    ; Data underrun?
      BMI DPVTX4     ; If so, tell upper level.
         ASL   R2                       ;SWITCH ON R2
         JMP   @DPVTSW(R2)
DPVTSW:  .WORD DPVT00                   ;UNWANTED INT
         .WORD DPVT01                ; Load TSOM to start.
         .WORD DPVT10                   ; Address byte to send.
         .WORD DPVT20                   ;SUBS. CHARS
         .WORD DPVT30                   ;CRC DONE
         .WORD DPVT40                   ;INTER-FRAME FLAGS
         .WORD DPVT50                   ;CLEARING
         .WORD DPVT60                   ;CLEARING (2)
;
; Irrelevant interrupt, leave TXDBUF alone to prevent another.
;
DPVT00:           INC DPVIRR     ; Count irrelevant ints.
         BR    DPVTEX
DPVIRR: .WORD 0
;
; Set TSOM in the TDSR.
;
DPVT01: MOV #TSOM,DPVTDB(R1)  ; TDSR now ready for TSOM.
      INCB STATE(R0)   ; Send address byte next.
      INC DPEMER       ; Is this code ever entered?
      BR DPVTEX        ; Exit.
DPEMER: .WORD 0
;
; The first character (the address byte).
;
DPVT10:  JSR   PC,LDC                   ;GET CHAR
         BEQ   DPVT21                   ;** SHOULD BE ERROR **!!
         BIC   #177400,R2               ;TOP BYTE USED TO CLEAR TSOM
         MOV   R2,DPVTDB(R1)            ;OUTPUT CHAR
         INCB  STATE(R0)                ;NEXT STATE
         BR    DPVTEX
;
; Characters following the address byte.
;
DPVT20:  JSR   PC,LDC                   ;GET CHAR
         BEQ   DPVT21                   ;NO MORE
         MOVB  R2,DPVTDB(R1)            ;SEND CHAR
         BR    DPVTEX
;
; Message is complete, send the checksum.
;
DPVT21: 
;
; N.B. The following instruction must be a byte instruction - MOV causes a
; zero byte before checksum, BIS causes repeat of the last data
; byte before the checksum.
;
  BISB   #TEOMUP,DPVTDB+1(R1)         ;SET TEOM TO TRANSMIT CRC
         INCB  STATE(R0)                ;NEXT STATE is idle flags.
         MOVB  #IFLAGS,P1(R0)           ;SET INTER-FRAME FLAG COUNT
         BR    DPVTEX
;
; CRC completed - Now send idle flags.
;
DPVT30:   MOV   #TSOM,DPVTDB(R1)         ; Clear TEOM and set TSOM for flags.
         INCB  STATE(R0)                ;NEXT STATE
         BR    DPVTEX
;
; FIRST FLAG SENT WITH CRC.  IDLE FLAGS WITH TSOM.
;
DPVT40:  MOV   #TSOM,DPVTDB(R1)         ; Reassert TSOM to clear DPVMTY.
         DECB  P1(R0)                   ;COUNT FLAG
         BLT   DPVT41                   ;LAST ONE
         BR    DPVTEX
DPVT41:  CLR -(SP)                 ; Flag no error.
DPVT42:  CLRB  STATE(R0)                ;RESET STATE
         MOV   (R1),P1(R0)              ;SAVE STATUS
         BIC #INTENB,DPVTCS(R1)  ; and no TX interrupts.
         JMP   SENDOUT
;
; THIS CODE DEALS WITH HANDLING DATA LATE ERRORS
;
DPVER1:  .WORD 0                        ;COUNT OF DATA LATE FAULTS
;
DPVTX4: INC DPVER1  ; Count data late errors.
         MOV   #TSOM,DPVTDB(R1)            ; Clear data underrun bit.
         MOVB  #6,STATE(R0)             ;CLEARING FLAG
         BR    DPVTEX
;
DPVT50:
         MOV   #TSOM,DPVTDB(R1)         ; Re-assert TSOM
         MOVB  #7,STATE(R0)             ;CLEARING 2
         BR    DPVTEX
;
DPVT60:
         MOV   #TSOM,DPVTDB(R1)         ;Reset TSOM (clears data late)
         MOV #1,-(SP)              ; Inform upper level of error.
         BR    DPVT42
;
;
;
;NORMAL EXIT
DPVTEX:  JMP   DSPNXT
;
;** RECEIVER START SEQUENCE **
;
; Note that the DPV11 hardware does not pass the
; CRC characters to the receiving software.
;
;
DPVRSS:  BIC   #INTENB+DPVREN,DPVRCS(R1) ;DISABLE AND RE-ENABLE..
         BIS   #INTENB+DPVREN,DPVRCS(R1) ;.. TO FORCE RE-SYNC.
         CLRB  STATE(R0)                ;CLEAR STATE
         JMP   DSPNXT
;
;** RECEIVER INTERRUPT SEQUENCE **
;
DPVRIS:  ADD   OFFTAB,R0                ;POINT AT TCB
         MOV   DPVRDB(R1),-(SP)         ;SAVE THE CHAR
         MOVB  STATE(R0),R2             ;SWITCH ON STATE
         ASL   R2
         MOV   DPVRSW(R2),R2
         RTS   R2
DPVRSW:  .WORD DPVR10                   ;1ST CHAR
         .WORD DPVR20                   ;2ND CHAR
         .WORD DPVR50                   ;SUBSEQUENT CHARS
;
;1ST CHAR
DPVR10:  JSR   PC,GETBUF                ;GET BUFFER
         BNE   DPVR11                   ;GOT ONE
         BIC   #DPVREN,(R1)              ;RESET RECEIVER TO ABORT FRAME
         BIS   #DPVREN,(R1)
         JMP   DSPNXT
;
DPVR20: JSR PC,DPVECH    ; Error?
 BNE DPVRER ; Report if error.
 JSR PC,DPVPUT  ; Stow character.
 BIT #REOM,R2  ; Block 2 chars long?
 BNE DPVR51 ; Pass up if complete.
 BR DPVRXX ; Next exit.
;
DPVR11: JSR PC,DPVECH      ; ERROR ON 1ST CHAR?
 BNE DPVRER
    BIT   #REOM,R2          ; EOM?
          BNE DPVRER          ; Exit if error.
         JSR   PC,DPVPUT                ;SAVE GOOD CHAR IN PARAM BLOCK
         BR    DPVRXX                   ;TAKE NEW STATE AND EXIT
;
;NEXT STATE EXIT
DPVRXX:  INCB  STATE(R0)                ;NEXT STATE
         JMP   DSPNXT
;
;SUBSEQUENT CHARS
DPVR50:  JSR PC,DPVECH    ; Any error bit set?
         BNE DPVRER     ; If so, report to upper level.
         MOV   R1,-(SP)                 ;SAVE R1 FROM STC
         JSR   PC,STC                   ; Save character in buffer.
         BNE DPVRNR                   ; Nibble request refused if Z=0
         MOV   (SP)+,R1                 ;RESTORE R1
;
; EOM? (DPV11 flags EOM on last character)
;
         BIT   #REOM,R2                 ;EOM?
         BNE   DPVR51                   ;YES
         JMP   DSPNXT   ; Return for next
;
;END OF MESSAGE
DPVR51:  CLR   -(SP)                     ;FLAG NO ERROR
DPVR52:  MOV   (R1),P1(R0)              ;SAVE MODEM STATUS
         CLRB  STATE(R0)                ;RESET STATE
         JMP   SENDIN                   ;DISPATCH MESSAGE TO HANDLER
;
;ERROR HANDLER
DPVRER:  MOV   #1,-(SP)                  ;FLAG ERROR
         BIC   #INTENB+DPVREN,(R1)       ;DISABLE RX
         BR    DPVR52                   ;AND EXIT NORMALLY
;
; Handle STC error:
;
DPVRNR:  MOV (SP)+,R1                    ; Restore R1,
         BR DPVRER                      ; and flag error.
;
; Routine to determine receive error condition.
;
DPVECH: BIT #ERCHK+RABORT+RCVOVR,R2 ; ERROR?
      RTS PC
;
;
;
;ROUTINE TO LOAD CHARS INTO PARAM BLOCK
DPVPUT:  MOV   R1,-(SP)                 ;SAVE
         MOVB  STATE(R0),R1             ;ONLY USED IN STATES 0 AND 1
         ADD   (R0),R1                  ;POINT AT PARAM (PUT PTR FIELD)
         ADD   #ADRCMD-PUTPTR,R1        ;POINT AT BUFFER BYTES
         MOVB  R2,(R1)                  ;SAVE THE BYTE
         MOV   (SP)+,R1
         RTS   PC
;
;END OF DPV11 HANDLER
;
;     ERROR REPORTING TO TTY
;
RPERR:   MOVB  (R2)+,R1                 ;GET CHARACTER
         BNE   RPERR1
         HALT                           ;END OF MESSAGE
         JMP   START                    ;RESTART
RPERR1:  TSTB 177564                   ;TTY READY
         BEQ   RPERR1
         MOVB  R1,177566                ;PRINT CHAR
         BR    RPERR
;
DSRM: .ASCII   /MODEM: DSR NOT UP/
      .BYTE 15,12,0
      .EVEN
CTSM: .ASCII   /MODEM: CTS NOT UP/
      .BYTE 15,12,0
      .EVEN
CARM: .ASCII/MODEM: CARRIER NOT UP/
      .BYTE 15,12,0
      .EVEN
^