.TITLE  DX11
        .SBTTL DX11 INTERRUPT ROUTINE - DATA AREAS AND DEFINTIONS
        ;DX11 INTERRUPT ROUTINE
        ;DATE: 03-FEBRUARY-84
;NOW READ SYSTEM CONFIGURATION FILE CONFIG PAL11
./ COPY=CONFIG
        DX11BITS=1
        DX11PAR=1
        .PARAM=1
        DEVPAR=1
        EMTNAM=1
;
./ COPY=SYSMAC
        .GLOBL $DX11I,DXTT,DXTTP,DXSPWT,DX11PCB,DXPROC,DXINIT,DXOPEN
        .GLOBL DXTRAN,DXSTPR,DXBAST,DXBSTB,DXBSTA,$V,$SAVE,$RESTORE
;
        DXMAX1=132. ;BURST LENGTH FOR LONG BURST DEVICES
;       DXMAX2=4  ;BURST LENGTH FOR TERMINALS
;       DXLONG=X'60  ;FENCE FOR LONG BURST
;       DXDEV1   -  LOWEST ADDRESS SUPPORTED
;       DXDEV2  - ONE MORE THAN HIGHEST ADDRESS SUPPORTED
        .GLOBL DXDEV1,DXDEV2
;
; DXDEV1 AND DXDEV2 MUST BE SET CORRECTLY TO MATCH THE ADDRESS RANGE
; RECOGNISED BY THE DX11 HARDWARE
;
        DXSPWD=1;SPW M.S BYTE - DST OFFSET
        DXSPWS=0;SPW L.S BYTE IS IMMEDIATE STATUS
;
;       BITS FOR XDFLAG
        XXOFFF=20       ;OFFLINE BASE -DETACH DEV WHEN IDLE
        XXSTAF=40       ;STATUS MAY BE RELEASED
        XXDATF=100      ;DATA TRANSFER REQUEST NOT STATUS REQUEST
        XXCHNF=200      ;DEVICE HAS TRANSFER OR STATUS IN PROGRESS

;       BITS FOR XXSTAT
        XXRDY=200       ;DEVICE IS FULLY READY - THIS MUST BE SIGN BIT
        XXRDYF=100      ;DEVICE BECOMING READY
        XXCMDF=40       ;PROCESSING NON-IMMEDIATE COMMANDS
        XXSTKS=10       ;STATUS IS STACKED
        XXNSTA=4        ;E.S. OUTSTANDING ;SET ON NON-IMMED CMD,
                        ;CLEAR TO PRESENT STATUS
        XXABOR=2        ;DO NOT DO DATA TRANSFERS
        XXRSTF=1        ;DO NOT PRESENT ES
;
; DX11 PROCESS CONTROL BLOCK
;
        .IFDF  USERMODE
        PROCMODE=UMODE
        .IFF
        PROCMODE=KMODE
        .ENDC
        STKSZE=100
DX11PCB:0,0,0
        DXPROC,PROCMODE   ;ENTRY POINT,PSW
        DX11STK+<STKSZE*2>
        DX11DB
        0,0,0,0,0,0     ;REGISTER STORAGE
        0               ;MMU ADDRESS REGISTER STORAGE
DX11STK:.=.+2*STKSZE
;
DX11DB:;DX11 BASE AREA
DXTTP:  0    ;TUMBLE TABLE SOFTWARE POINTER
DXQ1:   0
DXCHN2: 0    ;SECONDARY CHAIN USED FOR HOLD
DXCBSY: 0    ;HOLDS CUBSY TO RESET AFTER IR IF ALL DEV FINISHED RESETING
DXBYTE: 0    ;FOR READING ODD BYTE (NB FULLWORD)
DXCNTX: 0    ;COUNT OF DEV NOT FINISHED RESETING
;
;OFFLINE DEVICE QUEUES
;
XXSCNT: .BYTE 0         ;CNT OF DEV WITH PENDING OFFLINE SENSE
XXSCNS: .BYTE 0         ;COUNT OF DEV WITH PENDING OFFLINE SENSE AND HIO
XXSNQ2: .BYTE 0         ;CHAIN OF OFFLINE DEVICES WITH SENSE AND HIO
XXSNQ3: .BYTE 0         ;QUEUE FOR INITIALISING OFFLINE STATUS
XXSCN3: .BYTE 0         ;NUMBER OF ITEMS OM DXSNQ3
        .EVEN
;
DXIRSW: 0          ;INTERRUPT SWITCH
DXSEM:  0,0        ;SEMAPHORE USED BY INTERRUPT ROUTINE AND DX11 PROCESS
;
; OFFLINE DEVICE BASE
DXBAS1: .=.+DXXBLN
DXBEND:
      .=DXBAS1+XNSNS
      1                         ;ONE SENSE BYTE ONLY FOR OFFLINE DEVICES
      .=DXBEND
;
; ONLINE BASE ADDRESS TABLE
DXBSTA: .=.+2*<DXDEV2-DXDEV1>
DXBSTB:
DXBAST=DXBSTA-<2*DXDEV1>
;
        .PAGE
        .SBTTL  DX11 PROCESS CODE
DXPROC: ;FIRST ENTRY TO DX PROCESS
        JSR     R5,DXNITT ;QUEUE OFFLINE INITIALISING STATUSES
        BIC     #CUBSY,@#DXCS   ;CLEAR CUBSY UNLESS LOCKO SET EARLIER
        BIS     #INTEN,@#DXCS      ;ENABLE DX11 INTERRUPTS FOR FIRST TIME
        BR      DXNEXT
;
;REMOVE INACTIVE DEVICE BASE FROM CHAIN
;
DXAB01: BNE     DXER20  ;INVALID LENGTH
DXABOR: JSR     R5,TRANOK       ;TERMINATE DATA TRANSFER
DXNST:
        MOV     #DXQ1,R0        ;UNCHAIN BASE PROVISIONALLY
        JSR     R5,$UCHAIN      ;UNCHAIN HEAD FROM QUEUE
        BIC     #XXCHNF,-(R1)   ;MARK NOT CHAINED
        BEQ     DXIIII          ;EXIT IF NOTHING TO DO
        MOV     R1,R4
        SUB     #XDFLAG,R4      ;GET BASE POINTER
        CMP     #XXOFFF,(R1)    ;CHECK IF OFFLINE ACTION ONLY
        BEQ     1$
        JSR     R5,DXTR01       ;OR RECHAIN IF NEDDED
        BR      DXIIII
1$:     JSR     R5,DXSB2        ;DISCONNECT THIS DEIVCE FROM OFFLINE BAS
        BR      DXIIII
DXER20: TRAP    7               ;INVALID DATA LENGTH
DXNST1: BR      DXNST
;
;GO TO SLEEP AFTER RE-ENABLING DX11 INTERRUPTS
;
DXSLEEP:
        BIS     #INTEN,@#DXCS      ;ENABLE DX11 INTERRUPTS
        MOV     #DXSEM,-(SP)
        EMT     P               ;WAIT FOR IR TO SAY SOMETHING TO DO
DXNEXT:
        MOV     #DXSLEEP,-(SP)  ;SET LINK
        BIC     #INTEN,@#DXCS      ;DISABLE DX11 INTERRUPTS
