Trailing-Edge
-
PDP-10 Archives
-
bb-bt99p-bb
-
tmxkon.x22
There are 2 other files named tmxkon.x22 in the archive. Click here to see a list.
TITLE TMXKON - TM10B DEVICE DEPENDENT CODE FOR TAPSER V104
SUBTTL T.HESS/TAH/TW/DPM 21-FEBRUARY-89
SEARCH F,S,DEVPRM
$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
; 1974,1975,1976,1977,1978,1979,1980,1982,1984,1986,1988.
;ALL RIGHTS RESERVED.
.CPYRT<1974,1988>
XP VTMXKN,104 ;DEFINE VERSION NUMBER FOR STORAGE MAP
SALL
TMXKON::ENTRY TMXKON
TMXDMX==10 ;MAXIMUM DRIVES PER KONTROLLER
TMXHDN==TMXDMX-1 ;HIGHEST DRIVE NUMBER ON KONTROLLER
TMXELN==2 ;SIZE OF FEP TABLE
;DRIVER CHARARCTERISTICS
; TMX = TD2CNF
; MTA = MAGTAPE
; 0 = MAXIMUM DEVICES IN SYSTEM (NO LIMIT)
; K.TMB = KONTROLLER TYPE
; TMXDMX = MAXIMUM DRIVES PER KONTROLLER
; TMXHDN = HIGHEST DRIVE NUMBER ON KONTROLLER
; MDSEC0 = SECTION FOR KDB/UDB
; MDSEC0 = SECTION FOR DDB
DRVCHR (TMX,MTA,0,K.TMB,TMXDMX,TMXHDN,MDSEC0,MDSEC0,<DR.XAD!DR.MCD!DR.GCC!DR.DDN>)
.ORG TKBUDB ;START OF TM10B SPECIFIC DATA
TMXUTB:! BLOCK TMXDMX ;TABLE OF POINTERS TO UDBS
TMXIOB:! ;START OF I/O INSTRUCTIONS
TMXCOC:! BLOCK 1
TMXCIC:! BLOCK 1
TMXDIC:! BLOCK 1
TMXIOE:! ;END OF I/O INSTRUCTIONS
TTMBLK:! BLOCK 1 ;BLKI/BLKO POINTER
TTMCHE:! BLOCK 1 ;-1 IF CHANNEL DETECTED ERROR
TMXIUM:! BLOCK TMXDMW ;IGNORE DRIVE MASK
TMXNUM:! BLOCK TMXDMW ;NEW DRIVE MASK
TMXKLN:! ;LENGTH OF KDB
.ORG
.ORG TUBLEN
TMXICC:! BLOCK 1 ;LAST ERROR INITIAL CONI MTC
TMXICS:! BLOCK 1 ;LAST ERROR INITIAL CONI MTS
TMXFCC:! BLOCK 1 ;LAST ERROR FINAL CONI MTC
TMXFCS:! BLOCK 1 ;LAST ERROR FINAL CONI MTS
TMXULN:! ;LENGTH OF UDB
.ORG
TMXKDB: KDBBEG (TMX,TMXKLN)
SETWRD (KDBNAM,<SIXBIT/MT/>) ;KONTROLLER NAME
SETWRD (KDBIUN,<TKBUDB>) ;INITIAL POINTER TO UDBS
SETWRD (KDBCUN,<TKBUDB>) ;CURRENT POINTER TO UDBS
SETWRD (KDBIUM,<TMXIUM>) ;OFFSET TO IGNORE UNIT MASK
SETWRD (KDBNUM,<TMXNUM>) ;OFFSET TO NEW UNIT MASK
IFN FTMP,<SETWRD (TKBFCT,<TKBICT##>)> ;FAIRNESS COUNTER FOR QUEUED I/O
SETWRD (<TMXCOC>,<CONO 000,(T1)>)
SETWRD (<TMXCIC>,<CONI 000,T1>)
SETWRD (<TMXDIC>,<DATAI 000,T1>)
KDBEND
TMXUDB: UDBBEG (TMX,TMXULN)
SETWRD (UDBNAM,<SIXBIT/MT/>) ;DRIVE NAME
SETWRD (TUBIEP,<-TMXELN,,TMXICC>) ;INITIAL ERROR POINTER
SETWRD (TUBFEP,<-TMXELN,,TMXFCC>) ;FINAL ERROR POINTER
UDBEND
EQUATE (LOCAL,0,<TMXULP,TMXULB,TMXCKT>)
EQUATE (LOCAL,CPOPJ##,<TMXCMD,TMXONL,TMXLOD,TMXEDL>)
EQUATE (LOCAL,CPOPJ2##,<TMXBSY>)
TMXICD==TAPICD## ;PROTOTYPE INTERRUPT CODE ADDRESS
TMXICL==TAPICL## ;PROTOTYPE INTERRUPT CODE ADDRESS
TMXINT==TAPINT## ;INTERRUPT SERVICE
TMXELG==TPELGX## ;MAKE AN ERROR LOG ENTRY
TMXDSP: DRVDSP (TMX,TAPCHN##,TDVDDB##,TDVLEN##,TPMDIA##)
TPK (TMX,NO,377777) ;SERVICE DEPENDENT DISPATCH
;DEFAULT MONGEN'ED DEVICE TABLE
DEFMDT: MDKL10 (7,220,0,0,<MD.KON>) ;DEVICE CODE 220
MDTERM ;TERMINATE TABLE
;BYTE POINTERS
CTYUNI: POINT CM.UNS,T1,CM.UNP ;UNIT # IN CMD REG
CTYFCN: POINT CM.CMS,T1,CM.CMP ;FCN CODE IN CMD REG
;OFFSETS INTO TKBCCL
TKBSAV==TKBCCL+2 ;PLACE TO SAVE TM10A IOWD
TKBUNI==TKBCCL+3 ;CURRENT UNIT SELECTED (-1 IF NONE)
MTAFLG==TAPCHN##*10
;DEFINITIONS FOR COMMAND REGISTER
CM.UNS==3 ;SIZE OF UNIT FIELD
CM.UNP==^D20 ;RIGHT MOST BIT
CM.PAR==1B21 ;1=ODD PARITY, 0=EVEN PARITY
CM.CDF==1B22 ;CORE DUMP FORMAT (9TK ONLY)
CM.CMS==4 ;COMMAND BYTE SIZE
CM.CMP==^D26 ;RIGHT MOST BIT
CM.FNO==00 ;NO-OP
CM.FUR==10 ;UNIT READY
CM.FRW==01 ;REWIND
CM.FUN==11 ;REWIND / UNLOAD
CM.FRD==02 ;READ
CM.FR1==12 ;READ ACROSS BOUNDARIES
CM.FRC==03 ;READ / COMPARE
CM.FR2==13 ;READ / COMPARE ACROSS BOUNDARIES
CM.FWR==04 ;WRITE
CM.FWL==14 ;WRITE AFTER LONG ERG
CM.FTM==05 ;WRITE TAPE MARK
CM.FLG==15 ;WRITE 3" BLANK TAPE
CM.FFB==06 ;SKIP FORWARD BLOCK
CM.FFF==16 ;SKIP FORWARD FILE
CM.FBB==07 ;SKIP BACKWARD BLOCK
CM.FBF==17 ;SKIP BACKWARD FILE
CM.NUE==1B27 ;NEXT UNIT INTERUPT ENABLE
CM.DNS==2 ;DENSITY BYTE SIZE
CM.DNP==^D29 ;RIGHT MOST BIT
CM.D2==000 ;200 BPI
CM.D5==100 ;556 BPI
CM.D8==200 ;800 BPI
CM.DMX==3 ;MAX IORB DENSITY VALUE WE CAN HANDLE
CM.MSF==7B32 ;MASK FOR FLAGS PIA
CM.MSD==7 ;MASK FOR DATA PIA
;FLAGS IN LH SIDE (CONI ONLY)
CM.NUS==3 ;NEXT UNIT BYTE SIZE
CM.NUP==^D17 ;RIGHT MOST BIT
CM.EOR==1B14 ;WRITE EOF (MAINT)
NOPMSK==760300 ;UNIT,PARITY,DENSITY,FORMAT MASK
;DEFINITIONS FOR STATUS REGISTER
CI.CHN==1B9 ;DF10C FLAG
;UNKNOWN
CI.CPE==1B11 ;CONTROL WORD PARITY ERROR (TM10B)
CI.NXM==1B12 ;NON EX MEM (TM10B)
CI.DPE==1B13 ;DATA PARITY ERROR (TM10B)
CI.CWW==1B14 ;CONTROL WORD WRITTEN (TM10B)
CI.CCS==3 ;CHARACTER COUNTER BYTE SIZE
CI.CCP==^D17 ;RIGHT MOST BIT
;BITS IN RH SIDE
CI.HNG==1B18 ;UNIT HUNG
CI.REW==1B19 ;REWINDING
CI.LDP==1B20 ;TAPE AT LOAD POINT (BOT)
CI.ILL==1B21 ;ILLEGAL OPERATION
CI.TPE==1B22 ;TAPE PARITY ERROR
CI.EOF==1B23 ;END OF FILE (TAPE MARK SEEN)
CI.EOT==1B24 ;TAPE INDICATE (EOT)
CI.RCE==1B25 ;READ / COMPARE ERROR
CI.RLD==1B26 ;RECORD LENGTH DIFFERS
CI.DLE==1B27 ;DATA LATE ERROR (OVERRUN)
CI.BDT==1B28 ;BAD TAPE FLAG
CI.JBD==1B29 ;JOB DONE
CI.IDL==1B30 ;UNIT IDLE
CI.CHE==1B31 ;CHANNEL ERROR (BITS 11,12,13,OR 14)
CI.WLK==1B32 ;UNIT WRITE LOCKED
CI.7TK==1B33 ;7 TRACK UNIT
CI.LNU==1B34 ;LOAD NEXT UNIT
CI.DAT==1B35 ;DATA REQUEST
;BITS USED FOR CONO TMS,
CO.CPE==1B31 ;CLEAR PARITY ERROR
CO.CCW==1B32 ;CLEAR CONTROL WORD WRITTEN
CO.WCW==1B33 ;WRITE CONTROL WORD
CO.MBH==1B34 ;MOVE BR TO HR
CO.STP==1B35 ;STOP CURRENT COMMAND
ALLERS==CI.DLE!CI.TPE!CI.BDT!CI.RCE!CI.ILL!CI.HNG!CI.CHE
;ALL ERROR FLAGS OF INTEREST
SUBTTL TAPE INTERUPT SERVICE
;CALLED FROM TAPSER WITH W := KDB
TMXISR: XCT TMXCIC(W) ;GET COMMAND REG
LDB T2,CTYUNI ;GET UNIT SELECTED
PUSHJ P,SETUDB## ;SET UP U
PJRST SETM1 ;NON-EX UNIT
XCT TMXCIC(W) ;GET CMD REG AGAIN
MOVEM T1,TMXFCC(U) ;SAVE IN UDB
LDB T4,CTYFCN ;GET FCN
XCT KDBCNI(W) ;GET STATUS REG
MOVEM T1,TMXFCS(U) ;STASH STATUS REG IN UDB
PUSHJ P,CHKIRB## ;GET IORB
JRST TAPDIS## ;NONE - DISMISS INT.
MOVE T3,TMXFCS(U) ;GET STATUS IN T3
CAIN T4,CM.FUR ;IF A NOP
JRST TMXSTS ;READ THE STATUS NOW
MOVSI T2,TUSBOT## ;CLEAR BOT INDICATION
ANDCAM T2,TUBSTS(U) ; WE WILL SET IT AGAIN IF NECESSARY
LDB T2,PRBFCN## ;GET DESIRED FCN
CAILE T2,TMIMAX ;CHECK VALIDITY
JRST TAPIFI## ;FUNCTION ERROR
JRST @TMIDSP(T2) ;DO IT
TMIDSP: IFIW TAPIFI## ;(00) ILLEGAL
IFIW TMIRD ;(01) READ
IFIW TMIWT ;(02) WRITE
IFIW TAPIFI## ;(03) READ BACKWARDS (ILLEGAL)
IFIW TMISR ;(04) SKIP RECORD
IFIW TMIBR ;(05) BACKSPACE RECORD
IFIW TMISF ;(06) SKIP FILE
IFIW TMIBF ;(07) BACKSPACE FILE
IFIW TMIEG ;(10) ERASE GAP
IFIW TAPIFI## ;(11) DSE (ILLEGAL)
IFIW TMIRW ;(12) REWIND
IFIW TMIUN ;(13) REWIND / UNLOAD
IFIW TMITM ;(14) WRITE TAPE MARK
IFIW TMXOFL ;(15) FAKED INTERRUPT IF UNIT OFF-LINE
IFIW TMIRD ;(16) CORRECTION READ
IFIW TMIRD ;(17) READ LOW THRESHOLD
TMIMAX==.-TMIDSP-1
;ROUTINE TO MAKE CONTROLLER IDLE
CLRCTL: LDB T2,TUYKTP## ;UNIT TYPE
JUMPN T2,TMXIDL ;GO IF TM10B
MOVE T2,[JSR PIERR##] ;DON'T LEAVE DATAI/O ADDRESS
MOVEM T2,@KDBICP(W) ; HANGING AROUND IN PI LOC
TMXIDL: PUSH P,T1 ;SAVE IORB
SETZM TTMCHE(W) ;CLEAR ERROR FLAG
HLLZS @KDBCSO(W) ;NO MORE INTS
XCT TMXCIC(W) ;GET CTL CMD REG
ANDI T1,NOPMSK ;PRESERVE UNIT # ETC.
XCT TMXCOC(W) ;DO NO-OP TO DRIVE W/ PIA=0
SETOM TKBUNI(W) ;NO UNIT SELECTED
PJRST TPOPJ## ;RETURN
;HERE TO RESET ACTIVE I/O
TMXRES: XCT TMXCIC(W)
MOVEM T1,TMXFCC(U)
XCT KDBCNI(W)
MOVEM T1,TMXFCS(U)
MOVEI T1,CO.STP ;STOP CURRENT COMMAND
XCT KDBCNO(W) ;...
MOVSI T2,TKSSEL## ;SELECT BIT
HRRZ T1,TUBQUE(U) ;GET HEAD OF Q
JUMPE T1,CLRCTL ;NONE - EXIT
TDNE T2,TKBSTS(W) ;SELECTED?
PUSHJ P,ZAPEXL ;YES - FIX IOWD
PJRST CLRCTL ;CLEAR WORLD & EXIT
;ROUTINE TO CAUSE AN INTERUPT TO FORCE A SCHEDULE CYCLE
TMXSCH: MOVE T1,UDBPDN(U) ;PHYSICAL DRIVE NUMBER
LSH T1,^D35-CM.UNP
IORI T1,CM.NUE+MTAFLG ;INT ON NEXT UNIT AVAIL
MOVEI T2,CI.LNU ;ENABLE FOR LOAD NEXT UNIT
CONO PI,PI.OFF ;AVOID RACE
HRRM T2,@KDBCSO(W) ;...
XCT TMXCOC(W) ;...
CONO PI,PI.ON
POPJ P,
TMXCFG: MOVEI T1,6 ;MUST DISTINGUISH TM10A FROM TM10B
CONO PI,PI.OFF ;DON'T ALLOW INTERRUPTS
XCT .CPCNO## ;CONO DEV,(T1)
XCT .CPCNI## ;CONI DEV,T1
MOVE T2,T1 ;COPY RESULTS
MOVEI T1,0 ;SET PIA BACK TO 0
XCT .CPCNO## ;CONO DEV,(T1)
CONO PI,PI.ON ;TURN PI SYSTEM BACK ON
TRNE T2,1 ;TM10A RETURNS A 7
JRST CPOPJ1## ;TM10A NEEDS 18-BIT CHANNELS SO GIVE UP
XMOVEI T1,TMXMDT## ;MONGEN'ED DEVICE TABLE
XMOVEI T2,DEFMDT ;DEFAULT TABLE
MOVNI T3,1 ;NO MASSBUS UNIT OR DRIVE INFORMATION
MOVEI T4,MD.KON ;MATCH ON KONTROLLER DEFINITION
PUSHJ P,AUTMDT## ;SCAN THE TABLES
JRST CPOPJ1## ;NO MATCHES
PUSHJ P,SAVE1## ;SAVE P1
MOVSI T1,0 ;I/O BUS-STYLE CHANNEL
PUSHJ P,AUTCHN## ;BUILD A CHANNEL DATA BLOCK
POPJ P, ;NO CORE
HLRZ T1,P1 ;GET MASSBUS UNIT NUMBER
PUSHJ P,AUTKDB## ;BUILD A KDB
POPJ P, ;GIVE UP IF NO CORE
PUSHJ P,TAPCSA## ;SET UP CSO CONI ADDRESS
MOVSI T1,-<TMXIOE-TMXIOB> ;-LENGTH
XMOVEI T2,TMXIOB(W) ;STARTING ADDRESS
HRRZ T3,.CPDVC## ;DEVICE CODE
ADDI T3,1 ;CONVERT STATUS DVC TO COMMAND DVC
PUSHJ P,AUTDVC## ;FILL IN DEVICE CODES
PUSHJ P,TMXCF3 ;PUT CONTROLLER INTO A KNOWN STATE
TMXCF1: MOVSI P1,-1 ;NO MASSBUS UNIT,,DRIVE 0
TMXCF2: PUSHJ P,TMXDRV ;AUTOCONFIGURE A SINGLE DRIVE
JFCL ;IGNORE ERRORS
HRRZ T1,P1 ;GET DRIVE NUMBER
CAIGE T1,TMXHDN ;DONE ALL DRIVES?
AOJA P1,TMXCF2 ;LOOP BACK FOR MORE
TMXCF3: PUSHJ P,CLRCTL ;CLEAR WORLD
MOVE T2,KDBICP(W) ;GET PNTR TO PI LOC
MOVEM T1,1(T2) ;PUT IN PLACE
JRST CPOPJ1## ;TRY ANOTHER DEVICE ON SAME CHANNEL
TMXDRV: XMOVEI T1,TMXMDT## ;MONGEN'ED DEVICE TABLE
XMOVEI T2,DEFMDT ;AND THE DEFAULT TABLE
MOVE T3,P1 ;DRIVE INFORMATION
PUSHJ P,AUTMDT## ;FOUND A DRIVE MATCH?
POPJ P, ;NO
MOVE T2,T1 ;COPY DRIVE INFO
TRO T2,TUCIRD##+TUCD20##+TUCD55##+TUCD80##+K.TMB
HRLZ T1,P1 ;PHYSICAL DRIVE NUMBER
HRR T1,P1 ;UDB TABLE INDEX
XMOVEI T3,HNGTBL ;POINT TO HUNG TIMER TABLE
MOVE T4,['TU40 '] ;ASSUME 9-TRACK
TRNE T2,TUC7TK## ;7-TRACK?
TRO T4,10000 ;YES
PUSHJ P,TAPDRV## ;BUILD AND LINK UP UDB AND DDB
JFCL ;FAILED
JRST CPOPJ1## ;RETURN
SUBTTL START I/O
;ROUTINE TO START I/O
;USER JOB MUST BE NAILED DOWN - CAUSE SELECTION INTERUPT
;OR JUST START I/O IF UNIT ALREADY SELECTED
TMXSIO: MOVSI T1,TKSOFL## ;SET THE UNIT ON-LINE
ANDCAM T1,TUBSTS(U) ; WILL SET OFF-LINE IF IT ISN'T OK
MOVE T1,UDBPDN(U) ;PHYSICAL DRIVE NUMBER
LSH T1,^D35-CM.UNP ;PUT IN PROPER PLACE
XCT TMXCOC(W) ;SELECT UNIT
XCT KDBCNI(W) ;GET CTL STATUS
MOVEM T1,TMXFCS(U) ;SAVE IN UDB
;HERE WHEN DESIRED DRIVE HAS BEEN SELECTED
;CHECK FOR ERRORS AND UNIT IDLE
PUSHJ P,CHKIRB## ;GET IORB
JRST TAPDIS## ;NONE
MOVE T3,TMXFCS(U) ;GET STATUS REG
MOVSI T4,TUSWTL## ;WRITE LOCKED BIT
ANDCAM T4,TUBSTS(U)
TRNE T3,CI.WLK ;WRITE LOCKED?
IORM T4,TUBSTS(U) ;YES -SET BIT
LDB T2,PRBFCN## ;SEE WHAT FCN
TRC T3,CI.LNU ;MAKE NEXT TEST EASIER
TRNN T3,CI.REW!CI.IDL!CI.LNU ;IS UNIT READY OR REWINDING?
HRROI T2,RB.FYB ;NO, SET UP AS A YELLOW BALL
DPB T2,PRBFCN## ; FOR INTERRUPT LEVEL TO USE AS A FLAG
CAIN T2,RB.FYB ;STATUS CHECK?
JRST STSSEL ;YES - GO HANDLE
TRNE T3,CI.HNG!CI.ILL!CI.CHE
JRST TMXOFL ;UNIT OFFLINE
PUSH P,T2 ;SAVE T2
SETZM TTMCHE(W) ;CLEAR CHL ERROR FLAG
MOVE T2,KDBICP(W) ;SET UP ICPC IF TM10B
XCT KDBDTO(W) ;...
POP P,T2 ;RESTORE T2
PUSHJ P,SETCMD ;SET UNIT,PAR,DENS,COMPAT,FCN
PJRST STSSEL ;WRITE LOCKED
MOVEI T3,CI.HNG!CI.ILL!CI.JBD!CI.CHE
DOIT: MOVEI T1,MTAFLG(T2) ;ADD PIA & MOVE TO T1
CONO PI,PI.OFF ;SAVE US FROM OTHERS
HRRM T3,@KDBCSO(W) ;SET UP INT MASK
XCT TMXCOC(W) ;START DEVICE
CONO PI,PI.ON ;OK NOW
NXTINT: TDZA T1,T1 ;MORE INTERRUPTS COMING
SETM1: MOVNI T1,1
POPJ P, ;EXIT THIS INT
;HERE TO READ STATUS. HAVE TO HANDLE AFTER AN INTERRUPT
STSSEL: MOVE T2,UDBPDN(U) ;PHYSICAL DRIVE NUMBER
LSH T2,^D35-CM.UNP ;PUT IT IN RIGHT PLACE
TRO T2,<CM.FUR>B<CM.CMP>+CM.NUE
MOVEI T3,CI.HNG!CI.ILL!CI.JBD!CI.CHE!CI.LNU
JRST DOIT ;GO CAUSE A UNIT-SELECTED INTERRUPT
;HERE TO GET UNIT STATUS UPDATE ON REQUEST
TMXSTS: TRNE T3,CI.HNG ;IF HUNG?
JRST TMXOFL ;MUST BE OFF-LINE
TRNN T3,CI.LDP ;AT LOAD POINT?
TRNN T3,CI.REW ;OR NOT REW'D
PUSHJ P,REWDON## ;YES - SET BOT / CLR REW
PJRST TMIDON ;EXIT INTERUPT
;HERE IF NO STATUS WORTH REMEMBERING
TMXOFL: MOVSI T2,RB.SOL!RB.SER!RB.SNM ;SET OFF-LINE STATUS
IORM T2,TRBSTS(T1)
MOVSI T2,TKSOFL## ;TELL UPPER LEVEL THAT THE TAPE ISN'T THERE
IORM T2,TUBSTS(U)
PUSHJ P,CLRCTL ;RESET CTL
PJRST TMIDON ;AND RETURN
SUBTTL COMMAND SETUP
;ROUTINE TO SET UP CMD
;T1 := IORB FOR THIS REQUEST
;T3 CONTAINS CONI MTS, - DESTROYED
;T2 := COMMAND FOR CTL ON EXIT
SETCMD: LDB T4,PRBFCN## ;GET DESIRED FCN
SKIPN T2,IOFTAB(T4) ;CHECK LEGAL
JRST SETILG ;NOPE - ERROR
TLNE T2,(IOXWRT) ;WRITE OP?
JRST SETCMW ;YES - CHECK WRITE LOCK
PUSH P,TTMBLK(W) ;GET BLKI OR ZERO
SETCM1: MOVE T2,UDBPDN(U) ;PHYSICAL DRIVE NUMBER
LSH T2,^D35-CM.UNP ;WHERE IT WILL DO THE MOST GOOD
IOR T2,IOFTAB(T4) ;GET FCN CODE
TLZ T2,(IOXREW!IOXWRT) ;CLR UNWANTED BITS
POP P,T4 ;GET BLKI/O
HRR T4,TRBXCW(T1) ;GET DATA ADDRS OR SPACING COUNT
TLZE T2,(IOXLST) ;DATA?
JRST [PUSHJ P,SETCMX ;DO CTL SPECIFIC SETUP
JRST SETCM2] ;PROCEED
TLZN T2,(IOXSPC) ;SPACING OP?
JRST [MOVEI T4,0 ;NO - ILLEGAL DATA REQUEST
JRST SETCM2] ;SET IN CHL AREA
MOVNI T4,-1(T4) ;GET COUNT -1 NEGATED
JUMPE T4,[TRZ T2,7 ;CLEAR DATA PIA IF ONLY ONE
JRST SETCM2];AND STORE ZERO
LDB T3,TUYKTP## ;GET KONTROLLER TYPE
JUMPE T3,.+4 ;NO CHL IF TM10A
LSH T4,4 ;ONLY 14 BITS OF INFO
HRLZM T4,TKBCCL(W) ;SAVE IN CHL PGM AREA
HRLZ T4,TTMBLK(W) ;GET BLKO OR ZERO
HRRI T4,TKBCCL(W) ;SET ADDRS
SETZM TKBCCL+1(W) ;CHL HALT IF TM10B
SETCM2: MOVEM T4,@KDBICP(W) ;PUT IN CORRECT PLACE
LDB T4,PRBMOD## ;GET DESIRED MODE
CAIN T4,RB.MCD ;CORE-DUMP?
IORI T2,CM.CDF ;YES - SET BIT
LDB T4,PRBDEN## ;GET DENSITY BYTE
CAILE T4,CM.DMX ;CHECK MAX
MOVEI T4,CM.DMX
DPB T4,PRBDEN## ;REMEMBER SELECTED DENSITY
IOR T2,[CM.PAR+0
CM.PAR+CM.D2
CM.PAR+CM.D5
CM.PAR+CM.D8](T4)
MOVSI T4,RB.PAR ;CHECK PARITY
TDNE T4,TRBLNK(T1) ;ON FOR EVEN PARITY
TRZ T2,CM.PAR ;CLEAR BIT IN CMD
PJRST CPOPJ1## ;GIVE GOOD RETURN
;SET IMPROPER MODE AND RETURN
SETILG: MOVSI T2,RB.SIL!RB.SER ;ILLEGAL OP
IORM T2,TRBSTS(T1) ;SET IN IORB
POPJ P, ;ERROR RETURN
;HERE IF WRITING - CHECK WRLK
SETCMW: MOVS T2,TTMBLK(W) ;GET BLKO OR ZERO
PUSH P,T2 ;SAVE ON PDL
TRNN T3,CI.WLK ;WRITE LOCKED?
JRST SETCM1 ;NO - PROCEED
MOVSI T2,RB.SLK!RB.SER ;AND IN IORB
IORM T2,TRBSTS(T1) ;...
PJRST SETCM1 ;ERROR RETURN
;ROUTINE TO SETUP CMD LIST TERMINATION WORD FOR
;SPECIFIC CONTROLLER (A OR B)
;T4 := ADDRS OF CHL PGM
SETCMX: LDB T3,TUYKTP##
JRST @[SETCXA
SETCXB](T3) ;DISPATCH ACCORDING TO TYPE
;HERE FOR TM10A
SETCXA: MOVE T3,0(T4) ;SAVE ADDRS
HRLM T3,TRBEXL(T1) ; OF FIRST WORD FOR WORD-COUNT
MOVEM T3,TKBSAV(W) ;BLKI/O WORD SAVED
POPJ P, ; COMPUTATION AND RETURN
;HERE FOR TM10B
SETCXB: HLRZ T3,TRBEXL(T1) ;END OF XFER LIST
PUSH P,T2 ;SAVE AN AC
MOVEI T2,DF10ZR## ;HANDY ZERO
MOVEM T2,0(T3) ;CHL JUMP TO ZERO
POP P,T2 ;RESTORE USED AC
SETZM DF10ZR## ;GRNTEE ZERO
POPJ P, ;RETURN
;TABLE FOR I/O FUNCTIONS - ALREADY IN POSITION
DEFINE IOT(CMD,BITS) <
BITS+<CMD>B<CM.CMP>
>
;ALLOWABLE SPECIAL FCN BITS
IOXLST==1B0 ;DATA XFER LIST REQUIRED
IOXSPC==1B1 ;SPACING OPERATION
IOXREW==1B2 ;REWIND
IOXWRT==1B3 ;WRITE OPERATION
IOFTAB: 0 ;0 - ILLEGAL
IOT(CM.FRD,IOXLST) ;1 - READ
IOT(CM.FWR,IOXLST!IOXWRT) ;2 - WRITE
0 ;3 - ILLEGAL
IOT(CM.FFB,IOXSPC) ;4 - FORWARD SPACE BLOCK
IOT(CM.FBB,IOXSPC) ;5 - BACKWARD SPACE BLOCK
IOT(CM.FFF,IOXSPC) ;6 - FORWARD SPACE FILE
IOT(CM.FBF,IOXSPC) ;7 - BACKSPACE FILE
IOT(CM.FLG,IOXWRT) ;10 - WRITE LONG GAP
0 ;11 - ILLEGAL
IOT(CM.FRW,IOXREW) ;12 - REWIND
IOT(CM.FUN,0) ;13 - REWIND / UNLOAD
IOT(CM.FTM,IOXWRT) ;14 - WRITE TAPE MARK
IOT(CM.FFB,IOXSPC) ;USED WHEN UNIT DETECTED OFF-LINE
IOT(CM.FRD,IOXLST) ;16 - CORRECTION READ
IOT(CM.FRD,IOXLST) ;17 - READ LOW THRESHOLD
;HUNG TIMER TABLE
EXP ^D320 ;MAXIMUM TIMEOUT VALUE
HNGTBL: BYTE(9) ^D000,^D031,^D031,^D000 ;IL,RD,WT,RB
BYTE(9) ^D031,^D031,^D320,^D320 ;SR,BR,SF,BF
BYTE(9) ^D031,^D000,^D150,^D150 ;LG,SE,RW,RU
BYTE(9) ^D031,^D031,^D031,^D031 ;TM,YB,CR,RL
SUBTTL READ
;HERE ON DONE INTERUPT FOR READ
TMIRD: PUSHJ P,TMCKMV ;SEE IF TAPE MOVED
JSP T4,TMERD0 ;NO - PROBS
PUSHJ P,CHRCT ;GET CHARACTER COUNT
JRST [MOVSI T4,RB.STL+RB.SER
IORM T4,TRBSTS(T1)
JRST .+1]
MOVEM T2,TRBRCT(T1) ;SAVE COUNT IN IORB
MOVE T3,TMXFCS(U) ;RESTORE STATUS
SKIPN TTMCHE(W) ;CHL ERROR
TRNE T3,CI.CHE ;???
JRST TMECHN ;YES - HANDLE
PUSHJ P,TMSTM ;ENCOUNTER EOF?
JRST TMIRD1 ;NO - GO ON
AOS TUBFIL(U) ;PLUS 1 MORE FILE
TMIRD1: TRNE T3,ALLERS ;CHECK BADNESS
JSP T4,TMERD1 ;ERROR - HANDLE
MOVE T2,TRBRCT(T1) ;GET CHAR COUNT FOR THIS RECORD
ADDM T2,TUBCRD(U) ;AND UPDATE STATISTICS
ADDM T2,.CPTFI##
;HERE TO FINISH INTERUPT AND EXIT TO TAPSER
TMIDON: PUSHJ P,ZAPEXL ;CLEAN UP
MOVE T3,UDBPDN(U) ;PHYSICAL DRIVE NUMBER
MOVEM T3,TKBUNI(W) ;AND SAVE IT FOR LATER CHECK
HLRZ T3,TRBSTS(T1) ;LOOK AT FLAGS
JUMPE T3,CPOPJ## ;RETURN IF NONE
MOVSI T2,RB.EXC ;ELSE SET EXCEPTION
IORM T2,TRBLNK(T1) ;IN IORB
POPJ P, ;AND RETURN
;ROUTINE TO FIXUP TM10B XFER LIST
ZAPEXL: LDB T3,TUYKTP## ;GET TYPE
HLRZ T2,TRBEXL(T1) ;PNTR TO END OF XFER LIST
JUMPE T2,CPOPJ## ;RETURN IF NONE
JUMPE T3,ZAPEXA ;JUMP IF TM10A
SETZM 0(T2) ;CLEAR IT
POPJ P, ;RETURN
;RESTORE BLKI/O WORD
ZAPEXA: MOVE T2,TKBSAV(W)
HRRZ T3,TRBXCW(T1) ;PNTR TO XFER LIST
MOVEM T2,0(T3) ;STORE WORD
POPJ P, ;RETURN
SUBTTL WRITE
;HERE ON DONE INTERUPT FOR WRITE
TMIWT: PUSHJ P,TMCKMV ;DID IT MOVE
JSP T4,TMEWT0 ;NO - TRY TO FIX
SKIPN TTMCHE(W) ;CHL ERROR?
TRNE T3,CI.CHE
JRST TMECHN ;YES - LOOK AT THAT
MOVSI T2,RB.SET ;NOW CHECK EOT
TRNE T3,CI.EOT ;???
IORM T2,TRBSTS(T1) ;SET INFO IN IORB
TRNE T3,ALLERS ;EVERYTHING OK?
JSP T4,TMEWT1 ;NO - TRY TO FIX
PUSHJ P,CHRCT ;GET CHARACTER COUNT
JFCL ;DON'T CARE
ADDM T2,TUBCWR(U) ;ADD TO STATS
ADDM T2,.CPTFO##
PJRST TMIDON ;AND EXIT
;HERE ON DONE INTERUPT FOR WRITE TAPE MARK
TMITM: MOVSI T2,RB.SET ;JUST IN CASE
TRNE T3,CI.EOT ;WE SAW A TI
IORM T2,TRBSTS(T1) ;SET FLG IF SEEN
TRNE T3,ALLERS ;ANYTHING WRONG?
JSP T4,TMEWT1 ;YES - SORRY
SETZM TUBREC(U) ;ZEROTH RECORD
AOS TUBFIL(U) ;AND 1 MORE FILE
PJRST TMIDON ;EXIT
;ROUTINE SET SAY WE'VE SEEN A TAPE MARK
;ALSO RESETS RECORD COUNTER
TMSTM: TRNN T3,CI.EOF ;SEEN EOF?
POPJ P, ;NO - RETURN
MOVSI T2,RB.STM ;IORB FLAG ALSO
IORM T2,TRBSTS(T1) ;...
SETZM TUBREC(U) ;CLEAR RECORD COUNT
PJRST CPOPJ1## ;SKIP RETURN FOR FURTHER PROCESSING
SUBTTL REWIND/UNLOAD/BACKSPACE RECORD
;HERE ON INTERUPT AFTER STARTING REWIND
TMIUN: MOVE T2,TUBSTS(U)
TLZ T2,TUSREW## ;NOT REWINDING
JRST TMIRWU ;CARRY ON
TMIRW: TRNE T3,CI.HNG!CI.ILL ;CHECK BADNESS
JSP T4,TMERW ;HANDLE PROBLEM
MOVE T2,TUBSTS(U) ;SAY WE ARE REWINDING
TLO T2,TUSREW##
TMIRWU: MOVEM T2,TUBSTS(U)
TRNE T3,CI.LDP ;ALREADY DONE?
PUSHJ P,REWDON## ;YES - CLEAN UP THEN
SETZM TUBREC(U) ;IN CASE WE DON'T FINISH
SETZM TUBFIL(U) ;CLEAR THESE NOW
PJRST TMIDON ;AND EXIT
;HERE ON DONE INTERUPT FROM BACKSPACE RECORD
TMIBF:!
TMIBR: TRNE T3,CI.HNG!CI.CHE ;DEVICE PROBS?
JSP T4,TMERD1 ;WHOOPS PROBLEM
PUSHJ P,TMSTM ;LOOK FOR TM
JRST TMIBR1 ;NONE SEEN
SOS TUBFIL(U) ;ONE LESS FILE
TMIBR1: SOS TUBREC(U) ;ALSO ONE LESS RECORD
TRNN T3,CI.LDP ;SEE IF WE CRASHED INTO BOT
PJRST TMIDON ;NO - DONE
MOVSI T2,RB.SBT!RB.SNM ;YES - LITE BITS
SKIPN TUBREC(U) ;TRY TO GUESS IF TAPE MOVED
SKIPE TUBFIL(U) ; BY SEEING IF AT LOGICAL BOT
TLZ T2,RB.SNM ;FIRST TIME HERE
IORM T2,TRBSTS(T1) ;SET RESULT IN IORB
MOVSI T2,TUSBOT## ;AND UDB
IORM T2,TUBSTS(U) ;...
SETZM TUBREC(U) ;GET THINGS RIGHT
SETZM TUBFIL(U)
PJRST TMIDON ;EXIT
SUBTTL SKIP RECORD/FILE/ERASE GAP
;HERE ON DONE INTERUPT FROM SKIP FORWARD RECORD/FILE
TMISF:!
TMISR: PUSHJ P,TMCKMV ;SEE IF WE MOVED?
JSP T4,TMERD0 ;NOPE
TRNE T3,ALLERS ;CHECK ERRORS
JSP T4,TMERD1 ;HANDLE IT
PUSHJ P,TMSTM ;CHECK FOR TAPE MARK
JRST TMIDON ;NO TAPE MARK
AOS TUBFIL(U) ;INCR FILE COUNTER
JRST TMIDON ;AND EXIT
;HERE ON DONE INTERUPT FROM ERASE GAP
TMIEG: MOVSI T2,RB.SET ;IN CASE TAPE INDICATE
TRNE T3,CI.EOT ;SEEN ONE?
IORM T2,TRBSTS(T1) ;YES - SET BIT
TRNE T3,CI.HNG!CI.ILL!CI.CHE ;ERROR ALLOWED
JRST TMEWT1 ;YES - TREAT IT
PJRST TMIDON ;EXIT INT
;HERE FOR CHANNEL ERROR
TMECHN: TLNN T3,(CI.DPE) ;DATA PARITY ERROR?
JRST TMECH1 ;NO - HANDLE NOW
MOVEI T1,CO.STP!CO.CPE
XCT KDBCNO(W) ;STOP CHL & CLEAR ERROR
MOVEM T3,TTMCHE(W) ;FLAG ERROR SAVE CONI BITS
PJRST NXTINT ;AND WAIT FOR JOB DONE
TMECH1: MOVE T2,TTMCHE(W) ;GET ERROR CONI BITS
MOVEM T2,TMXFCS(U) ; SO DAEMON GETS THEM
PUSHJ P,SAVE1## ;SAVE P1
MOVEI T2,CHENXM## ;ASSUME NXM
MOVSI T4,IOCHNX ; ...
TLNE T3,(CI.DPE!CI.CPE)
MOVEI T2,CHEMPE## ;NO - PARITY ERROR
TLNE T3,(CI.DPE!CI.CPE)
MOVSI T4,IOCHMP ; ...
PUSH P,T1 ;SAVE IORB PNTR
MOVE T1,KDBICP(W) ;PNTR TO CCW
MOVE P1,KDBCHN(W) ;PNTR TO CHL DATA BLOCK
MOVE F,TUBCUR(U) ;PNTR TO DDB
IORM T4,CHNNUM##(P1) ;MARK MEMORY ERROR FOR LATER SWEEP
SKIPN TUBERR(U) ;CALL ERRCON ON FIRST ERROR ONLY
PUSHJ P,0(T2) ;EXERCISE ROUTINE
MOVEI T1,CO.CCW ;CLEAR CONTROL WORD WRITTEN
XCT KDBCNO(W) ;...
POP P,T1 ;RESTOR IORB
MOVSI T2,RB.SER!RB.SED
IORM T2,TRBSTS(T1) ;TELL HIM WORLD ENDED
PJRST TMIDON ;RETURN - NO RETRIES
;ROUTINE TO DETERMINE IF TAPE MOVED (DIVINATION)
TMCKMV: TRNE T3,CI.HNG!CI.ILL
POPJ P, ;TRY THIS FOR NOW
AOS TUBREC(U) ;MOVIN' ALONG
JRST CPOPJ1## ;SKIP RETURN
;ERRORS DETECTED DURING WRITE OPERATIONS
TMEWT0: MOVSI T2,RB.SNM!RB.SED ;TAPE DIDN'T MOVE
IORM T2,TRBSTS(T1)
TMEWT1: PUSHJ P,TMEANL ;ANALYSE ERROR
MOVSI T2,RB.SLK ;CHECK FOR WRITE LOCK
TRNE T3,CI.WLK
IORM T2,TRBSTS(T1) ;YES - SET BIT
PJRST TMIDON ;EXIT INTERUPT
;ERRORS DETECTED DURING READ / SPACING OPS
TMERD0: MOVSI T2,RB.SNM!RB.SED ;TAPE DIDN'T MOVE
IORM T2,TRBSTS(T1)
TMERD1: PUSHJ P,TMEANL ;ERROR ANALYSIS
PJRST TMIDON ;EXIT INT
;PROBLEM STARTING REWIND
TMERW: MOVSI T2,RB.SED!RB.SNM!RB.SOL
IORM T2,TRBSTS(T1) ;SET OFF-LINE ETC.
PUSHJ P,CLRCTL ;RESET CTL
PJRST TMIDON ;EXIT INT
;ROUTINE TO ANALYSE ERROR BITS IN RH(T3)
TMEANL: MOVEI T2,0 ;SET INITIAL ZERO
TRNE T3,CI.HNG
JRST TMEOFL ;DRIVE OFF-LINE
TRNE T3,CI.ILL
JRST TMECMR ;COMMAND REJECT
TRNE T3,CI.DLE
JRST TMEOVR ;OVERRUN
TRNE T3,CI.TPE!CI.BDT!CI.RCE
JRST TMEDC ;DATA CHECK
TMEXIT: IORM T2,TRBSTS(T1) ;SET SELECTED BITS
POPJ P, ;RETURN
TMEOFL: PUSHJ P,TMXOFL ;SET UNIT OFF-LINE
TMECMR: MOVSI T2,RB.SNM!RB.SED ;SET BITS (TAPE DIDN'T MOVE)
PJRST TMEXIT
TMEDC: TLO T2,RB.SDE ;DATA ERROR
TMEOVR: TLO T2,RB.SED ;ERROR DETECTED - RETRY
PJRST TMEXIT
SUBTTL COMPUTE CHARACTER COUNTS
;ROUTINE COMPUTES CHARACTER COUNT
;RETURNS COUNT IN T2 , T1 SAVED
;CALLED WITH C(T3) := CONI MTS,
CHRCT: PUSH P,T1 ;SAVE IORB PNTR
LDB T2,TUYKTP## ;GET CNTRL TYPE
PUSHJ P,@[WRDCTA
WRDCTB](T2) ;CALL CORRECT ROUTINE
SKIPA ;LENGTH ERROR RETURN
AOS -1(P) ;SET FOR SKIP RETURN
MOVEI T2,-1(T1) ;WORD COUNT -1 INTO T2
HLRZ T4,T3 ;NOW PLAY WITH BC CHAR CNT
ANDI T4,7 ;TO DETERMINE BYTE RESIDUE
JUMPE T4,[AOJA T2,CHRCT1] ;IF ZERO RE-ADJUST WORD COUNT
CHRCT1: DPB T4,PMTNCR## ;SAVE RESIDUE FOR MTCHR.
HRLM T2,TUBCHR(U) ;STORE LAST WORD COUNT FOR MTCHR.
TRNE T3,CI.7TK ;REAL EASY IF 7-TRACK
JRST CHRCT2 ;...
XCT TMXCIC(W) ;9TK - SEE WHAT MODE
MOVEI T3,5 ;ASSUME CORE-DUMP
TRNN T1,CM.CDF ;IS IT?
MOVEI T3,4 ;NO - COMPAT THEN
IMUL T2,T3 ;CONVERT TO BYTES
ADD T2,T4 ;PLUS REMAINDER
XCT TMXDIC(W) ;AND FETCH CRC
CHRCT3: DPB T1,PMTCRC## ;STORE IT FOR MTCHR.
PJRST TPOPJ## ;RESTORE T1 AND EXIT
CHRCT2: MOVE T1,(P) ;GET IORB
LDB T1,PRBMOD## ;MODE
IMUL T2,TMODTB##(T1) ;CHARS TAPUUO THINKS ARE IN A WORD
ADD T2,T4 ;PLUS LEFT OVERS
MOVEI T1,0 ;NO CRC FOR 7TK
JRST CHRCT3
;ROUTINE TO COMPUTE WORD COUNT FOR TM10A
;RETURNS WORD COUNT IN T1 , T3 PRESERVE
;CALLED WITH T1 := IORB
WRDCTA: HRRZ T4,TRBXCW(T1) ;ADDRS OF RESIDUE PNTR
HLRZ T2,TRBEXL(T1) ;ADR OF FIRST WORD -1
HRRZ T1,0(T4) ;LAST ADDRS
SUB T1,T2 ;DIFFERENCE IS WORD COUNT
TRNE T3,CI.RLD ;CHECK LENGTH ERROR
SKIPGE 0(T4) ;YES - SHORT RECORDS OK
JRST CPOPJ1## ;OK - LEN .LE. ACTUAL
POPJ P, ;ERRORR IF RECORD TOO LARGE
;ROUTINE TO COMPUTE WORD COUNT FOR TM10B
;CALLING CONVENTIONS SAME AS WRDCTA
WRDCTB: MOVE T1,KDBICP(W) ;PNTR TO INITIAL CONTROL WORD
PUSHJ P,SAVE1## ;SAVE P1
MOVE P1,KDBCHN(W) ;ADDRS OF CDB
PUSH P,T3 ;SAVE T3
PUSHJ P,WRDCNX## ;CALL ROUTINE IN COMMON
POP P,T3 ;RESTORE T3
TRNN T3,CI.RLD ;LENGTH = REQUEST?
JRST CPOPJ1## ;OK - GIVE GOOD RETURN
MOVE T2,KDBICP(W) ;ICPC PNTR
HLRZ T2,1(T2) ;LH TERMINATION WORD
LSH T2,-4 ;DF10C HAS 14 BIT ADDRS
SKIPN (T2) ;ARE WE AT END OF LIST
SOJA T1,CPOPJ## ;YES - RECORD IS TOO LONG
SOJA T1,CPOPJ1## ;NO - SHORT RECORD, OK
TMXEND: END