Trailing-Edge
-
PDP-10 Archives
-
bb-pbdea-bb
-
10,7/unsmon/saxser.mac
There are 5 other files named saxser.mac in the archive. Click here to see a list.
TITLE SAXSER - GENERAL SA10 SERVICE ROUTINES - V7
SUBTTL JOSEPH A. DZIEDZIC/JAD (DEC) & JEFF GUNTER/JEG (ADP) 02-AUGUST-89
SEARCH F, S, DEVPRM, SAXPRM
$RELOC
$HIGH
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1987,1988.
;ALL RIGHTS RESERVED.
.CPYRT<1987,1988>
XP VSAXSR,7 ;VERSION NUMBER FOR GLOB AND MAP
SAXSER::ENTRY SAXSER ;LOAD IN LIBRARY SEARCH MODE
SAXTBL==2*6 ;ENTRIES IN SA10 DATA TABLES - ALLOW FOR
; 2 SA10S PER EACH OF 6 CPUS
OP.NOP==3 ;NO-OPERATION (NO-OP) OPERATION CODE
OP.SNS==4 ;SENSE I/O OPERATION CODE
SUBTTL AUTOCONFIGURATION TABLES
SUBTTL DEFINITIONS
;DRIVER CHARARCTERISTICS
; SAX = SAXCNF
; SAX = SA10 IBM CHANNEL ADAPTER
; SAXTBL = MAXIMUM DEVICES IN SYSTEM
; 0 = KONTROLLER TYPE
; 0 = MAXIMUM DRIVES PER KONTROLLER
; 0 = HIGHEST DRIVE NUMBER ON KONTROLLER
; MDSEC0 = SECTION FOR KDB/UDB
; MDSEC0 = SECTION FOR DDB
DRVCHR (SAX,SAX,SAXTBL,0,0,0,MDSEC0,MDSEC0,<DR.MCD!DR.UCK!DR.UCU>)
EQUATE (LOCAL,0,<SAXUDB,SAXULN,SAXULP,SAXULB>)
EQUATE (LOCAL,CPOPJ##,<SAXINI,SAXRLD,SAXEDL>)
SAXDSP::DRVDSP (SAX,SAXCHN##,0,0,0)
;DEFAULT MONGEN'ED DEVICE TABLE
DEFMDT: MDKL10 (7,274,0,0,<MD.KON>) ;SA10 DEVICE CODE 274
MDKL10 (7,270,0,0,<MD.KON>) ;SA10 DEVICE CODE 270
MDTERM ;TERMINATE TABLE
SAXCKT: EXP 0 ;COMPATIBLE KONTROLLER TABLE
.ORG KDBSIZ
;*** DO NOT RE-ORDER THE FOLLOWING ***
SAXNCP:!BLOCK 2 ;NO-OP CHANNEL PROGRAM
;WORD 0: DVW
;WORD 1: HLT
SAXSCP:!BLOCK 4 ;SENSE CHANNEL PROGRAM
;WORD 0: NO-OP
;WORD 1: DVW
;WORD 2: DCW
;WORD 3: HLT
SAXSND:!BLOCK SNSWDS ;SENSE DATA BUFFER
;*** END OF DO NOT RE-ORDER ***
SAXCNI:!BLOCK 1 ;CONI IN CASE DEVICE CODE ISN'T RH10
SAXSAV:!BLOCK ^D16 ;DUMP SAVED COPY OF SA10 BASE AREA
SAXADR:!BLOCK 1 ;ADDRESS OF BASE AREA FOR THIS SA10
SAXKLN:!
.ORG
;PROTOTYPE KONTROLLER DATA BLOCK
SAXKDB: KDBBEG (SAX,SAXKLN)
SETWRD (KDBNAM,<SIXBIT /SAX/>)
SETWRD (SAXNCP,<F.NMT!F.XEC!F.SLI!<OP.NOP>B15>)
SETWRD (SAXSCP+SNSNOP,<F.NMT!F.XEC!F.SLI!F.CC!<OP.NOP>B15>)
SETWRD (SAXSCP+SNSDVW,<F.XEC!F.BYTE!<OP.SNS>B15<000>B23>)
SETWRD (SAXSCP+SNSDCW,<BYTE (1)1(DCSSIZ)-SNSBYT(DCSADR)SAXSND>)
KDBEND
SUBTTL AUTOCONFIGURATION - PROTOTYPE INTERRUPT CODE
SAXICD: PHASE 0 ;AUTCON MUST FILL IN OFFSETS
;CONSO SKIP CHAIN CODE
CONSO 000,SI.PIR ;(0) SA10 PI REQUEST?
JRST . ;(1) NOT FOR THIS DEVICE
JSR PIERR## ;(2) SAVE AC'S
SICDSC:!MOVEI M,-1 ;(3) LOAD GLOBAL SA10 SUBCHANNEL NUMBER OF S.C. ZERO
SKIPA W,.+1 ;(4) LOAD KDB ADDRESS
EXP 0 ;(5) AUTCON FILLS IN KDB ADDRESS
XJRST .+1 ;(6) DISPATCH TO INTERRUPT HANDLER
EXP SAXINT ;(7) INTERRUPT HANDLER ADDRESS
DEPHASE
SAXICL==.-SAXICD ;LENGTH OF CONSO SKIP CHAIN CODE
SUBTTL AUTOCONFIGURE ENTRY POINT
;CALLED WITH DEVICE CODE/4 IN T1 AND CONI DEV, IN T2
SAXCFG: TLNN T2,(SI.SAX) ;IS THIS AN SA10?
JRST CPOPJ1## ;NO
XMOVEI T1,SAXMDT## ;MONGEN'ED DEVICE TABLE
XMOVEI T2,DEFMDT ;DEFAULT TABLE
MOVSI T3,-1 ;MATCH ON ANY MASSBUS UNIT
MOVEI T4,MD.KON ;MATCH ON KONTROLLER DEFINITION
PUSHJ P,AUTMDT## ;SCAN THE TABLES
JRST CPOPJ1## ;NO MATCHES
MOVSI T1,CP.SAX ;GET CHANNEL TYPE BITS FOR SA10
PUSHJ P,AUTCHN## ;BUILD A CHANNEL DATA BLOCK FOR THE SA10
POPJ P, ;ERROR
MOVNI T1,1 ;NO MASSBUS UNIT NUMBER INFO
PUSHJ P,AUTKDB## ;BUILD AND LINK A KONTROLLER DATA BLOCK
POPJ P, ;ERROR, WOULD BE NICE TO DO SOMETHING ABOUT IT
MOVE T1,KDBCSO(W) ;GET ADDRESS OF CONSO SKIP CHAIN CODE
HRRE M,SICDSC(T1) ;GET GLOBAL SUBCHANNEL NUMBER FROM SKIP CHAIN CODE
JUMPGE M,SAXCF2 ;GO IF THIS SA10 HAS ALREADY BEEN FOUND
AOS M,SAXNUM ;COUNT ANOTHER SA10 FOUND
CAIL M,SAXTBL ;FOUND TOO MANY?
POPJ P, ;YES, NOTHING WE CAN DO AT THIS POINT
.CREF SCHNUM ;CREF THE LSH
LSH M,2 ;CONVERT TO GLOBAL SUBCHANNEL INDEX
HRRM M,SICDSC(T1) ;INSERT GLOBAL SA10 SUBCHANNEL NUMBER IN CODE
ADDM W,SAXSCP+SNSDCW(W) ;ADJUST SENSE BUFFER ADDRESS IN CHANNEL PROGRAM
MOVEI T4,0 ;SUBCHANNEL ZERO IS AS GOOD AS ANY
PUSHJ P,SASTPX ;STOP ON SELECTED SUBCHANNEL
MOVEI T2,SA.BA1 ;LOAD FIRST MICROINSTRUCTION
PUSHJ P,SAXCTX ;EXECUTE IT
MOVEI T2,SA.BA2 ;LOAD SECOND MICROINSTRUCTION
PUSHJ P,SAXCTX ;EXECUTE IT
MOVEI T1,SO.DT1 ;REGISTER TO READ
XCT KDBCNO(W) ;TELL THE SA10
XCT KDBDTI(W) ;READ BASE ADDRESS FOR SUBCHANNEL ZERO
MOVEM T2,SAXADR(W) ;SAVE SA10 BASE ADDRESS IN KDB FOR DUMP TIME
MOVEI T1,SO.CLK!SO.SET ;REQUEST TO TURN uPROC BACK ON
XCT KDBCNO(W) ;LEAVE THE SA10 RUNNING WHEN WE'RE DONE
HRLI M,-SCHNUM ;AOBJN POINTER TO FILL IN SUBCHANNEL ADDRESSES
SAXCF1: HRRZM T2,SAXSBA(M) ;STORE BASE ADDRESS OF SUBCHANNEL
ADDI T2,.CLLEN ;ADVANCE TO NEXT BASE AREA
AOBJN M,SAXCF1 ;LOOP FOR ALL SUBCHANNELS
SUBI M,SCHNUM ;BACK DOWN TO GLOBAL SUBCHANNEL NUMBER
PUSHJ P,SAXNXM ;GO SEE IF THIS SA10 IS CONNECTED
PJRST SAXRST ;RESET SA10 ON THE WAY OUT TO CLEAR INT REQ
HRRZ T1,SAXSBA(M) ;GET BASE ADDRESS OF SUBCHANNEL ZERO
PUSHJ P,SAXMBA ;MARK OFF THE BASE ADDRESSES
POPJ P, ;ERROR
;NOW WE LOOP THROUGH ALL SA10 SUB-DRIVERS, CALLING THEM AT THEIR
;SA10-SPECIFIC AUTO-CONFIGURATION ENTRY POINT. NOTE THAT THE
;"CFG" ENTRY WILL SIMPLY BE A JRST CPOPJ1##.
SAXCF2: PUSHJ P,SAVE4## ;FREE UP AN AC OR THREE
PUSHJ P,SAVR## ;THIS SEEMS USEFUL TOO
PUSH P,.CPDRV## ;SAVE OUR DISPATCH ADDRESS
XMOVEI P4,SAXSCP(W) ;POINT AT THE SENSE CHANNEL PROGRAM
HRLI M,-SCHNUM ;SET UP TO SCAN THROUGH SUBCHANNELS
SAXCF3: MOVSI P1,-MAXCUS ;SET UP TO SCAN THROUGH CONTROL UNITS
SAXCF4: HRRZ T1,P1 ;GET HIGH 'MAXCUA' BITS OF CONTROL UNIT ADDRESS
LSH T1,WIDUNA ;POSITION IT
DPB T1,[POINT DVSDVA, SAXNCP(W), DVNDVA] ;STORE DEVICE ADDRESS
DPB T1,[POINT DVSDVA, SAXSCP+SNSNOP(W), DVNDVA] ; OF UNIT ZERO
DPB T1,[POINT DVSDVA, SAXSCP+SNSDVW(W), DVNDVA] ; ...
XMOVEI T1,SAXNCP(W) ;POINT AT THE NO-OP CHANNEL PROGRAM
PUSHJ P,SAXRCP ;RUN THE CHANNEL PROGRAM, WAIT FOR A RESPONSE
JRST SAXCF7 ;NO RESPONSE, MUST NOT BE A CONTROL UNIT THERE
TLNE T1,(S.SE) ;SELECT ERROR?
JRST SAXCF7 ;YES, NO CONTROL UNIT EXISTS
SKIPE SAXDVP(M) ;HAS A DEVICE LIST ALREADY BEEN ALLOCATED?
JRST SAXCF5 ;YES, SKIP THIS
MOVE T1,[CP.SAX,,400000] ;GET CHANNEL TYPE BITS AND "IGNORE DUPS" FLAG
PUSHJ P,AUTCHN## ;BUILD CHANNEL DATA BLOCK
POPJ P, ;THAT'S ABOUT AS FAR AS WE CAN GO
MOVE T1,.CPCHA## ;GET CHANNEL DATA BLOCK ADDRESS
MOVEM T1,SAXCHA(M) ;STORE CHANNEL DATA BLOCK ADDRESS
MOVEI T1,DVLMAX+1 ;GET SPACE FOR DEVICE LIST
PUSHJ P,SAXCOR ;ASK FOR IT
POPJ P, ;ERROR
MOVEM T1,SAXDVP(M) ;SAVE PHYSICAL ADDRESS
MOVEM T2,SAXDVV(M) ;SAVE VIRTUAL ADDRESS
TLO T1,(BMXTIC) ;MAKE IT A BLOCK MUX TIC
MOVEM T1,@SAXSBA(M) ;SAVE IT AWAY
SAXCF5: LDB P2,[POINT 2,M,35] ;GET LOCAL SUBCHANNEL NUMBER
MOVE R,SAXLST ;GET FIRST ENTRY IN DRIVER LIST
SAXCF6: TRNN R,-1 ;END OF LIST?
JRST SAXCF7 ;YES
MOVE T1,SADDSP(R) ;GET THE REAL DRIVER DISPATCH
MOVEM T1,.CPDRV## ;SET IT UP
PUSHJ P,@SADCFS(R) ;CALL THE CONFIGURATION ROUTINE
;M/ GLOBAL SA10 SUBCHANNEL NUMBER
;P1/ JUNK,,DCU ADDRESS
;P2/ SA10 SUBCHANNEL NUMBER
;P3/ USABLE BY CALLEE
;P4/ ADDRESS OF SENSE CHANNEL PROGRAM
JRST SAXCF7 ;NON-SKIP RETURN MEANS DRV CLAIMED THIS CU
MOVE R,SADLNK(R) ;GET LINK TO NEXT DRIVER
JRST SAXCF6 ;LOOP
SAXCF7: AOBJN P1,SAXCF4 ;LOOP FOR ALL POSSIBLE DCU ADDRESSES
AOBJN M,SAXCF3 ;THEN LOOP FOR ALL SA10 SUBCHANNELS
POP P,.CPDRV## ;RESTORE DRIVER FOR AUTCON'S SAKE
POPJ P, ;RETURN WHEN DONE
;ROUTINE TO RUN A CHANNEL PROGRAM ON CHANNEL 0
;OF A NEWLY DISCOVERED SA10 TO MAKE SURE THAT THE SA10
;IS ACTUALLY ENABLED, AND IF NOT, TO RESET IT AND LEAVE IT ALONE
SAXNXM: PUSHJ P,SAXRST ;RESET ENTIRE SA10
MOVEI T1,SAXZRO ;POINT AT SIMPLE PROGRAM (ONLY A HALT)
PUSHJ P,SAXRCP ;RUN IT
JFCL ;EXPECT AN ERROR CUZ NO DEVICE
XCT .CPCNI## ;DO A CONI TO GET SA10 BITS
TRNN T1,SI.PAR!SI.NXM ;SKIP IF SOME SORT OF MEMORY ERROR
AOS (P) ;PASS BACK SKIP RETURN
POPJ P, ;PASS BACK THE ERROR
;ROUTINE TO RESET THE ENTIRE SA10
SAXRST: MOVEI T1,SO.RES ;RESET ENTIRE SA10 BIT
XCT .CPCNO## ;DO IT
MOVSI T1,7 ;A LONG DELAY
SOJG T1,. ;WAIT TO LET CU'S SETTLE
POPJ P, ;RETURN
;ROUTINE TO SAVE SA10 INFO IN A DUMP
SAXDMP::PUSHJ P,SAVT## ;SAVE SOME ACS
MOVEI T4,KDBTAB##+.TYSAX-KDBNXT ;POINT AT 1ST SA10 KDB
SAXDM1: SKIPN T4,KDBNXT(T4) ;STEP TO NEXT KDB
POPJ P, ;RETURN IF NO MORE SA10S
XCT KDBCNI(T4) ;GET SA10S CONI
MOVEM T1,SAXCNI(T4) ;SAVE THE VALUE
MOVEI T3,SAXSAV(T4) ;POINT AT SAVE AREA FOR BASE AREA
HRLI T3,-<SCHNUM*.CLLEN> ;COUNT FOR EVERY WORD OF BASE AREA
MOVE T2,SAXADR(T4) ;POINT AT PHYSICAL ADDRESS OF BASE AREA
SAXDM2: PMOVE T1,T2 ;GET A WORD FROM BASE AREA
MOVEM T1,(T3) ;SAVE IT IN SAVE AREA
ADDI T2,1 ;ADVANCE PHYSICAL ADDRESS
AOBJN T3,SAXDM2 ;LOOP FOR EVERY WORD OF BASE AREA
JRST SAXDM1 ;BRANCH BACK SO AS TO APPLY TO EVERY SA10
;ROUTINE TO READ DF10 IOWDS AND RETURN 2-WORD DESCRIPTORS
;
;ENTER:
; P1/ POINTER TO DF10 PROGRAM
;EXIT:
; P1/ UPDATED POINTER TO DF10 PROGRAM, FIRST UN-SEEN WORD
; T1/ +VE COUNT
; T2/ CORRECT 1ST WORD TO XFER
GETIOW::SETZB T1,T2 ;T1=ACCUMULATED COUNT,T2=1ST XFR ADDRESS
PUSHJ P,SAVR## ;R = POINTER TO END OF CONTIGUOUS AREA
GETIO1: PUSHJ P,GETIOX ;PICK UP T3=COUNT, T4=ADDRESS FROM (P1)
POPJ P, ;EXIT IF WE FIND HALT
DMOVE T1,T3 ;INIT T1=1ST COUNT, T2=1ST XFR ADR
GETIO2: ADD T4,T3 ;COMPUTE 1ST WORD NOT XFER'ED
MOVE R,T4 ;SAVE R=1ST WORD NOT XFER'ED
ADDI P1,1 ;ADVANCE PC TO PEEK AT NEXT IOWD
PUSHJ P,GETIOX ;GET NEXT IOWD
POPJ P, ;RETURN IF HALT, RE-FIND IT LATER
CAME T4,R ;SKIP IF IOWDS ACTUALLY CONTIGUOUS CORE
POPJ P, ;RETURN WITH DESCRIPTOR PAIR IN T1/T2
ADD T1,T3 ;INCLUDE THIS IOWD'S COUNT
JRST GETIO2 ;AND TRY ANOTHER
;ROUTINE TO FETCH NEXT DF10 IOWD
;
; PUSHJ P,GETIOX
; HERE IF HALT, T3=0, T4=0
; HERE IF XFER, T3=COUNT, T4=ADDRESS
; (BRANCHES HAPPEN INTERNALLY, AND UPDATE P1 AS NECESSARY)
GETIOX: LDB T3,[POINT 14,(P1),13] ;PICK UP COUNT FIELD FROM IOWD
LDB T4,[POINT 22,(P1),35] ;PICK UP ADDRESS FIELD FROM IOWD
JUMPN T3,GETIX1 ;BRANCH IF COUNT#0, (MUST BE XFER)
JUMPE T4,CPOPJ## ;IF BOTH=0, MUST BE HALT, DO NOT SKIP
HLRE T3,LOWPTR## ;GET # OF MAPPING WORDS
IMUL T3,[-1*<^D36*4>] ;COMPUTE # OF WORDS IN LOCORE
ADD T3,LOWLOC## ;COMPUTE 1ST WORD ABOVE LOCORE AREA
CAMGE T4,T3 ;SKIP IF ADR ABOVE LOCORE, MUST BE XFR
JRST [MOVE P1,T4 ;UPDATE PC IF A BRANCH
JRST GETIOX] ;AND CONTINUE SCAN FOR IOWD
LDB T3,[POINT 14,(P1),13] ;IF AN XFER, RELOAD COUNT
GETIX1: TDO T3,[777777,,740000] ;MAKE COUNT LOOK -VE
MOVNS T3 ;CONVERT TO +VE COUNT
AOJA T4,CPOPJ1## ;EXIT WITH T3=COUNT, T4=TRUE ADDRESS
;ROUTINE TO ALLOCATE CONTIGUOUS NZS CORE AND RETURN IT'S PHYSICAL ADDRESS
;CALL:
; MOVE T1, SIZE OF CHUNK DESIRED
; PUSHJ P,SAXCOR
; <NON-SKIP> ;ERROR
; <SKIP> ;T1 = 22-BIT PHYSICAL ADDRESS, T2 = VIRTUAL ADDRESS
SAXCOR::MOVE T2,T1 ;PUT IT WHERE ALLOCATOR WANTS IT
PUSH P,T1 ;SAVE NUMBER OF WORDS DESIRED
IFN FTXMON,< ;IF NZS MONITOR
MOVEI T1,(MS.SAX) ;SPECIFY "SA10 GENERAL" FOR SECTION
MOVEI T3,GFWNZN## ;ADDRESS OF ROUTINE TO CALL DURING ONCE ONLY
SKIPN DINITF## ;SKIP IF ONCE ONLY IN PROGRESS
>;END IFN FTXMON
MOVEI T3,GETWDS## ;ROUTINE TO CALL DURING "TIME SHARING"
PUSHJ P,(T3) ;CALL THE ALLOCATOR
JRST TPOPJ## ;OH DARN
SETZM (T1) ;CLEAR FIRST WORD
MOVE T2,T1 ;COPY ADDRESS
XMOVEI T3,1(T1) ;SET UP TO CLEAR REMAINDER
EXCH T1,(P) ;SAVE ADDRESS, GET COUNT
SUBI T1,1 ;NUMBER OF WORDS TO MOVE
EXTEND T1,[XBLT] ;ZERO THE CORE
MOVE T1,(P) ;GET VIRTUAL ADDRESS
MAP T1,(T1) ;TURN IT INTO PHYSICAL
TLZ T1,(MP.NAD) ;TURN OFF RANDOM BITS
JRST T2POJ1## ;POP VIRTUAL ADDRESS INTO T2 AND THEN RETURN
;ROUTINE TO ASSIGN DEVICE LIST SPACE TO A KONTROLLER.
;CALL:
; M/ GLOBAL SA10 SUBCHANNEL NUMBER
; P1/ JUNK,,DCU ADDRESS (HIGH 'WIDCUA' BITS)
; T1/ NUMBER OF ENTRIES DESIRED
; PUSHJ P,SAXDVL
; <NON-SKIP> ;COULDN'T ASSIGN SUFFICIENT DEVICE LIST ENTRIES
; <SKIP> ;SUCCESS, T1 = PHYSICAL ADDRESS OF FIRST ENTRY
SAXDVL::MOVE T2,SAXDVP(M) ;GET ADDRESS OF DEVICE LIST FOR THIS SUBCHANNEL
MOVSI T4,-DVLMAX ;SET UP TO SCAN FOR FREE SLOTS IN DEVICE LIST
SAXDV1: PMOVE T3,T2 ;GET THE ENTRY
JUMPE T3,SAXDV2 ;JUMP IF THIS ENTRY IS FREE
AOBJP T4,CPOPJ## ;RETURN IF ENTIRE LIST IS FULL
AOJA T2,SAXDV1 ;KEEP LOOKING
SAXDV2: MOVEI T3,DVLMAX ;SEE IF THERE IS ENOUGH SPACE FOR CALLER
SUBI T3,(T4) ;...
CAILE T1,(T3) ;...
POPJ P, ;NO, SORRY
MOVN T4,T1 ;YES, SET UP AN AOBJN
HRLZS T4 ;...
MAP T3,SAXZRO ;GET ADDRESS OF A NICE WORD OF ZEROES
TLZ T3,(MP.NAD) ;CLEAR NON-ADDRESS BITS
DPB P1,[POINT WIDCUA, T3, SANDLD-WIDUNA] ;STORE DEVICE ADDRESS OF
; UNIT ZERO
MOVEI T1,DL.TRM ;GET "TERMINATED" CODE
DPB T1,[POINT SASDLO, T3, SANDLO] ;STORE IT
MOVE T1,T2 ;SAVE START OF LIST FOR RETURN TO CALLER
SAXDV3: PMOVEM T3,T2 ;INSERT THE ENTRY
AOBJP T4,CPOPJ1## ;RETURN WHEN ALL ENTRIES ARE INSERTED
ADD T3,[1B<SANDLD>] ;INCREMENT THE DEVICE ADDRESS
AOJA T2,SAXDV3 ;BUMP DEVICE LIST ADDRESS AND LOOP
;SAXCTX EXECUTES AN SA10 MICROINSTRUCTION, ASSUMING THE CLOCK IS
; STOPPED ON THE DESIRED SA10 SUBCHANNEL.
;CALL:
; T2/ MICROINSTRUCTION TO EXECUTE
; T4/ DESIRED SUBCHANNEL NUMBER
; W/ KDB ADDRESS
;SASTPX STOPS THE SA10 CLOCK AT THE DESIRED SA10 SUBCHANNEL.
;CALL:
; T4/ DESIRED SUBCHANNEL NUMBER
SAXCTX: XCT KDBDTO(W) ;SEND THE DATA TO THE SA10
SASTPX: MOVEI T1,SO.CLK!SO.DT0 ;CLOCK CONTROL, SELECT REGISTER 0
XCT KDBCNO(W) ;STEP CLOCK
XCT KDBDTI(W) ;READ CONTENTS OF REGISTER 2
HLRZS T2 ;ISOLATE THE SELECTED SUBCHANNL #
CAIE T2,(T4) ;SKIP IF CORRECT SUBCHANNEL SELECTED
JRST SASTPX ;NO, TRY AGAIN
POPJ P, ;RETURN
;ROUTINE TO MARK OFF THE I/O BLOCKS USED FOR THE LOGOUT AREA FOR EACH
;OF THE SA10'S SUBCHANNELS.
;CALL:
; T1/ BASE ADDRESS OF SUBCHANNEL ZERO'S LOGOUT AREA
; PUSHJ P,SAXMBA
; <NON-SKIP> ;BASE ADDRESS ALREADY IN USE
; <SKIP> ;BASE ADDRESS MARKED OFF
;MOSTLY SWIPED FROM MRKIOW IN SYSINI
SAXMBA: PUSHJ P,SAVE4## ;FREE UP ARGUMENT ACS FOR SETOS
MOVE P1,T1 ;COPY BASE ADDRESS IN CASE DUPLICATE
SUB T1,LOWLOC## ;SUBTRACT BASE OF AREA
LSH T1,-2 ;CONVERT TO BIT NUMBER
IDIVI T1,^D36 ;GET WORD AND BIT IN TABLE
MOVE P4,T1 ;COPY OFFSET TO BIT
ADD P4,LOWPTR## ;ADD IN BASE OF AOBJN POINTER TO TABLE
MOVNS T2 ;GET -VE BIT NUMBER TO START WITH
HRLI P4,^D36(T2) ;BIT POSITION,,ADDRESS
MOVEI P3,SCHNUM ;GET NUMBER OF BLOCKS TO RETURN FOR SETOS
PUSHJ P,SETOS## ;MARK OFF THE BITS
STOPCD CPOPJ##,DEBUG,SAXBAI,DIEBAI, ;++SA10 BASE ADDRESS IN USE
MOVNI T1,SCHNUM ;NUMBER OF BLOCKS WE APPROPRIATED
ADDM T1,NOIOWD## ;DECREMENT COUNT ACCORDINGLY
JRST CPOPJ1## ;SKIP RETURN
;HERE FROM ERRCON ON AN "SAXBAI" STOPCD
DIEBAI: PUSHJ P,INLMES## ;START THE NOISE
ASCIZ /SA10 base address /
MOVE T1,P1 ;COPY BASE ADDRESS
PUSHJ P,PRTDI8## ;PRINT IT
PJSP T1,CONMES## ;MORE NOISE AND RETURN
ASCIZ / already in use/
SUBTTL RUN SA10 CHANNEL PROGRAM AND WAIT FOR COMPLETION
;ROUTINE TO RUN AN SA10 CHANNEL PROGRAM AND WAIT FOR COMPLETION.
;ONLY INTENDED FOR USE DURING ONCE-ONLY OR DURING AUTO CONFIGURATION.
;CALL:
; T1/ VIRTUAL ADDRESS OF CHANNEL PROGRAM
; M/ GLOBAL SA10 SUBCHANNEL NUMBER
; PUSHJ P,SAXRCP
; <TIMEOUT RETURN>
; <SOMETHING HAPPENED RETURN> ;T1/ CHANNEL STATUS WORD (.CLCSW)
SAXRCP::PUSHJ P,SAVE1## ;FREE UP AN AC
MAP T1,(T1) ;MAKE ADDRESS PHYSICAL
TLZ T1,(MP.NAD) ;TURN OFF NON-ADDRESS BITS
SETZ P1, ;START AFRESH
DPB M,[POINT 2,P1,^L<SO.CHN>] ;STORE SUBCHANNEL IN POSITION FOR CONO
PUSH P,@SAXSBA(M) ;SAVE EXISTING POINTER
TLO T1,(TIC) ;MAKE A TIC TO THE CHANNEL PROGRAM
MOVEM T1,@SAXSBA(M) ;POINT BASE AREA AT CHANNEL PROGRAM
MOVEI T3,10 ;NUMBER OF ATTEMPTS TO RUN THE CHANNEL PROGRAM
SAXRC1: MOVEI T1,SO.CLR!SO.STS(P1) ;CLEAR THE STATUS FLAG
XCT .CPCNO##
MOVE T1,SAXSBA(M) ;GET BASE ADDRESS OF SUBCHANNEL
SETZM .CLCSW(T1) ;CLEAR OLD STATUS
MOVEI T1,SO.SET!SO.GO(P1) ;SET THE GO FLAG
XCT .CPCNO##
LDB T1,[POINT 2,M,35] ;GET SA10 SUBCHANNEL NUMBER
MOVNS T1 ;NEGATE IT
MOVEI T2,SI.STS ;BIT FOR CHANNEL ZERO'S STATUS FLAG
LSH T2,(T1) ;MAKE BIT FOR THIS CHANNEL'S STATUS FLAG
MOVEI T4,10000 ;SET UP TIMEOUT
SAXRC2: XCT .CPCNI## ;GET THE STATUS
TRNE T1,SI.PAR!SI.NXM ;CHECK FOR CATASTROPHIC MEMORY ERROR
JRST SAXRC5 ;BRANCH IF MEMORY ERRORS SEEN
TRNN T1,(T2) ;WAIT FOR STATUS FLAG TO COME UP
SOJG T4,SAXRC2 ;WAIT UNTIL IT DOES
JUMPLE T4,SAXRC4 ;GIVE UP IF IT TIMED OUT
MOVE T1,SAXSBA(M) ;GET BASE ADDRESS
MOVE T1,.CLCSW(T1) ;GET ENDING STATUS
TLNE T1,(S.BUSY) ;SKIP IF NOT BUSY
JRST SAXRC6 ;BRANCH IF CU OR UNIT BUSY
TLNE T1,(S.SE!S.CTLE!S.CE!S.UC!S.UE) ;DID WE GET A REASONABLE
; CHANNEL STATUS?
JRST SAXRC3 ;YES
SOJG T3,SAXRC1 ;NO, TRY AGAIN WHILE WE CAN
JRST SAXRC4 ;COULDN'T RUN THE CHANNEL PROGRAM
SAXRC3: AOS -1(P) ;SET FOR SKIP RETURN
SAXRC4: PUSH P,T1 ;SAVE CHANNEL STATUS FOR RETURN TO CALLER
MOVEI T1,SO.CLR!SO.STS(P1) ;CLEAR STATUS FLAG
XCT .CPCNO##
MOVEI T1,SO.CLR!SO.GO(P1) ;CLEAR GO FLAG
XCT .CPCNO##
POP P,T1 ;RESTORE CHANNEL STATUS
POP P,@SAXSBA(M) ;RESTORE PROPER BASE POINTER
POPJ P, ;RETURN TO CALLER
SAXRC5: MOVE T1,SAXSBA(M) ;GET BASE ADDRESS
MOVE T1,.CLCSW(T1) ;GET CHANNEL STATUS FOR CALLER
JRST SAXRC4 ;JOIN COMMON CODE
;HERE IF WE GOT BUSY
SAXRC6: MOVSI T4,1 ;GET A LONG TIME OUT
MOVEI T1,SO.CLR!SO.STS(P1) ;CLEAR STATUS FLAG
XCT .CPCNO## ;...
SAXRC7: IMULI T1,1 ;PAUSE BRIEFLY BETWEEN CONIS
XCT .CPCNI## ;WAIT FOR ANOTHER STATUS FLAG
TRNN T1,(T2) ;SKIP IF IT COMES UP AGAIN
SOJG T4,SAXRC7 ;TRY AGAIN
SOJG T3,SAXRC1 ;SET GO FLAG AGAIN IF WE GET ANY STATUS
JRST SAXRC4 ;GIVE UP IF WE TIMED OUT
SUBTTL PROCESS SA10 INTERRUPT
;SA10 INTERRUPTS BRANCH HERE AFTER SAVING ACS.
;CALL:
; M/ GLOBAL SA10 SUBCHANNEL NUMBER OF S.C. ZERO
; W/ KDB ADDRESS
SAXINT: XCT KDBCNI(W) ;GET THE CONI BITS
MOVE T3,T1 ;PASS THEM TO THE DRIVER IN T3
;FIRST CHECK FOR MEMORY ERROR WHICH MUST BE HANDLED HERE, AND
;THEN PASSED ALONG TO THE DRIVER WHICH CONTROLS THE SUBCHANNEL
;ON WHICH THE ERROR OCCURRED.
TRNN T1,SI.PAR!SI.NXM ;PARITY ERROR OR NXM?
JRST SAXNME ;NO
MOVEI T1,SO.CLK ;STOP SA10 CLOCK SO CAN READ ITS REGISTERS
XCT KDBCNO(W)
MOVEI T1,SO.SDR+SO.DT1 ;SELECT SA10 REGISTER 1 (MEMORY ADDRESS)
XCT KDBCNO(W)
XCT KDBDTI(W) ;READ MEMORY ADDRESS
MOVE T4,T2 ;SAVE IT
MOVEI T1,SO.SDR+SO.DT2 ;SELECT SA10 REGISTER 2 (MEMORY USER,,XXX)
XCT KDBCNO(W)
XCT KDBDTI(W) ;READ MEMORY USER,,XXX (USER = SUBCHANNEL)
HLRZS T2 ;MOVE SUBCHANNEL TO RH
ADDI M,(T2) ;M NOW CONTAINS GLOBAL SA10 SUBCHANNEL NUMBER
MOVEI T1,SO.CLK+SO.SET ;START THE CLOCK AGAIN
XCT KDBCNO(W)
MOVEM T4,SAMERR(M) ;SAVE MEMORY ADDRESS
STOPCD .+1,INFO,SAXMER, ;SA10 DETECTED MEMORY-PARITY OR NXM
MOVE T1,SAXCHA(M) ;GET ADDRESS OF CHANNEL DATA BLOCK FOR SUBCHANNEL
PUSH P,T3 ;SAVE THE CONI STATUS BITS
SKIPA T1,CHNTBP(T1) ;GET AOBJN POINTER TO KDBS AND SKIP
SAXIN1: MOVE T3,(P) ;RESTORE STATUS BITS
MOVE W,(T1) ;GET THE KDB ADDRESS
PUSH P,T1 ;SAVE THE AOBJN
PUSHJ P,SAXCTD ;CALL THE DRIVER
POP P,T1 ;RESTORE AOBJN
AOBJN T1,SAXIN1 ;LOOP FOR REMAINING KDBS
ADJSP P,-1 ;CLEAN THE STACK
PUSH P,[1] ;PRETEND WE'VE SERVICED AT LEAST 1 KDB
PJRST SAXDU0 ;SCAN FOR SOFTWARE INTERRUPT REQUESTS
;HERE WHEN NOT A MEMORY ERROR - SEE IF ANY SUBCHANNEL HAS ITS
;STATUS FLAG UP, AND DISPATCH TO THE APPROPRIATE DRIVER IF SO.
;CONI RESULTS STILL IN T1.
SAXNME: ANDI T1,SI.AST ;MASK OFF ALL STATUS FLAGS
SKIPN T1 ;MAKE SURE SOMEONE INTERRUPTED!
STOPCD CPOPJ##,DEBUG,SAXNSI, ;++ NO STATUS ON INTERRUPT
LSH T1,^L<SI.STS> ;POSITION IN BITS 0-3
JFFO T1,.+1 ;GET INTERRUPTING SUBCHANNEL NUMBER IN T2
DPB T2,[POINT 2,M,35] ;M NOW CONTAINS GLOBAL SA10 SUBCHANNEL NUMBER
MOVE T4,SAXSBA(M) ;GET GLOBAL SUBCHANNEL'S CHANNEL LOGOUT AREA
LDB T1,[POINT CSSTYP,.CLCSW(T4),CSNTYP] ;GET STATUS TYPE
CAIN T1,S.DUM ;SKIP IF NORMAL STATUS OF SOME SORT
JRST SAXDUM ;OOPS - OUR STATUS, SCAN FOR KDB
LDB T4,[POINT CSSKON,.CLCSW(T4),CSNKON] ;GET HIGH HEX DIGIT OF KON
SKIPN T1,SAXCHA(M) ;GET ADDRESS OF CHANNEL DATA BLOCK
JSP T1,SAXCSR ;CLEAR STATUS REQUEST AND DISMISS INTERRUPT
MOVE T1,CHNTBP(T1) ;GET AOBJN POINTER TO CHANNEL'S KDBS
SAXNM1: MOVE W,(T1) ;GET A KDB ADDRESS
LDB T2,[POINT WIDCUA,KDBUNI(W),17] ;GET THIS KON'S CU ADDRESS
CAMN T4,T2 ;SKIP IF WE HAVEN'T FOUND KON YET
JRST SAXCTD ;YES
AOBJN T1,SAXNM1 ;KEEP LOOKING
; PJRST SAXDUM ;FALL INTO SAXDUM
;HERE AT END OF SCAN TO FIND KDBS THAT WOULD LIKE A "REQUESTED" INTERRUPT
SAXDUM: PUSH P,[0] ;NOTE THAT 0 KDBS HAVE BEEN SERVICED
SAXDU0: SKIPN T1,SAXCHA(M) ;GET ADDRESS OF CHN FOR THIS SUBCHANNEL
JSP T1,SAXCSR ;CLEAR STATUS REQUEST AND DISMISS INTERRUPT
MOVE T1,CHNTBP(T1) ;GET AOBJN TO ALL THE KDBS FOR THAT CHN
SAXDU1: MOVE W,(T1) ;GET A KDB
MOVE T2,KDBSTS(W) ;GET RANDOM BITS
TLZN T2,(KD.SIR) ;SOFTWARE INTERRUPT REQUEST?
JRST SAXDU2 ;NO
MOVEM T2,KDBSTS(W) ;YES, PUT BACK WITHOUT FLAG
PUSH P,T1 ;SAVE AOBJN
PUSHJ P,SAXCTD ;GO HANDLE SOFT INTERRUPT REQUEST
POP P,T1 ;RESTORE THE AOBJN
AOS (P) ;REMEMBER WE FOUND ONE
SAXDU2: AOBJN T1,SAXDU1 ;LOOK AT NEXT ONE
POP P,T1 ;GET THE SERVICE COUNT
JUMPN T1,CPOPJ## ;EXIT NOW IF SOMEONE GOT SERVICED
;*** IF THIS IS TRULY SPURIOUS, WE REALLY OUGHT TO CLEAR THE
;*** STATUS FLAG SINCE IT WILL PROBABLY CAUSE A PI LEVEL LOOP!
JSP T1,SAXCSR ;CLEAR STATUS REQUEST AND DISMISS INTERRUPT
;HERE TO CLEAR A STATUS REQUEST FOR A NON-EXISTANT CHANNEL (AT LEAST,
;IN OUR HUMBLE OPINION).
;CALL:
; JSP T1,SAXCSR
;NEVER RETURNS, DISMISSES INTERRUPT IN PROGRESS.
SAXCSR: STOPCD .+1,INFO,SAXISR,ISRDIE, ;++INVALID STATUS REQUEST
XCT KDBCNI(W) ;FETCH THE PI CHANNEL INFO
ANDI T1,SI.PIA ;ISOLATE PI CHANNEL
DPB M,[POINT 2,T1,^L<SO.CHN>] ;STORE SUBCHANNEL IN POSITION FOR CONO
TRO T1,SO.CLR!SO.STS ;STATUS-FLAG-CLR FUNCTION
XCT KDBCNO(W) ;CLEAR IT
POPJ P, ;DISMISS INTERRUPT
;HERE FROM ERRCON ON A SAXISR STOPCODE.
ISRDIE: PUSH P,T1 ;SAVE THE PC FROM THE JSP
PUSHJ P,INLMES## ;ADD SOME NOISE
ASCIZ /Invalid SA10 status request from PC /
POP P,T1 ;POP OFF THE PC
HRRZS T1 ;DON'T WORRY ABOUT NZS PCS
PUSHJ P,OCTPNT## ;PRINT IT
PUSHJ P,INLMES##
ASCIZ / for subchannel /
LDB T1,[POINT 2,M,35] ;GET SUBCHANNEL
PJRST PRTDI8## ;PRINT IT AND RETURN
;HERE TO CALL THE DRIVER ROUTINE
;CALL:
; W/ KDB ADDRESS
SAXCTD: MOVE T1,KDBDSP(W) ;GET DISPATCH TABLE ADDRESS
MOVE T1,DRVINT(T1) ;GET ADDRESS OF INTERRUPT HANDLER
TLNE T1,MXSECN ;NZS ADDRESSING DRIVER?
PUSHJ P,SSEC1## ;YES, GET INTO SECTION 1
JRST @T1 ;CALL THE ROUTINE AND RETURN
SUBTTL THE END
$LOW
.LNKEN .LKSAX, SAXLST ;END OF DEVICE DRIVER LIST
SAXLST: XWD 0,0 ;DEVICE DRIVER LIST
SAXNUM: EXP -1 ;SYSTEM-WIDE SA10 NUMBER
SAXZRO: EXP 0 ;A NICE WORD OF ZEROES IN THE LOW SEGMENT
;TABLES INDEXED BY GLOBAL SA10 SUBCHANNEL NUMBER
SAXCHA: BLOCK SAXTBL*SCHNUM ;ADDRESS OF CHANNEL DATA BLOCK
SAXDVP::BLOCK SAXTBL*SCHNUM ;PHYSICAL ADDRESS OF DEVICE LIST
SAXDVV::BLOCK SAXTBL*SCHNUM ;VIRTUAL ADDRESS OF DEVICE LIST
SAXSBA::BLOCK SAXTBL*SCHNUM ;SUBCHANNEL BASE ADDRESS (LOGOUT AREA ADDRESS)
SAMERR::BLOCK SAXTBL*SCHNUM ;SPACE FOR MEMORY ERROR WORD
$HIGH
$LIT
END