;
;DEAL WITH FIRST ITEM ON DX11 WORK QUEUE
;MUST BE OBEYED DISABLED FOR DX11 INTERRUPTS
DXIII:
        TST     DXCBSY   ;IF AFTER SYS OR SEL RST AND CNT EXHAUST
        BNE     1$              ;RESET INTERRUPT ROUTINE AND CUBSY
        TSTB    DXCNTX
        BNE     1$
        JSR     R5,DXRSR        ;GO TIDY UP
1$:
DXIIII: BIT     #DONE!GO,@#DXCS ;DON'T START ACTION IF ACTIVE (DXCB NOT
                                ;PROTECTED BY LOCKO
        BNE     DXXIT           ;(DONE SET PH 4 BEFORE GO RESET IN PH 7
        MOV     DXQ1,R4         ;LOOK FOR WORK ON MAIN QUEUE
        BEQ     DXXIT           ;B IF QUEUE EMPTY
        BIT     #XXDATF,-(R4)   ;TEST IF DATA TRANSFER WANTED
        BEQ     DXST            ;LOOK FOR STATUS OTHERWISE
        SUB     #XDFLAG,R4
        BITB    #XXCMDF,XXSTAT(R4);ERR IF DATA WHEN NOT IN CMD
        BEQ     DXER22
        BITB    #XXABOR,XXSTAT(R4);MARKED TO ABORT?
        BNE     DXABOR            ;B IF ABORTING
        TSTB    DXCNTX
        BNE     DXHOLD  ;TO HOLD WORK IF ANY DEV NOT FINISHED RESETING
;
        MOV     #-DXMAX1,R0
;
;       MOV     (PC)+,R0        ;SET COMPLEMENTS OF BOTH BURST LENGTHS
;       .BYTE   -DXMAX1,-DXMAX2 ;LONG SHORT
;       CMPB    XDADDR(R4),#DXLONG
;       BLO     3$
;       SWAB    R0
;3$:    MOVB    R0,R0                   ;CLEAN LENGTH
        CMP     R0,XDLEN(R4)            ;COMPARE WITH MAX ALLOWED
        BGT     4$                      ;B IF GREATER THAN MAX
        MOV     XDLEN(R4),R0            ;IF LT MAX USE IT
        BPL     DXAB01                  ;EXIT IF COUNT EXHAUSTED
4$:
        MOV     #SWDATA,DXIRSW          ;MARK DATA EXPECTED NEXT
        .IFNDF  MMU
        MOV     XDDATA(R4),@#DXBA       ;SET BUS ADDRESS
        MOV     #FCTN2,R1               ;PREPARE FOR OUTPUT TO  CHANNEL
        .ENDC
        .IFDF   MMU
        MOV     R2,-(SP)
        MOV     R0,-(SP)
        CLR     R0
        MOV     XDDATA(R4),R2           ;PICK UP VIRTUAL ADDRESS
        CMP     R2,#VSTART             ;IS ADDRESS REAL
        BLO     10$                     ;B IF NO EXTENDED ADDRESS
        MOV     XXAR(R4),R1             ;PICK UP PAGE ADDRESS REGISTER
        ASHC    #6,R0                   ;CONVERT BLOCK NUMBER TO ADDR
        BIC     #160000,R2              ;EXTRACT OFFSET FROM VIRT ADDR
        ADD     R1,R2
        ADC     R0                      ;FORM 18BIT ADDRESS IN R1,R0
        BEQ     10$
        TRAP    7
;EXTENDED ADDRESS BITS MUST BE ZERO
;       ASH     #3,R0                   ;SHIFT BITS 16 AND 17 FOR CSR
10$:    MOV     R2,@#DXBA               ;SET BOTTOM 16BITS OF ADDRESS
        MOV     #FCTN2,R1
;       MOV     R0,R2                   ;SAVE EXTENDED ADDRESS BITS
        MOV     (SP)+,R0                ;RESTORE BYTE COUNT
        .ENDC
        BITB    #1,XXCMD(R4)            ;CHECK FOR INPUT OR OUTPUT
        BEQ     5$
        ASR     R1                      ;SET INPUT FROM CHANNEL
        BIT     #1,XDDATA(R4)
        BEQ     5$                      ;EVEN ADDRESS IS SIMPLE
        MOV     #-1,R0                  ;SET UP SPECIAL READ
        MOV     #SWDATX,DXIRSW
        MOV     #DXBYTE,@#DXBA
5$:     MOV     R0,@#DXBC               ;SET BYTE COUNT IN DX11
        SUB     R0,XDLEN(R4)            ;SET LENGTH AND ADDRESS AS IF
        SUB     R0,XDDATA(R4)           ;TRANSFER HAD COMPLETED SUCESS
        .IFDF   MMU
;       BIS     R2,R1                   ;INSERT NEW EXTENDED ADDRESS
;EXTENDED ADDRESS BITS MUST BE ZERO
        MOV     (SP)+,R2
;       BIC     #36,@#DXCS              ;CLEAR OLD EXTENDED ADDRESS BITS
        .ENDC
        BIS     R1,@#DXCS               ;SET FUNCTION (READ/WRITE)
DXST3:
        MOVB    XDADDR(R4),@#DXCUAR     ;SET DEVICE ADDRESS IN DX11
        INC     @#DXCS                  ;SET GO FOR DX11
DXXIT:
        RTS     PC      ;TO SLEEP IF PROCESS,EXIT IF IR
;
DXER22: TRAP    7       ;ATTEMPT TO START DATA TRANSFER WITH NO COMMAND
;
;DEVICE HAS NO DATA OUTSTANDING - CHECK FOR STATUS
;PRO TEM NO SPECIAL ACTION IF SECONDARY STATUS ***BEWARE****
DXST:
        BIT     #XXSTAF,(R4)+
        BEQ     DXNST1  ;UNCHAIN DEVICE IF NO STATUS WANTED
        SUB     #XCHAIN,R4
        BITB    #XXRSTF,XXSTAT(R4)
        BEQ     DXST10          ;B UNLESS HAD RESET
        JSR     R5,STPRST       ;TIDY UP DEVICE
DXIIJ1:
        BR      DXIIII          ;GET NEXT ITEM ON WORK QUEUE
;
; PLACE WORK ON HOLD QUEUE WHILST AWAITING TERMINATION OF SEL RST
DXHOLD:
        MOV     #DXQ1,R0
        JSR     R5,$UCHAIN
        MOV     #DXCHN2,R0
        JSR     R5,$CHAIN
        BR      DXIIJ1          ;TO PROCESS NEXT ITEM OF WORK
;
; NORMAL STATUS PROCESSING
;
DXST10:
        TSTB    DXCNTX   ;SHOULD WE TEST DXCBSY
        BNE     DXHOLD;TO HOLD ANY WORK UNTIL ALL DEV FINISHED RESET
        MOVB    XSTATUS(R4),@#DXCUSR;SET STATUS FROM DEVICE BASE
        BICB    #XXABOR,XXSTAT(R4);CLEAR ABORT FLAG
        BPL     1$      ;B IF PRESENTING INITIALISING STATUS
        BITB    #XXCMDF,XXSTAT(R4);SEE IF PROCESSING CMD STATE
        BEQ     DXER21 ;ERR IF PRESENTING END STATUS WITH NO CMD
1$:
        MOV     #SWSTAT,DXIRSW  ;MARK ESEND EXPECTED NEXT
        BIS     #STKSTA!FCTN3,@#DXCS;SET SUPRESSIBLE STATUS PROVISIONALL
        BITB    #CHEND,XSTATUS(R4) ;NEVER CHANNEL END WITHOUT DEVICE END
        BEQ     DXST3   ;B IF SUPPRESSIBLE-I.E. NOT PRESENTING CE OR DE
        BITB    #XXSTKS,XXSTAT(R4);HAS IT ALREADY BEEN STACKED
        BNE     DXST3   ;B IF ALEADY STACKED
        BIC     #STKSTA,@#DXCS  ;NOT SUPPRESSIBLE
        BR      DXST3   ;B TO SET DEV ADDR AND GO
;
DXER21: TRAP    7
;
        .PAGE
        .SBTTL DX11 INTERRUPT ROUTINE -INTERRUPT CODE
        ;REGISTER USASE
        ;R0 - WORK REGISTER
        ;R1 - WORK REGISTER
        ;R2 - POINTER TO CURRENT TUMBLE TABLE ENTRY
        ;R3 - FIRST WORD OF TUMBLE TABLE ENTRY
        ;R4 - BASE (SCA)
        ;R5 - LINK REGISTER
;
;
;
;       SPECIAL SYSTEM RESET INTERRUPT ROUTINE
;       SYSTEM RESET HAS BEEN DETECTED IN THE MAIN IR WHICH HAS SWITCHED
;       THE INTERRUPT VECTOR TO HERE AS THERE MAY BE MORE SYSTEM RESETS
;       (BUT ONLY SYSTEM RESETS) AND WE MAY HAVE TO DEAL WITH THEM
;       QUICKLY - E.G 370 HDM
;
DXIR1:  BIC     #DONE,@#DXCS
        MOV     R2,-(SP)
        MOV     DXTTP,R2;PICK UP ADDRESS OF CURRENT TUMBLE TABLE ENTRY
        BR      DXIR12
DXIR11: CLR     (R2)+;CLEAR ENTRY(CAN ONLY BE ANOTHER SYSRT AS CUBSY SET
        TST     (R2)+   ;SKIP ADDRESS AND COMMAND
        BIT     #DXTTL-1,R2     ;CHECK FOR WRAP
        BNE     DXIR12          ;OVERFLOW HAS NOT OCCURED
        MOV     #DXTT,R2      ;BACK TO BEGINNING OF TABLE
DXIR12: TST     (R2)            ;IF NULL ENTRY THEN ALL PROCESSED
        BNE     DXIR11          ;CONTINUE
        MOV     R2,DXTTP       ;SAVE CURRENT TUMBLE TABLE POINTER
        MOV     (SP)+,R2
        RTI
;
;       MAIN INTERRUPT ROUTINE
;
;       MAIN TUMBLE TABLE SCAN LOOP
;
DXER3:  TRAP    7
$DX11I: JSR     R5,$SAVE        ;SAVE REGISTERS
        MOV     DXTTP,R2       ;SET UP TUMBLE TABLE POINTER
        BIC     #DONE,@#DXCS    ;CLEAR DONE TO PERMIT FURTHER INTERRUPTS
DXIMOR: MOV     (R2),R3         ;GET FIRST WORD OF ENTRY
        BNE     DXINXT          ;BRANCH IF USED
; NOW HAVE COME TO END OF TT PROCESSING
DXINON: SUB     DXTTP,R2       ;FIND NUMBER OF ENTRIES PROCESSED
        CMP     R2,#DXTTL       ;COMPARE WITH TABLE LENGTH
        BGE     DXER3           ;ERROR IF FULL TT DONE - OVERFLOW?
        ADD     R2,DXTTP       ;SAVE NEXT TT SLOT ADDRESS
        BIC     DXCBSY,@#DXCS;CLEAR CUBSY IF NO RESET OUTSTANDING
        JSR     PC,DXIII        ;*** RESTART TOP ENTRY ON Q
;
DXIXIT: JSR     PC,$RESTORE     ;RESTORE REGISTERS
        RTI
;
;
DXINXT: CLR     (R2)+           ;MARK ENTRY AS NOT IN USE (BIT EARLY)
        CLR     R0
        BISB    (R2),R0;DEVICE ADDRESS FROM TT
        TST     (R2)+           ;SKIP PAST SECOND WORD
        MOV     DXIRSW,R1       ;SAVE INTERRUPT SWITCH
        MOV     #SWNORM,DXIRSW  ;RESET TO NORMAL
        ASL     R0              ;DEVICE ADDRESS*2
        MOV     DXBAST(R0),R4   ;PICK UP SCA ADDRESS
        JSR     R5,(R1)         ;PROCESS TT ENTRY
        BIT     R2,#DXTTL-1     ;CHECK FOR WRAPAROUND
        BNE     DXIMOR
        MOV     #DXTT,R2
        BR      DXIMOR
;
;       INDIVIDUAL TUMBLE TABLE ENTRIES
;
;SUBROUTINE TO REMOVE DEVICE R0 FROM OFFLINE CHAIN
DXISC0: ASR     R0      ;SPECIAL ENTRY SHIFTING R0 ONE PLACE
DXISC:  MOV     (R5)+,R1;SEARCH AND REMOVE ITEM FROM OFFLINE CHAIN
        SUB     #DXSPWT+DXSPWD,R1;GET ADDRESS OF CHAIN HEAD
        MOV     @(R5)+,-(SP)
        BEQ     33$;B IF CHAIN EMPTY
        BR      32$     ;CHAIN NOT EMPTY
;
31$:    DECB    (SP)    ;COUNT DOWN CHAIN
        BEQ     33$     ;B IF REACHED END OF CHAIN
        MOVB    DXSPWT+DXSPWD(R1),R1 ;ON TO NEXT ON CHAIN
        BIC     #177400,R1
        ASL     R1
32$:    CMPB    R0,DXSPWT+DXSPWD(R1) ; CHECK IF FOUND
        BNE     31$                  ;B IF NOT FOUND
        ASL     R0
        MOVB    DXSPWT+DXSPWD(R0),DXSPWT+DXSPWD(R1);REMOVE FROM CHAIN
        DECB    @-2(R5)         ;ADJUST COUNT OF ITEMS ON CHAIN
        ASR     R0
33$:    TSTB    (SP)+           ;POP STACK AND SET CC
        RTS     R5
;DEAL WITH SEL RST AND HIO FOR OFFLINE DEVICES WITH SENSE,R0=2(DEV ADDR)
;NOTE DEV NOT AT HEAD OF MAIN CHAIN AS IS PSEUDO-OPEN
;HENCE 'OWNS' THE SPECIAL BASE
DXIOSH: JSR     R5,DXISC0 ;SHIFT R0 RIGHT,SEARCH AND IF FOUND ,REMOVE
        XDADDR,XXSCNT     ;MAIN CHAIN
        BNE     1$      ;B IF OUND ON MAIN CHAIN
        BIT     #SELRST,R3
        BEQ     2$      ;IF HIO ONLY THEN IGNORE IF ON 2ND OR 3RD CHAIN
        JSR     R5,DXISC
        XXSNQ2,XXSCNS ;CHAIN OF HIO'D DEVICES
        RTS     R5
;FOUND ON FIRST QUEUE
1$:     BIT     #SELRST,R3
        BNE     2$      ;FORGET IT IF SEL RST
        ASL     R0      ;2 (DEV ADDR)
        MOVB    XXSNQ2,DXSPWT+DXSPWD(R0);ELSE Q TO HEAD 2ND Q
                        ;TO PRESENT ENDING STATUS ONLY
        ASR     R0
        MOVB    R0,XXSNQ2
        INCB    XXSCNS
2$:
SWXIT:  RTS     R5
;
        .PAGE
        .SBTTL  NORMAL TT ENTRY PROCESSING
SWNOR1: TST     R4      ;RECONSTRUCT CONDITION CODE
SWNORM: BNE     NDATA0  ;B IF ONLINE DEVICE
OFFDE1: BIT     #SYSRST,R3;ADDRESS OF DEV IMMATERIAL IF SYS RESET
        BNE     ERR01     ;BRANCH IF SYSTEM RESET
        BIT     #SELRST!INFDSC,R3
        BNE     DXIOSH  ;B IF SEL RST OR HIO FOR OFFLINE DEV
        BIT     #UCHKS,R3;IF DEV NOT OPEN SHOULD HAVE SENT UC
        BNE     SWXIT    ;IGNORE UNIT CHECKS SENT FOR OFFLINE DEVICES
        BIT     #TTMSK-CHIS+STKSTB,R3;OFFLINE DEV ALLOWED SENSE
        BNE     1$       ;ERROR IF NOT CHIS FOR OFFLINE DEV
        JMP     DXISPS   ;GO AND TRY SENSE
1$:     TRAP    7        ;IMPOSSIBLE OFFLINE TT ENTRY
;       DATA TRANSFER OUTSTANDING - CHECK FOR CUIS
SWDATX: TST     @#DXBC  ;ADJUST FOR ODD BYTE
        BNE     SWDATA  ;NOTHING TO DO IF NO TRANSFER
        MOV     DXQ1,R1
        TST     -(R1)      ;SKIP OVER XDFLAG *** NOT IN CAMBRIDGE CODE
        MOV     -(R1),R1        ;REAL DATA ADDRESS
        MOVB    DXBYTE,-(R1)    ;*** COPY BYTE
SWDATA: MOV     DXQ1,R1         ;GET ASSOCIATED DEVICE
        TST     -(R1)
        ADD     @#DXBC,-(R1)    ;ALLOW FOR UNDONE PART OF TRANSFER
        ADD     @#DXBC,-(R1)
        SUB     #XDLEN,R1       ;GET BASE POINTER
        CMP     R1,R4           ;DOES TT ENTRY RELATE TO REQUEST
        BNE     SWNOR1          ;NO - TREAT AS UNSOLICITED
        BIT     #TTMSK-CHDEND-CUDEND,R3
        BNE     SWDAT0
        BIT     #CUDEND,R3
        BEQ     CHD00           ;DEAL WITH (NON-ERROR) CHDEND
        TST     XDLEN(R1)       ;TEST IF TRANSFER COMPLETE
        BMI     SWXIT
        JMP     TRANOK          ;REPORT COMPLETION
;
        ;CHDEND WITHOUT ERRORS
CHD00:  MOV     #XDCHD,R1  ;PREPARE TO REPORT CHANNEL TERMINATED DATA
        JMP     DXISE1
;       DATA TRANSFER REQUESTED - NOT CUIS OR ERRORS
SWDAT0: BIT     #CHIS+RESETS,R3 ;IS THIS UNRELATED TO DATA TRANSFER
        BNE     NDATA
; PARER OR NXM IN DATA
        BIT     #PARER!NXM,R3
        BEQ     2$      ;NO
        BISB    #UC,XSTATUS(R4) ;SET UNIT CHECK IN STATUS
        JSR     R5,SETSN1       ;SET EQUCHK OR BUSOCK AS APPROPIATE
        MOV     #XDERR,R1       ;*** USE OF R1
        JMP     DXISE1          ;AND CALL ERROR ROUTINE
;
2$:     TRAP    7       ;DX11 ERROR
;
OFFDEV: BR      OFFDE1
ERR01:  BR      ERR00
;
;       CHANNEL INITIATED SEQUENCE FOR ONLINE DEVICE
;             CHIS + ESEND NOT PROPERLY HANDLED
NDATA0: BIT     #CHIS+RESETS,R3
        BEQ     DXER63          ;IMPOSSIBLE SPONTANEOUS VALUE
NDATA:  BIT     #TTMSK+STKSTB-CHIS-CHENDS-ESEND,R3
        BNE     ERR00           ;BRANCH IF ERRORS STACKED STATUS ETC.
;       HERE ON NON-REJECTED CHIS - I.E. CHIS WITH OPTIONALLY CHENDS
;       NOTE SENSE FOR OFFLINE DEVICES IS FILTERED OFF EARLIER
        MOVB    -1(R2),R1       ;GET COMMAND CODE
        BEQ     SWXIT     ;IGNORE TIO (INCLUDING PENDING STATUS CASES
        BITB    #XXCMDF!XXRSTF,XXSTAT(R4) ;ALREADY PROCESSING COMMAND
                                          ;OR CMD REC DURING SEL RESET
        BNE     DXICHK  ;BRANCH IF SO
        BITB    #XXRDY!XXRDYF,XXSTAT(R4);SEE IF DEVICE READY OR GOING RE
        BMI     1$;BRANCH IF PROPERLY READY
        BEQ     DXER61  ;ERROR OTHERWISE
        BIC     #XXSTAF,XDFLAG(R4);CANCEL STATUS REQUEST
        BISB    #XXRDY,XXSTAT(R4);MARK PROPERLY READY IF ACCEPTED CMD
1$:
        BIT     #CHENDS,R3      ;BRANCH IF IMMEDIATE COMMAND
        BNE     SWXIT
        MOVB    R1,XXCMD(R4)    ;COMMAND TO DEVICE BASE (SCA)
        MOVB    #CHEND!DEVEND,XSTATUS(R4);PRESET NORMAL ENDING STATUS
        BISB    #XXCMDF!XXNSTA,XXSTAT(R4);MARK CMD PRESENT,ES OUTSTANDING
        CMPB    #SENSE,XXCMD(R4);IS IT A SENSE COMMAND
        BEQ     DXISNS
        CLR     XSENSE(R4) ;AS NOT IMMED CLEAR SENSE BYTES
        CLR     XSENSE+2(R4)
        CLRB    XCOUNT(R4) ;SET IN POS RANGE DURING COMMAND
        MOV     @XJUMP(R4),PC ;***** INFORM DEVICE OF COMMAND
                              ;RETURN TO TT SCAN
                              ;ASSUMES COMMAND IS FIRST ENTRY IN TABLE
;       SENSE FOR OPEN DEVICES
DXISNS:
        MOV     XJUMP(R4),XJCOPY(R4) :***SAVE REAL JUMP TABLE
        MOV     #DXSNSJ,XJUMP(R4) ;SET UP SENSE DATA REQUEST
        JMP     DXSENS
;
;COMMAND RECEIVED DURING EARLIER COMMAND OR DURING SEL RESET
DXER61: TRAP    7;DEVICE NOT READY OR GOING READY
DXICHK: TRAP    7
;
;       STATUS REQUEST OUTSTANDING
SWSTER: TRAP    7
;
SWSTAT: BEQ     OFFDEV ;NOT OURS IF OFFLINE DEVICE
        BIT     #TTMSK+CMDREJ-ESEND-UCHKS-CHENDS-BSYS,R3
        BNE     NDATA0 ;NOT OURS IF CHANNEL INITIATED (CHIS +ESEND)
        MOV     DXQ1,R1
        SUB     #XCHAIN,R1
        CMP     R1,R4 ;CHECK CORRECT DEVICE
        BNE     SWSTER ;FAULT IF NOT
DXIES1: BIT     #ESEND,R3 ;IS STATUS STACKED
        BNE     2$
        TSTB    XXSTAT(R4)
        BMI     1$;B UNLESS DOING INITIALISING STATUS PRESENTATION
        BITB    #XXSTKS,XXSTAT(R4)      ;IF STATUS WAS SUPPRESSIBLE
        BNE     2$                      ;THEN TREAT AS STATUS ACCEPTED
1$:
        BISB    #XXSTKS,XXSTAT(R4);MARK STATUS STACKED -NOW SUPPRESSIBLE
        RTS     R5                      ;RETURN TO TT SCAN
2$:
; TREAT STATUS WITHOUT DEVICE END AS SPECIAL ****************
;
;       CMPB    #CE,XSTATUS(R4)         ;CHECK FOR CHANNEL END
;       BEQ     3$              ;B IF STATUS TO BE PRESENTED AGAIN
;
        BICB    #XXCMDF!XXSTKS,XXSTAT(R4);CLEAR CURRENT CMD MARKERS
        BISB    #XXRDY,XXSTAT(R4)       ;SET READY IN CASE GOING READY
        CLRB    XXCMD(R4)               ;CLEAR OUTSTANDING COMMAND
3$:
        BIC     #XXSTAF,XDFLAG(R4)      ;RESET STATUS REQUEST
        RTS     R5
;
DXER63: TRAP    7 ;ENDING STATUS ACCEPTED FOR DEV NOT PRESENTING STATUS
;
STKTIO: TSTB    -1(R2)  ;COMMAND RECEIVED WHILE ACTIVE
        BNE     NOTTIO  ;FAULT IF NOT TIO
        BITB    #XXSTKS,XXSTAT(R4)
        BNE     DXIES1 ;TIO IS POSSIBLE ONLY IF STATUS IS STACKED
NOTTIO: TRAP    7
;
        .PAGE
        .SBTTL RESETS OR ERRORS
ERR00:  BIT     #RESETS,R3
        BNE     DXIF11 ;BRANCH IF SYSRST SELRST OR HIO
; CHIS WITH ONE OF PARER,BSYS,UCHKS OR STKSTB PRESENT
; OR ELSE NONSENSE TT ENTRY WITH ONE OF ESEND,CUDEND,CHDEND,NXM PRESENT
        BIT     #STKSTB!UCHKS!BSYS,R3
        BEQ     DXER63  ;NONSENSE ENTRY
        BIT     #RESETS+ESEND+CUDEND+CHDEND+NXM+CMDCHN,R3
        BNE     DXER63
        BITB    #XXCMDF,XXSTAT(R4) ;CHECK NO COMMAND PRESENT
        BNE     STKTIO
        TSTB    XXSTAT(R4)
        BMI     4$ ;SKIP IF PROPERLY READY
        BIC     #XXSTAF,XDFLAG(R4) ;OR FORCE READY
        BISB    #XXRDY,XXSTAT(R4)
4$:     BIT     #STKSTB,R3
        BNE     DXISTI  ;STACKED INITIAL STATUS
;WE HAVE CHIS + (UCHKS OR BSYS) - ASSUME UCHKS AND COMPLETE SENSE VALUE
;       INTREQ IF SPW NON-ZERO
;       BUSOCK IF PARER (BAD COMD PARITY)
;       EQC    IF NXM (BAD DST POINTER)
;       CMDREJ OTHERWISE (UC IN DST)

        MOV    #INTREQ,R1
        TSTB   DXSPWT+DXSPWS(R0)
        BNE    SETSEN ;SET INTERVENTION REQUIRED AS ASSUME TRYING TO CLS
        MOV    #CMDRJ,R1
        BIT    #PARER!NXM,R3
        BEQ    SETSEN           ;TO SET CMD REJECT IF NOT HARDWARE ERROR
SETSN1: MOV    #EQUCHK,R1
        BIT    #NXM,R3
        BNE    SETSEN           ;SET EQUIPMENT CHECK IF NXM
        MOV    #BUSOCK,R1
SETSEN: BISB   R1,XSENSE(R4)
        RTS    R5
;
;       STACKED INITIAL STATUS
DXISTI: MOV    DXSPWT(R0),R1    ;RECONSTRUCT STATUS FROM SPW
        MOVB   R1,XSTATUS(R4)
        BNE    1$
        BISB   -1(R2),R1        ;INSERT COMMAND NUMBER
        MOVB   (R1),XSTATUS(R4)
1$:     BISB   #XXRDY!XXRDYF!XXCMDF!XXSTKS,XXSTAT(R4);CMD PRESENT,STK ST
        JMP    DXSTP1           ;PRESENT STATUS - RETURN TO TT SCAN
;
DXER03: TRAP   7;POTENTIAL TT OVERRUN AT START OF SYS RESET PROCESSING
;
;     HIO,SYSTEM OR SELECTIVE RESET - R0 = 2(DEVICE ADDRESS)
DXIF11:BIT      #SYSRST,R3
       BEQ      DXIF12  ;B UNLESS SYSTEM RESET
;SYSTEM RESET HERE - HARDWARE HAS SET CUBSY
;      CHECK NO TT OVERRUN YET AND SAVE CURRENT TT POINTER
       SUB      DXTTP,R2       ;ENTRIES PROCESSED
       CMP      R2,#DXTTL
       BGE      DXER03                  ;ERROR IF POTENTIAL OVERRUN
       ADD      R2,DXTTP               ;SAVE NEXT TT SLOT ADDRESS
       BIT      #DXTTL-1,DXTTP         ;DID IT OVERRUN
       BNE      0$
       MOV      #DXTT,DXTTP          ;YES CORRECT POINTER
0$:    MOV      #DXIR1,@#DXI;SWITCH INTERRUPT ROUTINE IN CASE MORE INT
       SUB      #40,@#PSW;ALLOW DX INTS (CAN ONLY BE SY RST AS CUBSY SET
;      CARRY ON SYSTEM RESET PROCESSING
       CLRB     XXSCNS           ;RESET ALL OFFLINE DEVICES
       CLRB     XXSCN3
       TSTB     XXSCNT
       BEQ      1$
       MOVB     #1,XXSCNT       ;EXCEPT POSSIBLE CONNECTED DEVICE
1$:    INCB     DXCNTX          ;PREVENT RELEASE OF CUBSY
       CLR      DXCBSY          ;PRIME PROCESS TO RESET IR
       MOV      #DXCHN2,R1              ;RECHAIN EVERYTHING ON SECONDARY
       MOV      #DXQ1,R0                ;CHAIN TO MAIN CHAIN
       JSR      R5,$RECHN
       MOV      #DXBSTB,R5              ;SET TOP OF BASE TABLE
2$:    MOV      -(R5),R4                ;GET DEVICE BASE ADDRESS
       BEQ      3$                      ;LOOP IF THIS DEVICE NOT OPEN
       JSR      R5,DXISEX               ;PROCESS AS FOR SELRST
3$:    CMP      R5,#DXBSTA              ;DOWN TO LAST ENTRY
       BHI      2$                      ;LOOP IF NOT
;SIMULATE NORMAL INTERRUPT EXIT
       MOV      (SP)+,R5                ;POP UNWANTED LINK
       DECB     DXCNTX                  ;ALLOW RELEASE OF CUBSY
       JSR      R5,$WAKE                ;TELL DX11 PROCESS TO DO IT ALL
       JMP      DXIXIT
;
; HERE ON SELECTIVE RESET - ASSUME HARDWARE HAS SET CUBSY (IT HAS NOT!)
DXIF12: MOV     #XDHIO,R1
        BIT     #SELRST,R3      ;TEST FOR SEL RST
        BEQ     DXIHIE          ;IF NOT MUST BE HIO
        BIS     #CUBSY,@#DXCS   ;TRY TO FORCE CUBSY AS NOT DONE BY HARDW
DXISEX: BITB    #XXRSTF,XXSTAT(R4)
        BNE     DXISY3  ;IGNORE IF ALREADY BEING RESET
        MOV     #XDRST2,R1
        BITB    #XXCMDF,XXSTAT(R4)
        BNE     1$      ;B IF COMMAND ACTIVE
        TSTB    XXSTAT(R4)
        BMI     DXISY2;TO DO RST2 FOR FULLY READY DEV WITH NO ACTIVE CMD
1$:     TST     -(R1)   ;SWITCH TO RST1 ROUTINE
        BISB    #XXRSTF!XXABOR,XXSTAT(R4);MARK ABORTING BECAUSE OF RESET
        INCB    DXCNTX;INTERLOCK AWAITING 'ENDING STATUS'
        CLR     DXCBSY
DXIHIE: BITB    #XXNSTA,XXSTAT(R4);HIO ONLY RELEVANT DURING CMD PROCESSI
        BEQ     DXISY3;IGNORE IF PRESENTING STATUS OR NO CMD OUT
DXISE1:;CHDEND JOINS
        BISB    #XXABOR,XXSTAT(R4);MARK ABORTING
DXISY2: ADD     XJUMP(R4),R1
        MOV     (R1),PC ;ENTER ACTION ROUTINE -RET TO TT SCAN OR SELRST
;
      .PAGE
      .SBTTL DX11 INTERRUPT ROUTINE - CODE FOR DRIVING OFFLINE DEVICES
;
;SENSE ISSUED FOR OFFLINE DEVICE R0/2
DXISPS:CMPB     #SENSE,-1(R2)   ;CHECK IF IN FACT SENSE
       BNE      DXER70          ;ERROR AS NOT SENSE
       MOV      #DXBAS1,R4      ;ADDRESS OFFLINE SENSE BASE
       JSR      R5,DXISC0  ;REMOVE NEW DEVICE FROM INITIALISING CHAIN IF
                XXSNQ3,XXSCN3   ;NECESARY SHIFTING DOWN R0
       TSTB     XXSCNT          ;LENGTH OF SENSE CHAIN IS 0
       BEQ      2$              ;B IF CHAIN EMPTY
       ASL      R0              ;2(DEV ADDR)
       CLR      R1
       BISB     XDADDR(R4),R1   ;HEAD ITEM
       ADD      R1,R1
       MOVB     DXSPWT+DXSPWD(R1),DXSPWT+DXSPWD(R0) ;ADD TO CHAIN
       ASR      R0
       TSTB     XXSTAT(R4)      ;IF OLD DEVICE DISPLAYING INIT STATUS
       BPL      3$              ;DISPACE IT
       MOVB     R0,DXSPWT+DXSPWD(R1);ELSE QUEUE BEHIND IT
       BR       1$
3$:    MOVB     XXSNQ3,DXSPWT+DXSPWD(R1);MOVE INTO INITIALISING CHAI
       CLR      DXBAST(R1)      ;NO LONGER PSEUDO-OPEN
       ASR      R1
       MOVB     R1,XXSNQ3
       INCB     XXSNQ3
       BIC      #XXSTAF,XDFLAG(R4);CANCEL STATUS REQUEST
       DECB     XXSCNT            ;ADJUST MAIN CHAIN COUNT
2$:    JSR      R5,DXISP2         ;FIRE UP SENSE DATA FOR NEW DEVICE
1$:    INCB     XXSCNT            ;INCREMENT CHAIN LENGTH
DXISY3:RTS      R5
DXER70:TRAP     7
;
;DISCONNECT DEVICE FROM OFFLINE BASE AND LOOK FOR WORK
;CALLED WHEN OFFLINE BASE REMOVED FROM DX WORK CHAIN
DXSB2:
        CLR     R1
        BISB    XDADDR(R4),R1   ;ADDRESS OF DEVICE JUST FINISHED
        ADD     R1,R1           ;2(DEV ADDR)
        CLR     DXBAST(R1)      ;NO LONGER PSEUDO-OPEN
        CLR     R0
        BISB    DXSPWT+DXSPWD(R1),R0;NEXT DEVICE
        DECB    XXSCNT          ;DEC USE COUNT
        BEQ     DXSB22          ;B IF ALL DONE
DXISP2:
        MOVB    R0,XDADDR(R4)   ;SET SPECIAL BASE FOR THIS DEVICE
        MOVB    #SENSE,XXCMD(R4)
        ADD     R0,R0           ;2(DEV ADDR)
        JSR     R5,DXSBU1       ;PARTIAL BASE SETUP
        .BYTE   CE!DE,XXRDY!XXRDYF!XXCMDF ;STATUS FLAGS
        JMP     DXSENS
;START STATUS PRESENTATION FROM 2NDRY CHAIN - OFFLINE SENSE DEV BEEN HIO
DXSB22:
        TSTB    XXSCNS
        BEQ     DXSB25          ;B IF NONE TO DO
        JSR     R5,DXSBUP       ;MOVE FIRST ITEM TO (EMPTY) FIRST QUEUE
        XXSNQ2,XXSCNS
        .BYTE   CE!DE,XXRDY!XXRDYF!XXCMDF
        BR      DXSTP2
;
; ARE ANY STATUS PRESENTATIONS ON INITIALISING STATUS QUEUE
DXSB25:
        TSTB    XXSCN3
        BEQ     DXRTS1          ;B IF QUEUE  EMPTY
        JSR     R5,DXSBUP       ;MOVE TOP ITEM TO (EMPTY) FIRST QUEUE
        XXSNQ3,XXSCN3
        .BYTE   CE!DE!UE,XXRDYF ;STATUS FLAGS
        BR      DXSTP2
;SUBROUTINE TO TAKE FIRST ITEM OFF 2ND OR 3RD QUEUES AND PUT ON 1ST Q
DXSBUP:
        CLR     R0
        BISB    @(R5),R0        ;GET DEVICE ADDRESS OF QUEUE
        MOVB    R0,XDADDR(R4)   ;PUT ON FIRST QUEUE
        ASL     R0
        MOVB    DXSPWT+DXSPWD(R0),@(R5)+;MOVE UP QUEUE
        INCB    XXSCNT          ;COUNT UP ITEM ON FIRST QUEUE
        DECB    @(R5)+          ;COUNT DOWN ITEMS ON OTHER QUEUE
DXSBU1: MOVB    (R5)+,XSTATUS(R4);SET REQUIRED STATUS
        MOVB    (R5)+,XXSTAT(R4);AND DEVICE STATE
        MOVB    #INTREQ,XSENSE(R4);AND STANDARD SENSE DATA
        MOV     R4,DXBAST(R0)   ;PSEUDO OPEN
DXRTS1: RTS     R5
;
;ACTION SUBROUTINE JUMP TABLE FOR OFFLINE DEVICES
DXSNSJ: DXER70  ;COMMAND ENTRY MUST BE ERROR
        DXRTS1,DXRTS1,DXRTS1    ;ERR ,CHD, HIO
        DXRTS1,DXRTS1,DXSNS1    ;RST1, RST2, CAN'T HAPPEN DATA = SENSE
;
;SUBROUTINE CALLED BY DISPOSAL OF NORMAL SENSE DATA AFTER TRANSFER
DXSNS1:
        MOV     XJCOPY(R4),XJUMP(R4)    ;RESET NORMAL JUMP TABLE
        CLR     XSENSE(R4)              ;CLEAR SENSE BYTE(S)
        CLR     XSENSE+2(R4)
; FALL THROUGH TO STANDARD STATUS PRESENTATION
;
; STATUS PRESENTATION
; R4=DEVICE BASE
; USES R0,R1
;
DXSTPR: BITB    #XXCMDF,XXSTAT(R4)      ;ARE WE PROCESSING COMMAND
        BEQ     DXER37                  ;ERROR IF NOT IN COMMAND
;
;       IF DEVICE END NOT SET IN STATUS THEN DXSTPR WILL BE CALLED AGAIN
;
;       CMPB    #CE,XSTATUS(R4)         ;LOOK FOR CHANNEL END
;       BEQ     DXSTP1                  ;B IF MORE TO COME
;
        DECB    XCOUNT(R4)              ;SHOULD SET TO -1
DXSTP1:
        BICB    #XXNSTA,XXSTAT(R4)      ;MARK STATUS PRESENTATION

DXSTP2: MOV     R4,R1
        ADD     #XDFLAG,R1
        BISB    #XXSTAF,(R1)

DXTR01: MOV     @#PSW,-(SP)
        MOVB    #340,@#PSW      ;SPL 7
        TSTB    (R1)            ;TEST IF QUEUED
        BPL     DXTR00          ;JUMP IF BASE NEEDS QUEUEING (***FOR NOW
DXTR02: MOV     (SP)+,@#PSW
DXSTP4: RTS     R5
;
DXER37: TRAP    7
;
DXSTP3: BITB    #XXRSTF,XXSTAT(R4)
        BEQ     DXTR00          ;QUEUE IT UNLESS RESETING
; PROCESS 'ENDING STATUS' AFTER A RESET
STPRST: BIT     #DXTO+NPRTO,@#DXES      ;TRAP TOO SLOW RESPONSE
        BEQ     1$
        TRAP    7
1$:     MOVB    #XXRDY!XXRDYF,XXSTAT(R4);TIDY UP FLAGS
        CLRB    XXCMD(R4)       ;CLEAR OUT CURRENT COMMAND
        BIC     #XXSTAF,XDFLAG(R4);CANCEL STATUS REQUEST
        MOV     XJUMP(R4),R0
        JSR     R5,@XDRST2(R0)  ;CALL RST2 SUBROUTINE TO MARK END OF RST
        DECB    DXCNTX          ;COUNT DOWN DEVICES DOING RST PROCESSING
        BNE     DXSTP4          ;B IF NOT ALL FINISHED
DXRSR:
        MOV     #$DX11I,@#DXI   ;RESET STANDARD IR (IN CASE OF SYS RST)
        MOV     #CUBSY,DXCBSY   ;ALLOW CUBSY TO BE RESET ON IR EXIT
        BIC     #CUBSY,@#DXCS   ;ACTUALLY RESET CUBSY UNLESS IR PENDING
        MOV     #DXCHN2,R1
        MOV     #DXQ1,R0
        JMP     $RECHN          ;RECHAIN WORK HELD ON TO MAIN CHAIN
;
;
; INITIATE DATA TRANSFER
;
;
DXSENS: MOV     R4,R1           ;SPECIAL ENTRY FOR SENSE
        ADD     #XSENSE,R1
        MOV     XNSNS(R4),R0    ;PICK UP NUMBER OF SENSE BYTES
        NEG     R0              ;NEGATED COUNT REQUIRED
DXTRAN: BITB    #XXCMDF,XXSTAT(R4)
        BEQ     DXER37          ;ERROR IF NOT COMMAND
        ADD     #XDLEN,R4       ;POINT TO DATA LENGTH
        MOV     R0,(R4)+        ;SET DATA LENGTH
        BPL     DXTR03          ;COUNT EXHAUSTED
        MOV     R1,(R4)+        ;SET DATA ADDRESS
        .IFDF   MMU
;       ASH     #-12.,R1
;       BIC     #-16-1,R1       ;FIND PAGE NUMBER * 2
;       MOV     KISAR0(R1),XXAR-XDFLAG(R4) ;SET ADDRESS REGISTER
        .ENDC
        MOV     @#PSW,-(SP)
        MOVB    #340,@#PSW      ;SPL 7 - SET INTERLOCK
        BIT     #XXDATF+XXSTAF,(R4) ;CHECK NO OUTSTANDING ACTIVITY
        BNE     DXTER0
        MOV     R4,R1
        SUB     #XDFLAG,R4      ;*** RESTORE BASE POINTER
        BITB    #XXABOR,XXSTAT(R4) ;RETURN IF NO MORE DATA WANTED
        BNE     TRAN04
        BISB    #XXDATF,(R1)    ;SET DATA TRANSFER REQUEST
        BMI     DXTR02          ;EXIT IF BASE ALREAY QUEUED
DXTR00:
        BIS     #XXCHNF,(R1)+;MARK CHAINED
        MOV     (SP)+,@#PSW
        MOV     #DXQ1,R0
        JMP     $SEND           ;CHAIN REQUEST AND WAKE PROCESS
DXTR03: BNE     13$             ;ERROR IF POSITIVE COUNT
        SUB     #XDDATA,R4      ;****
        BR      TRAN01          ;RETURN REQUEST IF ZERO COUNT
13$:    TRAP    7               ;INVALID LENGTH ( >0 )
DXTER0: TRAP    7               ;SENDING DATA WHEN ACTIVE
;
;REPORT TERMINATION OF DATA TRANSFER
;
TRAN04: MOV     (SP)+,@#PSW
TRANOK: MOV     XDDATA(R4),R1   ;GET RESIDUAL ADDRESS AND LENGTH
        MOV     XDLEN(R4),R0
        BIC     #XXDATF,XDFLAG(R4) ;CANCEL DATA TRANSFER REQUEST
TRAN01: MOV     #XDTRAN,-(SP)
        ADD     XJUMP(R4),(SP)
        MOV     @(SP)+,PC       ;CALL USER SUBROUTINE - THEN RETURN
;
;
; OPEN A DEVICE
; CALL AS SUBROUTINE ON DEVICE BASE
; XDADDR MUST HAVE BEEN SET (R5)+ IS NEW SPW
; N.B. NOT INTERLOCKED - MAY ONLY BE CALLED WHILE DISABLED DURING
; SYSTEM INITIALISATION
;
DXOPEN:
        CLR     R0
        BISB    XDADDR(R4),R0   ;DEVICE ADDRESS
        ADD     R0,R0
        CLRB    XSTATUS(R4)     ;INITIALISE STATUS
        JSR     PC,DXNIT2       ;INITIALISE MOST FIELDS
        CLR     XDFLAG(R4)      ;NO DEVICE REQUESTS
        MOV     R4,DXBAST(R0)   ;SET BASE TABLE
        MOV     (R5)+,DXSPWT(R0);AND SPW
        MOV     (R5)+,XJUMP(R4) ;SET ACTION SUBROUTINE TABLE
        JMP     DXSTP2
;
DXNIT2:
        MOVB    #XXRDYF,XXSTAT(R4)
        MOVB    #CHEND!DEVEND!UXCEP,XSTATUS(R4) ;SET INTIALISING STATUS
        CLR     XSENSE(R4)              ;CLEAR SENSE BYTE(S)
        CLR     XSENSE+2(R4)
        CLRB    XXUFLAG(R4)             ;CLEAR USERS FLAGS
        MOVB    #-1,XCOUNT(R4)          ;INIT COUNT OF ACTIVE BUFFERS
        CLR     XSEM(R4)                ;INITIALISE SEMAPHORE
        CLR     XSEM+2(R4)
        RTS     PC
;
        .PAGE
        .SBTTL INITIALISE DX11
;
DXINIT:
        MOV     #CUBSY!GO,@#DXCS;CLEAR DONE,SET CUBSY ,RESET DX1
        MOV     #-1,@#DXBC      ;FORCE QUICK TERMINATION OF ANY TRANSFER
        BIT     #ONLINB,@#DXCB
        BNE     DXINIT          ;LOOP TILL OFFLINE
        MOV     #CUBSY!GO,@#DXCS;ENSURE RESET
        MOV     #DXSPWT,@#DXOS  ;SET SPW/DST POINTER

; ZERO TT,BASE TABLE, SET SPW'S
        MOV     #DXTT+DXTTL,R0
DXNITL: CLR     -(R0)
        MOV     #UC,-DXSPWL(R0) ;AND SET UC AND DST PTR=0 IN SPW TABLE
        CMP     R0,#DXTT
        BHI     DXNITL          ;LOOP FOR ALL DEVICES
        MOV     #DXBSTA,R0
DXNITB:
        CLR     (R0)+           ;CLEAR BASE TABLE
        CMP     R0,#DXBSTB
        BLO     DXNITB
;
        MOV     #DXTT,DXTTP     ;RESET SOFTWARE TT POINTER
        CLR     DXCNTX          ;CLEAR CHAINING MARKER AND CNT OF DEV
                                ;NOT YET FINISHED RESETING
        CLR     DXCHN2          ;CLEAR SUBSIDARY CHAIN
        MOV     #CUBSY,DXCBSY   ;SET FOR CLEARING CUBSY
        MOV     #SWNORM,DXIRSW  ;SET STANDARD INTERRUPT STATE
;SET UP DUMMY BASE FOR OFFLINE SENSES
        MOV     #DXBAS1,R4
        JSR     PC,DXNIT2       ;PERFORM MOST OPEN OPERATIONS
        MOV     #XXOFFF,XDFLAG(R4);REQUEST SPECIAL TUDYUP OPERATION
        CLR     XXSCNT          ;CLR CNT OF DEV ON OFFLINE SENSE CHAINS
        MOV     #DXSNSJ,XJUMP(R4);SET ACTION S/R JUMP TABLE ADDRESS
        CLRB    XXSCN3          ;CLEAR Q3
        MOV     #240,@#DXI+2    ;IR AT PRIORITY 5
        MOV     #$DX11I,@#DXI   ;IR ENTRY POINT
5$:
        BIS     #ONLINA!ENDEN!CUBSY,@#DXCS;PUT ONLINE BUT NO INTERRUPTS
        BIT     #ONLINB,@#DXCB ;LOOP UNTIL ONLINE
        BEQ     5$
        RTS     R5 ;NO OFFLINE DEVICE INTIALISATION PRO TEM
;
;QUEUE OFFLINE DEVICE INTIALISING STATUSES
;
DXNITT:
        MOV     #DXBAS1,R4
        MOV     #DXDEV1,R0              ;LOWEST DEVICE SUPPORTED
DXNITP: MOV     R0,R1
        ASL     R1
        TST     DXBAST(R1)
        BNE     1$                      ;B IF DEVICE ONLINE
        MOVB    XXSNQ3,DXSPWT+DXSPWD(R1);)ADD TO QUEUE
        MOVB    R0,XXSNQ3               ;)
        INCB    XXSCN3                  ;COUNT UP NUMBER TO DO
1$:
        INC     R0
        CMP     R0,#DXDEV2      ;CHECK FOR HIGHEST ADDRESS SUPPORTED
        BLT     DXNITP          ;LOOP FOR ALL DEVICES
        JMP     DXSB25
        .PAGE
        .SBTTL  CAMBRIDGE SYSTEM ROUTINE SIMULATION
        ;UNCHAIN FROM QUEUE
        ;R0 IS ADDRESS OF QUEUE POINTER
        ;R1 IS ADDRESS OF XCHAIN FIELD OF BASE ON RETURN
$UCHAIN:MOV     @#PSW,-(SP)
        MOVB    #340,@#PSW
        MOV     (R0),R1
        BNE     UCHN1
        TRAP    7               ;EMPTY QUEUE
UCHN1:  MOV     (R1),(R0)       ;DEQUEUE
        MOV     (SP)+,@#PSW
        RTS     R5
;
        ;CHAIN BASE WHOSE XCHAIN FIELD ADDRESS IS IN R1
        ;R0 IS ADDRESS OF QUEUE POINTER
$CHAIN: MOV    @#PSW,-(SP)
        MOVB   #340,@#PSW
1$:     TST    (R0)
        BEQ    TCHN             ;FOUND TAIL OF QUEUE
        MOV    (R0),R0          ;FIND NEXT BASE ON QUEUE
        BR     1$
TCHN:   MOV    R1,(R0)          ;ADD TO TAIL OF QUEUE
        CLR    (R1)             ;CLEAR LINK(XCHAIN)
        MOV    (SP)+,@#PSW
        RTS    R5
        ;WAKE DX11 PROCESS
$WAKE:  MOV    SP,R0
        SUB    #12,SP           ;SET NEW STACK BASE
        MOV    #DXSEM,-(R0)
        JSR    PC,$V
        ADD    #12,SP           ;RESET STACK
        RTS    R5
;
;
$RECHN: MOV    @#PSW,-(SP)
        MOVB   #340,@#PSW
1$:     TST    (R0)             ;CHECK FOR TAIL OF QUEUE
        BEQ    RCHN2
        MOV    (R0),R0          ;CHAIN DOWN QUEUE
        BR     1$
RCHN2:  MOV    (R1),(R0)        ;JOIN QUEUES
        CLR    (R1)
        JSR    R5,$WAKE
        MOV    (SP)+,@#PSW
        RTS    R5
;
$SEND:  MOV     @#PSW,-(SP)
        MOVB    #340,@#PSW
        JSR     R5,$CHAIN
        JSR     R5,$WAKE        ;WAKE DX11 PROCESS
        MOV     (SP)+,@#PSW
        RTS     R5
        .END