.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+ 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* 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