1
0
mirror of https://github.com/PDP-10/stacken.git synced 2026-03-06 19:11:04 +00:00
Files
Lars Brinkhoff 6e18f5ebef Extract files from tape images.
Some tapes could not be extracted.
2021-01-29 10:47:33 +01:00

610 lines
23 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
TITLE SAXSER - GENERAL SA10 SERVICE ROUTINES - V6
SUBTTL JOSEPH A. DZIEDZIC/JAD (DEC) & JEFF GUNTER/JEG (ADP) 26-JULY-88
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,6 ;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,KDBUNI(W) ;GET THE IDENTIFIER/BITS FIELD
TLZN T2,(SA.SIR) ;SOFTWARE INTERRUPT REQUEST?
JRST SAXDU2 ;NO
MOVEM T2,KDBUNI(W) ;YES, PUT KDBUNI 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