ON FILE 1 OF THIS TAPE YOU WILL FIND THE SOURCES AND KEYSHEETS. THE KEYSHEET IS THE INSTRUCTIONS FOR BUILDING THIS PRODUCT. PLEASE READ THE KEYSHEET AND THEN EXECUTE THE KEYSHEET AS A COMMAND FILE. EX. @KEYSHEETNAME.KS@ URDOS63.KSHH / COPYRIGHT C DATA GENERAL CORPORATION, 1972, 1973, 1974, 1975, / 1977 / ALL RIGHTS RESERVED. / / LICENSED MATERIAL - PROPERTY OF DATA GENERAL CORPORATION. / / / KEYSHEET FOR MODEL NUMBER 3189 / / / PRODUCT NAME: UNMAPPED NOVA RDOS / KEYSHEET NAME: URDOS63u.KS / / THE "U" PREFIX ON .RB, .LB FILE NAMES IS A SYSTEM CONVENTION / USED TO DISTINQUISH UNMAPPED NOVA RDOS MODULES. / / / ALL RDOS SOURCE(.SR) MODULES ARE INCLUDED IN THE "MAC" / STATEMENTS UNDER THE "ASSEMBLY PROCEDURE" SECTION(FOLLOWING). / THESE STJATEMENTS CAN BE CONSIDERED THE COMPONENTS LIST / AND SHOULD BE USED FOR REFERENCE PURPOSES. / / TO BUILD A SYSTEM FROM THE SOURCE THE FOLLOWING GENERAL / PROCEDURE IS RECOMMENDED: / / 1. BRING UP YOUR CURRENT RDOS SYSTEM. / 2. CREATE A SUBDIRECTORY FOR THE6& NEW SYSTEM: / / CDIR REV6SYSTEM / / 3. MAKE IT CURRENT: / / DIR REV6SYSTEM / / 4. LOAD THE NEW SYSTEM FROM FILE 1 OF THE SOURCE TAPE: / / INIT MT0 / LOAD/V MT0:1 / / 5. CREATE THE OPTIONS FILE(SEE BELOW). / 6. EXECUTE THE KEY SHEjiET TO BUILD THE SYSTEM. / 7. THE SOURCES ARE NOW INSTALLED- YOU CAN NOW SYSGEN. / / / BEFORE USING THESE COMMAND LINES YOU MUST CREATE A FILE CALLED OPTIONS / WHICH CONTAINS THE LISTING FILE AND THE ERROR FILE IF ANY. YOU CAN DO THIS / BY TYPING: / XFER/l,A $TTI OPTIONS / MT0:0/L $LPT/E ^Z / / NOTE THE FILE OPTIONS MUST NOT CONTAIN A CARRIAGE RETURN. IT IS ENDED / BY TYPING A (CONTROL Z) / / IF ANY OF THE OPTIONS ARE DEVICES (I.E. MAG TAPE) THE DEVICES MUST / BE INITED BEFORE THIS KEY SHEET IS EXECUTED. /7 / THESE PROCEDURES ASSUME THAT YOU HAVE THE FOLLOWING / FILES ON THE PRIMARY PARTITION OF THE DISK. / / MAC.SV / MACXR.SV / RLDR.SV / RLDR.OL / LFE.SV / NBID.SR / OSID.SR / NSID.SR /********************************************* MESSAGE MES]SAGE "BUILD 'URDOS'" MESSAGE / LINK THE FILES WE NEED SINCE WE ARE IN A SUBDIRECTORY / UNLINK -.- LINK MAC.SV/2 MACXR.SV/2 RLDR.SV/2 RLDR.OL/2 NBID.SR/2 OSID.SR/2 ^ NSID.SR/2 LFE.SV/2 / /*********************************************** MESSAGE MESSAGE "ASSh>EMBLE RDOS MODULES" MESSAGE / FIRST GET RID OF ANY OLD MAC.PS / DELETE MAC.PS / / ASSEMBLE MINUMUM TASK SCHEDULER / MAC/F/Z @OPTIONS@ NBID/S OSID/S NSID/S PARU/S NEID/S TMIN / / CREATE A NEW MAC.PS / MAC/N/F/Z @OPTIONS@ NBID,NSKID,OSID,NSID,PARU,RDOS,PARS,=QLITMACS,RDOSMACS / MAC/S/N NBID,NSKID,OSID,NSID,PARU,RDOS,PARS,QLITMACS,RDOSMACS / / ASSEMBLE RDOS MODULES. / MAC/F/Z/A @OPTIONS@ (INIT,CLIBT1 CLIBT2,CLIEN,^ INIT1,INIT2,INIT3,SCHED,PSPACE,SYMOD,SYSTE,PXXDB,OVLAY,OPPRO,TTY1D,^ TTYDR,DPMOD,RWBLK,BLKIO,FILInjO,GSUB,PLT1D,^ PLTDR,CDR1D,CDRDR,PTP1D,PTPDR,PTR1D,PTRDR,^ LP132,LP180,LP232,LP280,LPD1D,LPDDR,DCHLP,LPT1D,LPTDR,IOBUF,RTC1D,RTC2D,^ STACKS,CELLS,DK0DB,DK1DB,DSKDR,^ DP03DB,DP47DB,DP03FD,DP47FD,DKPDR,^ DS03DB,DS47DB,DSPDR,DZ03DB,DZ47DB,DZPDR,ECC,MCA1D,MCADhC,MCADR,^ ALMDB,ALM1D,ALMSPD,QTYDB,QTY1D,QTYDR,QTYMD,^ PWRFL,INTD,DUMP,MTDMP,FLDMP,SIZE,DMMP,PANIC,DDPMOD,TABLE,RESOLVE,^ TRES,DTSP,EITH,^ DFRWS,DFLR,UTIL1,CREATE,DELETE,FILSY,SOV1,SOV2,SOV3,SOV4,DVINI,^ CRSFS,RING1,RING2,RING3,SOV5,MTAIO,MTAUC,TUON,CDROV,|WDBLK,SPOLR,^ CODER,SOV6,SOV7,SOV8,SOV9,SOV10,SOV11,JEHOV,SOV12,SOV13,SOV14,^ SOV15,SOV16,FILS2,SOV17,SOV18,WDCBK,SOV19,SOV20,SOV21,SFTAB,^ SOV22,SOV23,SOV24,SOV25,FSTAT,DVRLS,SOV26,SOV27,SOV28,TUNOV,QTYOV,^ M0XDB,M1XDB,C0XDB,C1XDB,MTADR,SOV29,SOV30) MESSA|GE MESSAGE "ASSEMBLE THE TASK MONITOR AND SYS.LB MODULES" MESSAGE MAC/A/F/Z @OPTIONS@ (BFPKG,IOPC,OPCOM,TRDOP,TWROP,OPMSG,TOVLD,OVREL,^ OVKIL,OVEX,TOVLY,QTSK,DQTSK,TQTASK,AKILL,ASUSP,ARDY,TACALL,^ XMT,XMTW,REC,IXMT,TXMT,IDST,TIDS,TIDR,TIDK,TIDP,TIDC,PRI,^ hTPRI,DRSCH,ERSCH,TRSCH,ABORT,TABT,SUSP,TPEND,TUMOD,TSVRS,^ SINGL,MULTI,SMTSK,TASK,KILL,KILAD,TCBMON,DUMMY,NSAC3,N3SAC3) MESSAGE MESSAGE "ASSEMBLE THE DEBUGGERS" MESSAGE MAC/F/Z @OPTIONS@ (DEB,IDEB) NDEB<1,2,3> MESSAGE MESSAGE "ASSEMBLE THE BOOTS" MESSAGE MAC/F/A/Z @OPTIONS@ MAC/A/F/Z @OPTIONS@ MCABOOT.SR MAC/A/F/Z @OPTIONS@ (CBOOT,TBOOT) /************************************* MESSAGE MESSAGE "BUILD THE 'URDOS' LIBRARIES" MESSAGE / BUILD RDOSA.LB / LFE N URDOSA.LB/O URTC1D URTC2D^ UINIT1 UINIT2 UINIT3 USCHED UPSPACE USYMOD USYSTE UPXXDB UOVLAY UOPPRO^ UTTY1D UTTYDR UDPMOD URWBLK UBLKIO UFILIO UGSUB UPLT1D UPLTDR UCDR1D UCDRDR^ UPTP1D UPTPDR UPTR1D UPTRDR ULP132 ULP180 ULP232 ULP280 ULPDDR ULPD1D^ UDCHLP ULPTDR ULPT1D UIOBUF / / BUILD RDOSB.LB / LFE N URDOSB.LB/O UM0XDB UM1XDB UC0XDB UC1XDB UMTADR / / BUILD RDOSC.LB / LFE N URDOSC.LB/O USTACKS UCELLS UDK0DB UDK1DB UDSKDR ^ U ^ UDP0DB UDP4DB UDP0FD UDP4FD UDKPDR ^ U ^ UMCA1D UMCADC UMCADR UQTYDB UQTY1D UALMDB UALM1D ^ UQTYMD UQTYDR UPWRFL UINTD UDUMP ^ UMTDMP UFLDMP USIZE DMMP ^ UPANIC UDDPMOD UTABLE URESOLVE / / BUILD RDOSI.LB / LFE N URDOSI.LB/O UINIT UCLIBT TMIN NSAC3 UCLIEND / / BUILD RDOSO.LB / LFE N URDOSO.LB/O UDFRWS UDFLR UUTIL1 UCREATE UDELETE UFILSY USOV1 USOV2 USOV3 ^ USOV4 UDVINI UCRSFS URING1 URING2 URING3 USOV5 UMTAIO UMTAUC ^ UTUON UCDROV UWDBLK USPOLR UCODER USOV6 USOV7 USOV8 USOV9 ^ USOV10 USOV11 UJEHOV USOV12 USOV13 USOV14 USOV15 USOV16 UFILS2 ^ USOV17 USOV18 UWDCBK US`OV19 USOV20 USOV21 USFTAB USOV22 USOV23 ^ USOV24 USOV25 UFSTAT UDVRLS USOV26 USOV27 USOV28 UTUNOV UQTYOV USOV29 USOV30 MESSAGE MESSAGE "BUILD SYS.LB" MESSAGE LFE N SYS.LB/O BFPKG IOPC OPCOM TRDOP TWROP OPMSG TOVLD ^ OVREL OVKIL OVEX TOVLY QTSK DQTSK TQTASyK AKILL ASUSP ARDY ^ TACALL XMT XMTW REC IXMT TXMT IDST TIDS TIDR TIDK TIDP ^ TIDC PRI TPRI DRSCH ERSCH TRSCH ABORT TABT SUSP TPEND TUMOD ^ TSVRS SINGL MULTI SMTSK TASK KILL KILAD TCBMON TMIN ^ NSAC3 DEB DUMMY /***************************************** MESSAGE MESSAGE "BUILD THE BOOTS" MESSAGE RLDR/C/P @OPTIONS@ BOOT / RLDR/P @OPTIONS@ MCABOOT / RLDR/C/P @OPTIONS@ TBOOT / RLDR/C/P @OPTIONS@ CBOOT /************************************** MESSAGE MESSAGE "CLEAN UP" MESSAGE DELETE .RB / DELETE <mUM0XDB UM1XDB UC0XDB UC1XDB UMTADR>.RB / DELETE ^ UMCA1D UMCADC UMCADR UQTYDB UQTY1D UALMDB UALM1D ^ UQTYDR UQTYMD UPWRFL UINTD UDUMP ^ U-MTDMP UFLDMP USIZE DMMP ^ UPANIC UDDPMOD UTABLE URESOLVE UTRES UEITH UDTSP>.RB / DELETE .RB / DELETE .RB / DELETE .RB / DELETE .RB / DELETE OPTIONS /*************************************** MESSAGE MESSAGE "UNMAPPED NOVA RDOS BUILT!" MESSAGE NEID.SRB ) 6;EXTENDED NOVA I/O DEVICE MNEMONICS .DUSR ERCC= 2 ;ERROR CHECKING AND CORRECTION ; EXTENDED NOVA INSTRUCTION SET .DMRA LEF= 060000 .DEUR VCT= 061777 .DXOP XOP= 100030 .DXOP XOP1= 100070 .DICD ADI= 100010 .DICD SBI= 100110 .DISD DAD= 100210 .DISD DSB= 1003Y10 .DISD IOR= 100410 .DISD XOR= 100510 .DISD ANC= 100610 .DISD XCH= 100710 .DISD SGT= 101010 .DISD SGE= 101110 .DISD LSH= 101210 .DISD DLSH= 101310 .DICD HXL= 101410 .DICD HXR= 101510 .DICD DHXL= 101610 .DICD DHXR= 101710 .DISD BTO= 102010 .DEMR EJMP= 1020]70 .DISD BTZ= 102110 .DISD SZB= 102210 .DEMR PSHJ= 102270 .DISD SZBO= 102310 .DISD CLM= 102370 .DISD LOB= 102410 .DISD LRB= 102510 .DISD COB= 102610 .DISD LDB= 102710 .DISD SNB= 102770 .DISD STB= 103010 .DISD PSH= 103110 .DISD POP= 103210 .DIAC MSP= 1033700 .DUSR SVC= 103510 .DUSR SCL= 127510 .DUSR PSHR= 103710 .DIMM IORI= 103770 .DEMR EJSR= 106070 .DUSR POPB= 107710 .DEMR EISZ= 112070 .DUSR LMP= 113410 .DUSR BAM= 113710 .DEMR EDSZ= 116070 .DUSR POPJ= 117710 .DERA ELDA= 122070 .DIAC XCT= 123370 .DIMM XORI= 1<23770 .DUSR RTN= 127710 .DUSR DIVX= 137710 .DUSR BLM= 133710 .DERA ESTA= 142070 .DERA DSPA= 142170 .DIAC HLV= 143370 .DUSR MUL= 143710 .DIMM ANDI= 143770 .DUSR MULS= 147710 .DUSR DIV= 153710 .DUSR DIVS= 157710 .DERA ELEF= 162070 .DEUR SAVE= 163710 .DIMM ADDI= 163770 .DUSR RSTR= 167710 .DIAC HALTA= 063077 .DISD SYC= 103510 ; HARDWARE PAGE ZERO LOCATION DEFINITIONS USEDFUL FOR STACKING .DUSR SP= 40 ; STACK POINTER .DUSR CSP= 41 ; FRAME POINTER (LOGICAL STACK PTR) .DUSR CSL= 42 ; STACK LIMIT .DUSR CSO= 43 ; ҏSTACK OVERFLOW ROUTINE PTR .DUSR XOPA= 44 ; XOP ORIGIN ADDRESS .DUSR FPFA= 45 ; FLOATING POINT FAULT ADDRESS ; DEFINE OFFSETS FOR PAGE 0 INT STK LOCATIONS .DUSR ISP= 4 ; SKP SP .DUSR CMSK= 5 ; CURRENT MASK .DUSR ISL= 6 ; LIMIT .DUSR ISO= 7 ; OVERFLOW ADDR .EOT ;END OF NEID.SR TMIN.SR= %2.TITL TMIN .RB TMIN.RB ;.REV 6,00 .ENT TMIN .EXTN .SAC3,USTAD .LOC 17 SYST .LOC UST+USTSA TMIN .NREL ; MINIMUM TASK SCHEDULER FOR A NON-MULTITASKED ENVIRONMENT ; RDOS COMMUNICATION WORDS ARE AT HEAD OF CODE ; NOTE- SYST MUST PROCEED THE SCHED AQ DDR FOR RDOS !!!! SYST TMIN: LDA 2,@TACT ; GET CURRENT TASK LDA 1,TPRST,2 ; STATUS OF TASK MOVZL# 1,1,SZC ; SKP IF FREE JMP TNULL ; IF PENDED QUIT LDA 0,TAC0,2 LDA 1,TAC1,2 ; RESTORE 1 LDA 3,TUSP,2 ; RESTORE USP STA 3,USP LDA 3,1 ; SEE IF MRDOS MOVZR# 3,3,SZR ; SKIP IF YES JMP NOMAP LDA 3,TAC3,2 ; SET UP AC'S IN CASE BIRDY LDA 2,TAC2,2 LDA 0,C6 ; EXIT TRAP TO RDOS SCL ; NOOP IN 840 NIOC MAP NOMAP: LDA 3,TPC,2 MOVZR 3,3 ; RESTORE CARRY STA 3,TRTN ; SAVE PC LDA 3,TAC3,2 LDA 2,TeaAC2,2 INTEN JMP @TRTN TNULL: SUB 2,2 JMP TEXIT TRTN: 0 C6: 6 TACT: .GADD USTAD,USTCT ; CURRENT TCB POINTER PCTMP: 0 ; SYSTEM CALL LOGIC SYST: STA 3,PCTMP ; USER PC LDA 3,1 ; SEE IF MRDOS MOV# 3,3,SZR ; UNMAPPED SYSTEM? INTDS ; YES, DISABLE UKNMAPPED WORLD MOV# 3,3,SNR ; MAPPED SYSTEM? ISZ 1 ; YES, SET SCHEDULER STATE LDA 3,@TACT ; CURRENT TASK STA 0,TAC0,3 STA 1,TAC1,3 STA 2,TAC2,3 MOV 3,2 ; AC2 <- TCB .SAC3 ; AC3 <- RETURN TO USER IN AC3 STA 3,TAC3,2 ; SAVE IT LDA 3,PCTMP LDm A 1,USP ; SAVE USP STA 1,TUSP,2 ; LDA 1,0,3 ; LOAD SYST CONTROL WORD STA 1,TSYS,2 ; STORE IN TCB INC 3,3 INCL 3,3 ; ADD 2 FOR GOOD RTN STA 3,TPC,2 ; PUT BACK IN TCB LDA 1,TPRST,2 ; GET STATUS & PRIORITY ADDOR 1,1 ; SET TSSYS (SYSTEM PEND) STA~. 1,TPRST,2 TEXIT: LDA 3,1 ; SEE IF MAPPED MOVZR# 3,3,SZR JMP @2 ; NO, JUMP TO UNMAPPED SYSTEM MOV 2,0 SVC ; NOOP IN NON-BIRD NIOC MAP ; EXIT .END ; END OF TMIN.SR NSKID.SRB 9 *Đ .TITLE NSKID ;NOVA SKIP INSTRUCTION DEFINITIONS .DUSR NOP= JMP 1,1 ;NO OPERATION .DUSR SKIP= JMP 2,1 ;SKIP NEXT INSTRUCTION (1 WORD) ;EQUALITY INTEGER COMPARISONS (E.G., SEQ 0,1) .DISS SEQ= SUB# 0,0,SZR ;SKIP IF ACS == ACD .DISS SNE= SUB# 0,0',SNR ;SKIP IF ACS <> ACD ;UNSIGNED INTEGER COMPARISONS (E.G., USLE 2,3) .DISS USLE= SUBZ# 0,0,SNC ;SKIP IF ACS <= ACD .DISS USGT= SUBZ# 0,0,SZC ;SKIP IF ACS > ACD .DISS USLT= SUBZ# 0,0,SBN ;SKIP IF ACS < ACD .DISS USGE= SUBZ# 0,0,SEZ ;SKIP It.F ACS >= ACD ;NOTE THAT THE ABOVE SKIPS ARE ALL FORMED FROM SUBTRACT ;INSTRUCTIONS, SO THAT AN INSTRUCTION THAT MAKES ONE OF ;THE ABOVE TESTS CAN ALSO DO THE SUBTRACTION IF THE NO- ;LOAD SIGN IS REMOVED. ;NOVA SIGNED INTEGER COMPARISONS (E.G., F NSGE 2,1) ;WARNING: THESE COMPARISONS DO NOT WORK WHEN THE ; ARGUMENTS DIFFER BY 32K OR MORE. .DISS NSLE= SUBL# 0,0,SZC ;SKIP IF ACS <= ACD .DISS NSGT= SUBL# 0,0,SNC ;SKIP IF ACS > ACD .DISS NSLT= ADCL# 0,0,SZC ;SKIP IF ACS < ACD .DISS NSGE= ADCJL# 0,0,SNC ;SKIP IF ACS >= ACD ;SIGNED INTEGER COMPARISONS TO ZERO (E.G., SLTZ 2) .MACRO SEQZ ** MOV# ^1,^1,SZR ;SKIP IF AC == 0 % .MACRO SNEZ ** MOV# ^1,^1,SNR ;SKIP IF AC <> 0 % .MACRO SLTZ ** MOVL# ^1,^1,SNC ;SKIP IF AC < 0 % .MACRO SGEZ ** cMOVL# ^1,^1,SZC ;SKIP IF AC >= 0 % .MACRO SLEZ ** ADDO# ^1,^1,SEZ ;SKIP IF AC <= 0 % .MACRO SGTZ ** ADDO# ^1,^1,SBN ;SKIP IF AC > 0 % ;NOTE: NEGL# IS NOT USED FOR SGTZ AND SLEZ AS IT FAILS FOR 100000. ;INTEGER COMPARISONS TO MINUS 1 .MACRO SEQM1 ** q x COM# ^1,^1,SZR ;SKIP IF AC = -1 % .MACRO SNEM1 ** COM# ^1,^1,SNR ;SKIP IF AC <> -1 % .EOT ;END OF NSKID.SR PARU.SRB Q ;==================================== ; RDOS REVISION 06.30 USER PARAMETERS ;==================================== .TITL PARU ; ; USER FILE TABLE (UFT) TEMPLATE ; ; USER FILE DEFINITION (UFD) OF UFT .DUSR UFTFN=0 ;FILE NAME .DUSR UFTEX=5 ;EXTENSIO QN .DUSR UFTAT=6 ;FILE ATTRIBUTES .DUSR UFTLK=7 ;LINK ACCESS ATTRIBUTES .DUSR UFLAD=7 ;LINK ALTERNATE DIRECTORY .DUSR UFTBK=10 ;NUMBER OF LAST BLOCK IN FILE .DUSR UFTBC=11 ;NUMBER OF BYTES IN LAST BLOCK .DUSR UFTAD=12 ;DEVICE ADDRESS OF FIRST BLOCK (0' UNASSIGNED) .DUSR UFTAC=13 ;YEAR-DAY LAST ACCESSED .DUSR UFTYD=14 ;YEAR-DAY CREATED .DUSR UFLAN=14 ;LINK ALIAS NAME .DUSR UFTHM=15 ;HOUR-MINUTE CREATED .DUSR UFTP1=16 ;UFD TEMPORARY .DUSR UFTP2=17 ;WORDS/BLOCK .STAT.RSTA.CHST .DUSR UFTUC=20 ;USER CbOUNT .DUSR UFTDL=21 ;DCT LINK (RH) HIGH-ORDER DEVICE ADDRESS (LH) ; DEVICE CONTROL BLOCK (DCB) OF UFT .DUSR UFTDC=22 ;DCT ADDRESS .DUSR UFTUN=23 ;UNIT NUMBER .DUSR UFCA1=24 ;CURRENT BLOCK ADDRESS (HIGH ORDER) .DUSR UFTCA=25 ;CURRENT BLOCK ADDRESS (L_SOW ORDER) .DUSR UFTCB=26 ;CURRENT BLOCK NUMBER .DUSR UFTST=27 ;FILE STATUS .DUSR UFEA1=30 ;ENTRY'S BLOCK ADDRESS (HIGH ORDER) .DUSR UFTEA=31 ;ENTRY'S BLOCK ADDRESS (LOW ORDER) .DUSR UFNA1=32 ;NEXT BLOCK ADDRESS (HIGH ORDER) .DUSR UFTNA=33 ;NEXT BLOCK( ADDRESS (LOW ORDER) .DUSR UFLA1=34 ;LAST BLOCK ADDRESS (HIGH ORDER) .DUSR UFTLA=35 ;LAST BLOCK ADDRESS (LOW ORDER) .DUSR UFTDR=36 ;SYS.DR DCB ADDRESS .DUSR UFFA1=37 ;FIRST ADDRESS (HIGH ORDER) .DUSR UFTFA=40 ;FIRST ADDRESS (LOW ORDER) ; DCB EXTENSIOٌN .DUSR UFTBN=41 ;CURRENT FILE BLOCK NUMBER .DUSR UFTBP=42 ;CURRENT FILE BLOCK BYTE POINTER .DUSR UFTCH=43 ;DEVICE CHARACTERISTICS .DUSR UFTCN=44 ;ACTIVE REQ COUNT ;B0 INDICATES Q, 0=DSQ1,1=DSQ2 .DUSR UFTEL=UFTCN-UFTFN+1 ;UFT ENTRY LENGTH .DUSR  UFDEL=UFTDL-UFTFN+1 ;UFD ENTRY LENGTH  .DUSR UDBAT=UFTAT-UFTDC ;NEGATIVE DISP. TO ATTRIBUTES .DUSR UDDL=UFTDL-UFTDC ;NEGATIVE DISP. TO FIRST ADDRESS (HIGH ORDER) .DUSR UDBAD=UFTAD-UFTDC ;NEGATIVE DISP. TO FIRST ADDRESS (LOW ORDER) .DUSR UDBBK=UFTBK-UFTDC *;NEGATIVE DISP. TO LAST BLOCK .DUSR UDBBN=UFTBN-UFTDC ;POSITIVE DISP. TO CURRENT BLOCK ; FILE ATTRIBUTES (IN UFTAT) .DUSR ATRP =1B0 ;READ PROTECTED .DUSR ATCHA=1B1 ;CHANGE ATTRIBUTE PROTECTED .DUSR ATSAV=1B2 ;SAVED FILE .DUSR ATNRS=1B7 ;CANNOT BE f"A RESOLUTION ENTRY .DUSR ATUS1=1B9 ;USER ATTRIBUTE # 1 .DUSR ATUS2=1B10 ;USER ATTRIBUTE # 2 .DUSR ATPER=1B14 ;PERMANENT FILE .DUSR ATWP =1B15 ;WRITE PROTECTED ; FILE CHARACTERISTICS (IN UFTAT) .DUSR ATMSK=7B7 ;TO GET HIGH ORDER PART OF 3330 ; ADDRZESSES OUT OF UFTDL .DUSR ATLNK=1B3 ;LINK ENTRY .DUSR ATPAR=1B4 ;PARTITION ENTRY .DUSR ATDIR=1B5 ;DIRECTORY ENTRY .DUSR ATRES=1B6 ;LINK RESOLUTION (TEMPORARY) .DUSR ATCON=1B12 ;CONTIGUOUS FILE .DUSR ATRAN=1B13 ;RANDOM FILE ; ; DCT PARAMETERS. ; .DUSR ADCTBS=0 ;1B0=1 => DEVICE USES DATA CHANNEL .DUSR DCTMS=1 ;MASK OF LOWER PRIORITY DEVICES .DUSR DCTIS=2 ;ADDRESS OF INTERRUPT SERVICE ROUTINE ; DEVICE CHARACTERISTICS (IN UFTCH) .DUSR DCSTB= 1B15 ; SUPPRESS TRAILING BLANKS $CDR ONLY .DUSR DCCPO= 1B15 ; DEVICE REQUIRING LEADER/TRAILER .DUSR DCSTO= 1B15 ; USER SPECIFIED TIME OUT CONSTANT (MCA) .DUSR DCCGN= 1B14 ; GRAPHICAL OUTPUT DEVICE WITHOUT TABBING ; HARDWARE .DUSR DCIDI= 1B13 ; INPUT DEVICE REQUIRING OPERATOR INTERVENTION .DUSR DCLCD= 1B12 ;+ INPUT DEVICE IS 6053-TYPE TERMINAL .DUSR DCCNF= 1B12 ; OUTPUT DEVICE WITHOUT FORM FEED HARDWARE .DUSR DCTO= 1B11 ; TELETYPE OUTPUT DEVICE .DUSR DCKEY= 1B10 ; KEYBOARD DEVICE .DUSR DCNAF= 1B09 ; OUTPUT DEVICE REQUIRING NULLS AFTER FORM FEEDS .DUSR DCRAT@= 1B08 ; RUBOUTS AFTER TABS REQUIRED .DUSR DCPCK= 1B07 ; DEVICE REQUIRING PARITY CHECK .DUSR DCLAC= 1B06 ; REQUIRES LINE FEEDS AFTER CARRIAGE RTN .DUSR DCSPO= 1B05 ; SPOOLABLE DEVICE .DUSR DCFWD= 1B04 ; FULL WORD DEVICE (ANYTHING GREATER THAN .DUSR DCFFO= 1B03 ; FORM FEEDS ON OPEN .DUSR DCLTU= 1B02 ; CHANGE LOWER CASE ASCII TO UPPER .DUSR DCC80= 1B01 ; READ 80 COLUMS .DUSR DCDIO= 1B00 ; SUSPEND PROTOCOL ON TRANSMIT (MCA) .DUSR DCBDK= 1B00 ; DISK CHARACTERISTIC (SET NON-PARAMETRICALLY) ; SET MEANS ITS 333_:0 .DUSR DCSPC= 1B00 ; SPOOL CONTROL ; SET = SPOOLING ENABLED ; RESET = SPOOLING DISABLED ; ; DEVICE CHARACTERISTICS FOR QTY AND ALM (PARU.SR) ; .DUSR DCNI= 1B15 ;(MASKING ENABLES) CONSOLE INTERRUPTS ;.DUSR DCCGN= 1B14 ;(MASKING DISABLES) TAB EXPA{NSION .DUSR DCLOC= 1B13 ;LOCAL LINE (MASKING MAKES MODEM LINE) ; 1B12 ;SAVE FOR 3 MODEM PROTOCALS ;.DUSR DCTO= 1B11 ;_ FOR RUBOUT (MASKING GIVES BACKSPACE) ;.DUSR DCKEY= 1B10 ;(MASKING DISABLES) INPUT ECHOING, ; LINE EDITS, AND ^Z EOF ;.DUSR DCNAF= 1B9 ;(MASKING DISABLES) 20 NULLS AFTER FORM FEED .DUSR DCXON= 1B8 ;(MASKING ENABLES) XON/XOFF PROTOCALL FOR $TTR ; 1B7 ;SAVE FOR FUTURE USE ;.DUSR DCLAC= 1B6 ;(MASKING DISABLES) LINE FEED AFTER CARRAIGE RETURN ;.DUSR DCSPO= 1B5 ;(MUST BE OFF) SPOOLING ^#.DUSR DCCRE= 1B4 ;CARRAIGE RETURN ECHO ; (MASKING ENABLES CR AS ENTER KEY) ; ; .WRL TO LINE 64 ; ; AC0= CODE+LINE # ; AC1= DATA .DUSR W64DC= 0B7 ;CHANGE DEVICE CHARACTERISTIC MASK (AC1) .DUSR W64LS= 1B7 ;CHANGE LINE SPEED (AC1= 0 -> 3) .DUSR W64MS= 2YGB7 ;CHANGE MODEM STATE (AC1) AS FOLLOWS .DUSR W64DTR= 1B15 ; RAISE DATA TERMINAL READY ; ELSE LOWER .DUSR W64RTS= 1B14 ; RAISE REQUEST TO SEND ; ELSE LOWER ; ; SWITCHES ; .DUSR A.SW= 1B00 .DUSR B.SW= 1B01 .DUSR C.SW= 1B02 .DUS5R D.SW= 1B03 .DUSR E.SW= 1B04 .DUSR F.SW= 1B05 .DUSR G.SW= 1B06 .DUSR H.SW= 1B07 .DUSR I.SW= 1B08 .DUSR J.SW= 1B09 .DUSR K.SW= 1B10 .DUSR L.SW= 1B11 .DUSR M.SW= 1B12 .DUSR N.SW= 1B13 .DUSR O.SW= 1B14 .DUSR P.SW= 1B15 .DUSR Q.SW= 1B00 .DUSR R.SW= 1B01 .DUSR S.SW= 1B02 .DUSR T.SW= 1B03 .DUSR U.SW= 1B04 .DUSR V.SW= 1B05 .DUSR W.SW= 1B06 .DUSR X.SW= 1B07 .DUSR Y.SW= 1B08 .DUSR Z.SW= 1B09 ; ; SYSTEM CONSTANTS ; .DUSR SCWPB=255. ;WORDS PER BLOCK .DUSR SCDBS=256. ;SIZE OF DISK BLOCK .DUSR SCRRL=64. ;WORDS PER RANDOM RECORD .DUSR SCLLG=132. ;MAX LINE LENGTH .DUSR SCAMX=24. ;MAX ARGUMENT LENGTH IN BYTES .DUSR SCFNL=UFTEX-UFTFN+1 ;FILE NAME LENGTH .DUSR SCEXT=UFTEX-UFTFN ;EXTENSION OFFSET IN NAME AREA .DUSR SCMER=10. ;MAX ERROR RETRY COUNT .DUSR SCSTR=16 ;SAVE ȪFILE STARTING ADDRESS .DUSR SCTIM=-80. ;RINGIO 1 MS. LOOP TIME (SN) .DUSR SCPPL=0 ;PRIMARY PARTITION LEVEL .DUSR SCPPA=6 ;PRIMARY PARTITION BASE ADDRESS .DUSR SCDSK=3 ;ABSOLUTE ADDRESS OF DISK INFORMATION BLOCK .DUSR SCBAD=4 ;ABSOLUTE ADDRESS OF BAD BL5OCK TABLE BLOCK .DUSR SCSYS=0 ;SYS.DR ADDRESS OFFSET .DUSR SCPSH=1 ;PUSH DIRECTORY OFFSET .DUSR SCPNM=4 ;MAX NUMBER OF PUSH LEVELS .DUSR SCMAP=SCPNM*2+SCPSH ;RELATIVE BASE ADDRESS OF MAP.DR .DUSR SCBPB=1 ;RELATIVE BACKROUND PUSH BASE .DUSR SCFPB=SCBPB+SCPNM ;RELATIVE FOREGROUND PUSH BASE .DUSR SCFZW=SCPNM*4+SCBPB ;FRAME SIZE WORD (SKIP DOUBLE WORD PUSH INDICES) .DUSR SCNVW=SCFZW+1 ;NUMBER-OF-SYSTEM-OVERLAYS WORD .DUSR SFINT=1B0  ;INTERRUPT FLAG .DUSR SFBRK=1B15 ;BREAK FLAG .DUSR SCNSO=64. ;NUMBER OF SYSTEM OVERLAYS ; SYSTEM BOOTSTRAP CONSTANTS .DUSR SCTBP=0 ;TEXT STRING BYTE POINTER .DUSR SCINS=1 ;SWITCHED FULL/PARTIAL-OVERLAYS ADDRESS .DUSR SCPSA=2 ;PROGRAM START ADDRESS .DUSR SCPAR=SCPSA ;PARTIAL INIT ADDRESS .DUSR SCINT=3 ;FULL/PARTIAL-OVERLAY;S INIT ADDRESS .DUSR SCCLI=SCINT+1 ;ADDRESS OF END OF CLI .DUSR SCZMX=SCCLI+1 ;SQUASHED/UNSQUASHED FLAG .DUSR SCCPL=SCZMX+1 ;CURRENT PARTITION LEVEL .DUSR SCPBA=SCCPL+1 ;PARTITION BASE ADDRESS (LOW ORDER) .DUSR SCOFA=SCPBA+1 ;OVERLAY BASE ADDRESS (LOW ORDER) .DUSR SCPB1=SCOFA+1 ;PARTITION BASE ADDRESS (HIGH ORDER) .DUSR SCOF1=SCPB1+1 ;OVERLAY BASE ADDRESS (HIGH ORDER) .DUSR SCBAS=SCOF1+1 ;BASE OF INFORMATION BLOCK .DUSR SCSWC=SCBAS ;SWITCH FOR SCINS ENTRY .DUSR SCIDV=20 ;INITIAL DEVICE CODE .DUSR SCAUN=0 A;ASCII UNIT NUMBER .DUSR SCUN=1 ;UNIT (DEVICE CODE) .DUSR SCGO=2 ;ENTRY TO PASS FILENAME .DUSR SCNGO=4 ;ENTRY TO ASK FROM CONSOLE ; SYSTEM ERROR CODES  .DUSR ERFNO= 0 ; ILLEGAL CHANNEL NUMBER .DUSR ERFNM= 1 ; ILLEGAL FILE NAME .DUSR ERICM= 2 ; ILLEGAL SYSTEM COMMAND .DUSR ERICD= 3 ; ILLEGAL COMMAND FOR DEVICE .DUSR ERSV1= 4 ; NOT A SAVED FILE .DUSR ERWR0= 5 ; ATTEMPT TO WRITE AN EXISTENT FILE .DUSR EREOF= 6 ; END OF FILE .DUSR ERRPR= 7 ; ATTEMPT TO READ A READ PROTECTED FILE .DUSR ERWPR= 10 ; WRITE PRO4DTECTED FILE .DUSR ERCRE= 11 ; ATTEMPT TO CREATE AN EXISTENT FILE .DUSR ERDLE= 12 ; A NON-EXISTENT FILE .DUSR ERDE1= 13 ; ATTEMPT TO ALTER A PERMANENT FILE .DUSR ERCHA= 14 ; ATTRIBUTES PROTECTED .DUSR ERFOP= 15 ; FILE NOT OPENED .DUSR ERFUE= 16 ; FATAL UTIL=ITY ERROR .DUSR EREXQ= 17 ; EXECUTE CLI.CM (NO ERROR) .DUSR ERNUL= 20 ; INVISIBLE ERROR CODE .DUSR ERUFT= 21 ; ATTEMPT TO USE A UFT ALREADY IN USE .DUSR ERLLI= 22 ; LINE LIMIT EXCEEDED O .DUSR ERRTN= 23 ; ATTEMPT TO RESTORE A NON-EXISTENT IMAGE .DUSR ERPAR= 24 ; PARITY ERROR ON READ LINE .DUSR ERCM3= 25 ; TRYING TO PUSH TOO MANY LEVELS .DUSR ERMEM= 26 ; NOT ENUF MEMORY AVAILABLE .DUSR ERSPC= 27 ; OUT OF FILE SPACE .DUSR ERFIL= 30 ; FILE READ ERROR .DUSR ERSEL= 31 ; UNIT NOT PROPERLY SELECTED .DUSR ERADR= 32_ ; ILLEGAL STARTING ADDRESS .DUSR ERRD= 33 ; ATTEMPT TO READ INTO SYSTEM AREA .DUSR ERDIO= 34 ; FILE ACCESSIBLE BY DIRECT I/O ONLY .DUSR ERDIR= 35 ; FILES SPECIFIED ON DIFF. DIRECTORIES .DUSR ERDNM= 36 ; DEVICE NOT IN SYSTEM .DUSR EROVN= 37 ; ILLEGAL OVERL:@AY NUMBER .DUSR EROVA= 40 ; FILE NOT ACCESSIBLE BY DIRECT I/O .DUSR ERTIM= 41 ; USER SET TIME ERROR .DUSR ERNOT= 42 ; OUT OF TCB'S .DUSR ERXMT= 43 ; SIGNAL TO BUSY ADDR .DUSR ERSQF= 44 ; FILE ALREADY SQUASHED ERROR .DUSR ERIBS= 45 ; DEVICE ALREADY INP SYSTEM .DUSR ERICB= 46 ; INSUFFICENT CONTIGUOUS BLOCKS .DUSR ERSIM= 47 ; SIMULTANEOUS READ OR WRITE TO MUX LINE .DUSR ERQTS= 50 ; ERROR IN USER TASK QUEUE TABLE .DUSR ERNMD= 51 ; NO MORE DCB'S .DUSR ERIDS= 52 ; ILLEGAL DIRECTORY SPECIFIER .DUSR ERDSN= 53 (; DIRECTORY SPECIFIER NOT KNOWN .DUSR ERD2S= 54 ; DIRECTORY IS TOO SMALL .DUSR ERDDE= 55 ; DIRECTORY DEPTH EXCEEDED .DUSR ERDIU= 56 ; DIRECTORY IN USE .DUSR ERLDE= 57 ; LINK DEPTH EXCEEDED .DUSR ERFIU= 60 ; FILE IS IN USE .DUSR ERTID= 61 ; TASK ID ERROR .DUSR ERCMS= 62 ; COMMON SIZE ERROR .DUSR ERCUS= 63 ; COMMON USAGE ERROR .DUSR ERSCP= 64 ; FILE POSITION ERROR .DUSR ERDCH= 65 ; INSUFFICIENT ROOM IN DATA CHANNEL MAP .DUSR ERDNI= 66 ; DIRECTORY NOT INITIALIZED .DUSR ERNDD= 67 ; NO DEFAULT DIRECTORY .DUSR ERFGE= 70 ; FOREGROUND ALREADYS EXISTS .DUSR ERMPT= 71 ; ERROR IN PARTITON SET .DUSR EROPD= 72 ; DIRECTORY IN USE BY OTHER PROGRAM .DUSR ERUSZ= 73 ; NO ROOM FOR UFTS ON EXEC/EXFG .DUSR ERMPR= 74 ; ADDR ERROR ON .SYSTM PARAM .DUSR ERNLE= 75 ; NOT A LINK ENTRY9 .DUSR ERNTE= 76 ; CURRENT BG IS NOT CHECKPOINTABLE .DUSR ERSDE= 77 ; SYS.DR ERROR .DUSR ERMDE= 100 ; MAP.DR ERROR .DUSR ERDTO= 101 ; DEVICE TIME OUT .DUSR ERENA= 102 ; ENTRY NOT ACCESSIBLE VIA LINK .DUSR ERMCA= 103 ; MCA REQUEST OUTSTANDING .DUSR ERSRR= 104 ; INCOMPLETE TRANSMISSION CAUSED BY RECIEVER .DUSR ERSDL= 105 ; SYSTEM DEADLOCK .DUSR ERCLO= 106 ; I/O TERMINATED BY CHANNEL CLOSE .DUSR ERSFA= 107 ; SPOOL FILE(S) ACTIVE .DUSR ERABT= 110 ; TASK NOT FOUND FOR ABORT .DUSR ERDOP= 111 ; DEVICE PREVIOUSLY OPENED .DUSR EROVF= 112 ; SYSTEM STACK OVERFLOW .DUSR ERNMC= 113 ; NO MCA RECEIVE REQUEST OUTSTANDING .DUSR ERNIR= 114 ; NO INIT/RELEASE ON OPENED DEVICE (MAG TAPE) .DUSR ERXMZ= 115 ; .XMT & .IXMT MESSAGES MUST BE NON-ZERO .DUSR ERCANT= 116 ; 'YOU CAN'T DO 8THAT' .DUSR ERQOV= 117 ; .TOVLD NOT LOADED FOR QUEUED OVERLAY TASKS .DUSR EROPM= 120 ; OPERATOR MESSAGE MODULE NOT SYSGENED .DUSR ERFMT= 121 ; DISK FORMAT ERROR .DUSR ERBAD= 122 ; DISK HAS INVALID BAD BLOCK TABLE .DUSR ERBSPC= 123 ; INSUFFICIENT SPACE IN BAD BLOCK POOL (CORE) .DUSR ERZCB= 124 ; ATTEMPT TO CREATE CONTIG OF ZERO LENGTH .DUSR ERNSE= 125 ; PROGRAM IS NOT SWAPPABLE .DUSR ERBLT= 126 ; BLANK TAPE .DUSR ERRDY= 127 ; LINE NOT READY .DUSR ERINT= 130 ; CONSOLE INTERRUPT RECEIVED .DUSR EROVR= 131 ; CH!ARACTER OVER RUN ERROR .DUSR ERFRM= 132 ; CHARACTER FRAMING ERROR .DUSR ERSPT= 133 ; TOO MANY SOFT ERRORS (DOS ONLY) ; CLI ERROR CODES .DUSR CNEAR= 300 ; NOT ENOUGH ARGUMENTS .DUSR CILAT= 301 ; ILLEGAL ATTRIBUTE .DUSR CNDBD= 302 ; NO DEBUG ADDRESS .DUSR CCLTL= 303 ; COMMAND LINE TOO LONG .DUSR CNSAD= 304 ; NO STARTING ADDRESS .DUSR CCKER= 305 ; CHECKSUM ERROR .DUSR CNSFS= 306 ; NO SOURCE FILE SPECIFIED .DUSR CNACM= 307 ; NOT A COMMAND .DUSR CILBK= 310 ; ILLEGAL BLOCK TYPE .DUSR CSPER= 311 ; NO FILES MATC4H SPECIFIER .DUSR CPHER= 312 ; PHASE ERROR .DUSR CTMAR= 313 ; TOO MANY ARGUMENTS .DUSR CTMAD= 314 ; TOO MANY ACTIVE DEVICES .DUSR CILNA= 315 ; ILLEGAL NUMERIC ARGUMENT .DUSR CSFUE= 316 ; FATAL SYSTEM UTILITY ERROR .DUSR CILAR= 317 ; ILLEGAL ARGUMENT .DUSR  CCANT= 320 ; IMPROPER OR MALICIOUS INPUT .DUSR CTMLI= 321 ; TOO MANY LEVELS OF INDIRECT FILES .DUSR CSYER= 322 ; SYNTAX ERROR .DUSR CBKER= 323 ; BRACKET ERROR .DUSR CPARE= 324 ; PAREN ERROR .DUSR CCART= 325 ; < WITHOUT > OR > WITHOUT < .DUSR CCAR1= 326 ; ILLEGAL NESTING OF <> AND () .DUSR CINDE= 327 ; ILLEGAL INDIRECT FILENAME .DUSR CPAR1= 330 ; ILLEGAL NESTING OF () AND [] .DUSR CIVAR= 331 ; ILLEGAL VARIABLE .DUSR CILTA= 332 ; ILLEGAL TEXT ARGUMENT .DUSR CTATL= 333 ; TEXT ARGUMENT TOO LONG .DUSR CCMAX= CTATL ; MAX CLI ERROR CODE .DUSR ERML= 30. ; MAXIMUM ERROR MESSAGE LENGTH ; EXCEPTIONAL SYSTEM STATUS CODES .DUSR PNMPE= @1 ; MAP.DR ERROR .DUSR PNSDE= @2 ; SYSTEM DIRECTORY ERROR .DUSR PNCSO= @3 ; SYSTEM STACK FAULT .DUSR PNIDA= @4 ; INCONSISTENT SYSTE#M DATA .DUSR PNMDD= @5 ; MASTER DEVICE DATA ERROR .DUSR PNMDT= @6 ; MASTER DEVICE TIME OUT .DUSR PNDPE= @7 ; MOVING HEAD DISK ERROR .DUSR PNCUI= @10 ; UNCLEARABLE UNDEFINED INTERRUPT .DUSR PNCBK= @12 ; INSUFFICENT CONTIGUOUS BLOCKS TO BUILD ; PUSH SPACE} INDICES .DUSR PNILL= @11 ; ILLEGAL EXTENDED INSTRUCTION .DUSR PNPSH= @13 ; RTN BEYOND TOP OF WORLD .DUSR PNIPB= @14 ; INCONSISTENT OR IMPOSSIBLE CONDITION ; RELATED TO DUAL PROCESSORS (IPB) .DUSR PNITR= @15 ; INT WORLD TRAPPED .DUSR PNERC= @16 ; MULTIB8IT MEMORY ERROR .DUSR PNPAR= @17 ; MEMORY PARITY ERROR .DUSR PNMEM= @20 ; INFOS INSUFFICIENT MEMORY (INIT TIME) .DUSR PNSPL= @21 ; SPOOLER ; ; USER STATUS TABLE (UST) TEMPLATE ; .DUSR UST= 400 ; START OF BACKGROUND USER STATUS AREA .DUSR USTP=12 ; PZER!O LOC FOR UST POINTER ; NOTE- USTP MUST CORRESPOND TO PARS PZERO ALLOCATIONS .DUSR USTPC= 0 ; 0=>BACKGROUND, 1=>FOREGROUND ; (WHEN NOT IN SCHED STATE) .DUSR USTZM= 1 ; ZMAX .DUSR USTSS= 2 ; START OF SYMBOL TABLE .DUSR USTES= 3 ; END OF SYMBOL TABLE .DUSR USTNM= 4 ; NMAX .DUSR USTSA= 5 ; STARTING ADDRESS .DUSR USTDA= 6 ; DEBUGGER ADDRESS .DUSR USTHU= 7 ; HIGHEST ADDRESS USED .DUSR USTCS= 10 ; FORTRAN COMMON AREA SIZE .DUSR USTIT= 11 ; INTERRUPT ADDRESS .DUSR USTBR= 12 ; BREAK ADDRESS .DUSR USTCH= 13 ; #T TASKS (LEFT), # CHANS (RIGHT) .DUSR USTCT= 14 ; CURRENTLY ACTIVE TCB .DUSR USTAC= 15 ; START OF ACTIVE TCB CHAIN .DUSR USTFC= 16 ; START OF FREE TCB CHAIN .DUSR USTIN= 17 ; INITIAL START OF NREL .DUSR USTOD= 20 ; OVLY DIRECTORY ADDR .DUSR USTSV= 21 ; FrORTRAN STATE VARIABLE SAVE ROUTINE (OR 0) .DUSR USTRV= 22 ; REVISION ; ENVIRONMENT STATE WORD WHEN EXECUTING .DUSR USTIA= 23 ; TCB ADDR OF INT OR BREAK PROC .DUSR USTEN= USTIA ; LAST ENTRY .DUSR UFPT= 30 ; SAVE SOS ; ENVIRONMENT STATUS BITS (IN yUSTRV DURING EXECUTION) .DUSR ENMAP= 1B0 ;MAPPED MACHINE .DUSR ENUEC= 1B2 ;UNMAPPED ECLIPSE .DUSR ENMEC= 1B3 ;MAPPED ECLIPSE .DUSR ENUNV= 1B4 ;UNMAPPED NOVA .DUSR ENMNV= 1B5 ;MAPPED NOVA .DUSR ENUN3= 1B6 ;UNMAPPED NOVA 3 .DUSR ENMN3= 1B7 ;MAPPED NOVA 3 .DUSR ENUMN= 1B8 ;UNMAPPED MICRO NOVA .DUSR ENDOS= 1B11 ;DOS SYSTEM .DUSR ENINFO= 1B12 ;INFOS SYSTEM .DUSR ENSOS= 1B13 ;STAND ALONE SYSTEM .DUSR ENRTOS= 1B14 ;RTOS SYSTEM .DUSR ENRDOS= 1B15 ;RDOS SYSTEM ; ; TASK CONTROL BLOCK (TCB) TEMPLATE ; .DUSR TPC= 0 ;USER PC (B0-14) + CARRY (B15) .DUSR TAC0= 1 ;AC0 .DUSR TAC1= 2 ;AC1 .DUSR TAC2= 3 ;AC2 .DUSR TAC3= 4 ;AC3 .DUSR TPRST= 5 ;STATUS BITS (LEFT) + PRIORITY (RIGHT) .DUSR TSYS= 6 ;SYSTEM CALL WORD .DUSR TLNK= 7 ;LINK WORD .DUSR TUSP= 10 ;USP .DUSR TELN= 11 ;TCB EXTENSION ADDR .DUSR TID= 12 ;TASK ID .DUSR TTMP= 13 ;SCHEDULER TEMPORARY .DUSR TKLAD= 14 ;USER KILL PROC ADDR .DUSR TSP= 15 ;STACK POINTER .DUSR TFP= 16 ;FRAME POINTER .DUSR TSL= 17 ;STACK LIMIT .DUSR TSO= 20 ;OVERFLOW ADDR .DUSR TLN=TKLAD-TPC+1 ;SHO1RT TCB LENGTH .DUSR TLNB= TSO-TPC+1 ;LONG TCB LENGTH ; TASK STATUS BITS (IN TPRST) .DUSR TSSYS= 1B0 ;SYSTEM BIT .DUSR TSSUSP= 1B1 ;SUSPEND BIT .DUSR TSXMT= 1B2 ;XMT/REC AND OVERLAY BIT .DUSR TSRDOP= 1B3 ;.TRDOP BIT .DUSR TSABT= 1B4 ;ABORT LOCK BIT .DUMSR TSRSV= 1B5 ;RESERVED .DUSR TSUPN= 1B6 ;USER PEND BIT .DUSR TSUSR= 1B7 ;USER FLAG BIT ; ; OVERLAY DIRECTORY ; .DUSR OVNDS= 0 ;NUMBER OF NODES ; FOR EACH NODE: .DUSR OVRES= 1 ;CURRENT OVLY(B0-7), USE COUNT(B8-15) .DUSR OVDIS= 2 ;# OVLYS (B0-7), LOADINfG BIT (B8), ; SIZE IN BLKS (B9-15) .DUSR OVBLK= 3 ;STRT BLK # IN OVLY FILE FOR FIRST OVLY .DUSR OVNAD= 4 ;CORE ADDR FOR NODE(B1-15) ; 1B0 FLAGS VIRTUAL NODE ; ; USER TASK QUEUE TABLE ; .DUSR QPC= 0 ;STARTING PC .DUSR QNUM= 1 ;NUMBER OF TIMES TO EXEC .DUSR QTOV= 2 ;OVERLAY .DUSR QSH= 3 ;STARTING HOUR .DUSR QSMS= 4 ;STARTING SEC IN HOUR .DUSR QPRI= TPRST ;MUST BE SAME .DUSR QRR= 6 ;RERUN TIME INC IN SEC .DUSR QTLNK= TLNK ;MUST BE SAME .DUSR QOCH= 10 ;CHAN OVERLAYS OPEN ON .DUSR QCOND= 11 ;TYPE OF LOAD .DUSR QAC2= 12 ;WAKEUP AC2 ; 1B0= LOADING, 1B15= DEQUE REQ REC .DUSR QTLN= QAC2-QPC+1 .DUSR QPEX= QTLN ;USER TASK Q AREA EXTENSION ; ; USER PROGRAM TABLE FOR OPERATOR COMMUNICATIONS PACKAGE ; .DUSR LPN= 0 ;PROGRAM NUMBER .DUSR LOV= 1 ;OVERLAY NUMBER OR -1 .DUSR LCOND= 2 ;CONDITIONAL/UNCONDITIONAL LOAD .DUSR LTPR= 3 ;TASK ID (LEFT) + PRIORITY (RIGHT) .DUSR LPC= 4 ;PROGRAM COUNTER .DUSR LTLN= LPC-LPN+1 ;TABLE LENGTH .DUSR LPEX= LTLN ;COMMUNICATIONS EXTENSION AREA START ; ; TUNING FILE DISPLACEMENBTS ; .DUSR .TUN=0 ;OFFSET TO NUMBER WORD IN PAIR .DUSR .TUC=.TUN+1 ;OFFSET TO 1ST COUNT IN PAIR .DUSR .TUP=.TUC+2 ;OFFSET TO 2ND COUNT OF PAIR .DUSR .TUNX=.TUP+2 ;LENGTH OF COUNT PAIR .DUSR .TUNSTK=1 ;NUMBER STACKS IN SYSTEM .DUSR .TUSTK= .TUNSTK+.TUC-#.TUN ;STACK COUNT .DUSR .TUPSTK=.TUNSTK+.TUP-.TUN ;STACK PEND COUNT .DUSR .TUNCEL=.TUNSTK+.TUNX ;NUMBER CELLS IN SYSTEM .DUSR .TUCEL= .TUNCEL+.TUC-.TUN ;CELLS COUNTS .DUSR .TUPCEL=.TUNCEL+.TUP-.TUN .DUSR .TUNBUF=.TUNCEL+.TUNX ;BUFFERS, EXCLUDING TUNING BͽUFFERS .DUSR .TUBUF= .TUNBUF+.TUC-.TUN ;COUNTS .DUSR .TUPBUF=.TUNBUF+.TUP-.TUN .DUSR .TUNOV= .TUNBUF+.TUNX ;OVERLAYS .DUSR .TUOV= .TUNOV+.TUC-.TUN .DUSR .TUPOV= .TUNOV+.TUP-.TUN .DUSR TULEN=.TUNOV+.TUNX RDOS.SR 5 !; RDOS.SR ; NOVA RDOS SWITCHES ?NSW= 1 ; NOVA ONLY SWITCH ?N3SW= 1 ; NOVA 3 SWITCH ?ANSW= ?NSW!?N3SW ; ANY NOVA SWITCH ?BSW= 0 ; BIRD SWITCH ?ABSW= ?BSW ; ANY BIRD SWITCH ?RDOS= 1 ; RDOS SYSTEM SWITCH ?INFOS= 1-?RDOS ; INFOS SYSTEM SWITCH N]?MSW= 0 ; NOVA 840 MAP SWITCH N3?MSW= 0 ; NOVA 3 MAP SWITCH B?MSW= 0 ; SMALL BIRD MAP (128K) SWITCH BB?MSW= 0 ; BIG BIRD MAP (256K) SWITCH ?MSW= N?MSW!N3?MSW!B?MSW!BB?MSW ; MAPPED SYSTEM SWITCH ?USW= 1-?MSW ; UNMAPPED SYSTEM SWITCH NSW= ?USW&?N1SW ; NOVA SWITCH N3SW= ?USW&?N3SW ; NOVA 3 SWITCH BSW= ?USW&?ABSW ; BIRD SWITCH MNSW= ?MSW&?NSW ; MAPPED NOVA SWITCH MN3SW= ?MSW&?N3SW ; MAPPED NOVA3 SWITCH MBSW= ?MSW&?ABSW ; MAPPED BIRD SWITCH ANSW= ?ANSW ; ANY NOVA SWITCH ABSW= ?ABSW ; ANY BIRDl[D SWITCH USW= ?USW ; NOT MAPPED SWITCH MSW= ?MSW ; ANY MAPPED SWITCH IOSW= ?INFOS ; MAPPED IOCS SWITCH PARS.SRB S;====================================== ; RDOS REVISION 06.30 SYSTEM PARAMETERS ;====================================== .TITLE PARS ; ; LINKAGE & STACK STUFF ; .DO ?ANSW .MACRO RSAVE ; CALL TO SAVE REGISTERS STA 3,@CSP JSR @.SAV % .DUSR RiTRN= JSR @4 ; CALL TO RESTORE REGISTERS .DUSR RTLOC= 0 ; RETURN LOCATION (THIS FRAME) .DUSR AC0= 1 ; AC0 .DUSR AC1= 2 ; AC1 .DUSR AC2= 3 ; AC2 .DUSR TMP= 4 ; FIRST TEMPORARY .DUSR MXTMP= TMP+7 ; LAST TEMPORARY .DUSR VRTN= MXTMP+1 ; VIRTUAL RETURN (THIS FRAME) .DUSR SP= -1 ; CURRENT STACK POINTER .DUSR SLGT= VRTN-SP+1 ; STACK FRAME LENGTH .DUSR OSP= -SLGT+SP ; LAST FRAME POINTER .DUSR NSP= SLGT+SP ; NEXT FRAME POINTER .DUSR OTMP= TMP-SLGT ; OLD FIRST TMP POINTER .DUSR OAC0= AC0-SLGT ; OLD AC0 .DUSR OAC1= AC1-SLGT ; OLD AC1 .DUSR OAC2= AC2-SLGT ; OLD AC2 .DUSR ORTN= RTLOC-SLGT ; RETURN LOCATION (PREVIOUS FRAME) .DUSR OVRTN= VRTN-SLGT ; VIRTUAL RETURN (PREVIOUS FRAME) .DUSR NFRAM= 10 ; NUMBER OF SYSTEM STACK FRAMES .DUSR NDSF= 16 ; NUMBER FRAMES ON DP7ISK STACK .DO ?MSW .DUSR SVC= 103510 ; SYSTEM CALL ON NOVA 3 .DUSR SCL= 127510 ; SYSTEM CALL ON NOVA 3 .ENDC .ENDC .DO ?ABSW .MACRO RSAVE ; CALL TO SAVE STATE SAVE ^1+1 ; PLUS 1 FOR OVLY RTN % .DUSR RTRN= RTN ; CALL TO RESTORE STATE " .DUSR OAC0= -4 ; CALLER'S AC0 .DUSR OAC1= -3 ; CALLER'S AC1 .DUSR OAC2= -2 ; CALLER'S AC2 .DUSR OSP= -1 ; CALLER'S CSP .DUSR ORTN= 0 ; RETURN LOCATION .DUSR OVRTN= 1 ; CALLER'S VIRTUAL RETURN .DUSR TMP= 2 ; CALLEE'S FIRST TEMPORARY .DUSR SLGTH= 300  ; SYSTEM STACK LENGTH .DUSR ISLGT= 100 ; INTERRUPT STACK LENGTH .ENDC ; ; PAGE ZERO ; .DO ?ANSW ;.DUSR SYST= 2 ; SYSTEM CALL ADDRESS ;.DUSR NSTOV= 3 ; NOVA STACK OVER FLOW VECTOR ;.DUSR .RTN= 4 ; ADDRESS OF RETURN ROUTINE .DUSR CC= 5 ; CURRENT CELL z_.DUSR RLOC= 6 ; PAGE ZERO TEMP. .DUSR .SAV= 7 ; ADDRESS OF SAVE ROUTINE .DUSR CSP= 10 ; STACK POINTER .DUSR .PNIC= 11 ; PANIC ;.DUSR USTP= 12 ; USTP DEFINED IN PARU .DUSR CQ= 13 ; CURRENT TASK QUEUE .DUSR CRSEG= 14 ; PTR TO OVERLAY TABLE ENTRY .DUSR CMSK= t15 ; CURENT MASK .DUSR HRBEG= 40 ; START OF HARDWARE RESERVED AREA ; DEFINED IN NSID.SR ;.DUSR TRPC= 46 ; INSTRUCTION TRAP PC FOR NOVA 3 ;.DUSR TRHN= 47 ; INSTRUCTION TRAP HANDLER FOR NOVA 3 ;.DUSR CSL= 42 ; STACK LIMIT FOR NOVA 3 ;.DUSR CSO= 43 ; STACK OVERFLOW HANDLER FOR NOVA 3 .ENDC .DO ?ABSW ; HARDWARE RESERVED LOCATIONS .DUSR HRBEG= 40 ; START OF HARDWARE RESERVED AREA ; DEFINED IN NEID.SR ;.DUSR SP= 40 ; STACK POINTER ;.DUSR CSP= 41 ; FRAME POINTER (LOGICAL STACK PTR) ;.DUSR CSL= 42 ; STACK LIMIhT ;.DUSR CSO= 43 ; STACK OVERFLOW ROUTINE PTR ;.DUSR XOPA= 44 ; XOP ORIGIN ADDRESS ;.DUSR FPFA= 45 ; FLOATING POINT FAULT ADDRESS ; ;; DEFINE OFFSETS FOR PAGE 0 INT STK LOCATIONS ;.DUSR ISP= 4 ; SKP SP ;.DUSR CMSK= 5 ; CURRENT MASK ;.DUSR ISL= 6 ; LIMIT ;.TDUSR ISO= 7 ; OVERFLOW ADDR ; OTHER PAGE ZERO LOCATIONS ; LOCATION 12 IS USTP (DEFINED IN PARU) ; LOCATION 2 IS THE SYSTEM ENTRY POINT ; LOCATION 3 IS THE PROTECTION FAULT ROUTINE POINTER .DUSR CC= 10 ; CURRENT CELL .DUSR .PNIC= 11 ; PANIC .DUSR CQ= 13 ; sCURRENT TASK QUEUE .DUSR CRSEG= 14 ; CURRENT OVERLAY SEGMENT .ENDC .DO ?ANSW ; ; DEFINE DISPLACEMENTS IN INTERRUPT SAVE AREA ; .DUSR IPCC= TMP ; PC & CARRY .DUSR IAC0= TMP+1 ; AC0 .DUSR IAC1= TMP+2 ; AC1 .DUSR IAC2= TMP+3 ; AC2 .DUSR IAC3= TMP+4 ; AC3 .GDUSR ICMSK= TMP+5 ; CURRENT MASK .DUSR IRLOC= TMP+6 ; RLOC .DUSR INTUS= TMP+7 ; MAPPED STATE OF THE USER MAP .ENDC ; ; SHORT CUT SUBROUTINE ENTRY & EXIT: ; .DO ?ABSW .MACRO RPSHR ;SAVE RETURN FOR A PARASITING SUBROUTINE PSH 3,3 ;SAVE RETURN % .MAxCRO RPOPJ ;COMPLEMENTARY EXIT POPJ ;RETURN % .ENDC .DO ?ANSW .MACRO RPSHR STA 3,@CSP % .MACRO RPOPJ JMP @0,3 ; STACK POINTER MUST BE IN AC3 % .ENDC .DO ?INFOS ; DEFINE IOCS MAPPED ADDR SPACE .DUSR IDYSZ= 8. ;# DYNAMIC SLOTS .DUSR ISMSZ=[ 28. ;# STATIC SLOTS .DUSR IQVEC= 8. ;QUEUE VECTOR OF WINDOW DESIGNATORS .ENDC .DUSR SGCA=0 ;SOME KIND OF OVERLAY TABLE DISPLACEMENT ; MAP REGISTERS BIT DEFINITIONS .DO N?MSW ; 830/840 NOVA MAP  ; MAP STATUS OUTPUT WORD (DOA AC,MAP) .DUSR MPSTS= 176000 ; PROTECTION AND DCH ON .DUSR MPSIM= MPSTS ; INITIAL MAP STATE WORD .DUSR MPSU1= MPSTS ; PT1 MAP STATE WORD FOR PT .DUSR MPSU2= MPSTS ; PT2 MAP STATE WORD FOR PT .DUSR MPSA1= MPSTS ; ACCESS USER PT1 MAP .DUSR MPSA2= MPSTS ; ACCESS USER PT2 MAP ; MAP ADDRESS TRANSLATION DESCRIPTION WORD (DOA AC,MAP) .DUSR MPALG= 37B7 ; LOGICAL PAGE ADDRESS .DUSR MPAPH= 177 ; PHYSICAL PAGE NUMBER .DUSR MPAWP= 1B8 ; WRITE PROTECT PAGE .DUSR MPADC= 1B2 ; DATA CHANNEL ADDR. TRAN. .DUSR MPAU1= MPAPH!MPAWP ; PT1 UNUSED MAP ENTRY .DUSR MPAU2= MPAU1 ; PT2 UNUSED MAP ENTRY .DUSR MPAIN= 1B7 ; LOGICAL PAGE INCREMENT .DUSR MPAM1= 0 ; PT1 MAP ENTRY FIXED BITS .DUSR MPAM2= 0 ; PT2 MAP ENTRY FIXED BITS .DUSR MPAMD= MPADC ; DATA CHANNEL MAP FIXED BITS ; DEVICE PROTECT WORD (DOA AC,MAP) .DUSR MPDVP= 1B1 ; DEVICE PROTECT WORD .DUSR MPDDV= 377 ; DEVICE BITS .DUSR MPDCL= 7B7 ; DEVICE CLASS (0X-7X) .DUSR MPDI1= MPDVP!MPDDV ; INITIAL ALL DEVS PROTECT PT1 .DUSR MPDI2= MPDI1 ; AND PT2 .DUSR MPDIN= 1B7 ; DEVICE CLWASS INCREMENT ; MAP LAST BLOCK INITIAL WORD BEFORE PHYSICAL ADDRESS PUT IN ; (DOA AC,MAP) .DUSR MPLBK= MPALG .ENDC .DO N3?MSW ; NOVA 3 MAP ; MAP STATUS OUTPUT WORD (DOA AC,MAP) .DUSR MPSTS= 40112 ; PROTECTION AND DCH MAP ON .DUSR MPSEN= 1B0 ; MAPa TURN ON BIT .DUSR MPSSY= 0B15 ; ADDRESS SYSTEM MAP .DUSR MPSUS= 1B15 ; ADDRESS USER MAP .DUSR MPSPS= 0B10 ; SET SO PULSE ACCESS SYSTEM .DUSR MPSPU= 1B10 ; SET PULSE TO USER .DUSR MPSIO= 1B13 ; DISALLOW DEVICE ACCESS .DUSR MPSIM= MPSTS!MPSPU ; INITIAKGL MAP STATE WORD .DUSR MPSU1= MPSTS!MPSEN!MPSUS!MPSPU!MPSIO ; PT1 MAP STATE .DUSR MPSU2= MPSU1 ; WORD AND PT2 .DUSR MPSA1= MPSTS!MPSUS!MPSPU ; ACCESS PUT DON'T TURN ON .DUSR MPSA2= MPSA1 ; PT1 AND PT2 MAPS ; ADDRESS TRANSLATION DESCRIPTION WORD (DOA A=EC,MAP) .DUSR MPALG= 37B5 ; LOGICAL PAGE NUMBER .DUSR MPAPH= 377 ; PHYSICAL PAGE NUMBER .DUSR MPAWP= 1B7 ; WRITE PROTECT PAGE .DUSR MPASY= 0B6 ; TRAN FOR SYSTEM MAP .DUSR MPAUS= 1B6 ; TRAN FOR USER MAP .DUSR MPADC= 1B0 ; TRAN FOR DCH MAP .DUSR MPAU1c= MPAPH!MPAWP!MPAUS ; PT1 UNUSED MAP ENTRY .DUSR MPAU2= MPAU1 ; PT2 UNUSED MAP ENTRY .DUSR MPAIN= 1B5 ; LOGICAL PAGE INCREMENT .DUSR MPAM1= MPAUS ; PT1 MAP ENTRY FIXED BITS .DUSR MPAM2= MPAM1 ; PT2 MAP ENTRY FIXED BITS .DUSR MPAMD= MPADC ; DATA CHANNEL MAP FIXED BITS ; DEVICE PROTECT WORDS IN PT, CONTAINS ONE BIT FOR EACH DEVICE ; WHEN ONE IS ENABLED THEN USER DEVICE ACCESS IS ALLOWED.  .DUSR MPDI1= 377 ; INITIAL ALL DEVS PROTECT PT1 .DUSR MPDI2= MPDI1 ; AND PT2 .DUSR MPDIN= 0 ; DEVICE CLASS INC+REMENT ; MAP LAST BLOCK INITIAL WORD BEFORE PHYSICAL ADDRESS PUT IN ; (DOA AC,MAP) .DUSR MPLBK= MPALG!MPASY .ENDC .DO B?MSW ; SMALL BIRD MAP (128K) ; MAP STATUS OUTPUT WORD (DOA AC,BMAP) .DUSR MPSTS= 76 ; PROTECTION AND DCH ON .DUSR MPSEN= 1B15 ;AY MAP ENABLE .DUSR MPSUA= 0B2 ; ACCESS MAP A .DUSR MPSUB= 1B2 ; ACCESS MAP B .DUSR MPSLF= 1B9 ; ACTIVATE SHORT LEFS .DUSR MPSIM= MPSTS ; INITIAL MAP STATE WORD .DUSR MPSU1= MPSTS!MPSEN!MPSUB ; PT1 MAP STATE WORD FOR PT .DUSR MPSU2= MPSTS!MPSEN!MPSUA ;9 PT2 MAP STATE WORD FOR PT .DUSR MPSA1= MPSTS!MPSUB ; ACCESS USER PT1 MAP .DUSR MPSA2= MPSTS!MPSUA ; ACCESS USER PT2 MAP ; MAP ADDRESS TRANSLATION DESCRIPTION WORD (DOA AC,BMAP) .DUSR MPALG= 37B5 ; LOGICAL PAGE ADDRESS .DUSR MPAPH= 177 ; PHYSICAL PAGE` NUMBER .DUSR MPAWP= 1B8 ; WRITE PROTECT PAGE .DUSR MPAUA= 2B7 ; MAP A ADDR. TRAN. .DUSR MPAUB= 3B7 ; MAP B ADDR. TRAN. .DUSR MPADC= 1B7 ; DATA CHANNEL ADDR. TRAN. .DUSR MPAU1= MPAPH!MPAWP!MPAUB ; PT1 UNUSED MAP ENTRY .DUSR MPAU2= MPAPH!MPAWP!MPAUA ; p}PT2 UNUSED MAP ENTRY .DUSR MPAIN= 1B5 ; LOGICAL PAGE INCREMENT .DUSR MPAM1= MPAUB ; PT1 MAP ENTRY FIXED BITS .DUSR MPAM2= MPAUA ; PT2 MAP ENTRY FIXED BITS .DUSR MPAMD= MPADC ; DATA CHANNEL MAP FIXED BITS ; DEVICE PROTECT WORD (DOA AC,BMAP) .DUSR MPDVP= 1B1 ; DEVICE PROTECT WORD .DUSR MPDDV= 377 ; DEVICE BITS .DUSR MPDCL= 7B5 ; DEVICE CLASS (0X-7X) .DUSR MPDUA= 0B2 ; MAP A PROTECT WORD .DUSR MPDUB= 1B2 ; MAP B PROTECT WORD .DUSR MPDI1= MPDVP!MPDDV!MPDUB ; INITIAL ALL DEVS PROTECT PT1 .DUSR MPDDI2= MPDVP!MPDDV!MPDUA ; AND PT2 .DUSR MPDIN= 1B5 ; DEVICE CLASS INCREMENT ; MAP LAST BLOCK INITIAL WORD BEFORE PHYSICAL ADDRESS PUT IN ; (DOB AC,BMAP) .DUSR MPLBK= 0 .ENDC .DO BB?MSW ; BIG BIRD MAP ((1K)K) ; MAP STATUS OUTPUT WORD (DOA AC,BMAP) .DUSR MPSTS= 32 ; PROTECTION AND DCH ON .DUSR MPSEN= 1B15 ; MAP ENABLE .DUSR MPSUA= 0B8+0B13 ; ACCESS MAP A .DUSR MPSUB= 2B8+1B13 ; ACCESS MAP B .DUSR MPSDC= 4B8 ; ACCESS DCH MAP .DUSR MPSIO= 1B10 ; DON'T ALLOW ACCESS TO DEVICES .DUSR MPSLF= 1B9 ; ACTIVfATE SHORT LEFS .DUSR MPSIM= MPSTS ; INITIAL MAP STATE WORD .DUSR MPSU1= MPSTS!MPSEN!MPSIO!MPSUB ; PT1 MAP STATE WORD FOR PT .DUSR MPSU2= MPSTS!MPSEN!MPSIO!MPSUA ; PT2 MAP STATE WORD FOR PT .DUSR MPSA1= MPSTS!MPSUB ; ACCESS USER PT1 MAP .DUSR MPSA2= MPSTS!MPSUA ; ACCESS USER PT2 MAP ; MAP ADDRESS TRANSLATION DESCRIPTION WORD (LMP) .DUSR MPALG= 37B5 ; LOGICAL PAGE ADDRESS .DUSR MPAPH= 1777 ; PHYSICAL PAGE NUMBER .DUSR MPAWP= 1B0 ; WRITE PROTECT PAGE .DUSR MPAU1= MPAPH!MPAWP ; PT1 UNUSED MAP ENTRY .DUSR MPAU2= MPAPH!MPAWP ; PT2 UNUSED MAP ENTRY .DUSR MPAIN= 1B5 ; LOGICAL PAGE INCREMENT .DUSR MPAM1= 0 ; PT1 MAP ENTRY FIXED BITS .DUSR MPAM2= 0 ; PT2 MAP ENTRY FIXED BITS .DUSR MPAMD= 0 ; DATA CHANNEL MAP FIXED BITS ; DEVICE PROTECT WORDS IN PT, C+ONTAINS ONE BIT FOR EACH DEVICE ; WHEN ONE IS ENABLED THEN USER DEVICE ACCESS IS ALLOWED. .DUSR MPDI1= 377 ; INITIAL ALL DEVS PROTECT PT1 .DUSR MPDI2= MPDI1 ; AND PT2 .DUSR MPDIN= 0 ; DEVICE CLASS INCREMENT ; MAP LAST BLOCK INITIAL WORD BEFORE PHYSICA[L ADDRESS PUT IN ; (DOB AC,BMAP) .DUSR MPLBK= 0 .ENDC ; ; BUFFER ENTRY ; .DUSR BQCYL= -15 ; CYLINDER FOR DKP .DUSR BQTLA= -14 ; TIME LAST ASSIGNED ( 0 = USE ME FIRST) .DUSR BQUSC= -13 ; COUNT OF BUF USERS .DUSR BQDCB= -12 ; DCB ADDRESS .DUSR BQQLK= -11 ; DEVICE REQUEST Q .DUSR BQDST= -10 ; (HEAD,SECTOR,UNIT,COUNT FOR DKP) .DUSR BQERC= -7 ; ERROR COUNT .DUSR BQST= -6 ; STATUS WORD .DUSR BQDCT= -5 ; DCT ADDRESS .DUSR BQUN= -4 ; UNIT NUMBER .DUSR BQCA1= -3 ; CURRENT BLOCK DEVICE ADDRESS (HIGH ORDER) .DUpSR BQCA= -2 ; CURRENT BLOCK DEVICE ADDRESS (HIGH ORDER) .DUSR BQNXT= -1 ; LINK TO NEXT BUFFER .DUSR BQBF= 0 ; START OF DATA .DUSR BQNXL= 377 ; LINK WORD/FILE NUMBER .DUSR BQXTA= 400 ; XTRA WORD .DUSR BQHDL= -BQCYL+1 ; HEADER LENGTH .DUSR BQEL= BQXTA+BQHDLB- ; ENTRY LENGTH ; ; DEFINE BUFFER STATUS ; .DUSR QTMOD= 1B15 ; BUFFER MODIFIED .DUSR QTER= 1B14 ; ERROR DETECTED .DUSR QTIOP= 1B12 ; I/O IN PROGRESS .DUSR QTDSU= 1B11 ; BUFFER HAS DEVICE SET UP .DUSR QTIND= 1B10 ; INDIRECT MODE (ADDRESS IN BQNXT) .DUSR QTEMD= 1B09 ; ERROR MODE (MAG TAPE) .DUSR QTCT= 1B08 ; CONTIGUOUS FILE .DUSR QTLKI= 1B07 ; LOCK IN PROGRESS (IPB) .DUSR QTEXI= 1B06 ; I/O IS TO EXTENDED MEMORY ARRAY (MAPPED ONLY) .DUSR QTSIO= 1B05 ; SPECIAL MODE DISK IO FLAG .DUSR QTNBAD= 1B04 ; INHIBIT B7AD BLOCK MAPPING & REALLOCATION .DUSR QTLKW= 1B0 ; LOCK WAITING (IPB); REFERENCED NON- ; SYMBOLICALLY BY BUFFER RELEASE ROUTINES ; ; FOR FAKE BUFFER HEADERS ; .DUSR BQADR= -1 ; ADDRESS OF CORE BUFFER .DUSR BQUST= 0 ; USER STATUS WORD .DUSR BQNBK= 1}= ; # OF BLOCKS TO MOVE .DUSR BQARD= 2 ; ARRAY ADDR - POINTS TO BQNBK WORDS .DUSR BQSCT= BQARD ; # OF SECTORS FOR CONTIGUOUS I/O ; ; DEVICE CONTROL BLOCK (ACTUALLY A FILE CONTROL BLOCK) ; .DUSR DCBDC=UFTDC-UFTDC ;DCT ADDRESS .DUSR DCBUN=UFTUN-UFTDC ;UNIT NUMBER .DUSR DBCA1=UFCA1-UFTDC ;CURRENT BLOCK ADDRESS (HIGH ORDER) .DUSR DCBCA=UFTCA-UFTDC ;CURRENT BLOCK ADDRESS (LOW ORDER) .DUSR DCBCB=UFTCB-UFTDC ;CURRENT BLOCK NUMBER .DUSR DCBST=UFTST-UFTDC ;STATUS .DUSR DCBUC=UFEA1-UFTDC ;USER COUNT .DUSR DCBPD=UFTEA-UFTDC ;PAD .DUSR DBNA1=UFNA1-UFTDC ;NEXT ADDRESS (HIGH ORDER) .DUSR DCBNA=UFTNA-UFTDC ;NEXT ADDRESS (LOW ORDER) .DUSR DBLA1=UFLA1-UFTDC ;LAST ADDRESS (HIGH ORDER) .DUSR DCBLA=UFTLA-UFTDC ;LAST ADDRESS (LOW ORDER) .DUSR DCBDR=UFTDR-UFTDC ;SYS.2DR DCB POINTER .DUSR DBFA1=UFFA1-UFTDC ;FIRST ADDRESS (HIGH ORDER) .DUSR DCBFA=UFTFA-UFTDC ;FIRST ADDRESS (LOW ORDER) ; ; DEFINE SYSTEM FILE DCB OFFSETS ; .DUSR SFMSZ= -14 ;DIRECTORY FRAME SIZE .DUSR SFLNA= -13 ; LOGICAL NAME OFFSET .DUSR SFKEY= -6 ; DEhVICE KEY (FIRST WORD) .DUSR SFKY1= -5 ; DEVICE KEY (SECOND WORD) .DUSR SFLK= -4 ; MAP.DR LINK (-1 IF NOT DISK) .DUSR SFNX= -3 ; NEXT ENTRY IN CHAIN .DUSR SFBK= -2 ; NUMBER OF LAST LOGICAL BLOCK .DUSR SFBC= -1 ; BYTES IN LAST BLOCK .DUSR SFDCB= 0 ; DCB ENTRY .DUSR SFEL=DCBFA-SFKEY+1 ;ENTRY LENGTH .DUSR SFTYPE=SFEL+SFLK ;TYPE WORD: 0=PRIMARY, 1=2NDARY PARTITION, ; -1=SUBDIRECTORY .DUSR MPLCK=SFNX ;MAP LOCK WORD: ; 0 IF UNLOCKED, ; PTR TO CELL WHILE THIS SIDE IS IN PROCESS OF LOCKING BOTH SIDES, ; -1 IF L`~OCKED BY THIS SIDE, ; 1B0 SET IF LOCKED BY OTHER SIDE ; ; DEFINE FILE STATUS ; .DUSR STER= 1B15 ; ERROR DETECTED .DUSR STIOP= 1B14 ; I/O IN PROGRESS .DUSR STFWR= 1B13 ; FIRST WRITE FLAG .DUSR STDIU= 1B12 ; DIRECTORY IN USE ; 1B11 IS ANOTHER DIRECTORY IN "USE BIT .DUSR STUTP= 1B10 ;UFT PROTECTED FROM CHATR CHLAT SPOS ; (QTY AND MCA) .DUSR STRWD= 1B09 ; OPENED FOR MTA R/W BLOCK .DUSR ST7T= 1B08 ; 7 TRACK MAG TAPE .DUSR STLKW = ST7T ;LOCK WAITING (IPB) FOR MAP DCB .DUSR STMOD= 1B07 ;FILE HAS BEEN WRITTENN TO .DUSR STTOPN= 1B06 ;FILE TRANSPARENTLY OPENED .DUSR STEOT= 1B05 ; PHYSICAL END OF MAG TAPE .DUSR STIOI= 1B03 ; INIT'D BY IOCS .DUSR STOPN= 1B02 ; DCB OPENED (MTA) .DUSR STINI= 1B01 ; NO INIT FLAG .DUSR STCMK= 1B00 ; SET = READ (BLKIO) ; INIT/RELEASE BIT ; ;FORMAT OF DISK BAD BLOCK MAP TABLE, AS IT RESIDES IN BLOCK 4: ; .DUSR BALEN= 0 ;NUMBER OF WORDS USED FOR THIS TABLE .DUSR BASTART=1 ;BASE OF REALLOCATION AREA (DOUBLE-WORD) .DUSR BASIZE= 3 ;SIZE OF THAT AREA, IN BLOCKS .DUSR BALIST= 4 ;START OF OR7DERED LIST OF BAD BLOCK ; ADDRESSES (DOUBLE-WORDS), POSITION INDICATING WHICH ; BLOCK OF REALLOCATION AREA TO USE ; ;BAD TABLE ENTRY IN CORE - FOR MORE COMPLETE INFORMATION, ; REFER TO DESCRIPTION ACCOMPANYING GBLKNO & FIXWRITE ; .DUSR BEUNI=0 ;LINK TXO UNIT DEVICE CONTROL BLOCK .DUSR BEHSZ=1 ;HEADER SIZE .DUSR BELEN= BALEN+BEHSZ ;IMAGE OF DISK'S TABLE .DUSR BESTART=BASTART+BEHSZ .DUSR BESIZE= BASIZE+BEHSZ .DUSR BELIST= BALIST+BEHSZ .DUSR BEXSZ=BEHSZ+1 ;SIZE OF HEADER + LINK WORD AT END OF ENTRY .DUSR BLLK=2 ;LINK WORD IN A LINK (FOLLOWS DOUBLE-WORD ADDRESS) .DUSR BLSZ=3 ;SIZE OF A LINK ; ; DEFINE THE COMMAND OFFSETS ; .DUSR OF= 0 ; OPEN A FILE .DUSR CF= 1 ; CLOSE A FILE .DUSR RS= 2 ; READ SEQUENTIAL .DUSR RL= 3 ; READ LINE .DUSR RR= 4 ; READ RANDOM .DUSR WS= 5 ; WRITE SEQUENTIAL .DUSR WL= 6 ; WRITE LINE .DUSR WR= 7 ; WRITE RANDOM .DUSR OA= 10 ; OPEN FOR APPENDING .DUSR RO= 11 ; OPEN FOR READING ONLY .DUSR EO= 12 ; EXCLUSIVE READ/WRITE OPEN .DUSR TO= 13 ; TRANSPARENT (EXCLUSIVE) OPEN ; ; DCT )PARAMETERS. ; ; DEFINED IN PARU.SR ;.DUSR DCTBS=0 ;=3B1 => DEVICE USES DATA CHANNEL ;.DUSR DCTMS=1 ;MASK OF LOWER PRIORITY DEVICES ;.DUSR DCTIS=2 ;ADDRESS OF INTERRUPT SERVICE ROUTINE .DUSR DCTCH=3 ;DEVICE CHARACTERISTICS .DUSR DCTCD=4 ;DEVICE CODE .1LDUSR DCTEX=5 ;WHERE TO EXECUTE I/O INSTRUCTIONS .DUSR DCTDT=6 ;COMMAND ENABLE DISPATCH TABLE ;1B0=1 => DEVICE IS A DISK .DUSR DCTST=7 ;DEVICE STARTUP ROUTINE .DUSR DCTBC=10 ;SIZE OF DEVICE BUFFER IN BYTES .DUSR DCTBP=11 ;POINTER TO DEVICE BUFFER .}3DUSR DCTPC=12 ;RESTART CONSTANT .DUSR DCTPP=13 ;PROGRAM BYTE POINTER .DUSR DCTQL=14 ;LINK TO DEVICE REQUEST BEAD CHAIN .DUSR DCTDP=15 ;DEVICE BYTE DATA POINTER .DUSR DCTDC=16 ;DEVICE DATA COUNT .DUSR DCTQS=17 ;BEAD STATUS WORD .DUSR DCTBD=20 ;BEAD Aj6DDRESS (.-4) .DUSR DCTQP=21 ;DEVICE QUEUE STARTING ADDRESS .DUSR DCTT1=22 ;TEMP 1 FOR DEVICE CONTROL .DUSR DCTT2=23 ;TEMP 2 FOR DEVICE CONTROL .DUSR DCTTO=24 ;TIME OUT/TIME IN CONSTANT .DUSR DCTCC=25 ;COLUMN COUNTER (OUTPUT DEVICE) .DUSR DCTLC=26 ;LI]NE COUNTER (OUTPUT DEVICE) .DUSR DCTPR=25 ;ECHO DEVICE PAIR POINTER (TTI ONLY) .DUSR DCTLK=26 ;LINK TO TTR (TTI ONLY) .DUSR DCTON=27 ;ON DCB ADDRESS FOR SPOOLER .DUSR DCTOF=30 ;OFF DCB ADDRESS FOR SPOOLER .DUSR DCTSL=31 ;LINK TO SPOOL DCT'S .DUSR DCTO0P=32 ;DEVICE QUEUE STARTING ADDRESS FOR OP MESSAGES .DUSR DCTT3=33 ;TEMP FOR OP MESSAGE STATUS .DUSR DCTLS=32 ;LAST STATUS OF DATA CHANEL CHARACTER DEVICE .DUSR DCTBX=33 ;NUMBER OF CHARS LAST TRIED TO TRANSFER .DUSR DCHMC=34 ;FIRST SLOT IN DATA CHANN5EL MAP .DUSR DCHNC=35 ;NUMBER OF SLOTS NEEDED IN MAP ; ; DEFINE THE BEAD DISPLACEMENTS ; .DUSR RQLK= 0 ;REQUEST LINK .DUSR RQPTR= 1 ;REQUEST BYTE POINTER .DUSR RQCNT= 2 ;RUNNING BYTE COUNT .DUSR RQST= 3 ;REQUEST STATUS WORD .DUSR RQCC= 4 ;REQUEST TCB ADLDRESS (FOR RDOPR) .DUSR RQP1= 5 ;BYTE POINTER TO USER AREA (FOR RDOPR) .DUSR RQBCT= 6 ;# BYTES READ ; BEAD STATUS BITS IN RQST AND DCTQS .DUSR BSUPE=1B0 ;UNPEND ON ANY CHARACTER AND CLEAR FLAG .DUSR BSUPC=1B1 ;UNPEND ON REQUEST COMPLETION .DUSR BSFCD5I=1B2 ;FOREGROUND CONSOLE DEVICE .DUSR BSBCD=1B3 ;BACKGROUND CONSOLE DEVICE .DUSR BSFOP=1B4 ;FOREGROUND OPER MESSAGE .DUSR BSBOP=1B5 ;BACKGROUND OPER MESSAGE .DUSR BSDOP=1B6 ;DEVICE HAS BEEN OPENED .DUSR BSFBF=1B6 ;FREE BUFFER ON REQUEST COMPLETEION .ÑDUSR BSOBG=1B7 ;OPEN TO BACKGROUND .DUSR BSOFG=1B8 ;OPEN TO FOREGROUND .DUSR BSQIT=1B9 ;THE QUIET BIT .DUSR BSIOC=1B10 ;IOCS CALL .DUSR BSRDL=1B11 ;.RDL MODE ($CDR ONLY) .DUSR BSLPA=1B12 ;LAPPABLE BUFFER .DUSR BSLPD=1B13 ;BUFFER IS IN LAPPED MODE .DUSR BSCTS=1B14 ;CONTROL-S IN EFFECT ON OUTPUT DEVICE .DUSR BSECH=1B14 ;ECHO MODE (TTI ONLY) .DUSR BSEOF=1B14 ;EOF ($CDR ONLY) .DUSR BSDON=1B15 ;REQUEST DONE ; STATUS BITS FOR OPERATOR MESSAGES IN DCTT3 ; 1B0 "!" HAS BEEN RECEIVED ; 1B15 "F" OR "B" HAS BEEN R ECEIVED ; ; COMMON TO BLOCK TRANSFER DEVICE DCTS ; SAME AS CHARACTER SERVICE DCTS ; ;.DUSR DCTBS=0 ;1B0=1 => DEVICE USES DATA CHANNEL ;.DUSR DCTMS=1 ;MASK OF LOWER PRIORITY DEVICES ;.DUSR DCTIS=2 ;ADDRESS OF INTERRUPT SERVICE ROUTINE ;.DUSR DCTCH=3Ϫ ;DEVICE CHARACTERISTICS ;.DUSR DCTCD=4 ;DEVICE CODE ;.DUSR DCTEX=5 ;WHERE TO EXECUTE I/O INSTRUCTIONS ;.DUSR DCTDT=6 ;COMMAND ENABLE DISPATCH TABLE ;1B0=1 => DEVICE IS A DISK ; ; COMMON TO ALL BLOCK TRANSFER DEVICES ; THAT DO NOT USE UNIT DESCRIPTORS ; .DUSR DCSTR=7 ;START DEVICE .DUSR DCDST=10 ;SET DST WORD .DUSR DCCRQ=11 ;CURRENT REQUEST POINTER .DUSR DCHMP=12 ;FIRST SLOT IN DATA CHANNEL MAP .DUSR DCHNM=13 ;NUMBER OF SLOTS NEEDED IN DCH MAP .DUSR DCTPD=14 ; POINTER TO PARENT DCT .DUSR DCTRL=15 ;READ LAST BLOCK .DUSR DCTRD=16 ;READ A BLOCK .DUSR DCTRN=17 ;READ NEXT BLOCK .DUSR DCTIN=20 ;DEVICE INITIALIZATION .DUSR DCTRS=21 ;DEVICE RELEASE .DUSR DCNB1=22 ;NUMBER OF BLOCKS ON DEVICE (HIGH ORDER) .DUSR DCNBK=23 ;NUMBER OF BL5OCKS ON DEVICE (LOW ORDER) ; ; DCT OF BLOCK TRANSFER DEVICE USING ; UNIT DESCRIPTORS ;.DUSR DCTBS=0 ; 1B0 - DEVICE USES DATA CHANNEL ;.DUSR DCTMS=1 ; MASK OF LOWER PRIORITY DEVICES ;.DUSR DCTIS=2 ; ADDRESS OF INTERRUPT SERVICE ROUTINE ; RESERVED 4 ;.DUSR DCTCD=4 ; DEVICE CODE ;.DUSR DCTEX=5 ; WHERE TO EXECUTE I/O INSTRUCTIONS ;.DUSR DCTDT=6 ; 1B0 FOR DISK ELSE 0 ;.DUSR DCSTR=7 ; START DEVICE ;.DUSR DCDST=10 ; SET DST WORD ;.DUSR DCCRQ=11 ; CURRENT REQUEST POINTER ;.DUSR DCHMP=12 ; FIRST SLOT IN DATA CHANNEL MAP ;.DUSR DCHNM=13 ; NUMBER OF SLOTS NEEDED IN DCH MAP ;.DUSR DCTPD=14 ; POINTER TO PARENT DCT ; ***** FIXED-HEAD DISK ADDITION .DUSR DCTFH=15 ; BASE VALUE FOR FIXED HEAD COMMAND QUEUE .DUSR MXBLK=4 ; MAX # OF BLOCKS IN A CONTIG TRANSFER .DUSR MAXPAGE=1 ; MAX # OF PAGES FOR CONTIG TRANSFER ; FORMAT OF 5 WORD COMMAND QUEUE ENTRIES. THERE ARE MXBLK ; SUCH ENTRIES. COMMAND QUEUE VALUES ARE OFFSETS FROM A ; POINTER TO THE COMMAND QUEUE ENTRY. .DUSR DSPAD=0 ; ADDRESS OF DISK BLOCK .DUSR CMDWsJD=1 ; COMMAND WORD FOR FIXED-HEAD DISK .DUSR MEMAD=2 ; CORE BUFFER ADDRESS FOR DATA .DUSR STWD=3 ; STATUS WORD RETURN LOCATION .DUSR USRWD=4 ; USER AVAILABLE WORD (UNUSED) ; ***** ; ; COMMON TO DISK UNIT DESCRIPTORS ; .DUSR DCTUN=0 ; UNIT NUMBER .DI~USR DCTBL=1 ; LINK TO BAD BLOCK TABLE .DUSR DCTBF=2 ; BAD BLOCK TABLE UPDATE FLAG ;.DUSR DCTCH=3 ; DEVICE CHARACTERISTICS ;.DUSR DCTCD=4 ; DEVICE CODE ;.DUSR DCTEX=5 ; WHERE TO EXECUTE IO INSTRUCTIONS ;.DUSR DCTDT=6 ; COMMAND DISPATCH TABLE 1B0=1 FO FOREGROUND DEVICE ; RIGHT BYTE - DEVICE CODE .DUSR UIDCH = 1 ; LH - NUMBER OF SLOTS USED IN DCH MAP ; RH - FIRST ASSIGNED oSLOT IN DCH MAP ; = 0 => NON DATA CHANNEL DEVICE .DO ?ANSW .DUSR UILTH = UIDCH-UIDCD+1 .ENDC .DO ?ABSW ; ;DCT AREA FOR MAPPED BIRDOS ; .DUSR UIDEX = 2 ; COMMON USER DEVICE ROUTINE ADDRESS .DUSR UIMSK = 3 ; DEVICE MASK (COPIED FROM USER DCT) ձ.DUSR UIDIS = 4 ; INTERRUPT SERVICE ROUTINE ADDDRESS ; (IN USER SPACE) .DUSR UIDCT = 5 ; DCT ADDRESS IN USER SPACE .DUSR UILTH = UIDCT-UIDCD+1 .ENDC .ENDC ; ; DEFINE SYSTEM TASK REQUEST CELL DISPLACEMENTS ; .DUSR CATCB=0 ;USER TCB ADDR (MUST UREMAIN AT 0) .DUSR CAC0=1 ;USER AC'S .DUSR CAC1=2 .DUSR CAC2=3 .DUSR CENT=4 ;PROCESSING ENTRY POINT .DUSR CPROG=5 ;PROG PRI + FLAGS .DUSR CENT2=6 ;SECOND PROC ENTRY POINT .DUSR CCHAN=7 ;UFT ADDR .DUSR CTEMP=10 ;UTILITY .DUSR CPTAD=11 ;PROG TABLE BADDR .DUSR CTMP2=12 .DUSR CERR=CTMP2 ;ERROR WORD .DUSR CTMP3=13 .DUSR CTMP4=14 .DUSR CTMP5=15 .DUSR CTMP6=16 .DUSR CLNK=17 ;LINK TO NEXT CELL OR -1 ; TASK REQUEST CELL FLAGS ; B0 - DEV ACTION ; 1B1 - TASK WAKEUP IN MAP MODE .DUSR CLN=CLNK-CATCB+1 ;CELL LENGTH ; ; DEFINE SYSTEM TASK QUEUE DISPLACEMENTS ; .DUSR QSDCP=0 ;POINTER TO QSDCB .DUSR QSUFP=1 ;POINTER TO QSUFT .DUSR QSTKC=2 ;POINTER TO BASE OF TASK'S STACK .DUSR QDCT=3 ;DCT ASSOC WITH QUEUE OR 0 ; ; THE OFFSETS 4-7 ARE RESERVED FOR SYSTEM PROG TABLE ; LOCATIONS WHICH MUST BE COMMON ; .DUSR QSTAT=4 ;=PSTAT .DUSR QALNK=5 ;=POLNK ; ; PPRI=6 ; PPC= 7 ; .DUSR QCURR=10 ;ADDR CURRENT CELL BEING PROCESSED .DUSR QKEY=11 ;KEY FOR UNPEND LOGIC .DUSR QLNK=12 ;CELL LINK WORD .DUSR QCRSG=13 .DUSR QSTK=14 ;TASK'S CURRENT STACK POINTER .DUSR QNXT=15 ;ADDR NEXT QUEUE .DUSR QTIME=16 ;PEND TIME WAIT .DUSR QCNT=17 ;ON QUEUE COUNT/WAKE UP ADDR .DO ?RDOS .DUSR QSUFT=20 ;QUEUE SUFT/SDCB AREA .ENDC .DO ?INFOS .DUSR QIMAP=20 ;DYNAMIC MAP .DUSR <0QIVEC=QIMAP+IDYSZ ;QUEUE VECTOR .DUSR QBCB1=QIVEC ;BCB 1 .DUSR QDES1=QBCB1+1 ;FIRST WINDOW DESIGNATOR .DUSR QLMA1=QDES1+1 ;FIRST LAST MAPPED BCB ADDRESS .DUSR QWTC1=QLMA1+1 ;FIRST WINDOW USE COUNT .DUSR QBCB2=QWTC1+1 ;SECOND BCB .DUSR QDES2=QBCB2+1 ;SECOND WINDOW DESGINATOR .DUSR QLMA2=QDES2+1 ;SECOND LAST MAPPED BCB ADDRESS .DUSR QWTC2=QLMA2+1 ;SECOND WINDOW USE COUNT .DUSR QSUFT=QIMAP+IDYSZ+IQVEC ;UFT .ENDC .DUSR QSDCB=QSUFT+UFTDC ;OFFSET INTO UFT FOR DCB .DUSR QEND=QSUFT+UFTEL-1 .DUSR QLN=QEND8-QSDCP+1 ;QUEUE LENGTH .DUSR SQLN=QSUFT-QSDCP ;SHORT QUEUE LENGTH ; ; TASK STATUS BITS ; .DUSR TSAB= 1B13 ; ABORT FLAG .DUSR TSACT= 1B14 ; TASK IS ACTIVE .DUSR TSWIO= 1B15 ; TASK WAITING FOR I/O .DUSR TSMPB= 1B1 ; IOCS MAPPED TASK STATE .DUSR BTSMP=QSTAT*16.+1 ;BIT ADDR ; DEFINE PROGRAM STATUS BITS .DUSR PSRDY= 1B00 ; COMMON TO ALL ENTRIES - READY TO RUN .DUSR PSCP= 1B11 ; CP REQUEST FOR THIS PROGRAM .DUSR PSEW= 1B13 ; WAITING FOR RDOS ACTION .DUSR PSBRK= 1B12 ; OPERATOR INTERRUPT OR BREAK FOR PROGRAM .DUSR PSQW= 1B01 ; QWAIT ACTIVE FLAG ; NOTE - 1B0 & 1B1 ARE SET NON-PARAMETRICALLY ; ; PROGRAM FLAGS: 1B00 - PROGRAM NOT OPERATOR INTERRUPTABLE ; 1B15 - PROGRAM NOT CHECKPOINTABLE ; .DO ?USW ; PROGRAM TABLE OFFSETS ; OFFSETS 4-7 MUST BE COMMON BETWEEN  ALL ENTRIES ; 4-7 FOLLOW IN THE ACTIVE CHAIN ; 1B0 IS A COMMON STATUS FLAG- =0 ENTRY READY TO RUN .DUSR PCLAC=0 ;USER CLOCK ACTIVE COUNT .DUSR PCLCN=1 ;USER CLOCK CONSTANT .DUSR PCLAD=2 ;USER CLOCK PROC ADDR .DUSR PLNK=3 ;INTERNAL PROG TABLE LINK ;  COMMON ENTRIES .DUSR PSTAT=4 ;STATUS .DUSR POLNK=5 ;ACTIVE CHAIN LINK .DUSR PPRI=6 ;PRI (0-377) .DUSR PPC=7 ;PC TO RETURN TO .DUSR PDFR=10 ;DELAY CHAIN START .DUSR PDEN=11 ;DELAY CHAIN END .DUSR PDTOT=12 ;TOTAL DELAY ON QUEUE .DUSR PUSTP=13 ;UST POJaINTER .DUSR PSWD=14 ;TEMP .DUSR PDDCB=15 ;DDCB ADDR .DUSR PTPB1=16 ;PARTITION BASE ADDRESS (HIGH ORDER) .DUSR PTPBA=17 ;PARTITION BASE ADDRESS (LOW ORDER) .DUSR PTCLF=20 ;CURRENT LEVEL FLAGS .DUSR PTSPN=21 ;SYSTEM PUSH NUMBER .DUSR PINTU=22 ;PROGRAM INTERRUPT WORD .DUSR PUFPT=23 ;UFPT .DUSR PCMST=24 ;COMMON START .DUSR PCMSZ=25 ;COMMON SIZE .DUSR PDCNT=26 ;DELAY ACTIVE COUNT ;***************************************************************** .DUSR PFLNK=27 ;FILE SYSTEM LINK .DUSR PFLN1=30 ; AND ANOTHER ;**O*************************************************************** .DUSR PSSV1=PFLN1+1 ;SAVE AREA FOR LOCATIONS 40-47 .DUSR PSSV2=PSSV1+1 .DUSR PSSV3=PSSV2+1 .DUSR PSSV4=PSSV3+1 .DUSR PSSV5=PSSV4+1 .DUSR PSSV6=PSSV5+1 .DUSR PSSV7=PSSV6+1 .DUSR PSSV8=PSSV7+1ͧ .DUSR PMPC=PSSV8+1 .DUSR PMAC0=PMPC+1 ; USER REGISTER SAVE IF IN USER MONITOR .DUSR PMAC1=PMAC0+1 .DUSR PMAC2=PMAC1+1 .DUSR PMAC3=PMAC2+1 .DUSR PMUSP=PMAC3+1 ; SAVE USER USP .DO ?N3SW .DUSR PN3SP=PMUSP+1 ; NOVA 3 STACK REGISTER SAVE .DUSR PN3FP=PN3SP+1 .DUSR PFPSV=PN3FP+1 .ENDC J .DUSR PFPSV=PMUSP+1 [J] .DO ?ABSW .DUSR PFPED=PFPSV+17. ;LAST SAVE LOCATION .ENDC .DO ?ANSW .DUSR PFPED= PFPSV+10 .ENDC .DUSR PFLAG= PFPED+1 ;FLAGS .DUSR PLN=PFLAG-PCLAC+1 .ENDC .DO ?MSW ; PROGRAd!M TABLE OFFSETS ; OFFSETS 4-7 MUST BE COMMON BETWEEN ALL ENTRIES 4-7 FOLLOW IN THE ; ACTIVE CHAIN ; 1B0 IS A COMMON STATUS FLAG- =0 ENTRY READY TO RUN .DUSR PMST=0 ;BIRD/NOVA 3 MAP STATUS WORD .DUSR PCLAC= 1 ;USER CLOCK COUNT .DUSR PCLCN=2 ;USER CLOCK CONSTANT .DUSR PCLAD=3 ;USER CLOCK PROC ADDR ; COMMON ENTRIES .DUSR PSTAT=4 ;STATUS .DUSR POLNK=5 ;ACTIVE CHAIN LINK .DUSR PPRI=6 ;PRI (0-377) .DUSR PPC=7 ;PC TO RETURN TO .DUSR PDFR=10 ;DELAY CHAIN START .DUSR PDEN=11 ;DELAY CHAIN END .DUSR PDTODT=12 ;TOTAL DELAY ON QUEUE .DUSR PUSTP=13 ;UST POINTER .DUSR PSWD=14 ;TEMP .DUSR PDDCB=15 ;DDCB ADDR .DUSR PTPB1=16 ;PARTITION BASE ADDRESS (HIGH ORDER) .DUSR PTPBA=17 ;PARTITION BASE ADDRESS (LOW ORDER) .DUSR PTCLF=20 ;CURRENT LEVEL FLAGS .DUSR PTSPN=21 c;SYSTEM PUSH NUMBER .DUSR PINTU=22 ;PROGRAM INTERRUPT WORD .DUSR PUFPT=23 ;UFPT .DUSR PCMST=24 ;COMMON START .DUSR PCMSZ=25 ;COMMON SIZE .DUSR PDCNT=26 ;DELAY ACTIVE COUNT ;*********************************************************** .DUSR PFLNK=27 ;FILE SYSSTEM LINK .DUSR PFLN1=30 ; AND ANOTHER ;************************************************************** .DUSR PLNK= 31 ;INTERNAL LINK .DUSR PMAP= 32 ;USER MAP .DUSR PMLB= PMAP+31. ;LAST BLOCK .DUSR PMSZ= PMLB+2 .DUSR PDEV= PMSZ+1 .DUSR PDINC= PDEV+10 ;DELA~Y TIME INC .DUSR PMPC= PDINC+1 ;STATE SAVE FOR MON INT .DUSR PMAC0=PMPC+1 .DUSR PMAC1=PMAC0+1 .DUSR PMAC2=PMAC1+1 .DUSR PMAC3=PMAC2+1 .DO ?N3SW .DUSR PN3SP=PMAC3+1 ; NOVA 3 STACK REGISTER SAVE .DUSR PN3FP=PN3SP+1 .DUSR PFPSV=PN3FP+1 .ENDC J .DUSR PFPSV=PMAC3+1 ;FPU SAVE AREA [J] .DO ?ABSW .DUSR PFPED=PFPSV+17. ;LAST SAVE LOCATION .ENDC .DO ?ANSW .DUSR PFPED=PFPSV+10  .ENDC .DUSR PFLAG= PFPED+1 ;FLAGS .DUSR PVST= PFLAG+1 ;START OF VIRTUAL OVLY AREA .DUSR PVEND= PVST+1 ;END OF OVLY,s AREA .DUSR PEOCT= PVEND+1 ;# OVLY SLOTS .DUSR PMWIN= PEOCT+1 ;VIRTUAL DATA WINDOW STARTING SLOT .DUSR PMWSZ= PMWIN+1 ;# SLOTS IN WINDOW .DUSR PEDCT= PMWSZ+1 ;# BLKS IN DATA AREA .DUSR PEOMP= PEDCT+1 ;STARTING EXTENDED MAP SLOT FOR OVLY .DUSR PEDMP= P*EOMP+1 ;STARTING EXTENDED SLOT FOR DATA .DUSR PEMAP= PEDMP+1 ;EXTENDED MAP START .DUSR PEMEN= PEMAP+(MPAPH&377)-7 ;END .DUSR PLN=PEMEN-PMST+1 .ENDC ; DISK DCB MACRO ; ^1=DCB NAME ; ^2=DCT ADDRESS OR ZERO ; ^3=UNIT # OR ZERO ; ^4=NEXT DCB IN CHAIN OR, -1 IF LAST ; ^5=LOGICAL NAME OR NOTHING IF NO LOGICAL NAME ; ^6=SYMBOL TO BE PUT ON THE FIRST WORD OF DCB. ; USED BY .LIMIT .MACRO .DDCB ** .TXTM 1 ** ** .PUSH .TXTN ** .TXTN 1 ** ** .PUSH .NOCON ** .NOCON 1 ; DON'T LIST CONDITIONAL STUFF ^6: .BLK/ 1 ; DIRECTORY FRAME SIZE **.DO '^5'<>'' .TXT '^5' ; LOGICAL NAME .BLK 3 ; PAD SPACE .TXT '^5' ; KEY **.ENDC J .BLK 5 ; LOGICAL NAME .BLK 2 ; KEY **[J] M^1 ; MAP DCB LINK **.DO ^4.==-1 ; DO IF LAST ONE -1 ; END OF DCB CHAIN **.ENDC J ^4 ` ; NEXT DCB IN CHAIN **[J] .BLK 1 ; NUMBER OF LAST LOGICAL BLOCK .BLK 1 ; NUMBER OF BYTES IN LAST BLOCK ^1: ^2 ; DCT ADDRESS ^3 ; UNIT # .BLK 1 ; CURRENT BLOCK ADDRESS HIGH ORDER .BLK 1 ; CURRENT BLOCK ADDRESS LOW ORDER .BLK 1 ; CURRENT BLOiCK NUMBER STCMK ; STATUS SHOW UNIT RELEASED .BLK 1 ; USER COUNT .BLK 1 ; PAD .BLK 1 ; NEXT ADDRESS HIGH ORDER .BLK 1 ; NEXT ADDRESS LOW ORDER .BLK 1 ; LAST ADDRESS HIGH ORDER .BLK 1 ; LAST ADDRESS LOW ORDER ^1 ; SYS.DR DCB POINTER .BLK 1c ; FIRST ADDRESS HIGH ORDER .BLK 1 ; FIRST ADDRESS LOW ORDER .BLK 2 ; PAD .BLK 1 ; 0 PRIMARY, 1 SEC'RY, -1 SUBDIR .BLK 1 ; PAD .BLK 1 ; NUMBER OF LAST LOGICAL BLOCK .BLK 1 ; NUMBER OF BYTES IN LAST BLOCK M^1: ^2 ; DCT ADDRESS ^3 ; UNIT V# .BLK 1 ; CURRENT BLOCK ADDRESS HIGH ORDER .BLK 1 ; CURRENT BLOCK ADDRESS LOW ORDER .BLK 1 ; CURRENT BLOCK NUMBER .BLK 3 ; PAD .BLK 1 ; NEXT ADDRESS HIGH ORDER .BLK 1 ; NEXT ADDRESS LOW ORDER .BLK 1 ; LAST ADDRESS HIGH ORDER .BLK 1 ; LAST ADDRESS LOW ORDER ^1 ; SYS.DR DCB POINTER .BLK 1 ; FIRST ADDRESS HIGH ORDER .BLK 1 ; FIRST ADDRESS LOW ORDER ** .NOCON .POP ; START LISTING CONDITIONAL STUFF ** .TXTN .POP % ; DISK UNIT DESCRIPTOR MACRO ; ^1=UNIT DESCRIPTOR NAME ; ^2=LOGICAL UNIlT NUMBER ; ^3=CONTROLLER DEVICE NAME (DKP OR DKP1, ETC.) ; ^4=DEVICE NAME (DSK OR DKP, ETC) .MACRO .DDCU ; UNIT DEVICE CONTROL TABLE ** .PUSH .NOCON ** .NOCON 1 ^1: ^2 ; UNIT NUMBER -1 ; BAD BLOCK TABLE LINK 0 ; BAD TABLE UPDATE WORD .BLK 1 ; P}AD ^3 ; DEVICE CODE ^3EX ; LOC TO XEQ I/O INSTRUCTIONS @DSKDT ; DISPATCH TABLE ADDRESS ^4ST ; DEVICE STARTUP ROUTINE ^4DST ; SETUP DST WORD IN QUEUE ENTRY 100 ; SECTORS PER TRACK 100 ; NUMBER OF HEADS 0 ; FRAME SIZE, 0 = DEVICE NOT SIZED ^׷3DC ; ADDRESS OF PARENT DCT RDLBK ; READ LAST BLOCK RDCBK ; READ CURRENT BLOCK RDNBK ; READ NEXT BLOCK **.DO '^4'=='DSK' DKINI ; DISK PACK INIT ROUTINE **.ENDC J DPINI ; DISK INIT ROUTINE **[J] DVRLS ; DISK PACK RELEASE ROUTINE .BLK 1 ; NUMBEtJR OF BLOCKS HIGH ORDER .BLK 1 ; NUMBER OF BLOCKS LOW ORDER ** .NOCON .POP % ; MAGTAPE CASETTE DCB MACRO ; ^1=DCB NAME ; ^2=DCT ADDRESS OR ZERO ; ^3=UNIT # OR ZERO ; ^4=NEXT DCB IN CHAIN OR -1 IF LAST ; ^5=LOGICAL NAME OR NOTHING IF NO LOGICAL NAME ; ^6@D=SYMBOL TO BE PUT ON FIRST WORD OF DCB. ; USED BY .LIMIT .MACRO .NDDCB ** .TXTM 1 ** ** .PUSH .TXTN ** .TXTN 1 ** ** .PUSH .NOCON ** .NOCON 1 ; DON'T LIST CONDITIONAL STUFF ^6: .TXT '^5' ; LOGICAL NAME .BLK 3 ; PAD SPACE .TXT '^5' ; KEY -1 ; NO MAP DCB **.DO ^4.==-1. ; DO IF LAST ONE -1 ; END OF DCB CHAIN **.ENDC J ^4 ; NEXT DCB IN CHAIN **[J] .BLK 1 ; NUMBER OF LAST LOGICAL BLOCK .BLK 1 ; NUMBER OF BYTES IN LAST BLOCK ^1: ^2 ; DCT ADDRESS ^3 ; UNIT # .BLK 1 ; CURRENT BLOCK AQDDRESS HIGH ORDER .BLK 1 ; CURRENT BLOCK ADDRESS LOW ORDER .BLK 1 ; CURRENT BLOCK NUMBER STCMK ; STATUS SHOW UNIT RELEASED ** .NOCON .POP ; START LISTING CONDITIONAL STUFF ** .TXTN .POP % ; MCA DCB MACRO ; ^1=DCB NAME ; ^2=DCT ADDRESS ; ^3=NEXT  DCB IN CHAIN OR -1 IF LAST ; ^4=LOGICAL NAME ; ^5=KEY .MACRO .SPDCB ** .TXTM 1 ** ** .PUSH .TXTN ** .TXTN 1 ** ** .PUSH .NOCON ** .NOCON 1 ; DON'T LIST CONDITIONAL STUFF ** ??A= (.LOC) ; SAVE LOCATION COUNTER .TXT '^4' ; LOGICAL NAME ** .LOC ??A+SFz KEY-SFLNA ; PAD OUT LOGICAL NAME ** ??A= (.LOC) ; SAVE LOCATION COUNTER .TXT '^5' ; KEY ** .LOC ??A+SFLK-SFKEY ; PAD OUT KEY -1 ; NO MAP DCB **.DO ^3.==-1. ; DO IF LAST ONE -1 ; END OF DCB CHAIN **.ENDC J ^3 ; NEXT DCB IN CHAIN **[J] .BLK 1 ; PAD .BLK 1 ; PAD ^1: ^2 ; DCT ADDRESS .BLK 1 ; PAD .BLK 1 ; PAD .BLK 1 ; PAD .BLK 1 ; PAD STINI+STUTP ; NO INIT OR RELEASE ; AND UFT PROTECTED FROM GPOS ; SPOS CHATR CHLAT ** .NOCON .POP ; START LISTING CONDITIONAL STUFF ** .TXTN .POP % ; IF MACRO ; CALLING SEQUENC: IF EXPRESSION CONSTANT EXPLANATION ; WHERE EXPLANATION IS 6 WORDS OR LESS ; EG IF A+B NE 6 CHECK IN LINE MULTIPLIES ; ON ERROR: F ADDR VALUE OF A+B A+B NE 6 ;CHECK IN LINE MULTIPLIES ; RELA ALLOWED (EQ,NE,GT,LT,GE,LE). ANY OTHER THE STRING IS ; ALWAYS PRINTED AS IS .MACRO IF ** **.DO '^2'=='EQ' ** .DO ^1==^3 ** .ENDC MSG **.ENDC DONE ** **.DO '^2'=='NE' ** .DO ^1<>^3 ** .ENDC MSG **.ENDC DONE ** **.DO '^2'=='GT' ** .DO ^1>^L3 ** .ENDC MSG **.ENDC DONE ** **.DO '^2'=='LT' ** .DO ^1<^3 ** .ENDC MSG **.ENDC DONE ** **.DO '^2'=='GE' ** .DO ^1>=^3 ** .ENDC MSG **.ENDC DONE ** **.DO '^2'=='LE' ** .DO ^1<=^3 ** .ENDC MSG **.ENDC DONE ** **: _;^1 ^2 ^3 ^4 ^5 ^6 ^7 ^8 ^9 **ԧ **.GOTO DONE ** **[MSG] ** ^1 ^2 ^3 _;^4 ^5 ^6 ^7 ^8 ^9 ** **[DONE] % ; SYSTEM OVERLAYS ; ; OVERLAY OVERLAY OVERLAY FILE ; NUMBER NAME BASE ADDRESS ; ; 0............DFRWS...............0 ; 1............DFLR................400 ; 2......޲......UTIL1...............1000 ; 3............CREATE..............1400 ; 4............DELETE..............2000 ; 5............FILSY...............2400 ; 6............SOV1................3000 ; 7............SOV2................3400 ; 10............SOV3................4000 ; 11............SOV4................4400 ; 12............DVINI...............5000 ; 13............CRSFS...............5400 ; 14............RING1...............6000 ; 15............RING2...............6400 ; 16..(..........RING3...............7000 ; 17............SOV5................7400 ; 20............MTAIO...............10000 ; 21............MTAUC...............10400 ; 22............TUON................11000 ; 23............CDROV...............11400 ; C 24............WDBLK...............12000 ; 25............SPOLR...............12400 ; 26............CODER...............13000 ; 27............SOV6................13400 ; 30............SOV7................14000 ; 31............SOV8................R\14400 ; 32............SOV9................15000 ; 33............SOV10...............15400 ; 34............SOV11...............16000 ; 35............JEHOV...............16400 ; 36............SOV12...............17000 ; 37............SOV13.......I:........17400 ; 40............SOV14...............20000 ; 41............SOV15...............20400 ; 42............SOV16...............21000 ; 43............FILS2...............21400 ; 44............SOV17...............22000 ; 45............SOV108...............22400 ; 46............WDCBK...............23000 ; 47............SOV19...............23400 ; 50............SOV20...............24000 ; 51............SOV21...............24400 ; 52............SFTAB...............25000 ; 53........t....SOV22...............25400 ; 54............SOV23...............26000 ; 55............SOV24...............26400 ; 56............SOV25...............27000 ; 57............FSTAT...............27400 ; 60............DVRLS...............30000 ; 61............SOV26...............30400 ; 62............SOV27...............31000 ; 63............SOV28...............31400 ; 64............TUNOV...............32000 ; 65............QTYOV...............32400 ; 66............SOV29...............3300.0 ; 67............SOV30...............33400 QLITMACS.SR5  .MACRO ?L?1X **.DO .MCALL==0 **.DO .PASS==0 **.DO T'?L?NS&1B5==0 **.DUSR ?L?NS = 0 **.ENDC **.DO T'?L?NI&1B5==0 **.DUSR ?L?NI = 1 **.ENDC **.DUSR ?L?IR = 10. **.DUSR ?L?G1 = 1B0 **.DUSR ?L?CO = 1B1 **.DUSR ?L?FG = 1B2 **?L?DU ?L?US = 0 **.ENDC **?L ?DU ?L?CL = 0 **?L?DU ?L?GN = 0 **.DUSR ?L?PL = 0 **.DUSR ?L?LO = 0 **.ENDC % .MACRO ?L?DU **.DO ?L?NS<>0 **^1 ^2 ^3 **.ENDC X **.DUSR ^1 ^2 ^3 **[X] % ; LIT - USE A LITERAL .MACRO LIT ?L?NL **.DO .MCALL==0 **?L?1X **.ENDC **.DUSR ?L?UR = .R$DX **.RDX ?L?IR **.DO ?L?CL/1000<>0 **: ;ERROR: TOO MANY LITERALS DEFINED **.ENDC EXIT **.PUSH .NOMAC **.NOMAC 1 **.PUSH ?I **.LOC .-1 **?L?DU ?U\?L?CL = . **.DO .PASS==0 **.DUSR ?I = .ARGCT<>1 **.MACRO ?W\?L?CL **.RDX .POP _^1_^2_^3_^4_^5_^6^1 ^2 ^3 ^4 ^5 ^6 ^7 ^8 ^9 _% **?L?L1 ^1 **.ENDC PASS2 **?L?L2 ^1 **[PASS2] **.LOC .+1 **.DUSR ?I = .POP **.NOMAC .POP **.RDX ?L?UR **[EXIT] **% ;(SINCE LIT'S ARGS IN BRACKETS) .MACRO ?L?L1 **?L?DU ?L?US = ?L?US+1 **.RDX ?L?UR **.DO ?I==0 **.DO 1 **?L?T1 ?I ^1 z**.ENDC **.DO 1 **?L?T2 ?I ^1 **.ENDC **.DUSR ?I = ?I/2. **.DO ?I==0 **?L?T3 ?I ^1 **.ENDC **.ENDC **.RDX ?L?IR **.DUSR ?G\?L?CL = ?I*?L?CO+?L?UR **.DO ?I==0 **.RDX ?L?UR **.DUSR ?I = ^1 ;INVALID FORWARD REFERENCE EXPRESSION **.RDX ?L?IR **?L?DU ?V\?L?=CL = ?I **.ENDC **?L?DU ?L?CL = ?L?CL+1 % .MACRO ?L?L2 **.DO ?G\?L?CL&?L?CO==0 **.RDX ?L?UR **.DUSR ?I = ^1 **.RDX ?L?IR **.DO ?V\?L?CL<>?I **: ;ERROR: VALUES ON TWO PASSES OF LIT DIFFER **.ENDC **.ENDC **?L?DU ?L?CL = ?L?CL+1 **.DO ?L?US>?L?CL **.DO ?G\?L?CL&?L?G1<>0 **.DUSR ?L?NL = ?L\?L?CL **.ENDC X **.DUSR ?L?NL = ?L\?L\?L?CL **[X] **.ENDC % ; MACROS FOR TESTING LIT'S ARGUMENT FOR OPTIMIZABILITY .MACRO ?L?T1 **.DO ^2==0 **.DUSR ^1 = ^1+1 % .MACRO ?L?T2 **.DO ^2<>0 **.DUSR ^1 = ^1+1 % _ .MACRO ?L?T3 **.DUSR ^1 = 1 **.DO (-16449.&T'^2-(^2))<>0 **.DUSR ^1 = 0 % ;NOTE: PARENTHESES ABOVE ARE REQUIRED (!!?!!) ; IN ORDER TO HANDLE LEADING +, -, ( ; LPOOL - DEPOSIT ALL LITERALS USED SINCE LAST LPOOL .MACRO LPOOL **.DO .MC/ALL==0 **?L?1X **.ENDC **.DUSR ?L?UR = .RDX **.RDX ?L?IR **.PUSH .NOMAC **.NOMAC ?L?NS **.PUSH .NOCON **.NOCON 1 **.PUSH ?A **.PUSH ?B **.PUSH ?C **.PUSH ?D **.PUSH ?I **.DO .PASS==0 **?L?P1 **.ENDC PASS2 **?L?P2 **[PASS2] **.DUSR ?I = .POP **.DUSR ?D = . POP **.DUSR ?C = .POP **.DUSR ?B = .POP **.DUSR ?A = .POP **.NOCON .POP **.NOMAC .POP **.RDX ?L?UR **.DO ?L?PL<>?L?CL **LPOOL **.ENDC % .MACRO ?L?DL **.DUSR ?B = ^2/10 **.DUSR ?C = ^2-(?B*10)+5. **.DUSR ?A = ?B/10 **.DUSR ?B = ?B-(?A*10)+5. **.DUSR ?A = ?A+5. **.PUSH ?G\?L?PL&31. **?W\^4 ^1 ?L ^?A ^?B ^?C ^3 **.RDX ?L?IR **% ;(SINCE ?L?DL'S ARGS IN BRACKETS) .MACRO ?L?P1 **.DO ?L?CL==?L?PL **.ENDC DONE **.DO ?L?PL-?L?LO **.DO (?G\?L?LO&(?L?G1+?L?CO)<>?L?G1)!((?L\?L?LO-?U\?L?PL)>128.) **.DUS'R ?L?LO = ?L?LO+1 **.ENDC GOOD **.ENDC **[GOOD] **.DO ?L?CL-?L?PL **.DO T'?L\?L?PL&1B5<>0 **.ENDC NXTLIT **.DO ?G\?L?PL&(?L?G1+?L?CO+?L?FG)==0 **.DUSR ?I = ?L?LO **.DO ?L?PL-?L?LO **.DO ?G\?I&(?L?G1+?L?CO)==?L?G1 **.DUSR ?D = ?L\?I-?U\?L?PL **.DO (?V\?L?cPL==?V\?I)&(?D<128.)&(?D>=-128.) **?L\?L?PL = ?I **.ENDC NXTLIT **.ENDC **.DUSR ?I = ?I+1 **.ENDC **.ENDC **.DUSR ?D = . **.DO ?G\?L?PL&?L?CO==0 **.PUSH ?G\?L?PL&31. **?W\?L?PL **.DUSR,__ ,?I= **.RDX ?L?IR **.DO ?I<>?V\?L?PL **.PUSH ?V\?L?PL **?L?DL [_____P_ ,?L?PL,:______ .POP______ ______;______ ,?L?PL 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J] **.ENDC SKIP **.ENDC **?L?DL [______ ,?L?PL,:______ ,?L?PL 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J] **[SKIP] **?L?DU ?L?GN = ?L?GN+.-?D **.DUSR ?G\?L?PL = ?G\?L?PL!c?L?G1 **[NXTLIT] **.DUSR ?L?PL = ?L?PL+1 **.ENDC **[DONE] **.DO ?L?US>0 **.DUSR ?L?NL = ?L000 **.ENDC % .MACRO ?L?P2 **.DO ?L?CL-?L?PL **.DO ?G\?L?PL&?L?G1==0 **?L?DL [______;,?L\?L?PL,:______ ,?L?PL 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J] **.ENDC NXTLIT **.DUSR ?D = . **.DO ?G\?L?PL&?L?CO==0 **.PUSH ?G\?L?PL&31. **?W\?L?PL **.DUSR,__ ,?I= **.RDX ?L?IR **.DO ?I<>?V\?L?PL **.PUSH ?V\?L?PL **?L?DL [______ ,?L?PL,:______ .POP______ ______;______ ,?L?PL 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J] **.ENDC SKIP **.ENDC **?L?DL [______ ,?L?PL,:______ ,?L?PL 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J] **[SKIP] **?L?DU ?L?GN = ?L?GN+.-?D **.DUSR ?G\?L?PL = ?G\?L?PL!?L?G1 **[NXTLIT] **.DUSR ?L?PL = ?L?PL+1 **.ENDC % ; X INSTRUCTIONS .MACRO ?L?XI **.DO .MCALL==0 **?L?1X **.ENDC **.DUSR ?L?UR = .RDX **.PUSH ?D **.PUSH ?F **.DO '^3'&-1B7=='#' **?L?XN ^1,^2,^3 ^4 ^5 ^6 ^7 ^8 ^9 **.ENDC DONE **.DO '^3'&-1B7=='=' **?L?XE ^1,^2,^3 ^4 ^5 ^6 ^7 ^8 ^9 **.ENDC DONE **?L?XR ^1,^2,^3 ^4 ^5 ^6 ^7 ^8 ^9 **[DONXE] **.DUSR ?F = .POP **.DUSR ?D = .POP % .MACRO ?L?XN **.DO '^3'<>'#' **:; YOU FORGOT THE SPACE AFTER THE # SIGN **^1 ^2 LIT[,0+0+0+0+0] **.ENDC DONE **.DO (.PASS==0)!(?L?NI<>0) **^1 ^2 LIT[,^4 ^5 ^6 ^7 ^8 ^9] **.ENDC DONE **?L?DI ^1,^2,,0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J **.DUSR ?F = LIT[,^4 ^5 ^6 ^7 ^8 ^9] **[DONE] % .MACRO ?L?XE **.DO '^3'<>'=' **:; YOU FORGOT THE SPACE AFTER THE = SIGN **^1 ^2 LIT[,0+0+0+0+0] **.ENDC DONE **.DO (.PASS==0)!(?L?NI<>0) **^1 ^2 LIT[^4 ^5 ^6 ^7 ^8 ^9] **.ENDC t#DONE **?L?DI ^1,^2,,0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J **.DUSR ?F = LIT[^4 ^5 ^6 ^7 ^8 ^9] **[DONE] % .MACRO ?L?XR **.PUSH .NOLOC **.NOLOC 1 **.DUSR ?D = 1 **.DO T'^3==(1B1+1B12) **.ENDC PUNT **.DO T'^3==(1B1+3.B12) **.DUSR ?D = 0 **.ENDC X **.DUSRk ?F = . **.DO (T'^3&15.)<>(T'?F&15.) **.ENDC PUNT **.DO ^3<>0 **.DUSR ?D = ^3-. **.ENDC **[X] **.DO (-128.<=?D)&(?D<=0) **.DO (.PASS==0)!(?L?NI<>0) **^1 ^2 ^3 ^4 ^5 ^6 ^7 ^8 ^9 **.ENDC XY **.DO '^2'=='' ^1 ^3 ^4 ^5 ^6 ^7 ^8 ^9 **.ENDC XY ^1 ^2,^3 ^4 ^5 ^6 ^7 ^8 ^9 **[XY] **.ENDC DONE **[PUNT] **.DO (.PASS==0)!(?L?NI<>0) **^1 ^2 @LIT[^3 ^4 ^5 ^6 ^7 ^8 ^9] **.ENDC XY **?L?DI ^1,^2,@,0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J **.DUSR ?F = LIT[^3 ^4 ^5 ^6 ^7 ^8 ^9] **[XY] **[DONE] **.NOLOC (.POP) %  .MACRO ?L?DI **.PUSH ?A **.PUSH ?B **.PUSH ?C **.PUSH ?D **.DUSR ?D = ?L?CL **.RDX ?L?IR **.DO ?G\?D&?L?G1==0 **.DUSR ?D = ?L\?D **.ENDC **.DUSR ?B = ?D/10 **.DUSR ?C = ?D-(?B*10)+4. **.DUSR ?A = ?B/10 **.DUSR ?B = ?B-(?A*10)+4. **.DUSR ?A = ?A+4. **.RDX Ǡ?L?UR **?L?D2 ^1,^2,^3,^?A,^?B,^?C **.DUSR ?D = .POP **.DUSR ?C = .POP **.DUSR ?B = .POP **.DUSR ?A = .POP % .MACRO ?L?D2 **.PUSH .NOLOC **.NOLOC 1 **.DO '^2'=='' ^1 ^3?L^4^5^6 **.ENDC DONE ^1 ^2,^3?L^4^5^6 **[DONE] **.NOLOC (.POP) % .MACRO ?L?XX **.DO .MCALL==0 **?L?1X **.ENDC **.DUSR ?L?UR = .RDX **.PUSH ?D **.PUSH ?F **.DO '^3'&-1B7=='#' **?L?XN ^1,^2,^3 ^4 **.ENDC DONE **.DO '^3'&-1B7=='=' **?L?XE ^1,^2,^3 ^4 **.DUSR ?D = 5. **.ENDC REACH **?L?XR ^1,^2,^3 **.DO (-128.<=?D)&(?D<=0) **.ExNDC DONE **.DUSR ?D = 4. **[REACH] **.DO .PASS==0 **.DO '^?D'<>'' **?L?XO ^?D **.ENDC NOBOOK **.DUSR ?D = ?D-1 **?L?XO .^?D **[NOBOOK] **.ENDC **[DONE] **.DUSR ?F = .POP **.DUSR ?D = .POP % .MACRO ?L?XO **.DUSR ?F = ?L?CL-1 **.RDX ?L?IR **.DO (?G\?F&v?L?CO==0)&(T'^1&1B5==0) **.ENDC DONE **.DO T'^1&1B5==0 **.DUSR ^1 = ?F **.ENDC DONE **.DO ^1>=?L?PL **.ENDC REUSE **.DO .-?L\^1>=128. **.DUSR ^1 = ?F **.ENDC DONE **[REUSE] **.DUSR ?L\?F = ^1 **[DONE] **.RDX ?L?UR % .MACRO ?L?XM **.DO ^2==0 **.MACRO X^1 **?L?XI ^1,,_^1 _^2 _^3 _^4 _^5 _^6 _^7 _^8 _^9 _% **.MACRO XX^1 **?L?XX ^1,,_^1 _^2 _^3 _% **.ENDC **.DO ^2==1 **.MACRO X^1 **?L?XI ^1,_^1,_^2 _^3 _^4 _^5 _^6 _^7 _^8 _^9 _% **.MACRO XX^1 **?L?XX ^1,_^1,_^2 _^3 _^4 _% **.ENDC % ?L?XM JMP 0 ?L?XM JSR 01 ?L?XM ISZ 0 ?L?XM DSZ 0 ?L?XM LDA 1 ?L?XM STA 1 RDOSMACS.SRB* ; RDOS MACROS FOR REV 5.01 ; ; MACROS USE MACROES DEFINED IN THE "LITMACS.SR" MODULE .TITLE RMACS .DO ?ANSW ; NOVA LOAD BYTE INSTRUCTION .MACRO LDB **.DO (.ARGCT<>2.) **:; WRONG NUMBER OF ARGS TO LOAD BYTE INSTRUCTION **.ENDC **.DO (^1<>1)!(^2<>0) **:; WRONG ARGS YOU DODO **.ENDC **.DO .MCALL==0 ** .EXTN LDBT **.ENDC ** XXJSR LDBT,.LDBT % ; NOVA STORE BYTE INSTRUCTION .MACRO STB **.DO (.ARGCT<>2.) **:; WRONG NUMBER OF ARGS TO STORE BYTE INSTRUCTION **.ENDC **.DO (^1<>1)!(^2<>0) **:; WRONG ARGS YKOU DODO **.ENDC **.DO .MCALL==0 ** .EXTN STBT **.ENDC ** XXJSR STBT,.STBT % .ENDC ; ON THE ECLIPSE THE ACTUAL ECLIPSE INSTRUCTION IS USED ; FOR LOAD/STORE BYTE. ; MAPPED LOAD/STORE BYTE. USED TO GET BYTE FROM USER ; ADDRESS SPACE. .DO ?USW&?ANSW ; ION THE UNMAPPED NOVA THIS IS THE SAME AS LOAD/STORE BYTE .MACRO MLDB ** .PUSH .NOMAC ** .NOMAC ?L?NI LDB 1,0 ** .NOMAC .POP % .MACRO MSTB ** .PUSH .NOMAC ** .NOMAC ?L?NI STB 1,0 ** .NOMAC .POP % .ENDC .DO ?USW&?ABSW ; ON THE UNMAPPED BIRD THE JACTUAL LOAD/STORE ; BYTE INSTUCTIONS ARE USED. .DISD MLDB= LDB 0,0 .DISD MSTB= STB 0,0 .ENDC .DO ?MSW ; ON ALL MAPPED A ROUTINE IS CALLED TO DO THE LOAD/STORE ; MAPPED LOAD BYTE INSTRUCTION .MACRO MLDB **.DO (.ARGCT<>2.) **:; WRONG NUMBER OF ARGS TI O MAPPED LOAD BYTE INSTRUCTION **.ENDC **.DO (^1<>1)!(^2<>0) **:; WRONG ARGS YOU DODO **.ENDC **.DO .MCALL==0 ** .EXTN MLDBT **.ENDC ** XXJSR MLDBT,.MLDBT % ; MAPPED STORE BYTE INSTRUCTION .MACRO MSTB **.DO (.ARGCT<>2.) **:; WRONG NUMBER OF ARGS TO MAPP!ED STORE BYTE INSTRUCTION **.ENDC **.DO (^1<>1)!(^2<>0) **:; WRONG ARGS YOU DODO **.ENDC **.DO .MCALL==0 ** .EXTN MSTBT **.ENDC ** XXJSR MSTBT,.MSTBT % .ENDC ; OVERLAY CALL MACRO. ARGUMENT IS THE NAME OF THE OVERLAY BEING ; CALLED WHICH USER MUST DEC~LARE AS EXTERNAL. .MACRO CALLO **.DO .MCALL==0 ** .EXTN OVLAY **.ENDC ** .EXTN ^1 ** XXJSR OVLAY,.OVLAY ** .PUSH .NOMAC ** .NOMAC ?L?NI ^1 ** .NOMAC .POP % ; INTERNAL OVERLAY CALL MACRO. ARGUMENT IS LABEL IN CURRENT OVERLAY ; WHICH USER WISHES TO CAT*LL AS A SUBROUTINE. .MACRO CALLI **.DO .MCALL==0 ** .EXTN OICAL **.ENDC ** XXJSR OICAL,.OICAL ** .PUSH .NOMAC ** .NOMAC ?L?NI ^1 ** .NOMAC .POP % ; OVERLAY CALL MACRO FOR USE WHEN ONE OR MORE SUBROUTINE CALLS ARE ; MADE INTERNAL TO A MACRO WITHOUT THE USE OF "CALLI" OR A CALL IS ; DONE TO RESIDENT CODE WHICH THEN WANTS TO CALL A SUBROUTINE. ARGUMENT ; IS ENTRY POINT TO OVERLAY WHICH USER MUST DECLARE EXTERNAL. .MACRO CALLF **.DO .MCALL==0 ** .EXTN FLAK1 **.ENDC ** XXJSR FLAK1,.FLK1 ** .PUSH .NOMAC ** .NOMAC ?L?NI ^1 ** .NOMAC .POP % ; DECLARE ERROR AND DO SUBROUTINE RETURN. IF CALL HAS NO ARGUMENTS ; THEN THE ERROR CODE IS PRESUMED TO BE IN REGISTER AC2. IF HAS ARGUMENT ; THEN ARGUMENT IS THE ERROR CODE. .MACRO ERROR **.DO .MCALL==0 ** .EXTNaI RETER,RETE2 **.ENDC ** ** .PUSH .NOLOC ** .NOLOC 1 ** **.DO .ARGCT==0 ** XXJSR RETE2,.RET2 **.ENDC **.DO .ARGCT<>0 ** XXJSR RETER,.RETER ** .PUSH .NOMAC ** .NOMAC ?L?NI ^1 ** .NOMAC .POP **.ENDC ** ** .NOLOC (.POP) % ; DECLARE TIME TO PANIC MACRO. ARNGUMENT IS THE PANIC CODE. .MACRO PANIC ** .PUSH .NOMAC ** .NOMAC ?L?NI JSR @.PNIC ^1 ** .NOMAC .POP % ; RDOS RTITLE MACRO. MACRO CAUSES CORRECT TITLE TO BE ASSIGNED ; AMODULE DEPENDING ON WHICH VERSION OF RDOS IS BEING ASSEMBLED. ; FIRST ARGUMENT IS THE MODULE NAME, SECOND IS THE SHORTENED VERSION ; USED IF FIRST IS OVER 5 CHARS LONG. .MACRO RTITLE ** .DUSR ?L?NS = 0 ; LIST LPOOL CONTENTS ** .DUSR ?L?NI = 1 ; DON'T LIST MAC INSTRUCTION EXPANSIONS ** .PUSH ?Y ** .DUSR ?Y = 1 **.DO .ARGCT>1 **F .DUSR ?Y = 2 **.ENDC % .IFN ?USW&?ANSW .MACRO RTITLE .TITLE U^?Y .RB U^1.RB % .ENDC .IFN ?MSW&?NSW&N?MSW .MACRO RTITLE .TITLE M^?Y .RB M^1.RB % .ENDC .IFN ?MSW&?N3SW&N3?MSW .MACRO RTITLE .TITLE N^?Y .RB N^1.RB % .ENDC * .IFN ?USW&?ABSW .MACRO RTITLE .TITLE B^?Y .RB B^1.RB % .ENDC .IFN ?MSW&?ABSW&B?MSW&?RDOS .MACRO RTITLE .TITLE A^?Y .RB A^1.RB % .ENDC .IFN ?MSW&?ABSW&BB?MSW&?RDOS .MACRO RTITLE .TITLE Z^?Y .RB Z^1.RB % .ENDC .IFN ?MSW&K9?ABSW&B?MSW&?INFOS .MACRO RTITLE .TITLE I^?Y .RB I^1.RB % .ENDC .IFN ?MSW&?ABSW&BB?MSW&?INFOS .MACRO RTITLE .TITLE J^?Y .RB J^1.RB % .ENDC .MACRO RTITLE ** L?LPOOL= .NREL ; ADDRESS WHERE LAST LPOOL STARTED ** OV?SZ= .NREL ; FIRSTo ADDRESS OF OVERLAY ** .DUSR ?Y = .POP % ; END OF OVERLAY LENGTH CHECK MACRO .MACRO ENDOV ** .PUSH ?Y ** .DUSR ?Y = .-OV?SZ **.DO ?Y>400 ** BY= ?Y-400 **: OVERLAY IS TOO LARGE \BY WORDS **.ENDC ** .DUSR ?Y = .POP % ; CONDITIONAL LPOOL, ONLY DOES IT IF LAST LPOOL WAS MORE THAN ; 140 OCTAL FROM THE LAST CONDITIONAL LPOOL CALL. .MACRO CLPOOL ** .IFN (.-L?LPOOL)>=140 ** LPOOL ** L?LPOOL= . % ; UNCONDITIONAL LPOOL .MACRO ULPOOL ** LPOOL ** L?LPOOL= . % ; MAPPED LOAD AND STORE WORD .DO ?USW ; IF NOT MAPPED THEN JUST USE REGULAR INSTRUCTIONS .DMRA MLDA= 020000 .DMRA MSTA= 040000 .ENDC .DO ?MSW .MACRO MLDA ** .PUSH .NOMAC ** .NOMAC ?L?NI % .IFN N?MSW .MACRO MLDA NIOP MAP NOP % .ENDC .IFN N3?MSW .MACRO MLDA NIOP MAP % .ENDC .IFN B?MSW!BB?MSW .MACRO MLDA NIOP BMAP % .ENDC .MACRO MLDA ** .PUSH .NOCON ** .NOCON 1 **.DO .ARGCT==2 LDA ^1,^2 **.ENDC **.DO .ARGCT==3 LDA ^1,^2,^3 **.ENDC ** .NOCON .POP ** .NOMAC .POP % .MACRO MSTA ** .PUSH .NOMAC ** .NOMAC ?L?NI % .IFN N?MSW .MACRO MSTA NIOP MAP NOP % .ENDC .IFN N3?MSW .MACRO MSTA NIOP MAP % .ENDC .IFN B?MSW!BB?MSW .MACRO MSTA NIOP BMAP % .ENDC .MACRO MSTA ** .PUSH .NOCON ** .NOCON 1 **.DO .ARGCT==2 STA  ^1,^2 **.ENDC **.DO .ARGCT==3 STA ^1,^2,^3 **.ENDC ** .NOCON .POP ** .NOMAC .POP % ; MACRO TO SET MAP LAST BLOCK TO MAPPING DEPICTED IN ; REGISTER GIVEN AS ARGUMENT TO MACRO CALL. .MACRO SMLB ** .PUSH .NOMAC ** .NOMAC ?L?NI % .IFN B?MSW!BB?MSW[ .MACRO SMLB DOB ^1,BMAP % .ENDC .IFN N?MSW .MACRO SMLB DOA ^1,MAP % .ENDC .IFN N3?MSW .MACRO SMLB DOB ^1,MAP % .ENDC .MACRO SMLB ** .NOMAC .POP % ; SET MAP BLOCK TO STATE DEFINED IN REGISTER GIVEN AS ; ASG TO MACRO "CALL. ON THE BIG BIRD MAP, THE MACRO ; EXPECTS THAT THE MAP HAS ALREADY BEEN SET UP TO LOAD ; INTO THE PROPER MAP (IE A, B, OR DCH) .MACRO SMBK ** .PUSH .NOMAC ** .NOMAC ?L?NI % .IFN B?MSW .MACRO SMBK DOA ^1,BMAP % .ENDC .IFN N?MSW .MACORO SMBK DOA ^1,MAP % .ENDC .IFN N3?MSW .MACRO SMBK DOB ^1,MAP % .ENDC .IFN BB?MSW .MACRO SMBK **.DO .MCALL==0 ** .EXTN STMBK ; SET MAP BLOCK ROUTINE **.ENDC PSH ^1,^1 PSHJ STMBK POP ^1,^1 % .ENDC .MACRO SMBK *)* .NOMAC .POP % ; SET MAP STATUS MACRO (ARGUMENT IS AC CONTAINING STATUS) .MACRO SMST ** .PUSH .NOMAC ** .NOMAC ?L?NI % .IFN N?MSW!N3?MSW .MACRO SMST DOA ^1,MAP % .ENDC .IFN B?MSW!BB?MSW .MACRO SMST DOA ^1,BMAP % .ENDC .MACRUO SMST ** .NOMAC .POP % ; SET WHAT MAP TO LOAD ( IF ONLY ONE ARG THEN LOAD THAT ; REGISTER INTO MAP STATUS, IF 2 ARGS ; THEN LOAD VALUE OF SECOND ARG INTO ; REGISTER AND LOAD MAP) .MACRO SMLD ** .PUSH .NOMAC ** .NOMAC ?L?NI % .IFN N?MSW!N3?MSW !B?MSW .MACRO SMLD % .ENDC .IFN BB?MSW .MACRO SMLD ** .PUSH .NOLOC ** .NOLOC 1 **.DO .ARGCT==2 ** .NOLOC .TOP ELEF ^1,^2 **.ENDC DOC ^1,BMAP ** .NOLOC .POP % .ENDC .MACRO SMLD ** .NOMAC .POP % .ENDC INIT.SRB .LCNS ;COPYRIGHT (C) DATA GENERAL CORPORATION,1972,1973,1974,1975,1976,1977 ;ALL RIGHTS RESERVED ;LICENSED MATERIAL-PROPERTY OF DATA GENERAL CORPORATION RTITLE INIT .DO ?RDOS .REV 6,30. ; REV 6.30 WILL COME OUT OF CLI REV ; COMMAND .ENDC .DO ?INFOS R .REV 2,30. ; REV 2.30 WILL COME OUT OF CLI REV ; COMMAND .ENDC .ENT BOOT .EXTN SSINI ; PARTIAL INIT ADDRESS .EXTN SSINT ; INIT, FULL OR PARTIAL-OVERLAYS .EXTN SSINS ; SWITCHED INIT FULL/PARTIAL-OVERLAYS .DO ?USW .EXTN LCLID ; ADDRESS OF END OF CLI .ENDC .EXTN CLIBT ; LOAD THE CLI .EXTN SYST ; DRAG IN SYSTE .EXTN DSKDT ; & FILIO .DO ?MSW .EXTD GMBLK ;DRAG IN MAPZ .EXTN PNIC ;PANIC .ENDC .TXTM 1 ; PACK 'EM LEFT TO RIGHT BOOT=. ; RESOLVED FOR LIBRARY LOAD .LOC SCTBP ; HOLDS BYTE POINTER TO SYSTEM NAME PRMPT*2 ; TEXT STRING PRINTED BY "BOOT" WHEN ; SYSTEM BOOTED .LOC SCINS ; HOLDS SYSTEM START ADDRESS USED SSINS ; WHEN SYSTEM BOOTED UP BY "MCABOOT" ; FOR THIS ENTRY "SWSWC" (THE FULL/PARTIAL ; INIT SWITCH) IS SET BY "MCABqOOT" BEFORE ; PROGRAM IS STARTED. .LOC SCPSA ; HOLDS SYSTEM START ADDRESS USED SSINI ; WHEN SYSTEM BOOTED UP BY "BOOT" ; FOR THIS ENTRY "SWSWC" IS NOT USED. ; HOWEVER "SCBAS" POINTS TO THE INFO ; LEFT BY "BOOT" ABOUT WHAT SYSTEM WAS ; LO[ADED AND FROM WHERE. .LOC SCINT ; HOLDS SYSTEM START ADDRESS USED SSINT ; WHEN SYSTEM BOOTED UP BY "TBOOT", ; "CBOOT", OR FROM PAPERTAPE. FOR THIS ; ENTRY "SCSWC" (THE FULL/PARTIAL INIT ; SWITCH) IS SET BY THE START UP CODE ; BY ASKING THEV USER WHAT HE WISHES. .DO ?USW .LOC SCCLI ; LOCATION HOLDS END ADDRESS OF STARTUP LCLID ; CLI FOR UNMAPPED SYSTEMS ; WHY (????????) .ENDC .LOC SCZMX ; THIS LOCATION BEING NON-ZERO TELLS "BOOT" 1 ; THIS IS AN RDOS SYSTEM SAVE FILE. ; ALSO SAYSn SYSTEM IS UNSQUASHABLE WHICH ; IS A NOW DISCARDED FEATURE OF THE OPERATING ; SYSTEM. .LOC SCCPL ; LOCATION SET BY "BOOT" TO INDICATE WHETHER SCPPL ; SYSTEM LOADED FROM PRIMARY OR SECONDARY ; PARTITION .LOC SCPB1 ; SET BY "BOOT" TO DISK BLOC:K NUMBER OF START 0 ; OF PARTITION THAT SYSTEM WAS LOADED FROM. .LOC SCPBA ; NORMALY LOAD IS FROM PRIMARY PARTITION SCPPA ; SO VALUES PRESENT ARE THE ONES USED. .LOC SCOF1 ; SET BY "BOOT" TO START DISK ADDRESS OF THE 0 ; SYSTEM OVERLAY FILE. IF THESE WORDS ARE .LOC SCOFA ; ZERO THEN NO OVERLAY FILE WAS PRESENT AT 0 ; "BOOT" TIME. .LOC SCBAS ; ="SCSWC". THIS LOCATION HOLDS TWO MEANINGS -1 ; FOR "BOOT" THE NAME "SCBAS" IS USED AND THE ; HOLDS THE ADDRESS OF THE DATA PACKET LEFT BY ; "BOOT" OF THE SYSTEM NAME AND WHERE IT CAME ; FROM. THE PACKET HAS THE FORM: ; WORDS (-15)-(-14) DEVICE NAME (DP0,DP4F,...) ; WORDS (-13)-(-20) SECONDARY PARTITION ; NAME. PRESENT IF "SCCPL" ; NOT EQUAL TO ZERO. ; WORDS (-7)-(-1) SYST\EM NAME ; FOR ALL OTHERS "SCSWC" IS USED ; TO INDICATE WHETHER A FULL/PARTIAL INIT IS ; TO BE DONE. WHEN LOADED BY "MCABOOT" THIS ; LOCATION IS SET BY "MCABOOT" TO INDICATE ; WHAT IS TO BE DONE. FOR ALL OTHERS, THE USER ; IS ASKED WHETH^3ER FULL/PARTIAL IS TO BE DONE ; ONCE START UP ROUTINE GETS GOING. MINUS ONE ; INDICATES FULL INIT TO BE DONE, ONE INDICATES ; PARTIAL INIT TO BE DONE. IF NOT PAPERTAPE ; OR "MCABOOT" THEN USER IS GIVEN OPTION OF DOING ; PARTIAL INIT WITHOUTa OVERLAY LOAD. IN THIS CASE ; THIS LOCATION IS NOT SET. .LOC SCIDV ; LOCATION HOLDS DEVICE CODE OF DEVICE FROM WHICH 0 ; FROM WHICH SYSTEM WAS BOOTED. IS SET TO ZERO ; IF SYSTEM WAS BOOTED FROM PAPERTAPE .LOC 377 ; RESTART ADDRESS FOR PAPER TAmPE JMP @SCINT .ZREL .DO ?USW&?ANSW ** .NOLOC 1 PRMPT: .TXT /<15><12>NOVA RDOS REV 6.30<15><12>/ ** .NOLOC 0 .ENDC .DO ?MSW&?NSW ** .NOLOC 1 PRMPT: .TXT /<15><12>MAPPED NOVA RDOS REV 6.30<15><12>/ ** .NOLOC 0 .ENDC .DO ?MSW&?N3SW ** .NOLOC 1 PRMPT:$ .TXT /<15><12>MAPPED NOVA 3 RDOS REV 6.30<15><12>/ ** .NOLOC 0 .ENDC .DO ?USW&?BSW ** .NOLOC 1 PRMPT: .TXT /<15><12>ECLIPSE RDOS REV 6.30<15><12>/ ** .NOLOC 0 .ENDC .DO ?RDOS&?MSW&?BSW&B?MSW ** .NOLOC 1 PRMPT: .TXT /<15><12>MAPPED ECLIPSE RDOS REV 6.30<y15><12>/ ** .NOLOC 0 .ENDC .DO ?RDOS&?MSW&?BSW&BB?MSW ** .NOLOC 1 PRMPT: .TXT "<15><12>MAPPED ECLIPSE (S/130,S/230,C/330) RDOS REV 6.30<15><12>" ** .NOLOC 0 .ENDC .DO ?INFOS&?MSW&?BSW&B?MSW ** .NOLOC 1 PRMPT: .TXT "<15><12>INFOS (C/300) REV 2.30<15><12>"˴ ** .NOLOC 0 .ENDC .DO ?INFOS&?MSW&?BSW&BB?MSW ** .NOLOC 1 PRMPT: .TXT "<15><12>INFOS (C/330) REV 2.30<15><12>" ** .NOLOC 0 .ENDC .END CLIBT1.SRB ł.LCNS ;COPYRIGHT (C) DATA GENERAL CORPORATION,1972,1973,1974,1975,1976,1977 ;ALL RIGHTS RESERVED ;LICENSED MATERIAL-PROPERTY OF DATA GENERAL CORPORATION RTITLE CLIBT ; THIS IS SOURCE FILE "CLIBT1.SR" - MUST BE ASSEMBLED WITH "CLIBT2.SR". .TXTM 1 U.ENT CLIBT CLIBU ** .NOCON 1 ; DONT LIST CONDITIONAL CODE ; DEFINE STACK DISPLACEMENTS .DUSR ORTN= -4 ; OLD RETURN ADDRESS .DUSR OAC0= -3 ; OLD AC0 .DUSR OAC1= -2 ; OLD AC1 .DUSR OAC2= -1 ; OLD AC2 .DUSR RTN= 0 ; RETURN ADDRESS .DUSR AC0= 1 ; AC0 .DUSRx AC1= 2 ; AC1 .DUSR AC2= 3 ; AC2 .DUSR STKSZ= AC2+1 ; STACK LENGTH ; DEFINE OTHER MISC STUFF .DUSR ENTR= STA 3,@USP ; DEFINE THE SUBROUTINE ENTRY .DUSR NOP= 401 ; JMP .+1 .DUSR CH0= 0 ; DEFINE THE CHANNELS .DUSR CH1= 1 .DUSR CH2= 2 .DUSR UNDX1= 22 ; DEFINE AN AUTO INC LOC .DUSR ERUNK= -1 ; DEFINE UNKNOWN ERROR CODE .MACRO ZREL ** .DO .MCALL==0 ** I=50 ** PZSIZ= 0 ** .ENDC ** K=1 ** LOC= (.LOC) ** .DO .ARGCT/2 ** ^K=I ** .LOC BUF1+PZSIZ ** K=K+1 ** ^K ** K=K+1 ** PZSIZ=PZSIZ+1 ** I=I+1 ** .ENDC ** .LOC  *LOC % .NREL CLIBT: ; NOTE - MUST BE AT DISPLACEMENT 0 FOR MRDOS BUF1: .BLK 210 ; BUFFER FOR LOAD AND TEMP STORAGE ; FOR PAGE ZERO BUF2: .BLK 400 ; INPUT BUFFER ; PAGE ZERO STUFF ZREL TEM0P TEMP0 ; POINTER TO FIRST ADDRESS OF TEMPS ZREL TEMP0 0 ; rTEMPS FOR ALL KINDS OF THINGS ZREL TEMP1 0 ZREL TEMP2 0 ZREL TEMP3 0 ZREL TEMP4 0 ZREL TEMP5 0 ZREL TEMP6 0 ZREL TEMP7 0 ZREL TEMP8 0 ZREL TEMP9 0 ZREL CHAN 0 ; CHANNEL # FOR SYSER ZREL BUF1P BUF1*2 ; BYTE POINTER TO LOAD BUFFER ZREL FLAG 0 ; FULL/PARTIAL FLAG ZREL CLINP MSCLI*2 ; POINTER TO "CLI.SV" ZREL K6 6 ; CONSTANTS ZREL K12 12 ZREL K15 15 ZREL K1000 1000 ZREL GETBS BUF2*2 ; START OF GET BUFFER ZREL GCOUN 1 ; GET COUNTER CLIST: LDA 1,.PZSIZ ; MOVE PAGE ZERO TO LDA 2,.BUF1 ; WHERE IT REALY BELONGS| LDA 3,PZSTR CLIS1: LDA 0,0,2 STA 0,0,3 INC 2,2 INC 3,3 INC 1,1,SZR JMP CLIS1 LDA 0,USP ; SAVE FULL PARTIAL FLAG STA 0,FLAG FLUSH ; FLUSH THE SYSTEM AND SET STACK LDA 0,KCPU ; ENABLE CPU FOR EL MAPO .SYSTM .DEBL NOP READS 1 ; READ THE SWITPCHES LDA 0,RSTNP ; AC0 > RESTART.SV COM# 1,1,SZR ; AUTO RESTART ?? JMP DATE CLIS2: .SYSTM ; RESET THE WORLD .RESE NOP STA 0,TEMP0 ; SAVE NAME IN CASE OF ERROR SUBZR 1,1 ; AC1 = CHAIN SUB 2,2 ; FOR CLI .SYST ; BYE BYE .EXEC ERPNT ; HELLO ?? FLUSH ; CLEAN UP DATE: LDA 0,TTIP ; OPEN TTI SUB 1,1 ; DON'T SUPPRESS ANYTHING .SYSTM .OPEN CH0 SYSER JMP DATES ; GO GET DATES TTIP: TTIN*2 RSTNP: MSRST*2 .PZSIZ: ZRSIZ .BUF1: BUF1 PZSTR: 50 ; START OF PAGE ZERO DATER: WRLI ; AN ERROR GIVE HIM SOMETHING TO STUDY MSDER*2 TEMP3 TEMP4 TEMP5 CPU DATES: LDA 0,KSLA ; SET SLASH AS DELIMITER STA 0,TEMP7 WRLI ; ASK FOR DATE MSDAT*2 CPU JSR GETT ; GO GET DATE JMP DATES ; TOO BAD LDA 2,TEMP5 ; GET YEAR LDA 1,GD19K ; TAKE OUT CENTURY SUBZ 1. ,2,SNC ; COME OUT ?? ADD 1,2 ; NO PUT IT BACK LDA 1,GD68 ; TAKE OUT DAY 0 SUBZ 1,2,SNC ; COME OUT ?? JMP DATER ; NO TRY AGAIN LDA 0,TEMP4 ; GET DAYS LDA 1,TEMP3 ; AND MONTHS MOV 0,0,SZR ; ZERO DAY ? MOV 1,1,SNR ; OR MONTH ?? JMP DATER ; YES-x - CAN'T LET THAT HAPPEN .SYSTM ; TRY TO SET DATE .SDAY JMP DATER ; TRY TRY AGAIN JMP TIMES TIMER: WRLI ; WRITE TIME ERROR MESSAGE MSTER*2 TEMP3 TEMP4 TEMP5 CPU TIMES: LDA 0,KCOL ; SET : AS LIMITER STA 0,TEMP7 WRLI MSTIM*2 CPU JSR GETT ; GET TIME JMP TIMES ; BAD NEWS LDA 0,TEMP5 LDA 1,TEMP4 LDA 2,TEMP3 .SYSTM ; TRY TO SET TIME OF DAY .STOD JMP TIMER JMP TYPE ; GO SEE WHAT TYPE OF INITIALIZATION GD68: 68. GD19K: 1900. KCOL: ": KSLA: "/ GETT: ENTR ; SAVE ALL SAV? LDA 0,K3 ; SET ENTRY COUNT STA 0,TEMP2 LDA 2,TEM0P ; POINT TO TEMP0 ADD 2,0 STA 0,TEMP6 ; POINT TO TEMP3 SUB 0,0 ; CLEAR RESULT WORDS STA 0,TEMP3 STA 0,TEMP4 STA 0,TEMP5 LDA 0,BUF1P ; READ THE LINE .SYSTM .RDL CH0 SYSER ; COME ON ! GETT1: DECO ; CONVERQT TO OCTAL STA 1,@TEMP6 ; STORE IT ISZ TEMP6 ; POINT TO NEXT ENTRY LDBT ; AC1 = TERMINATOR LDA 2,K40 SUB# 2,1,SNR ; A SPACE ?? JMP NEXT ; YES CONTINUE LDA 2,TEMP7 ; A WHATEVER ?? SUB# 2,1,SNR JMP NEXT ; YES GO TO IT LDA 2,K15 SUB# 2,1,SNR ;k: A CR ?? JMP GETTR ; YES DONE STA 1,TEMP8 ; STOW ILLEGAL CHARACTER WRLI ; SEND ERROR MESAGE MSILG*2 TEMP8 KCPU: CPU RET? ; TRY AGAIN NEXT: DSZ TEMP2 ; DONE THREE ?? JMP GETT1 ; NO TRY AGAIN GETTR: ISZ ORTN,3 ; BUMP RETURN RET? ; GO HOME K3: O3 K40: 40 TYPE: LDA 1,FLAG ; PICK UP TYPE OF INIT COM# 1,1,SZR ; PARTIAL ?? JMP TAPI1 ; YES GO TO IT FLUSH ; RESET ALL LDA 2,SCIDV ; AC2 = DEVICE CODE LDA 1,MTC ; AC1 = MAG TAPE DEVICE CODE LDA 0,MTDEV ; AC0 -> MT0 SUB 2,1,SNR ; MAG TAPE ?? JMP6 TAPIN ; YES INIT IT LDA 1,CAC LDA 0,CTDEV ; AC0 -> CT0 SUB 2,1,SZR ; CASSETTE ?? JMP CKMCA ; NO CHECK MCA STA 0,MTDEV ; SAVE DEVICE (ONE TIME CODE) WRLI ; SEND CT0 PROMPT MESSAGE CTPRM*2 CPU .SYSTM ; WAIT FOR USER .GCHA SYSER ; CAN'T HAPμPEN TAPIN: LDA 0,MTDEV ; RESTORE BYTE POINTER TO DEVICE NAME ; SUB 1,1 ; PARTIAL INIT .SYSTM ; INIT IT .INIT SYSER JSR LOAD ; GO LOAD TAPE LDA 0,MTDEV ; RELEASE TAPE .SYSTM .RLSE SYSER TAPI1: FLUSH LDA 0,CLINP STA 0,TEMP0 ; SAVE IN CASE OF ERROR SUBZR 1,1 ; CHAIN SUB 2,2 STA 2,CHAN ; SAVE CHAN FOR ERROR .SYSTM .EXEC NOP ; YOU AGAIN *** SYSER ; THATS ALL ; SEE IF PRIMARY OR SECONDARY MCA CKMCA: LDA 0,PMCBP ; ASSUME PRIMARY LDA 1,DMASK ; AC1 = UNIT MASK ANDS 2,1 ; AC1 = UNIT LDA 3,K377 ; AC3 = DEVICE CODE MASK AND 3,2 ; AC2 = DEVICE CODE LDA 3,MCB SUBZ# 3,2,SNR ; PRIMARY ?? JMP CKMCG ; YES GO SEE ABOUT UNIT NUMBER LDA 3,MCC SUBZ# 3,2,SZR ; SECONDARY ?? JMP CKMCE ; NO GO TO LOAD LDA 0,SMCBP ; AC0 -> TO NAME CKMCG: STA 24w,SCIDV ; SAVE DEVICE CODE MOV 0,2 ODEC ; PUT IN UNIT NUMBER 2B14+0 ; TWO DIGITS NO SIGN LDA 2,SCIDV ; RESTORE DEVICE CKMCE: LDA 3,USP JSR LOAD ; GO DO LOAD JMP TAPI1 ; GO TO CLI.SV DVTAB: .+1 CAC: CAS DV34*2 MTC: MTA DV22*2 PTR DV12*2 TTI HDV10*2 MCB: MCAR DV7*2 MCC: MCAR1 DV47*2 -1 DMASK: 17*400 PMCBP: DV7*2+5 SMCBP: DV47*2+6 MTDEV: MSMTA*2 CTDEV: MSCTA*2 DEVER: MOV 2,0 ; SAVE DEVICE CODE LDA 2,K377 ; ERROR CODE 377 SYSER ; THATS IT ;LOAD ; LOAD RDOS STYLE DUMP TAPES LOAD: ENTR3 SAV? ISZ TEMP7 ; SET END COUNTER TO 1 ISZ TEMP9 ; SET DUMMY COUNTER LDA 3,DVTAB ; POINT TO DEVICE TABLE LOAD3: LDA 1,0,3 ; GET A DEVICE CODE INC 3,3 ; BUMP POINTER INC 3,3 COM# 1,1,SNR ; END OF TABLE JMP DEVER ; YES SEND BAD NEWS SUB# 2,1,SZR ; THIS ONE IT ?? JMP LOAD3 ; NO TRY AGAIN LDA 0,-1,3 STA 0,TEMP1 ; SAVE FILE NAME LOAD0: SUBZL 1,1 ; INIT BUFFER COUNT TO ZERO (1) STA 1,GCOUN LDA 1,K400 ; OPEN FILE WITH NO PARITY CHECK .SYSTM .OPEN CH1 ; OPEN INPUT FILE SYSER LOAD1: LDA 0,BUF1_CP ; SKIP LEADER SUBZL 1,1 RDS LDBT ; GET THE BYTE MOV 1,1,SNR ; NULL JMP LOAD1 ; YES TRY AGAIN LDA 2,LODSP ; POINT TO DISPATCH TABLE LOOK ; DISPATCH TO PROPER ROUTINE JMP @1,2 LODSP: .+1 K377: 377 LONAM ; NAME BLOCK 376 LODAT ; DATA BLOC K 375 LOERR ; ERROR BLOCK 374 LOEND ; END BLOCK 373 LOTIM ; TIME BLOCK 372 LOLIN ; LINK BLOCK 371 LOLAT ; LINK ATTRIBUTE BLOCK 370 LODUM ; DUMMY BLOCK -1 LOBAD ; ILLEGAL BLOCK TYPE ; ; PROCESS A NAME BLOCK LONAME: LDA 0,TEMP7 ; SET/ƀRESET IGNORE FLAG MOVZR 0,0 STA 0,TEMP4 LOFIN: LDA 0,TEMP2 MOVZL 0,0,SNR ; OUTPUT CHANNEL OPEN JMP LONA0 ; NO CONTINUE LDA 0,ATRIB ; SET ATTRIBUTES .SYSTM .CHATR CH2 SYSER ; BAD NEWS LDA 0,LINAT .SYSTM .CHLAT CH2 SYSER SUB 0,0 ; CLEAR ....4.. STA 0,ATRIB STA 0,LINAT STA 0,CLENG STA 0,TEMP8 CLOS ; YES CLOSE IT CH2 SUBZR 0,0 ; MARK IT CLOSED STA 0,TEMP2 LONA0: LDA 0,TEMP7 MOV 0,0,SNR ; ALL DONE ?? RET? ; YES RETURN READ ; READ ATTRIBUTES CH1 SYSE STA 1,ATRIB ; SAVE ATTRIBUTE0S LDA 2,ADIR AND 1,2,SZR ; DIRECTORY ?? ISZ TEMP7 ; YES BUMP END BLOCK COUNT LDA 2,ACONT AND 1,2,SNR ; CONTIGUOUS ?? JMP LONA1 ; NO CONTINUE READ ; YES SKIP BLOCK CLUNT CH1 SYSE STA 1,CLENG ; SAVE LENGTH LONA1: LDA 0,LOBFP ; READ FILE NAME RDL JMP LOAD1 ; CONTINUE ATRIB: 0 LINAT: 0 CLENG: 0 ; ; PROCESS AN ILLEGAL BLOCK TYPE LOBAD: MOV 1,0 ; SEND ILLEGAL BLOCK TYPE MESSAGE LDA 2,K310 SYSER K310: 310 ACONT: ATCON ADIR: ATDIR ARAND: ATRAN K400: 400 ; ; PROCESS A LINK ATTRIBUTE BLOCK L+OLAT: READ ; READ ATRIBUTES CH1 SYSE STA 1,LINAT ; SAVE LINK ATTRIBUTES JMP LOAD1 ; CONTINUE ; ; PROCESS A LINK BLOCK LOLIN: LDA 0,BUF1P RDL NEG 1,1 ADC 1,0 ; POINT TO TERMINATOR MOV 0,2 LDA 0,BUF1P LDA 1,CCOL SUB# 0,2,SZR ; A DIRECTORY ?? USTBT ; YES STORE A ":" MOV 2,0 RDL NEG 1,1 ADC 1,0 LDA 1,TEMP4 MOV 1,1,SZR ; IGNOR SET ?? JMP LODA2 ; YES GET NEXT BLOCK LDA 1,BUF1P SUB# 0,1,SNR ; ANYTHING ?? SUB 1,1 ; NO SET TO 0 LDA 0,LOBFP ; AC0 -> NAME .SYSTM .LINK JMP LOCER JM%P LODA2 ; CONTINUE ; ; PROCESS A DATE/TIME BLOCK LOTIM: LDA 1,K6 ; TIME BLOCK SKIP SIX WORDS LDA 0,TBUFP RDS STA 0,TEMP8 ; SHOW WE HAD TIME BLOCK JMP LODA2 ; PROCESS NEXT BLOCK ; ; PROCESS AN END BLOCK LOEND: DSZ TEMP7 ; DONE ?? JMP LODA2 ; NO PROCESS NEXT BLOCK CLOS ; CLOSE INPUT CHANNEL CH1 JMP LOFIN ; GO CLOSE FILE IF NECESSARY ; AND EXIT ; ; PROCESS AN ERROR BLOCK LOERR: WRLI LOEMS*2 CPU ISZ TEMP4 ; SET NO LOAD JMP LODA2 ; PROCESS NEXT BLOCK TBUFP: TBUF*2 CCOL: ": ; ; PROCESS FILE NAME LDA 1,ATRIB ; AC1 = ATTRIBUTES LDA 3,ARAND AND 1,3,SZR ; RANDOM ?? JMP CRAND LDA 3,ACONT AND 1,3,SZR ; CONTIG ?? JMP CCONT ; YES GO TO IT MOVZR 2,2,SZR ; DATE BLOCK ? JMP TCREA ; YES DO TRANSPAR CREAT .SYSTM .CREA JMP LOCER J+MP LOPEN ; GO OPEN IT TCREA: .SYSTM .TCREA JMP LOCER JMP LOPEN ; GO OPEN IT LOBFP: LOBUF*2 CRAND: MOVZR 2,2,SZR ; DATE BLOCK ?? JMP TCRAN ; YES DO TRAN THING .SYSTM ; NO DO REGULAR THING .CRAN JMP LOCER JMP LOPEN ; GO TO OPEN TCRAN: .SYSTM  ; USE TIME FROM TAPE .TCRND JMP LOCER JMP LOPEN CCONT: LDA 1,CLENG ; GET LENGTH MOVZR 2,2,SZR ; DATE BLOCK ?? JMP TCCON ; YES DO TRANS CCONT .SYSTM ; NO DO NORMAY CCON .CCON JMP LOCER TCCON: .SYSTM .TCCON JMP LOCER JMP LOPEN LOPEN: OPEW eo CH2 SYSE LODA4: LDA 0,BUF1P ; YES WRITE OUT DATA LDA 1,TEMP5 .SYSTM .WRS CH2 SYSER LODA2: JMP @.+1 ; CONTINUE LOAD1 LOCER: LDA 1,.ERCR SUB# 1,2,SZR ; FILE ALREADY EXISTS ?? SYSER ; NO WE TRIED ERPNT ; YES GIVE ERROR ISZ TEMP4 ; SET NOLOA[D JMP LODA2 ; AND PROCESS NEXT BLOCK .ERCR: ERCRE ; LODUM ; PROCESS DUMMY BLOCKS - IE EOT BLOCKS LODUM: READ ; READ "ATTRIBUTES" CH1 SYSE COM# 1,1,SZR ; -1 ?? JMP LOCKS ; NO MUST BE READ ERROR ISZ TEMP9 ; YES BUMP TAPE NUMBER READ ; READ TAPE NUMBER CH1 SYSE STA 1,TEMP5 ; SAVE TAPE NUMBER LDA 0,BUF1P ; READ NAME INTO A SAFE PLACE RDL LDA 1,TEMP9 MOVZR 1,1 MOV 0,0,SZC ; EOT ?? JMP LODET ; YES GO TO IT STA 1,TEMP3 ; NO SAVE NUMBER FOR ERROR LDA 0,TEMP5 ; ACO = TAPE NUMBER READ  SUB 1,0,SZR ; == ?? JMP LODMB ; NO TELL THE DUMMY LDA 0,BUF1P ; AC0 -> NAME READ LDA 2,LOBFP ; AC2 -> NAME EXPECTED STCOM ; NAME CORRECT ?? JMP LOFST ; NO - BUT MAY BE OK LODUR: JMP @.+1 ; YES - ALL IS WELL RETURN LOAD1 LODMB: WRLI ; TELL HMIM OF HIS BLUNDER LOMWT*2 BUF1P TEMP5 LOBFP TEMP3 CPU DSZ TEMP9 ; PRETRND IT DIDN'T HAPPEN LODET: CLOS ; CLOSE INPUT CHANNEL CH1 LDA 0,TEMP1 ; PICK UP INPUT FILE NAME JMP @.+1 LOAD0 ; AND GO OPEN IT AGAIN LOCKS: LDA 2,K305 ; CHECKSUM ERROR  LDA 0,LOBFP ; AC0 -> FILE NAME SYSER ; GIVE ERROR LOFST: MOVZR 1,1,SNR ; FIRST TIME ?? JMP LODUR ; YES JUST RETURN JMP LODMB ; NO TELL THE DUMMY K305: 305 ;CLOS ; CLOSE THE CHANNEL FOLLOWING THE CALL ; CALLING SEQUENCE ; CLOS ; (CHANNEL NUMBzER) ; (RETURN) ; CHANNEL CLOSED ZREL .CLSR CLOSR CLOS= JSR @.CLSR CLOSR: ENTR ; SAVE ALL SAV? LDA 2,@ORTN,3 ; GET THE CHANNEL NUMBER ISZ ORTN,3 ; BUMP THE RETURN STA 2,CHAN ; SAVE CHANNEL IN CASE OF ERROR .SYSTM .CLOS CPU ; CLOSE THE CHANNEL SYS'ER ; AN ERROR PUNISH RET? ;FLUSH ; ROUTINE TO RESET THE SYSTEM, FLUSH OUT TEMPS 0-9 AND RESET THE ; STACK POINTER (USP) TO THE TOP OF THE STACK. ; CALLING SEQUENCE ; FLUSH ; (RETURN) ZREL .FLUS FLUSR FLUSH= JSR @.FLUS FLUSR: STA 3,FLURT ; SAVE REzTURN .SYSTM .RESE NOP LDA 0,FLSTP ; RESET STACK POINTER TO TOP STA 0,USP LDA 3,TEM0P ; CLEAR OUT TEMPS LDA 2,K12 SUB 0,0 FLUS1: STA 0,0,3 ; CLEAR A TEMP INC 3,3 ; BUMP POINTER ADC 0,2,SZR ; DONE ? JMP FLUS1 ; NO DO NEXT JMP @FLURT ; YES RETURN FLURT: 0 FLSTP: STACK ;LDBT ; ROUTINE TO LOAD BYTE POINTED TO BY AC0 ; CALLING SEQUENCE ; LDA 0,(BYTE POINTER) ; LDBT ; (NORMAL RETURN) ; ACO UPDATED ; AC1 CONTAINS BYTE IN BITS 8-15 ZREL .LDBT LDBTR LDBT= JSR @.LDBT LDBTR: ENTR ; SAVE ALL SAV? ISZ OAC0,3 ; BUMP POINTER MOVZR 0,2 ; MAKE BYTE POINTER A WORD POINTER LDA 1,0,2 ; AC1 = WORD LDA 0,K377M ; AC0 = MASK MOV 0,0,SNC ; WHICH HALF ?? MOVS 1,1 ; LEFT SWAP WORD AND 0,1 ; MASK OUT HIGH ORDER HALF STA 1,OAC1,3 ; RETURN BYTE TO CALLER RET? ;STBT ; ROUTINE TO STORE THE BYTE IN BITS 8-15 OF AC1 IN THE LOCATION ; POINTED TO BY AC2 ; CALLING SEQUENCE ; LDA 2,(BYTE POINTER) ; STBT ; (NORMAL RETURN) ; AC2 UPDATED & BYTE STORED ZREL .STBT STBTR STBT= JSR @.STBT STBTR: ENTN~R ; SAVE ALL SAV? LDA 0,K377M AND 0,1 ; MASK TO 8 BITS JUST IN CASE ISZ OAC2,3 ; UPDATE BYTE POINTER MOVZR 2,3,SNC ; WHICH HALF ?? MOVS 1,1 ; LEFT SWAP BYTE LDA 2,0,3 ; GET DESTINATION WORD MOV 2,2,SZC ; WHICH HALF ? MOVS 0,0 ; RIGHT HALF 0SWAP MASK AND 2,0 ; CLEAR OUT DESTINATION ADD 1,0 ; ADD IN NEW BYTE STA 0,0,3 ; STORE UPDATED WORD RET? ; THAT'S ALL K377M: 377 ;LOOK ; LOOK FOR A MATCH BETWEN AC1 AND THE DISPATCH TABLE ; POINTED TO BY AC2. -1 IN DISPATCH TABLE MATCHES ALL ; WHEN A MATCH IS FOUND RETURN WITH AC2 POINTING TO MATCHING ; ENTRY. ; CALLING SEQUENCE ; LDA 2,(DISPATCH TABLE ADDRESS) ; LOOK ; (RETURN) ; AC2 -> MATCHNG ENTRY ZREL .LOOK LOOKR LOOK= JSR @.LOOK LOOKR: ENTR ; SAVE ALL SAV? LOOK1: LDA 0,0,2 ; GET NEXT.L ENTRY COM# 0,0,SZR ; MATCH ALL ? SUB 1,0,SNR ; OR MATCH JMP LOOK2 ; YES RETURN INC 2,2 INC 2,2 ; MOVE TO NEXT ENTRY JMP LOOK1 ; TRY AGAIN LOOK2: STA 2,OAC2,3 ; RETURN ERROR CODE RET? ;OCTA ; OCTAL TO ASCII CONVERSION ROUTINE ; CALLING SEQDUENCE ; LDA 2,(DESTINATION BYTE POINTER) ; LDA 1,(OCTAL VALUE) ; OCTA ; (RETURN) ; AC2 UPDATED ; UNDX1 DESTROYED ZREL .OCTA OCTAR OCTA= JSR @.OCTA OCTAR: ENTR ; SAVE ALL SAV? LDA 0,OCTA3 ; POINT TO POWER OF 2 TABLE STA 0,UNDX1 ; SAVE IN AUTO INC LOC MOV 1,0 ; SAVE VALUE OCTA1: LDA 1,K60 ; PICK UP AN ASCII 0 LDA 2,@UNDX1 ; GET POWER MOV 2,2,SNR ; END OF TABLE ? RET? ; YES RETURN OCTA2: SUBZ 2,0,SZC ; NO POWER GO IN ? INC 1,1,SKP ; YES BUMP CHARACTER AND TRY AGAIN ADD 2,0,SKP ; ϭNO RESTORE VALUE AND OUTPUT CHARACTER JMP OCTA2 LDA 2,OAC2,3 ; PICK UP BYTE POINTER ISZ OAC2,3 ; BUMP BYTE POINTER STBT ; STORE CHARACTER JMP OCTA1 ; CONTINUE OCTA3: . ; ADDRESS OF POWER OF TWO TABLE 100000 ; 2**15 10000 ; 2**12 1000 ; 2**9 100 ; 2**6 10 ; 2**3 1 ; 2**0 0 ; END OF TABLE ;ODEC ; OUTPUT AC1 AS A DECIMAL STRING STARTING AT THE BYTE ; POINTED TO BY AC2. OUTPUT SIGN AND THE NUMBER OF ; DIGITS AS INDICATED IN THE WORD FOLLOWING THE CALL ; CALLING SEQUENCE ; LDA 2,(BYTVE POINTER FOR STRING) ; LDA 1,(VALUE) ; ODEC ; (NUMBER OF DIGITS)*2+(0 FOR NO SIGN OR 1 FOR SIGN) ; (RETURN) ; AC2 UPDATED ; ; STRING STORED ; UNDX1 DESTROYED ZREL .ODEC ODECR ODEC= JSR @.ODEC ODECR: ENTR ; SAVE ALL SAV? LDA 2,@ORTN,3 ; GET COMMAND WORD ISZ ORTN,3 ; ADJUST RETURN ADDRESS LDA 0,K15 ; MAKE COUNT 6-COUNT SUBOR 2,0 ; AND SET CARRY TOREFLECT SIGN FLAG STA 0,ODESC ; SAVE COUNT MOV 0,0,SNC ; SIGNED ?? JSR ODECS ; YES GO PROCESS SIGN LDA 2,ODETB ; GET POWER TABLE STA 2,UNDX1 ; } AND STORE IN AUTO INC MOV 1,0 ; SAVE INPUT VALU ODEC1: LDA 1,K60 ; PICK UP ASCII 0 LDA 2,@UNDX1 ; GET POWER MOV 2,2,SNR ; END OF TABLE RET? ; YES RETURN ODEC2: SUBZ 2,0,SZC ; POWER GO IN INC 1,1,SKP ; YES BUMP CHARACTER AND TRY AGAIN ADD 2,0,SZ KP ; NO RESTORE VALUE AND OUTPUT JMP ODEC2 DSZ ODESC ; TIME TO OUTPUT YET JMP ODEC1 ; NO FORGET IT LDA 2,OAC2,3 ; YES GET BYTE POINTER ISZ ODESC ; FUDGE COUNT FOR NEXT TIME STBT ; STORE THE BYTE STA 2,OAC2,3 ; SAVE THE BYTE POINTER JMP ODEC1 ; AND CONTINUE ODECS: STA 3,ODTMP ; SAVE ALL LDA 3,USP ; RESTORE CSP MOV 1,0 ; SAVE VALUE LDA 1,K53 ; GET A PLUS SIGN MOVZL# 0,0,SZC ; NEGATIVE ? LDA 1,K55 ; YES GET A MINUS SIGN LDA 2,OAC2,3 ; GET BYTE POINTER FOR STORE STBT ; STORE THE S11 JMP DECO2 Ď; MUST BE BREAK CHARACTER LDA 2,DECRE ; GET PREVIOUS RESULT JSR DEMUL ; MULTIPLY BY 10 AND ADD NEW STA 2,DECRE ; SAVE NEW RESULT JMP DECO1 ; BACK TO MAIN LOOP K11: 11 K53: 53 K55: 55 K60: 60 DECO2: LDA 3,USP ; PICK UP CSP STA 0,OAC0,3 ; RETURN UPDATyED BYTE POINTER DSZ OAC0,3 ; ADJUST LDA 1,DECRE ; AC1 CONTAINS RESULT LDA 0,DECSI ; AC0 CONTAINS SIGN FLAG MOV 0,0,SZR ; - SIGN ? NEG 1,1 ; YES NEGATE VALUE STA 1,OAC1,3 ; RETURN VALUE RET? DEMUL: ENTR ; SAVE LINK MOVZL 2,3 ; *2 MOVZL 3,3 ; *.4 ADDZL 3,2 ; *10 ADD 1,2 ; ADD IN NEW LDA 3,USP ; RESTORE CSP JMP @0,3 ; RETURN DECSI: 0 DECRE: 0 ;OPER ;OPEW ; OPEN THE FILE POINTED TO BY AC0 ON THE CHANNEL NUMBER FOLLOWING THE ; CALL. IF OPER CHECK FOR READ PROTECT, IF OPEW CHECK FOR WRITEY PROTECT. ; IF PROTECTED GIVE ERROR RETURN. ; CALLING SEQUENCE ; LDA 0,(BYTE POINTER TO FILE NAME) ; OPE(R/W) ; (CHANNEL NUMBER) ; (ERROR RETURN) ; ERROR CODE IN AC2 ; (NORMAL RETURN) ; ATTRIBUTES IN AC1 ; BYTE POINTER TO FILE NAME IN TEMP(X) WHERE  ; X IS THE CHANNEL NUMBER ZREL .OPER OPRD ZREL .OPEW OPWR OPER= JSR @.OPER OPEW= JSR @.OPEW OPRD: MOVZ 0,0,SKP ; CARRY ZERO = READ OPWR: MOVO 0,0 ; CARRY ONE = WRITE ENTR ; SAVE ALL SAV? LDA 2,@ORTN,3 ; AC2 = CHANNEL NUMBER ISZ ORTN,3 ; BUMPBk RETURN LOCATION MOV 0,0,SZC ; READ OR WRITE ? JMP OPWR1 ; WRITE GO TO IT JSR OPEN ; READ - OPEN THE FILE AND GET ATTRIBUTES LDA 2,ATRPR MOVZL# 0,0,SZC ; READ PROTECTED ?? JMP OPRER ; YES GIVE ERROR RETURN ISZ ORTN,3 ; NO GIVE NORMAL RETURN P RET? OPWR1: JSR OPEN ; OPEN THE FILE LDA 2,ATWPR MOVZR# 0,0,SZC ; WRITE PROTECTED ? JMP OPRER ; YES GIVE ERROR ISZ ORTN,3 ; NO NORMAL RETURN RET? ATWPR: ATWP ATRPR: ATRP OPEN: ENTR ; SAVE LINK LDA 3,TEM0P ; FORM ADDRESS OF TEMP(X) ADD 2,3 STA 0,0,3 ; STORE BYTE POINTER IN TEMP(X) MOVZL 2,2,SNC ; USER SUPPLIED MASK ?? SUB 1,1 ; NO CLEAR AC1 MOVZR 2,2 ; MOVE BACK CHANNEL NUMBER WITHOUT BIT 0 .SYSTM .TOPEN CPU ; OPEN THE FILE JMP OPRER ; AN ERROR - TAKE ERROR RETURN .SYSTM ; GET THE _ATTRIBUTES .GTATR CPU JMP OPRER ; ERROR RETURN STA 0,OAC1,3 ; RETURN ATTRIBUTES IN AC1 JMP @0,3 ; RETURN OPRER: STA 2,OAC2,3 ; STORE ERROR CODE RET? ; AND TAKE ERROR RETURN CLIBT2.SRB O J} ; THIS IS SOURCE FILE "CLIBT2.SR" AND MUST BE ASSEMBLED WITH "CLIBT2.SR". ;READ ; READ A WORD (2BYTES) FROM THE CHANNEL FOLLOWING THE CALL ; INTO AC1 ; IF END OF FILE OCCURS TAKE NORMAL RETURN IF A BYTE HAS BEEN ; READ AND EOF RETURN IF NO BYTE HAS vBEEN READ. ; CALLING SEQUENCE ; READ ; (CHANNEL #) ; (END OF FILE RETURN) ; (NORMAL RETURN) ; AC1 CONTAINS WORD ZREL .REA READR READ= JSR @.REA READR: ENTR ; SAVE ALL SAV? LDA 2,@ORTN,3 ; GET CHANNEL NUMBER STA 2,CHAN ; SAVE CHANNEL IN CASE OF UQERROR ISZ ORTN,3 ; BUMP RETURN GET ; GET A BYTE RET? ; END OF FILE RETURN MOVS 1,0 ; SAVE THE BYTE GET ; GET SECOND BYTE MOV 0,1,SKP ; END OF FILE NO SECOND BYTE ADD 0,1 ; COMBINE THE BYTES STA 1,OAC1,3 ; RETURN THE WORD ISZ ORTN,3 ; GOOD RETURN RET? ; THATS IT ;RDS ; SIMULATE .SYSTM .RDS ZREL .REDS RDSR RDS= JSR @.REDS RDSR: ENTR ; SAVE ALL SAV? MOV 0,2 ; MAKE BYTE POINTER USEFUL NEG 1,0,SNR ; ZERO BYTES ? RET? ; YEP ALL DONE RDSR1: GET ; GET A BYTE SYSER ; EOF RETURN STBT ; STORE IT IN CALLERS SPACE INC 0,0,SZR ; DONE ?? JMP RDSR1 ; NO GET ANOTHER RET? ; THATS IT ;RDL ; SIMULATE READ LINE ZREL .REDL RDLS RDL= JSR @.REDL RDLS: ENTR ; SAVE ALL SAV? MOV 0,2 ; MAKE BYTE POINTER USEFUL SUB 0,0 ; ZERO BYTES TO STALRT RE1: GET ; GET A BYTE SYSER ; EOF RETURN INC 0,0 ; COUNT THIS BYTE STBT ; STORE IN USER SPACE MOV 1,1,SZR ; NULL - END OF LINE ?? JMP RE1 ; NO CONTINUE STA 0,OAC1,3 ; RETURN COUNT READ RET? ; RETURN ;GET ; GET A CHARACTER FROM THE INPUT ]CSTREAM ZREL .GET GETS GET= JSR @.GET GETS: ENTR SAV? ; SAVE ALL DSZ GCOUN ; ANY CHARACTERS LEFT ?? JMP GETS1 ; YES CONTINUE JMP GETMO ; NO GET SOME MORE GETS1: LDA 0,GETBP ; YES GET NEXT ONE LDBT ISZ GETBP ; BUMP POINTER STA 1,OAC1,3 ; RETURN־ BYTE TO CALLER ISZ ORTN,3 ; BUMP RETURN FOR GOOD READ RET? GETMO: LDA 0,GETBS ; GET START ADDRESS OF BUFFER STA 0,GETBP ; RESET BYTE POINTER LDA 1,K1000 .SYSTM ; READ 1000 BYTES .RDS CH1 JMP GETEF ; END OF FILE I HOPE GETM1: STA 1,GCOUN ; SAVE COAUNT JMP GETS1 ; CONTINUE GETEF: LDA 0,K6 ; TEST ERROR TO DETERMINE WHAT TYPE SUB# 0,2,SZR ; END OF FILE ??? SYSER ; NO BOMB OUT MOV 1,1,SNR ; ANYTHING COME IN ?? RET? ; NO ERROR RETURN JMP GETM1 ; YES CONTINUE GETBP: 0 ;SAV? ; SAVE REGISTERS ROUuTINE ; CALLING SEQUENCE ; ENTR ; SAV? ; (NORMAL RETURN) ; AC3 -> UPDATED STACK POINTER ZREL .SSAV SAVER SAV?= JSR @.SSAV SAVER: STA 3,SAC3 ; SAVE SUBROUTINE ENTRY POINT LDA 3,USP ; AC3 = OLD STACK POINTER STA 0,AC0,3 ; SAVE AC'S STA 1,AC1,3 STA 2',AC2,3 LDA 2,SSIZE ; ADJUST STACK POINTER ADD 2,3 STA 3,USP ; SAVE NEW STACK POINTER LDA 2,OAC2,3 ; RESTORE AC2 JMP @SAC3 ; ENTER SUBROUTINE SAC3: 0 ; TEMP STORAGE ;RET? ; ROUTINE TO RESTORE REGISTERS AND RETURN TO CALLER ; CALLING SEQUENCE w ; RET? ; NO RETURN FROM THIS ROUTINE IS POSSIBLE ; ; SINCE CONTROL IS PASSED TO THE CALLING PROGRAM ZREL .RET RTRNR RET?= JSR @.RET RTRNR: LDA 3,USP ; PICK UP STACK POINTER LDA 2,SSIZE ; REMOVE THIS STACK FRAME SUBC 2,3 STA 3,USP ; RESTORE USP LDA 0,AC0,3 ; RESTORE AC'S LDA 1,AC1,3 LDA 2,AC2,3 JMP @RTN,3 SSIZE: STKSZ ;STCOM ; COMPARE STRING POINTED TO BY AC0 TO STRING POINTED ; TO BY AC1. BOTH STRINGS MUST BE TERMINATED BY A NULL ; IF STRINGS COMPARE RETURN TO CALL +2 ELSE CALL +1 ; CALLING SEQUENCE ; LDA 0,(BYTE POINTER TO STRING 1 ; LDA 2,(BYTE POINTER TO STRING 2 ; STCOM ; (ERROR RETURN) ; (MATCH RETURN) ; ALL ACS PRESERVED ZREL .STCOM STCOR STCOM= JSR @.STCOM STCOR: ENTR ; SAVE ALL SAV? STA 0,STBP1 ; SAVE BYTE POINTERS STA 2,STBP2 STCO1: LDBT ; GET A BYTE FROM STRING 1 MOV 1,2 ; SAVE BYTE LDA 0,STBP2 LDBT ; GET A BYTE FROM FILE 2 SUB 1,2,SZR ; MATCH ? RET? ; NO TAKE ERROR RETURN MOV 1,1,SNR ; NULL ? JMP STCO2 ; YES TAKE NORMAL RETURN ISZ STBP1 ; BUMP BYTE POINTE(RS ISZ STBP2 LDA 0,STBP1 ; PICK UP POINTER TO FIRST STRING JMP STCO1 ; AND CONTINUE STCO2: ISZ ORTN,3 ; TAKE MATCH RETURN RET? STBP1: 0 STBP2: 0 ;SYSE ;SYSER ;ERPNT ; SYSTEM ERROR ROUTINES ; ZREL .SYSE SYSRR ZREL .SYSR SYSEE ZREL .ERPN SYSE0 SY؏SE= JSR @.SYSE SYSER= JSR @.SYSR ERPNT= JSR @.ERPN SYSRR: LDA 1,-2,3 ; PICK UP CHANNEL # STA 1,CHAN ; SAVE IT SYSEE: STA 0,SYAC0 ; SAVE ALL AC'S STA 1,SYAC1 STA 2,SYAC2 STA 3,SYAC3 JMP SYSE1 SYSE0: STA 0,SYAC0 ; DITTO STA 1,SYAC1 STA 2,SYAC2 STA ^3,SYAC3 ENTR ; SAVE ALL FOR ERPNT SAV? ADC 1,1,SKP ; SHOW ERPNT SYSE1: SUB 1,1 ; SHOW SYSER STA 1,SYSEF ; SAVE FLAG LDA 3,SYAC3 ; SEE IF ERROR RETURN FROM SYSTEM LDA 0,-3,3 ; GET WHAT SHOULD BE A SYSTEM CALL LDA 1,SSYST ; AND A SYSTEM CALL SUB 1m;,0,SZR ; A SYSTEM CALL ? JMP SYSE2 ; NO ASSUME CHANNEL IS IN CHAN LDA 0,-2,3 ; YES GET COMMAND WORD STA 0,SYCMN ; SAVE COMMAND WORD LDA 1,K77 AND 1,0 ; STRIP OUT COANNEL NUMBER SUB# 1,0,SNR ; ASSEMBLED CHANNEL NUMBER ? SYSE2: LDA 0,CHAN ; NO MuUST BE IN CHAN STA 0,SYCHN ; SAVE CHANNEL NUMBER LDA 2,TEM0P ; GET FILE NAME OUT OF TEMP(X) ADD 0,2 LDA 0,0,2 ; PICK UP POINTER TO NAME STA 0,SYAC1 ; SAVE FILE NAME POINTER LDA 2,ERTAP ; POINT TO ERROR DISPATCH TABLE LDA 1,SYAC2 ; AC1 = ERROR CODE =LOOK ; LOOK UP ERROR LDA 3,1,2 ; AC3 -> ERROR DATA LDA 0,0,3 ; GET ARGUMENT NUMBER INCZL 3,1 ; MAKE BYTE POINTER TO MESSAGE STA 1,SYSM1 ; SAVE IN MESSAGE SUBCR 1,1 ; SAVE FATAL FLAG LDA 3,SYARP ; AC3 -> ARGUMENT LIST ADD 0,3 LDA 0,0,3 ; GET ARGUMENT STA 0,SYSM2 ; STORE IT IN MESSAGE WRLI ; WRITE THE ERROR MESSAGE TO TTO SYSM1: 0 SYSM2 K77: CPU ISZ SYSEF ; ERPNT ? JMP SYSE3 ; NO GO TO TOP RET? ; YES RETURN SYSE3: .SYSTM .RESE NOP JMP . ; WAIT A LONG TIME SSYST: .SYSTM SYARP: SYAC0 SYSEF: 0 SYAC0: 0 SYAC1: 1 SYAC2: 2 SYAC3: 3 SYCHN: 4 SYCMN: 5 SYDUM: " SYSM2: 0 ERTAP: ERTAB ERTAB: ERFNM ; ERFNM IRFNM ERSV1 ; ERSV1 IRSV1 EREOF ; EREOF IREOF ERCRE ; ERCRE IRCRE ERDLE ; ERDLE IRDLE ERPAR ; ERPAR IRPAR ERMEM 8 ; ERMEM IRMEM ERSPC ; ERSPC IRSPC ERFIL ; ERFIL IRFIL ERSEL ; ERSEL IRSEL ERADR ; ERADR IRADR ERDNM ; ERDNM IRDNM ERICB ; ERICB IRICB ERSDE ; ERSDE IRSDE ERMDE ; ERMDE IRMDE CCKER ; CCKER ICKER CILBK ; CILBK IILB7K 377 ; UNKNOWN DEVICE CODE IRUND ERUNK ; ERUNK IRUNK ** .NOLOC 1 IRFNM: 0 .TXT *<15>ILLEGAL FILE NAME ^T<15>* IRSV1: 0 .TXT *<15>NOT A SAVE FILE: FILE ^T<15>* IREOF: 1 .TXT *<15>END OF FILE: FILE ^T<15>* IRCRE: 0 .TXT *<15>FILE ALREADY EXISTS: FILE ^T<15>* IRDLE: 0 .TXT *<15>FILE DOES NOT EXIST: FILE ^T<15>* IRPAR: 1 .TXT *<15>PARITY ERROR: FILE ^T<15>* IRMEM: @6 .TXT *<15>NOT ENOUGH MEMORY AVAILABLE^A<15>* IRSPC: 1 .TXT *<15>OUT OF SPACE: FILE ^T<15>* IRFIL: 1 .TXT *<15>FILE READ ERROR: FILE ^T<15>* IRSEL: 0 .TXT *<15>UNIT INPROPERLY SELECTED: ^T<15>* IRADR: 0 .TXT *<15>ILLEGAL STARTING ADDRESS: FILE ^T<15>* IRDNM: 0 .TXT *<15>DEVICE NOT IN SYSTEM: DEVICE ^T<15>* IRICB: 0 .TXT *<15>INSUFFICENT CONTIGUOUS BLOCKS: FILE ^T<15>* ICKER: 1` .TXT *<15>CHECKSUM ERROR: FILE ^T<15>* IILBK: 0 .TXT *<15>ILLEGAL BLOCK TYPE: ^O<15>* IRSDE: @6 .TXT *<15>SYS.DR ERROR^A<15>* IRMDE: @6 .TXT *<15>SYS.DR ERROR^A<15>* IRUND: 0 .TXT *<15>UNKNOWN DEVICE CODE ^O<15>* IRUNK: @2 .TXT *<15>UNKNOWN ERROR CO.DE ^O<15>* CTPRM: .TXT *LOAD CT0, STRIKE ANY KEY<15><15>* MSDER: .TXT *ILLEGAL DATE ^D/^D/^D<15>* MSDAT: .TXT *DATE (M/D/Y) ? * MSTER: .TXT *ILLEGAL TIME ^D:^D:^D<15>* MSTIM: .TXT *TIME (H:M:S) ? * MSILG: .TXT *ILLEGAL CHARACTER ^A<15>* MSCLI: .TXT *CLI.STV* MSRST: .TXT *RESTART.SV* MSMTA: .TXT *MT0* MSCTA: .TXT *CT0* DV34: .TXT *CT0:0* DV22: .TXT *MT0:1* DV12: .TXT *$PTR* DV7: .TXT *MCAR:00* DV47: .TXT *MCA1R:00* DV10: .TXT *$TTR* LOEMS: .TXT *ERROR BLOCK - OUTPUT FILE VACANT<15><15>* LOMWT: .TXT *YOU LeOADED ^T TAPE# ^D<15> I WANT ^T TAPE# ^D..... TRY AGAIN <15>* ** .NOLOC 0 LOBUF: .BLK 12 TBUF: .BLK 3 ;WRLI ; WRITE FORMATED LINE ROUTINES ; WRLI - WRITE LINE WITH A .WRL ZREL .WRLI WRLIR WRLI= JSR @.WRLI WRLIR: ENTR ; SAVE ALL SAV? WRLI0: LDA 2,WG"RLOB ; SET UP OUTPUT POINTER LDA 0,@ORTN,3 ; AC0= BYTE POINTER TO MESSAGE ISZ ORTN,3 ; ADJUST RETURN LOC WRLI1: STA 2,WRLBP ; SAVE OUTPUT POINTER WRLI2: LDBT ; GET NEXT BYTE MOV 1,1,SNR ; END OF MESSAGE ? JMP WRLIF ; YES OUTPUT IT LDA 2,UPAR ; NO UPARROW ? SUB# 2,1,SZR JMP WRLI3 ; NO JUST STORE IT LDA 2,WRLTB ; YES DISPATCH TO APPRO ROUTINE LDBT ; GET THE COMMAND LOOK JMP @1,2 WRLI3: LDA 2,WRLBP ; AC2 = OUTPUT BYTE PONTER WRLI4: STBT JMP WRLI1 ; CONTINUE UPAR: 136 WRDEC: JSR WuzRGET ; GET VALUE ODEC ; CONVERT IT 2B14+0 ; 2 DIGITS NO SIGN JMP WRLI1 ; CONTINUE WROCT: JSR WRGET ; GET VALUE OCTA ; CONVERT TO ASCII JMP WRLI1 ; CONTINUE WRASC: JSR WRGET ; GET THE CHARACTER JMP WRLI4 ; AND GO STORE IT WRTEX: JSR WRGET ; GET THE BYTE POINTER STA 0,WRTMP ; SAVE MAIN BYTE POINTER MOV 1,0 ; MOVE THIS POINTER TO AC0 WRTE1: LDA 1,WRLEB ; AC1= END OF BUFFER SUBZ# 2,1,SNC ; LINE TOO LONG ?? JMP WRLIF ; YES PRINT WHAT WE HAVE LDBT ; NO GET NEXT BYTE MOV 1,1,SNR ; NULL ? JRMP WRTE2 ; YES BACK TO MAIN LOOP STBT ; NO STORE THE BYTE JMP WRTE1 ; AND TRY NEXT WRTE2: LDA 0,WRTMP ; RESTORE MAIN BYTE POINTER JMP WRLI1 ; AND RETURN WRWRD: JSR WRGET ; GET THE WORD MOVS 1,1 ; SWAP TO LEFT BYTE STBT ; STORE IT MOVS 1,1 ; GET RIGHT BYTE JMP WRLI4 ; STORE IT WRLBP: 0 WRTMP: 0 WRGET: ENTR ; SAVE RETURN LDA 3,USP ; RESTORE CSP LDA 2,@ORTN,3 ; GET ARGUMENT LDA 1,0,2 ISZ ORTN,3 ; BUMP RETURN LDA 2,WRLBP ; GET OUTPUT POINTER JMP @0,3 ; RETURN WRLIF: SUB 1,1 ; STORE NULL JUST IN CASE STBT LDA 0,WRLOB ; AC0 -> LINE ISZ ORTN,3 ; BUMP RETURN WRLI5: LDBT ; GET THE BYTE MOV 0,2 ; SAVVE BYTE POINTER WRLI6: MOV 1,0,SNR ; NULL ?? RET? ; YES RETURN .SYSTM .PCHAR NOP LDA 3,K15 LDA 1,K12 SUB# 3,0,SNR ; CR ?? JMPe WRLI6 ; YES FOLLOW IT WITH A LINE FEED MOV 2,0 ; RESTORE BYTE POINTER JMP WRLI5 ; AND DO NEXT WRLTB: .+1 "D WRDEC ; DECIMAL "A WRASC ; ASCII CHARACTER "W WRWRD ; WRITE WORD "T WRTEX ; TEST STRING "O WROCT ; OCTAL -1 SYSER ; BIG TROWUBLE WRLOB: WRLBF*2 WRLBF: .BLK 140./2 WRLEB: .-6*2 ; END OF BUFFER ** .NOLOC 1 TTIN: .TXT *$TTI* ** .NOLOC 0 STACK: .BLK STKSZ*10. ; RUNTIME STACK CLIBU: .IFE MSW!MBSW @UF1-CLIBU @UF2-CLIBU @UF3-CLIBU UF1: .BLK UFTEL UF2: .BLK UFTEL UF3: .BLK UFT&IsEL .ENDC ZRSIZ= -PZSIZ .END CLIST CLIEN.SRB &5y RTITLE CLIEND .NREL .ENT LCLID LCLID=. .END INIT1.SRDD 4 RTITLE INIT1 INI1 .NREL .TXTM 1 .ENT SSINI ; PARTIAL INIT ENTRY FROM ; "BOOT" .ENT SSINT ; FULL OR PARTIAL INIT ENTRY ; FORM EITHER "CBOOT", "TBOOT" ; OR PAPERTAPE .ENT SSINS ; ENTRY FROM "MCABOOT" WITH ; FULL/PARTIAL SWITCH SETX2 BY ; "MCABOOT" .ENT RDCH,TYCH .EXTN DLALM,ALMIN .EXTN ENVIR ; WORD CONTAINS ENVIRONMENT WORD ; WHICH INDICATES THE TYPE OF SYSTEM ; FOR UNMAPPED NOVA THE INIT CODE ; CHECKS TO SEE IF COMPUTER IS A ; NOVA 3 AND IF SO SETS THAT INTO ; ENVIRONMENT WORD INSTEAD OF ; SAYING PLAIN NOVA. .EXTN PTPSW ; SET TO (-1) BY INIT1 CODE TO ; INDICATE TO REST OF INIT CODE ; THAT INIT IS COMMING FROM ; PAPERTAPE. .EXTN P00DB ; SPARE DCB FOR BOOTING INTO PART .EXTN SIZIT .EXTWN CLIBT .EXTN SS .EXTN MSG ; ROUTINE TO PRINT MESSAGES POINTED ; TO BY A WORD POINTER IN AC2. .EXTN PT1,PT2 .EXTN MDCB .EXTN ADTDB .EXTN DIRR .EXTN CMPWD .EXTN PFLTB .EXTN SQ .EXTN TACT .EXTN CFREE .EXTN NCEL,MNSTK,BCEC .EXTN RTCDV ; RTCD DEVICE CODE .EXTN SYSQ .EXTN IVFWA,IVLWA .EXTN SYSTM ;PSEUDO TIME FOR BUFFER AGES .EXTN SYSFL .EXTN ITBL .EXTN TTIDC .EXTN BQ .EXTN OVBAS,OVBA1 .EXTN INTS .EXTN SYST ;SYSTEM CALL HANDLER .EXTN FCELL .EXTN PNIC .EXTN STK00,PS1 .EXTN OSNAM h.EXTN MVWD .EXTN PPDCB .EXTN .IPINIT,SENQ,.IPBQ .DO ?ANSW .EXTN SAVEM .EXTN RETN .EXTN USTKO .ENDC .DO ?ABSW .EXTN IUD .EXTN MAGIC .EXTN SSL .EXTN OVFLO .EXTN SSOVF .EXTN RTCDC ; REAL TIME CLOCK DCT .ENDC .DO ?MSW&?ABSW .EXTD VNIOC .EXTD STKMN .EXTN MAPST .ENDC .DO ?MSW .DO N?MSW!N3?MSW .EXTD CLSTB .ENDC .EXTD C31K .EXTD RMBLK .EXTN MDCH1,MDCH2 .EXTN NBUFT,NFUFT .EXTD SYSEN .EXTD BBLKC,BBLK1 .EXTD FBLKC,FBLK1 .ENDC .DO ?INFOS .EXTN INDYM ;IOCS -INIT DYN MAP .ENDC TESTN3 = 100010 ; ADI 1,0 TRAPS ON NOVA 3 ; ENTRY TO INIT FROM "BOOT". EXPECTS THAT "SCBAS" POINTS TO ; THE PARAMETER BLOCK LEFT BY BOOT OF WHERE WE ARE BOOTING TO. ; ALSO THAT "SCPBA"/"SCPB1" HAS IN IT THE DISK BLOCK NUMBER OF ; THE BASE OF THE PARTITION BEINwG BOOTED INTO. "SCOFA"/"SCOF1" ; CONTAINS THE BLOCK NUMBER WHERE THE SYSTEM OVERLAY FILE ; STARTS. ; MAKE SURE THAT THERE IS AN OVERLAY FILE PRESENT SSINI: LDA 0,SCOF1 ; GET HIGH/LOW PARTS OF THE LDA 1,SCOFA ; OVERLAY DISK ADDRESS SEQZ 1 ; IF ADDRESS IS ZERO JMP OVOK ; THEN NO OVERLAY FILE SNEZ 0 ; IS PRESENT SO WE MUST JMP OVERR ; GO REPORT ERROR AND HALT ; OVERLAY ADDRESS OK, SAVE IT FOR LATER USE OVOK: XSTA 0,OVBA1 XSTA 1,OVBAS ; GET ADDRESS WHERE PARAMETER BLOCK LEFT BY "BOOT" LIVES LDA 0,{SCBAS ; GET SPECIFIER BLOCK ADDRESS XLDA 1,= -SCFNL*2-1 ; SPECIFIER OFFSET ADD 1,0 ; FORM ADDRESS STA 0,.SCBAS ; SAVE FOR LATER ; GO FLAG AS PARTIAL INIT JMP SSPAR ; TELL USER NO OVERLAYS PRESENT ON "BOOT" AND THEN HALT OVERR: XLDA 2,= OVMSG ; OVERLAY ERROR MESSAGE XXJSR MSG HALT JMP .-1 ; ENTRY FROM "TBOOT", "CBOOT", AND PAPERTAPE. LOCATION ; "SCIDV" CONTAINS THE DEVICE CODE OF DEVICE FROM WHICH ; BOOT IS BEING DONE. CONTAINS ZERO IF BOOT IS FROM ; PAPERTAPE. PROGRAM ASKS USER WHETHER WANTS BGFULL/PARTIAL ; INIT. ; ASK THE USER WHETHER HE WANTS TO DO FULL/PARTIAL INIT SSINT: XLDA 2,= FULLOR XXJSR MSG ; NOW READ IN THE USERS ANSWER JSR RD2 ; READ IN UP TO 2 CHARACTERS SKIP ; 0 OR 1 CHARS + CR - FINE JMP SSINT ; DIDN'T TYPE CR, REPEAT T,HE ; QUESTION SNEZ 2 ; IF NO CHARS, ONLY CR JMP SSPOV ; THEN DO PARTIAL ELSE XLDA 1,= "F ; IF USER WISHES FOR SNE 1,2 ; A FULL INIT THEN JMP SSFUL ; LET HIM HAVE IT ELSE XLDA 1,= "P ; IF USER WISHES PARTIAL SEQ 1,2 ; THEN SKIP ELSE USER HAS JMP SSINT ; NOT ANSWERED CORRECTLY SO ; GO BACK AND ASK AGAIN ; USER WISHES TO DO PARTIAL INIT, SEE IF DOING IT FROM PAPERTAPE SSPOV: LDA 0,SCIDV ; IF NOT FROM PAPER TAPE THEN SEQZ 0 ; WE WILL ASSUME LOADING JMP WOVLY ; OF OVERLAYS ELSE ; LOADING FROM PAPERTAPE, ASK USER IF WISHES TO LOAD OVERLAYS XLDA 2,= OVMS XXJSR MSG ; GET USERS RESPONSE TO THIS QUESTION, (0=NO OVERLAYS, ; 1=OVERLAYS) JSR RD2 ; READ IN UP TO 2 CHARACTERS SKIP ; 0 OR 1 CHARACTER OK JMP SSPOV ; TOO MANY CHARS, GO ASK AGAIN SNEZ 2 ; IF JUST GOT CARRIAGE RETURN JMP NOVLY ; THEN ASSUME NO OVERLAYS ELSE XLDA 1,= "1 ; IF USER TYPED A ONE THEN SUB 1,2,SNR ; THEN DO INIT WITH OVERLAY JMP WOVLY ; OVERLAY LOAD ELSE SEQM1 2 ; IF USER TYPED A ZERO THEN SKIP JMP SSP:OV ; ELSE ERROR, GO ASK QUESTION AGAIN ; LOAD FROM PAPERTAPE WITH NO OVERLAYS, SET PAPERTAPE SWITCH NOVLY: ADC 2,2 ; SET PAPER TAPE SWITCH XXSTA 2,PTPSW ; FOR INIT2 ; ASK USER WHAT DISK WE ARE TO INIT XLDA 2,= BOMSG ; GET POINTER TO QUESTION JSR GMASTR ; ASK AND STORE DISK NAME ; FLAG AS PARTIAL INIT AND GO JOIN THE COMMON INIT CODE SSPAR: SUB 1,1 ; FLAG AS PARTIAL INIT JMP SSCMN ; JOIN COMMON CODE ; FLAG AS PARTIAL INIT WITH OVERLAYS WOVLY: SUBZL 1,1,SKP ; PARTIAL WITH OVERLAYS ; FLAG AS FULL  GET ADDRESS OF LAST BLOCK ; WRITE TO ALL FREE MEMORY, JUST TO BE A NICE PERSON ; AND TO PREVENT ERCC AND NOVA 3 PARITY FROM BELCHING IF ; SEMI-CONDUCTOR MEMORY. STA 3,0,3 ; STORE INTO FIRST WORD OF PAGE LDA 1,0,3 ; AND LOAD IT BACK. SUB# 1,3,SZR ;W IF MATCH, THEN MEMORY EXISTS JMP HIFND ; IF NOT, END OF MEMORY. LDA 1,M1777 ; -1777 PAGLP: INC 3,3 ; BUMP TO NEXT WORD IN PAGE STA 2,0,3  ; WRITE MEMORY INC 1,1,SZR ; DONE WITH PAGE ? JMP PAGLP ; NO- CONTINUE JMP MEMHI ; AND CONINUE 'TILL NO MvkORE MEMORY. M1777: -1777 ; AC2 = # BLOCKS ; AC0 = LAST BLOCK OF CLIBT HIFND: ; MAKE SURE ONLY HAVE BLOCK # XLDA 1,= MPAPH ; MASK ALL BUT PHYSICAL BLOCK # AND 2,1,SKP ; GET LAST BLOCK #+1 ; RELEASE BLOCKS INTO FREE BLOCK LIST, AC1=HIGHEST BLOCK ; TO R hELEASE, AC0=LOWEST BLOCK TO RELEASE HIF0: JSR RMBLK ; RELEASE BLOCK TO FREE NEG 1,1 ; DEC BLOCK # COM 1,1 ; BY 1 AND CHECK SEQ 1,0 ; IF NOT ALL RELEASED JMP HIF0 ; RELEASED THEN LOOP ELSE ; CALCULATE NUMBER OF BLOCKS IN POSSESION OF THE BACKGROUND LDA 1,BBLK1 ; GET # OF FREE BLOCKS XLDA 2,= 4 ; ADD IN 4 BLOCKS ALREADY ASSIGNED ADD 2,1 ; TO GET TOTAL # OF USER BLOCKS STA 1,BBLKC ; SAVE THIS FOR BACKGROUND ; SET THAT THE FOREGROUND HAS NO BLOCKS SUB 1,1 STA 1,FBLKC ; HAS NO BLOCKS AND STA]6 1,FBLK1 ; NO FREE BLOCKS .DO ?ANSW JMP IQUE ; GO SET UP THE Q'S .ENDC J JMP BLDMP ; GO LOAD UP THE MAP [J] BMVCT: 3 ; # OF BLOCKS OF CLIBT MAPPING LPOOL ; LOAD UP THE A AND B MAPS ON THE BIRD FOR THE TWO GROUNDS .DO B?MSW!BB?MSW BLDMP: ; LOAD THE BACKGOUND MAP .DO BB?MSW XLDA 1,= MPSA2 ; SET UP TO LOAD THE MAP SMST 1 ; FOR BACKGROUND .ENDC SUB 0,0 ; SET TO NOT ADD TO WHAT IS STORED XXLDA 2,= PT2 ; CALC ADDR OF THE BACKGOUND ADDI PMAP,2 ; MAP DEFINITION AREA XLDA 1,= 3xz2. ; AND SET TO LOAD ALL OF MAP LMP ; LOAD THE BACKGROUND MAP ; LOAD THE FOREGROUND MAP TOO .DO BB?MSW XLDA 1,= MPSA1 ; SET TO LOAD THE FOREGROUND SMST 1 ; MAP .ENDC XXLDA 2,= PT1 ; CALC ADDR OF THE FOREGROUND ADDI PMAP,2 ; MAP DEFINITIOnN AREA XLDA 1,= 32. ; AND SET TO LOAD ALL OF MAP LMP ; LOAD FOREGROUND MAP .ENDC ; LOAD DEVICE PROTECTION MAP .DO B?MSW ; LOAD BACKGROUND DEV PROTECTION MAP XXLDA 2,= PT2 ADDI PDEV,2 XLDA 1,= 8. LMP ; LOAD FG DEV TOO XXLDA 2,= PT1 ADDI PMAP,2 XLDA 1,= 8. LMP .ENDC .ENDC ; INITIALIZE QUEUES IQUE: XLDA 3,= SQ XLDA 2,= SYSQ ;INIT 2 SO FIRST STORE WILL NO ; CLOBBER IQNXT: LDA 1,0,3 ;QUEUE ADDR SNEZ 1 ;END ? JMP IOVLY ;IF YES SNEM1 1 ;UNDEFINED DEVICE ? JMP IQNUL ;IF YES S#ZTA 1,QNXT,2 ;LINK LAST (IN AC2) TO THIS ; QUEUE MOV 1,2 .DO ?INFOS PSH 3,3 ;IOCS -SAVE SQ PTR EJSR INDYM ;IOCS -INIT DYN MAP POP 3,3 ;IOCS -GET SQ PTR BACK .ENDC ADC 0,0 ;-1 STA 0,QLNK,2 ;Q EMPTY XLDA 0,= QSDCB ;SET UP QSDCB,QSUFT POINTERS ;ADD 2,0 STA 0,QSDCP,2 XLDA 0,= QSUFT ADD 2,0 STA 0,QSUFP,2 XLDA 0,= TACT ;DEFAULT PROC ADDR LDA 1,PPC,2 ;IS ONE DEFINED ? SNEZ 1 STA 0,PPC,2 ;NO-USE TACT IQNUL: INC 3,3 ;BUMP QUEUE ADDR POINTER JMP IQNXT IOVLY: ADC 1,1 STA 1,QNXT,2 ;TERMINAT0\E QUEUES ; TERMINATE CELL LIST LDA 3,CC ;FCELL XLDA 0,= NCEL ;# CELLS NEG 0,0,SKP ;NEG AND INC FOR FCELL (AT ; LEAST 3 CELLS..) LDA 3,CLNK,3 ;NEXT INC 0,0,SZR ;DONE ? JMP .-2 ;NO STA 1,CLNK,3 ;TERMINATE IT JMP INIT1 ; CONTINUE LPOOL TmTIL= 100 ; DISPLACEMENT TO TTIDCT IN ITBL TTI1L= 102 ; DISPLACEMENT TO TTI1DC IN ITBL INIT1: XLDA 0,= SCBPB ; FIRST BLOCK OF PUSH SPACE XXLDA 3,= PT2 ; BACKROUND PROGRAM TABLE STA 0,PTSPN,3 ; SET PUSH LEVEL XXLDA 3,= PT1 .DO ?USW ADC 0,0 ;-1 IF# NOT MAPPED .ENDC .DO ?MSW XLDA 0,= SCFPB .ENDC STA 0,PTSPN,3 ;FG PUSH SUB 0,0 XSTA 0,SYSTM ; ZERO SYSTEM TIME XSTA 0,SYSFL ; & SYSTEM FLAG WORD XLDA 1,= RTCDV ; SEE IF REAL TIME CLOCK AROUND SNEM1 1 ; WELL ?? JMP NOCLK ; NOT AROUND CONTINUE 5 XXLDA 3,= IVFWA ; YES PUT VECTOR IN INTD ADD 1,3 ; PROPER PLACE .DO ?ANSW XLDA 1,= 1B0 ; DCT ADDRESS .ENDC .DO ?ABSW XLDA 1,= RTCDC .ENDC STA 1,0,3 ; PUT IN TABLE AT 14 OR 54 NOCLK: XXLDA 1,= IVLWA ; GET LAST INTERRUPT VECTOR ; ADDRESS XXLDA 3˶,= ITBL ; GET START OF INTERRUPT VECTOR ; NOTE: POWERFAIL DOES NOT GET MODIFIED SUB 3,1 ; END - START COM 1,1 ; -(END - START) -1 .DO ?ANSW SSDCT: LDA 0,0,3 ; GET DCT ADDRESS OR -1 COM# 0,0,SZR ; DEVICE IN SYSTEM ? ADDOR 0,0,SNR JMP NOTIN ; ] NO- IGNORE THIS ENTRY STA 0,0,3 ; RETURN IT TO THE VECTOR .ENDC .DO ?ABSW SSDCT: LDA 0,0,3 ; GET DCT ADDRESS OR -1 ADDOR# 0,0,SNR ; IS 1B0 SET ONLY ? JMP NOTIN ; YES, IGNORE THIS TABLE ENTRY SEQM1 0 ; = -1? ADDOR 0,0,SKP ; NO - SET 1B0 XXLDA 0,'= IUD ; YES - GET HANDLER ADDRESS STA 0,0,3 ; UPDATED TABLE ENTRY MOVL# 0,0,SNC ; DEFINED DEVICE? JMP NOTIN ; NO MOV 0,2 ; YES - DCT ADDRESS TO AC2 LDA 0,DCTBS,2 ;FIRST WORD OF DCT PSH 0,0 ;SAVE FOR LATER .DO ?USW LDA 0,DCTIS,2 ; SEFVICE ROU|TINE ADDRESSS .ENDC .DO ?MSW XLDA 0,= MAPST ; COMMON ROUTINE ADDRESS .ENDC MOVL 0,0 ; SET 1B0 MOVOR 0,0 STA 0,DCTBS,2 ; AND PUT IN FIRST WORD OF DCT POP 0,0 ;DCTBS PUSHED EARLIER STA 0,DCTEX,2 .ENDC .DO ?MSW ;SET UP THE DATA CHANNEL MAP I~ ; ASSIGNMENTS .DO ?ANSW MOV 0,2 ;DCT ADDRESS LDA 0,DCTBS,2 .ENDC MOVL 0,0,SNC ;DATA CHANNEL DEVICE? JMP NOTIN ;NO MOVL 0,0,SNC ; IF IS NOT CHARACTER DCH JMP NCDCH ; DEVICE THEN BRANCH ELSE LDA 0,BDCH ; NEXT AVAILABLE SLOT STA 0,DCHMC,2 ;H~ REMEMBER IT LDA 2,DCHNC,2 ; GET NUMBER NEEDED JMP NDDCH NCDCH: LDA 0,BDCH ;NEXT AVAILABLE SLOT STA 0,DCHMP,2 ;REMEMBER IT LDA 2,DCHNM,2 ;NUMBER OF SLOTS THIS DEVICE ; USES NDDCH: MOVS 2,2 ;GET IN LEFT HALF .DO N3?MSW!B?MSW!BB?MSW ; NOTE FORMA[T OF DCHMP IS DIFFERENT MOVZL 2,2 MOVZL 2,2 ;POSITION .ENDC ADD 2,0 ;ADVANCE AVAILABLE POINTER STA 0,BDCH .ENDC NOTIN: INC 3,3 ; BUMP THE POINTER INC 1,1,SZR ; TESTED THEM ALL ? JMP SSDCT ; NO, MORE SYSTEM DCT'S XXLDA 2,= IVFWA ; INTERUPT VE9CTOR TABLE IS NOW SET UP LDA 0,TTI,2 ; SO NOW COPY TTI AND TTI1 VECTORS TO STA 0,TTIL,2 ; TO THERE SECRET HIDEING PLACES LDA 0,TTI1,2 STA 0,TTI1L,2 .DO ?MSW LDA 2,BDCH ; NEXT AVAIL SLOT .DO MPAMD==0 MOVS 2,2 ; SLOT NUMBER OF 1ST AVAILABLE SLOT Ɲ .ENDC X XLDA 0,= MPAMD SUBS 0,2 ; SLOT NUM OF FIRST AVAIL SLOT [X] .DO MPALG==37B7 NEG 2,2 .ENDC X MOVZR 2,2 ;POSITION FOR EB NEGOR 2,2 ;WOW [X] ADC 0,0 GSX0: MOVZR 0,0,SNR ; ONE MORE OPEN SLOT JMP GSX ; MORE THAN SIXTEEN INC 2,2,SZR  ; DONE YET? JMP GSX0 ; NO - KEEP SHIFTING XSTA 0,MDCH1 ; SET FIRST WORD JMP INIT2 GSX1: MOVZR 0,0,SKP ; ONE MORE GSX: ADC 0,0 ; INITITALIZE FOR SECOND SLOT INC 2,2,SZR ; MORE? JMP GSX1 ; WIP,WIP XSTA 0,MDCH2 ; SET SECOND WORD .ENDC JMP INIT2 MEMER: XXLDA 2,= MEMMS ; MEMORY ERROR MESSAGE POINTER XXJSR MSG HALT JMP .-1 .DO ?MSW BDCH: MPAMD .ENDC LPOOL INIT2: XLDA 3,= BQ ; FIRST BUFFER ADDRESS XLDA 1,= BQEL ; BUFFER SIZE SUB 0,0 BUFLP: MOV 3,2 ; BUFFER ADDRESS TO AC2 STA 0,BQTLA,2 ; CLEAR TIME LAST ASSIGNED STA 0,BQUSC,2 ; & USER COUNT STA 0,BQST,2 ; & STATUS STA 0,BQDCB,2 STA 0,BQDCT,2 ; & DCT ADDRESS ADD 1,3 ; NEXT BUFFER ADDRESS STA 3,BQNXT,2 ; LINK NEXT TO THIS ONE DSZ NBUFS ; DIZ THE COUNT JMP BUFLP ; NOT DONE ADC 3,3 ; -1 STA 3,BQNXT,2 ; IS LAST LINK .DO ?MSW ISZ BQUSC,2 ;RESERVE- CMOVE IS IN BQ6 .ENDC .DO ?USW XLDA 3,= BQEL-BQHDL ; MAGIC BUFFER CONSTANT ADD 2,3 ; FORM LAST SYSTEM ADDRESS XLDA 0,= SCDBS*8. ; GET MEMORY INCREMENT ADCZR 2,2,SKP ; BIGGEST BMEMORY SZLUP: SUB 0,2 ; DECREMENT THE ADDRESS STA 2,0,2 ; STORE INTO MEMORY(?) LDA 1,0,2 ; READ IT BACK SEQ 1,2 ; REAL MEMORY ? JMP SZLUP ; NO USLE 3,2 ; YES, WILL BUFFERS FIT ? JMP MEMER ; NOPE .ENDC ; SEE IF TTY IS A TTY OR A CRT XLDA '3,= TTIDC ; DCT ADDRESS LDA 3,DCTPR,3 ; ECHO FAKE DCT ADDRESS XLDA 0,= 7 ; GET A BELL CHAR LDA 1,M10K ; -10000. DOAS 0,TTO ; DING SKPDZ TTO ; DONE ? JMP ITSCRT ; YES- ITS A CRT INC 1,1,SZR ; NO- WAITED LONG ENOUGH ? JMP .-3 ; NOPE ITSCRT: SUB(BZR 0,0 ; 1B0 MOV 1,1,SZR ; TTY ? STA 0,DCTTO,3 ; NO - CHANGE THE RUBOUT ECHO XXLDA 3,= ITBL ; BASE OF INTERRUPT TABLE LDA 3,TTI1-1,3 ; TTI1 DCT ADDRESS .DO ?ABSW XXLDA 2,= IUD SNE 2,3 ; IS TTY1 IN SYSTEM? .ENDC .DO ?ANSW SNEM1 3 ;SKIP IF DEFIPNED .ENDC JMP T6053 ; NO - GO ON TO NEXT ROUTINE LDA 3,DCTPR,3 ; PLAY THE SAME GAME FOR TTY1 XLDA 0,= 7 LDA 1,M10K ; -10000. DOAS 0,TTO1 SKPDZ TTO1 ; CHAR DONE ? JMP NOTTY ; YES- IT'S A CRT INC 1,1,SZR ; NO- END OF COUNT ? JMP .-3 ; NO- STILX[L MIGHT BE CRT NOTTY: SUBZR 0,0 ; 1B0 MOV 1,1,SZR ; TTY ? STA 0,DCTTO,3 ;SEE IF LCD (6053) TERMINAL IS HOOKED UP AS PRIMARY OR ;SECONDARY CONSOLE T6053: NIOS TTI ;START IT UP XLDA 0,= "E-100 ;SEND OUT CONTROL-E DOAS 0,TTO ;6053 WILL RESPOND SKPDN }TTO ;SKIP IF DONE JMP .-1 ;CHECK FOR RESPONSE LDA 1,M10K WTLP: SKPDZ TTI JMP IS6053 ;GOT RESPONSE INC 1,1,SZR JMP WTLP ;LOOP TILL RESPONSE OR TIMEOUT JMP NOT6053 ;NO RESPONSE ;TERMINAL IS 6053 TYPE, SET CHARACTERISTICS BIT IS6053: XLDA 3,= TTIDC ;GET DCT LDA 1,DCTCH,3 ;CHARACTERISTICS LDA 0,.DCLCD ;SET 6053 BIT ADD 0,1 STA 1,DCTCH,3 ;AND SAVE IT ;TRY SAME TRICK ON FOREGROUND TERMINAL, IF ANY NOT6053: XXLDA 3,= ITBL ; BASE OF INTERRUPT TABLE LDA 3,TTI1-1,3 ;TTI1 DCT .DO ?ABSW XXLDA 2,= IUD SGNE 2,3 ;SKIP IF NO FOREGROUND .ENDC .DO ?ANSW SNEM1 3 .ENDC JMP INIPB ;WE HAVE FG TERMINAL, CHECK IF 6053 NIOS TTI1 ;START IT UP XLDA 0,= "E-100 ;CONTROL-E DOAS 0,TTO1 ;SEND IT OUT  LDA 1,M10K ;DON'T WAIT FOR DONE HERE INC 1,1,SZR ; 'CAUSE IF FG)h IS SYSGENED JMP .-1 ; BUT NOT PRESENT, SYSTEM LDA 1,M10K ; WILL HANG WTLP2: SKPDZ TTI1 JMP FIS6053 ;FG TTY IS 6053 INC 1,1,SZR JMP WTLP2 JMP INIPB ;FG TTY IS 6053 TYPE. SET CHARACTERISTICS BIT FIS6053: LDA 1,DCTCH,3 ;CHARACTERISTICS LDA 0,.DCLC7D ADD 0,1 ;SET 6053 BIT STA 1,DCTCH,3 ;AND SAVE IT INIPB: .DO ?ABSW ; NOW TURN ON ERCC IF WE HAVE IT OR NOT !!!! ADC 1,1 ; ALL BITS TURNS IT ON IN NORMAL MODE DOA 1,ERCC .ENDC .DO N3SW!MN3SW NIOS PAR ; TURN ON NOVA 3 PARITY MEMORY OPTION .ENDC XHLDA 0,= 1B6 ; MASK OUT THE IPB FOR A WHILE STA 0,CMSK ; SAVE AS SOFTWARE MASK DOBS 0,CPU ; AND HARDWARE MASK XJMP SIZIT ; GO TO SIZIT WITH INTERUPTS ON ! .DO ?MSW NBUFS: 6 .ENDC .DO ?USW NBUFS: BCEC .ENDC M10K: -10000. .DCLCD: DCLCD ;6053 CHARACTKERISTICS BIT LPOOL LB="< RB="> ** .NOLOC 1 FULLOR: .TXT /<15><12>FULL(F) OR PARTIAL(P OR CR)? / OVMS: .TXT /<15>WITH OVERLAYS ("1") OR WITHOUT ("0" OR <LB>CR) ? / IZMSG: .TXT /<15><12>INITIALIZING WHAT DISK? / BOMSG: .TXT /<15><12>BOOTING1 TO WHAT DISK? / OVMSG: .TXT /<15><12>OVERLAY FILE NOT FOUND<15><12>/ IERMS: .TXT /<15><12>MASTER DEVICE DRIVER NOT LOADED - SYSGEN ERROR.<15><12>/ DCBMS: .TXT /<15><12>NO SPARE DCB AVAILABLE - SYSGEN ERROR.<15><12>/ MEMMS:.TXT /<15><12>INSUFFICIENT MEMO}RY FOR OPERATING SYSTEM - SYSGEN ERROR.<15><12>/ ** .NOLOC 0 ; SYSTEM'S PAGE ZERO TEMPLATE .DO ?ANSW PZERO: INTS ; INTERRUPT SERVICE ADDRESS SYST  ; SYSTEM ENTRY POINT USTKO ; USER STACK OVERFLOW (NOVA3) RETN ; POP STATE ROUTINE ADDRESS FCELaL ; FIRST CELL -1 ; PAGE ZERO TEMPORARY (RLOC) SAVEM ; PUSH STATE ROUTINE ADDRESS STK00 ; FIRST STACK PNIC ; PANIC PROCESSOR ADDRESS UST ; BACKROUND UST ADDRESS SYSQ ; INITIAL CURRENT QUEUE -1 ; CURRENT OVERLAY SEGMENT 0 ; END OF iTABLE .ENDC .DO ?ABSW PZERO: INTS ; INTERRUPT SERVICE ADDRESS .DO ?USW SYST ; SYSTEM ENTRY POINT .ENDC .DO ?MSW VNIOC ; SCL  .ENDC MAGIC ; PROTECTION FAULT HANDLER SS ; INTERRUPT STACK BASE POINTER -1 ; CURRENT MASK (CMSK) SSL 4 ; INTERRUPT STACK LIMIT OVFLO ; INTERRUPT STACK OVERFLOW FCELL ; CURRENT CELL PNIC ; PANIC PROCESSOR ADDRESS UST ; BACKGROUND UST ADDRESS SYSQ ; INITIAL CURRENT QUEUE -1 ; CURRENT OVERLAY SEGMENT 0 ; END OF TABLE .ENDC LPOOL .ENDD INIT2.SRB  RTITLE INIT2 INI2 .NREL .TXTM 1 ;LEFT TO RIGHT .ENT SIZIT .ENT PTPSW ;FOR INIT1 .EXTN MSG,OVIN,DADR ;FROM INIT3 .EXTN RDCH ;FROM INIT1 .EXTN ASBUF,BLKIN .EXTN RELDB,RLMPB .EXTN DEBLK,WDCBK .EXTN PT2 .EXTN FNDCB .EXTN OVLY1,OVLAY .EXTRN DIVD .EXTN OVBA1,OVBAS .EXTN MDCB,NSEG .EXTN FCELL .EXTN SACHN .EXTN SYMP,SYMB,DEBAD .EXTN CREL .EXTN SPOLQ .EXTN PPDCB .EXTN SMON1 .EXTN CLEAR .EXTN QUENT,WAIT .EXTN RELB .EXTN .IPBQ,SENQ,.IPINIT .EXTN RTCI,RTCST .EXTN MVWD,ENCONT,STLINK : .IFN MSW .EXTN CMOVE .ENDC ; DEFINE THE INFO BLOCK DISPLACEMENTS SDREV= 0 ; REVISION NUMBER SDCHK= 1 ; CHECKSUM SDHED= 2 ; NUMBER OF HEADS SDSEC= 3 ; NUMBER OF SECTORS/TRACK SDBL1= 4 ; NUMBER OF BLOCKS/DEVICE HIGH ORDER SDBLK= 5 ; NUMBERZ OF BLOCKS/DEVICE LOW ORDER SDFMZ= 6 ; FRAME SIZE SDCHR= 7 ; CHARACTERISTICS ; DEFINE THE TEMPS USED BY THE SIZER BUFAD=TMP BLKC1=BUFAD+1 BLKCT=BLKC1+1 ; ..MDCB: MDCB .SCDSK: SCDSK .ASBUF: ASBUF .QTSIO: QTSIO .QUENT: QUENT .WAIT: WAIT CMDSS: -SCDB&$S CREV: 1 PPA: SCPPA SIZIT: LDA 2,@..MDCB ; DCB ADDRESS SUB 0,0 ; SET CURRENT BLOCK TO SCDSK STA 0,DBCA1,2 ; HIGH ORDER = 0 LDA 0,.SCDSK ; LOW ORDER = SCDSK STA 0,DCBCA,2 JSR @.ASBUF ; GET A BUFFER STA 1,BUFAD,3 ; SAVE BUFFER ADDRESS MOV 1,2 ; MAKE BUFFER ADDRESS ACCESSABLE LDA 0,.QTSIO ; SET SPECIAL MODE IO BIT IN STATUS LDA 1,BQST,2 AND# 0,1,SNR ; ALREADY THERE ADD 0,1 ; NO PUT IT THERE STA 1,BQST,2 JSR @.QUENT ; READ THE BLOCK JSR @.WAIT ; WAIT FOR IT JMP SITIM ; TIMEOUT {~ JMP SIDAR ; DATA ERROR LDA 2,BUFAD,3 ; RESTORE BUFFER ADDRESS LDA 1,CMDSS ; WORDS PER BLOCK SUB 0,0 ; CLEAR CHECKSUM WORD SIZI1: LDA 3,0,2 ; TEST CHECKSUM ADD 3,0 INC 2,2 ; BUMP POINTER INC 1,1,SZR ; DONE ? JMP SIZI1 ; NO CONTINUE LDA 3,CSP ; RESTORE STACK POINTER MOV 0,0,SZR ; CORRECT ? JMP SIFME ; NO GIVE FORMAT ERROR LDA 2,BUFAD,3 ; YES GET BUFFER ADDRESS AGAIN LDA 0,CREV ; NIM REV I CAN USE LDA 1,SDREV,2 ; REV OF THIS PACK SUBZ# 0,1,SNC ; CAN I USE IT JMP PRERE ; NO WAY CHARLIE LDA 3,@..MDCB ; GET DCT ADDRESS  LDA 3,DCBDC,3 LDA 0,SDHED,2 ; # HEADS STA 0,DCTNH,3 LDA 0,SDSEC,2 ; # SECTORS/TRACK STA 0,DCTNS,3 LDA 1,SDBL1,2 ; NUMBER OF SECTORS HIGH ORDER STA 1,DCNB1,3 LDA 0,SDBLK,2 ; NUMBER OF SECTORS LOW ORDER STA 0,DCNBK,3 LDA 0,SDFMZ,2 ; FRAME SIZE STA 0,DCTFO,3 MOV 0,0,SNR ; FRAME SIZE MUST BE NON ZERO JMP SIFME ; SORRY LDA 0,SDCHR,2 ; CHARACTERISTICS WORD STA 0,DCTCH,3 ; SAVE CHARACTERISTICS LDA 1,NOTAL AND 0,1,SZR ; BOOTING FROM FLOPPY DISK? JMP BADSHOW JSR @.RELDB ; RELEASE AND DESTROY LDA 2,@.MDCB ; MASTER DCB ADDRESS LDA 3,DCBDC,2 ; DCT ADDRESS LDA 0,DCNB1,3 ; TOTAL BLOCK COUNT LDA 1,DCNBK,3 ; NOW GET TOTAL BLOCK COUNT LDA 3,PPA ADDZ 3,1,SZC ;FIND TRUE TOTAL BLOCK COUNT INC 0,0 LDA 3,CSP ; STACK POINTER STA 0,BLKC1,3 ; SAVE TOTAL BLOCK COUNT STA 1,BLKCT,3 ; SAVE TOTAL BLOCK COUNT LDA 0,SFKY1,2 ; GET ASCII UNIT # LDA 1,K177 AND 1,0,SNR ; IS IT A FIZED PLATTER ? JMP DVNOK ; NO CONTINUE LDA 3,DCBDC,2 ; YES MAKE- SURE DISK IS A TOP LOADER  LDA 1,DCTCH,3 ; CHARACTERISTICS WORD ADDZL# 1,1,SNC ; WELL ?? JMP WROND ; WRONG DISK MY FRIEND DVNOK: LDA 3,DCBDCT,2 ;FIND DCT LDA 0,DCTFO,3 ;FRAMESIZE STA 0,SFMSZ,2 ;SET THE FRAMESIZE IN THE DCB SUB 0,0 LDA 1,.BAD ;ADDRESS OF BAD BLOCK TABLE BLOCK STA 0,DBCA1,2 STA 1,DCBCA,2 JSR @.ASBUF ; GET A BUFFER STA 1,BUFAD,3 ; SAVE BUFFER ADDRESS MOV 1,2 ; FOR QUENT JSR @.QUENT ; READ THE BLOCK JSR @.WAIT ; WAIT FOR IT JMP SITIM ; TIMEOUT JMP SIDAR ; DATA ERROR LDA 2,BUFAD,3 ; RESTORE BUFFER ADDRESS LDA 0,BASTART,2 LDA 1,BASTART+1,2 ;ADDRESS OF REALLOCATION AREA LDA 2,BASIZE,2 ADDZ 2,1,SZC ;FIND ADDRESS OF END OF IT INC 0,0 LDA 2,BLKC1,3 USLE 0,2 ;IS IT WITHIN THE DISK? JMP SIFME ;NOPE SEQ 0,2 ;RST- cARE HIGH ORDER SECTORS ;RST- EQUAL? JMP DVNO1 ;RST- NO, DON'T COMPARE ;RST- LOW ORDER LDA 2,BLKCT,3 USLE 1,2 ;LOW ORDER, TOO JMP SIFME DVNO1: LDA 2,BUFAD,3 LDA 0,BALEN,2 ;LENGTH-OF-TABLE WORD LDA 1,MINLEN MOVR# 0,0,SNC ;MUST BE EVEN USGdE 0,1 ;MUST HAVE AT LEAST A HEADER JMP SIFME ;INVALID BAD BLOCK TABLE, NO INIT LDA 1,MAXLEN USLE 0,1 ;MUST FIT IN A DISK BLOCK JMP SIFME LDA 1,EXTRA ;IN-CORE EXTRA HEADER SPACE ADD 1,0 ;CORE REQUIREMENT FOR TABLE LDA 2,@.ENCONT ADD 2,0 ;POTENGTIAL NEW POOL END ADDRESS INTDS ;DON'T LET INT HANDLER GRAB LINKS WHILE WE CHECK LDA 1,@.STLINK ;START OF LINK SPACE USLE 0,1 ;WOULD WE OVERWRITE? JMP NOSPACE ;YOU BET STA 0,@.ENCONT ;NO, NEW END OF CONTIG SPACE INTEN LDA 0,BUFAD,3 ;RECOVER BUFFER POINTER LDA 3,@.MDCB ; DCB ADDRESS AGAIN LDA 3,DCBDCT,3 ;UNIT DCT STA 3,BEUNI,2 ;MAKE BACK LINK IN BAD BLOCK TABLE STA 2,DCTBL,3 ;DCT LINK TO BAD BLOCK TABLE LDA 1,.BEHSZ ;HEADER SIZE ADD 2,1 ;POINT TO IMAGE AREA MOV 0,3 LDA 2,BALEN,3 ;LENGTH OF IMAGE JSR @.MVWD ;MOVE TABLE FROM BUFFER TO CORE POOL ADD 1,2 ;POINT TO LINK WORD ADC 0,0 STA 0,0,2 ;NO LINKS FOR NOW LDA 2,BUFAD,3 JSR @.RELB ;RELEASE BUFFER, SO MUCH FOR BAD BLOCK STUFF JMP SZDON ; ALL DONE DISK IS SIZED  BADSHOW: LDA 2,MSBNA JMP SERRR SITIM: LDA 2,MSTIM ; DISK TIMEOUT JMP SERRR SIFME: LDA 2,MSFME ; FORMAT ERROR JMP SERRR SIDAR: LDA 2,MSDAE ; DISK FORMAT ERROR JMP SERRR WROND: LDA 2,MSNTL ; NOT A TOP LOADER JMP SERRR NOSPA: LDA 2,MSNOS ; NO SPACE IN BBT JMP SERRR PREREV: LDA 2,MSPRE ; OLD REV OF DISK SERRR: JSR @MSGP ; PUT OUT MESSAGE JMP . ; WHOA ..ASBU: ASBUF ..WAIT: WAIT ..QUEN: QUENT MSNOS: NOSMS MSNTL: ILGMS .MVWD: MVWD MSGP: MSG MSBNA: BOOTNA MSTIM: TIMOU MSDAE: DATER MSFME: FMTER ; FORMAT ERROR MSPRE: PRERM .MDCB: MDCB .RELB: RELB .RELDB: RELDB PTPSW: 0 NOTAL: 1B14 K177: 177 .BAD: SCBAD MINLEN: BALIST MAXLEN: SCDBS EXTRA: BEXSZ .BEHSZ: BEHSZ .ENCONT:ENCONT .STLINK:STLINK .PT2: PT2 MDSTS: STINI R3PTCH=TMP R3PT1=R3PTCH+1 PBUF=R3PT1+1 SPBUF=PBUF+1 CNTR=SPBUF+1 PLEVEL=CNTR+1 SZDON: LDA 2,@.MDCB ;MASTER DEVICE DCB LDA 3,.PT2 ; SET DEFAULT IN STA 2,PDDCB,3 ; BEGINNING PROGRAM TABLE LDA 0,PTCLF,3 ; CURRENT LEVEL FLAG STA 0,SFTYPE,2 ; SET DCB TYPE WORD LDA 0,MDSTS ; MASTER DEVICE STATUS STA 0,DCBST,2 ; SET INTO MASTER DCB LDA 3,DCBDC,2 ; MASTER DCT ADDRESS LDA 1,DCNBK,3 ; NUMBER OF BLKS ON DEVICE (LOW ORDER) LDA 0,DCNB1,3 ; NUMBER OF BLOCKS ON DEVICE (HIGH ORDER) LDA 2,BPB ; BITS PER BLOCK JSR @.DIVD ; DIVIDE MOV 0,0,SZR ; I~F THERE IS ANY REMAINDER INC 1,1 ; INCREMENT THE QUOTIENT LDA 0,RBOM ; GET RELATIVE BASE OF MAP.DR ADD 1,0 ; TRUE ADDRESS OF OVERLAYS LDA 1,USP ;INIT SWITCH LDA 2,PTPSW ;PAPER TAPE PARTIAL SWITCH COM# 2,2,SZR ;PARTIAL FROM PAPER TAPE? MOV# 1,1],SZR ;OR OVERLAYS REQUIRED? JMP .+2 ;YES JMP DVINT ;NO - SKIP OUT STA 0,@.DADR ; TO OVERLAY READ ROUTINE STA 0,@.OBAS ; SET OVERLAY BASE FOR OVLAY SUB 0,0 STA 0,@.OBS1 ; & HIGH ORDER MOV# 1,1,SNR ;OVERLAYS REQUIRED? JMP DVINT ;NO - SKIP COM# 1,1,SNR ;FULL INIT? JMP OVRD ;YES, ALWAYS READ LDA 2,@CQ ;SEE IF IT'S A GOOD IDEA TO READ LDA 3,.PT2 LDA 0,PTPB1,3 ;PARTITION BASE LDA 1,PTPBA,3 ;& LOW ORDER LDA 3,PUAD ;TO PUSH BLOCK ADDZ 3,1,SZC INC 0,0 STA 0,DBFA1,2 ;PUSH ADDR TO QUEUE DCB  STA 1,DCBFA,2 LDA 1,@.MDCB JSR @.FNDCB ;FULL INIT JSR @..ASBUF ; ASSIGN A BUFFER MOV 1,2 STA 2,SPBUF,3 ; SAVE THE BUFFER ADDRESS JSR @..QUENT ; READ THE BLOCK JSR @..WAIT ; WAIT FOR IT JMP SITIM ; TIMEOUT JMP SIDAR ; DATA ERROR LDA 2,SPBUF ,3 ; BUFFER ADDRESS AGAIN LDA 0,0,2 ;FIRST WORD IS FLAG WORD MOVOR 0,0 INC 0,0 ;IS DISK PRE-REAL-REV-4? COM# 0,0,SZR ;(REAL REV 4 IS -3 OR -4) JMP OVERR ;YOU DON'T REALLY WANT YOUR ;DIRECTORY BLOWN UP, DO YOU? LDA 0,SCNVW,2 ;REAL REV 4, GET N݆BR OF OVERLAYS LDA 1,NOV ;NUMBER OF OVERLAYS WE NEED SUBZ# 1,0,SNC ;FIT? JMP OVERR ;NO JSR @.RELDB ;YES, THERE'S SPACE OVRD: JSR @.OVIN ; YES, READ THE OVERLAYS ; START THE CLOCK IF DEFINED DVINT: LDA 0,.RTCI ; GET FREQUENCY CONSTANT COM# 0,0,SZR ; IS CLOCK DEFINED ? RTCST ; YES, START THE CLOCK ; NOTE THE IPB HAS BEEN MASKED OUT UNTIL THIS POINT AND ; ALL DISK IO HAS BEEN DONE WITH QUENT SO THAT THE OTHER SIDE ; DOES NOT KNOW THAT WE ARE HERE YET. INTDS ; QUIET PLEASE SUB 0,0 ; CLEAR HARDWARE AND SOFT MASK STA 0,CMSK DOB 0,CPU ; HARDWARE MASK TO ZERO LDA 3,@..IPINIT COM# 3,3,SNR ; IPB LOADED ? JMP NOIPB ;NOPE ;KICK THE TIMER TO MAKE SURE IT DOESN'T TIME OUT BEFORE RTC ;HANDLER PICKS IT UP. MUST BE DONE BEFORE CALL TO IPINIRT. NIOS IVT JSR 0,3 ; CALL IPINIT ; NOTE IPINIT TURNS ON INTERUPTS LDA 2,@..IPBQ JSR @.SENQ ;PUT IPB PROCESS ON ACTIVE CHAIN NOIPB: INTEN ;IN CASE WE DIDN'T CALL IPINIT LDA 1,USP ;INIT SWITCH AGAIN LDA 2,@.MDCB ; MASTER DCB LDA 3,DCBDC,2 ; MElASTER DCT ADDRESS LDA 0,DCTIN,3 ; DEVICE INIT ROUTINE ADDRESS LDA 3,CSP STA 0,TMP,3 ; PUT ADDRESS IN THE STACK LDA 3,.PT2 ; BACKROUND PROGRAM TABLE MOVL 2,2 INCZ 1,1 ;SET CARRY IF FULL INIT, ELSE CLEAR MOVR 2,2 ;PASS INIT CODE IN SIGN BIT LDA 0q,PTPB1,3 ; HIGH ORDER PARTITION BASE ADDRESS LDA 1,PTPBA,3 ; LOW ORDER PARTITION BASE ADDRESS JSR @.OVLY1 ; INIT THE MASTER DEVICE JMP SIFME ; AND ANOTHER ERROR BITES THE DUST LDA 2,@CQ ; Q DCB ADDRESS LDA 3,.PT2 ;BACKGROUND TABLE POINTER LDA 0,PnUTPB1 ,3 ; HIGH ORDER BASE ADDRESS LDA 1,PTPBA,3 ; BASE ADDRESS LOW ORDER LDA 3,PUAD ; RELATIVE PUSH ADDRESS ADDZ 3,1,SZC ; GET ACTUAL ADDRESS INC 0,0 ; CARRY STA 0,DBFA1,2 ; SET ADDRESS STA 1,DCBFA,2 ; REST OF IT LDA 3,CSP STA 0,R3PT1,3 STA 1,R/3PTCH,3 ; NEED THIS IF REV03 DISK LDA 1,@.MDCB ; MASTER DCB JSR @.FNDCB ; FULL INIT IT JSR @.BLKIN JMP @.SIDAR ; DATA ERROR PROBABLY STA 0,PBUF,3 ; SAVE ADDRESS OF PUSH BLOCK BUFFER STA 0,SPBUF,3 ; NEED TO GIVE IT BACK LATER LDA 0,@PBUF,3 ; FIRST ]WORD TO TELL PUSH FORMAT LDA 1,USP COM# 1,1,SNR ; FULL ? JMP FULL ; YES, ASSIGN INDEX BLOCKS INC 0,0 INC 0,0 INC 0,0 COM# 0,0,SNR ; BEEN CREATED YET ? JMP GPSBK ; NO GIVE BACK SPACE AND CREATE MOV 0,0,SZR ; REV 4 OR LATER ? JMP @PRERP ; NgO SORRY CHARLIE ISZ PBUF,3 ; REV04 DIRECTORY LDA 0,M8 ; -(NUMBER OF ENTRIES) STA 0,CNTR,3 ; SAVE ON STACK NPLVL: LDA 0,@PBUF,3 ; HIGH ORDER INDEX BLOCK ADDRESS ISZ PBUF,3 ; UPPOINTER LDA 1,@PBUF,3 ; LOW ORDER OF INDEX BLOCK ADDRESS JSR @.FBLK ; GpIVE THE BLOCKS BACK ISZ PBUF,3 ; UP POINTER ISZ CNTR,3 ; DONE ? JMP NPLVL ; NO, TRY NEXT LEVEL LDA 2,SPBUF,3 ; BUFFER ADDRESS JSR @.RLB ; RELEASE NO MODIFICATION JMP @.+1 INIT6 PUAD: SCPSH .FNDCB: FNDCB BPB: SCDBS*20 .DIVD: DIVD RBOM: SCPPA+SCMAP NOV: NSEG .DADR: DADR .OVIN: OVIN .OBAS: OVBAS .OBS1: OVBA1 .OVLY1: OVLY1 M8: -8. M7: -7 C2: 2 .MMSG: MSG OVMS: MSOV .BLKIN: BLKIN .OVLAY: OVLAY .SIDAR: SIDAR ..IPINIT:.IPINIT ;DOUBLE LEVEL INDIRECT ..IPBQ: .IPBQ ; SO AS NOT TO FORCE LOADING .SENQ: SENQ .FBLK: FBLK .RLB: RELB PRERP: PREREV .RTCI: RTCI OVERR: LDA 2,OVMS ;OVERLAYS WON'T FIT JSR @.MMSG JMP . ;CAN'T GO NO MORE GPSBK: LDA 0,M7 ; GIVE BLOCKS BACK STA 0,CNTR,3 LDA 0,R3PT1,3 LDA 1,R3PTCH,3 ; GET PUSH SPACE ADDRESS DLOP: INC 1,1,SNR ; DON'T GIVE FIRST ONE BACK INC 0,0 JSR @.OVLAY DEBLK JSR DEPER ISZ CNTR,3 ; DONE ? JMP DLOP ; NO ; NOW GET CONTIGUOUS BLOCKS FOR PUSH SPACE INDEXES FULL: ISZ @PBUF,3 ; SHOW PUSH SPACES CREATED ISZ PBUF,3 LDA 0,M8 STA 0,CNTR,3 ; INDEX BLOCK COUNTER DEPLP: LDA 1,C2 ; INDEXES ARE 2 CONTIG BLOCKS EACH LDA 2,@CQ JSR @.OVLAY WDCBK JMP BLKER ; SCREW IT STA 0,@PBUF,3 ; HIGH ORDER ADDRESS ISZ PBUF,3 STA 1,@PBUF,3 STA 0,DBCA1,2 ; SET AS CURRENT STA 1,DCBCA,2 JSR @.BLKIN ; GET IT JMP @.SIDDAR ; MUST BE DATA ERROR MOV 0,2 ; BUFFER ADDRESS LDA 0,BLKSZ JSR @.CLEAR JSR @.RLMPB ; LET IT GO LDA 2,@CQ ;CLEAR SECOND INDEX BLOCK ISZ DCBCA,2 ; GET NEXT ADDRESS JMP .+2 ISZ DBCA1,2 ;OVERFLOW JSR @.BLKIN JMP @.SIDAR MOV 0,2 ; FOR CLEAR 2 LDA 0,BLKSZ JSR @.CLEAR JSR @.RLMPB ISZ PBUF,3 ISZ CNTR,3 ;DONE ? JMP DEPLP LDA 2,SPBUF,3 ; RETURN BUFFER JSR @.RLMPB ; FLUSH IT OUT JMP @.+1 ; ALL DONE HERE INIT6 SCNTR=TMP BAD=SCNTR+1 SBAD=BAD+1 WCNTR=SBAD+1 MBFLG=WCNTR+1 FBLK: RSAVE 10 LDA 2,C2 ; # OF INDEX BLOCKS PER PUSH LEVEL STA 2,SCNTR,3 ; COUNTER LDA 2,@CQ ; GET DCB STA 0,DBCA1,2 ; SET CURRENT ADDRESS STA 1,DCBCA,2 LLOOP: JSR @.BLKIN ; GET BLOCK JMP @.SIDAR ; DATA ERROR ?? STA 0,BAD,3 ; SAVE BUFFER ADDRESS STA 0,SBAD,3 ; SAVE IT AGAIN LDA 0,WCNT1 ; # OF ENTRIES/BLOCK STA 0,WCNTR,3 ; COUNTER SUB 1,1 STA 1,MBFLG,3 ; BUFFER MODIFIED FLAG DEPB: LDA 0,@BAD,3 ; GET HIGH ORDER ADDRESS STA 1,@BAD,3 ; CLEAR SLOT ISZ BAD,3 ; UP POINTER LDA 1,@BAD,3 ; LOW ORDER MOV# 0m,0,SZR ; SEE IF VACANT JMP DPBK ; NO, GIVE IT UP MOV# 1,1,SZR ; LAST CHANCE JMP DPBK GOUT: LDA 0,MBFLG,3 ; GET MODIFIED FLAG LDA 2,SBAD,3 ; BUFFER ADDRESS MOV# 0,0,SZR ; MODIFIED ? JMP .+3 ; YES JSR @.RLB ; RELEASE IT JMP .+2 JSR @.RLMPB ; ZRELEASE IT MODIFIED DSZ SCNTR,3 ; DONE ? JMP .+2 RTRN ; YES LDA 2,@CQ ; GET DCB ISZ DCBCA,2 ; GET NEXT BLOCK JMP .+2 ISZ DBCA1,2 ; OVERFLOW JMP LLOOP ; TRY AGAIN DPBK: JSR @.OVLAY DEBLK ; DEPOSIT IT JSR DEPER SUB 1,1 ; CLEAR LOWER HALF OF SLOT ADDRESS STA 1,@BAD,3 ISZ BAD,3 ; UP POINTER ISZ MBFLG,3 ; SHOW MODIFIED ISZ WCNTR,3 ; DONE ? JMP DEPB JMP GOUT ; BLOCK DONE GET OUT .RLMPB: RLMPB BLKSZ: SCDBS .CLEAR: CLEAR WCNT1: -SCDBS/2 ; # OF ENTRIES PER BLOCK DEPER: RSAVE 0 LDA 2,.MPEMS JSR @.MSGX RTRN BLKER: JSR @.PNIC PNCBK .MSGX: MSG .MPEMS: .+1 .NOLOC 1 .TXT /<15><12>WARNING: MASTER DEVICE MAP.DR IS ERRONEOUS.<15><12>/ PRERM: .TXT /<15><12>INCOMPATIBLE DISK FORMAT !!<15><12>/ MSOV: .TXT /NOT ENOUGH SPACE FOR OVERLA+YS IN BOOTSYS.OL.<15><12>/ ILGMS: .TXT /MASTER DEVICE NOT A TOP LOADER <15><12>/ NOSMS: .TXT /NOT ENOUGH ROOM IN BAD BLOCK TABLE<15><12>/ TIMOU: .TXT /DISK UNIT NOT READY<15><12>/ FMTER: .TXT /DISK FORMAT ERROR <15><12>/ DATER: .TXT /DISK STATUS ERROR <15><12>/ BOOTNA: .TXT /ILLEGAL MASTER DEVICE<15><12>/ .NOLOC 0 .FCELL: FCELL .SPOLQ: SPOLQ .SACHN: SACHN .CREL: CREL .UST: UST .SYMP: SYMP .SYMB: SYMB .DEBAD: DEBAD INIT6: LDA 3,.UST LDA 3,USTAC,3 ;ONLY TC LDA 0,USP ;PASS USP TO CLIBT STA 0,TUSP,3 LDA 2,.SYMB ;SEE IF THERE IS A DEB LDA 3,.UST LDA 1,USTSS,3 MOV# 1,1,SNR JMP INIT7 ;IF NO DEB STA 1,0,2 ;MOVE POINTERS TO PATCH LDA 1,USTES,3 STA 1,1,2 STA @2,.SYMP ;NEW SYMP LDA 0,USTDA,3 ; GET DEBUGGER START ADDRESS STA 0,@.DEBAD ; STORE IN T TY DRIVER FOR CONTROL-S INIT7: SUB 0,0 DOBS 0,CPU ; ENABLE EVERYBODY LDA 2,.FCELL ;RELEASE CELL JSR @.CREL .IFE MSW INTDS LDA 2,.SPOLQ STA @2,.SACHN ;START OF ACT CHAIN LDA 3,CQ ;SYSQ SUB 0,0 STA 0,QSTAT,3 STA 0,POLNK,3 LDA 2,@...IPBQ ;PUT 0IPB PROCESS BACK ON ACTIVE CHAIN COM# 2,2,SNR ; (IF IT EXISTS) JMP JSMON1 SUB 0,0 ;DON'T LET SENQ THINK STA 0,POLNK,2 ; IT'S ALREADY ON THE QUEUE JSR @..SENQ JSMON1: INTEN JMP @.SMON1 .SMON1: SMON1 ...IPBQ: .IPBQ ;CAN'T REFERENCE DIRECTLY, SINCE _THAT WOULD ..SENQ: SENQ ; FORCE IT TO BE LOADED .ENDC S LDA 1,MPUST ;SET USTP TO MAPPED ADDR STA 1,USTP JMP @.+1 ;MAPPED - FINISH UP IN BQ6!!!!! CMOVE MPUST: 76400 [S] .END INIT3.SRB d /* RTITLE INIT3 INI3 .NREL .TXTM 1 ;LEFT TO RIGHT .ENT OVIN .ENT DADR .ENT MSG .EXTN BQ .EXTN BQ2 .EXTN TTRTB .EXTN PTRTB .EXTN OBUF .EXTN SETMOD .EXTN QUENT .EXTN WAIT .EXTN MDCB .EXTN DEQUE .EXTN RDCH MCAMK=1B12 ;TEMP ; READ DUMP TA\PE OF OVERLAYS AND WRITE TO DISK OVIN: RSAVE 5 RESTAR: LDA 0,DADR STA 0,@.WDADR LDA 0,BQAD ; BUFFER Q START LDA 1,NXT1 ; OFFSET TO NEXT BUFFER ADD 1,0 STA 0,MTBQ ; BUFFER FOR MAG TAPE .IFE MSW STA 0,MMTBQ ;BUFF ADDR FOR I/O .ENDC .IFN MSW ; SET UP DC MAP FOR MT I/O LDA 1,C1777  AND 0,1 ;SAVE LOW ORDER BITS LDA 2,C7K ;MT MAPPED ADDR FOR BLK 1 ADD 2,1 STA 1,MMTBQ ;FOR I/O LDA 1,C377L ANDS 1,0 ;MAKE ADDR A BLK NUMBER MOVZR 0,0 MOVZR 0,0 LDA 1,CMT1 ;FIRST DC MAP SLOT+INSTRUCTION ADD 0,1 SE8MLD 0,MPSDC ; SET TO LOAD DCH MAP SMBK 1 LDA 0,CNXTM ;BUMP EACH HALF BY 1 ADD 0,1 SMBK 1 .ENDC JMP RSW1 RSW: INTDS ; QUIET PLEASE LDA 2,.MSGI ;UNKNOWN DEVICE CODE JSR @.MSG JSR @.RDCH ; GET A CHARACTER ADC 2,2 ; JUST IN CASE AN INVALID INP_UT LDA 1,C61 ; AN ASCII 1 SUB 1,0,SNR ; $PTR ?? LDA 2,PTRDL ; YES GET DEVICE CODE COM# 0,0,SNR ; $TTR ?? LDA 2,TTRDL ; YES GET DEVICE CODE COM# 2,2,SNR ; A VALID INPUT ? JMP RSW ; NO TRY AGAIN STA 2,SCIDV ; SAVE DEVICE CODE RSW1: LDA 3,.DVTAB ; TABLE ADDRESS LDA 0,SCIDV ; GET CODE FROM BOOTSTRAP DVX: LDA 1,0,3 ; MUST BE CODE COM# 1,1,SNR ; END OF TABLE? JMP RSW ; ILLEGAL - HIT SWITCHES AGAIN INC 3,3 SUB# 1,0,SNR ; MATCH? JMP GOT1 ; FOUND IT INC 3,3 ; KEEP TRYING INC 63,3 JMP DVX GOT1: LDA 1,0,3 STA 1,@.RDIN LDA 3,1,3 STA 3,.DVINI INTDS ; MUST DISABLE JSR 0,3 ;GO SET UP DEVICE INTEN ; CAN ENABLE NOW JMP @.+1 ; AND GET GOING TOP .RDIN: RDIN DADR:0 .WDADR:WDADR .DVINI:0 .RDCH: RDCH TTRDL: 10 PTRDL: 12 C[61: 61 MTIN: RSAVE 0 SKPBZ MTA ; WAIT FOR IDLE UNIT JMP .-1 JMP PRIMR ; NOW GO TO IT CASIN: RSAVE 0 LDA 2,MSG3 JSR @.MSG ; PRINT CASSETTE PROMPT SKPDN TTI ; WAIT FOR RESPONSE JMP .-1 DIAC 0,TTI ; CLEAR THE REGISTER PRIMR: LDA 0,MTBQ ; TAPE BUFFER LDA 1,EOB ; END OF BUFFER CONSTANT ADDZL 1,0 ; LARGEST BYTE POINTER STA 0,MTBUF ; SAVE IT JSR @.RR RTRN .RR: RDRCD TTRIN: RSAVE 0 LDA 1,@.TTRDC ; TTR DCT ADDRESS STA 1,INDCT ; STORE READER DCT ADDR LDA 2,MSG2 ; TELETYPE MESSAGE JMP SETUP PTRIN: RSAVE 0 LDA 2,@.PTRDC ; PTR DCT ADDRESS COM# 2,2,SNR ; SYSGEN'D IN ? JMP NSDER ; NO, CAN'T CONTINUE STA 2,INDCT ; STORE PTR DCT ADDRESS LDA 2,MSG1 ; $PTR MESSAGE SETUP: JSR @.MSG ; PRINT THE PROMPT MESSAGE LDA 0,MTBQ ; BUFFER ADDcRESS MOVOL 0,0 ; MAKE BYTE POINTER STA 0,MTBP INC 0,0 ; LIMIT BYTE POINTER STA 0,MTBUF ; SAVE ALSO SKPDN TTI JMP .-1 ; WAIT FOR INPUT DIAC 0,TTI ; GET THE BYTE & CLEAR JSR @RDIN ; START THE INPUT RTRN BQAD: BQ NXT1: 2*BQEL .DVTAB: DVTAB .T?@TRDC: TTRTB .PTRDC: PTRTB .MSG: MSG MSG1: PTMSG MSG2: TTMSG MSG3: CASMG .MSGI: MSGI MTBQ: -16 .IFN MSW CMT1: MPAMD!(30*MPAIN) ;USE PAGE 30 AND 31 CNXTM: MPAIN!1 C7K: 30B5 C1777: 1777 C377L: 377B7 .ENDC MMTBQ: 0 NSDEM: MSG5 SFCMD: 30 MTBUF: 0 EOB: 377 NESDER: LDA 2,NSDEM JSR@ .MSG ; THIS ROUTINE IS TO RETRIEVE THE OVERLAYS FROM AN MCA MCARD: RSAVE 0 LDA 0,MTBQ ; GET BUFFER ADDRESS LDA 1,C400 ; GET END OF BUFFER (WORDS) ADDZL 0,1 ; MAKE END OF BUFFER BYTE POINTER STA 1,MTBUF ; SAVE IT MOVZL 0,1v ; GET BYTE POINTER TO BEGINNING OF BUFFER STA 1,MTBP ADC 1,1 ; # OF WORDS IN FIRST PROTOCOL LDA 0,MMTBQ ; GET MAPED ADDRESS OF BUFFER JSR MCADO ; FILL BUFFER ADCZL 1,1 ; SECOND PROTOCOL JSR MCADO ; GET IT LDA 1,MCAEB ; # OF WORDS IN MESSAGE K JSR MCADO ; FILL IT LDA 0,.DIC ; OK CKECK STATUS LDA 2,SCIDV ADD 2,0 STA 0,.+1 0 LDA 2,MCMSK AND 2,0 #SUBZ 0,2,SNR ; OK ? RTRN ; YEP LDA 2,.MSG7 JSR @.MSG HALT JMP .-1 ; WE REALLY MEAN IT C400: 400 .MSG7: MSG7 .DIC: DIC 0,0 MCAEB: -400z MCMSK: 1B14 MMSK: MCAMK ;MASK FOR SETTING MCMS: 0 ;MASK FOR CLEARING ; MCA INITIALIZATION, CALLED WITH INTERRUPTS OFF MCAIT: RSAVE 0 LDA 0,CMSK ;PICK UP INTERRUPT MASK LDA 1,MMSK ; (INTERRUPTS ARE DISABLED) AND# 1,0,SZR ;MCA BIT SET? JMP MCITRD ;YES, LEAVE ALONE ADD 1,0 ;NO, SET IT STA 1,MCMS ;REMEMBER TO CLEAR IT LATER MSKO 0 ;MASK OUT MCA INTERRUPTS FOR A WHILE STA 0,CMSK MCITRD: JSR MCARD ; FILL BUFFER RTRN ; GENERAL READ BLOCK ROUTIINE FOR MCA AC1 HAS # OF WORDS (2'S COMP) MCADO: R&SAVE 0 LDA 3,.DOA LDA 2,SCIDV ADD 2,3 STA 3,.+1 ; SET ADDRESS 0 LDA 3,.DOBS ADD 2,3 STA 3,.+1 ; SET WORD COUNTER 0 LDA 3,.SKPDN ADD 2,3 STA 3,.+1 ; WAIT FOR COMPLETION 0 JMP .-1 RTRN .DOA: DOA 0,0 .DOBS: DOBS 1,0 .SKPDN: SKPDN 0 ; HOLDS ADDRESS OF READ CHARACTER ROUTINE IN USE RDIN: 0 ; HOLDS ADDRESS OF DCT USED FOR PTR OR TTR READS INDCT: 0 RDTT: RSAVE 0 LDA 0,MTBQ MOVOL 0,0 STA 0,MTBP RDTT1: INTEN ; ENABLE LDA 2,INDCT ; TTR DCT ADDRESS INTDS ; DIABLE JSR @.OBUF ; GET ysA CHARACTER JMP RDTT1 ; NOTHING THERE - TRY AGAIN INTEN ; ENABLE AS YOU LEAVE STA 0,@MTBQ ; SAVE IT RTRN .OBUF: OBUF MTBP: 0 RCLT: -SCDBS-1 RDRCD: RSAVE 1 LDA 0,RTYCN ; RETRY CONSTANT STA 0,TMP,3 ; SAVE IN STACK INTDS ; MUST DISABLE RCDLP:i LDA 0,SCIDV ; BOOTSTRAP DEVICE CODE LDA 2,RCLT ; RECORD LENGTH LDA 1,.DOC ; DOC SKELETON ADD 0,1 STA 1,.+1 0 ; DOC 2,0 LDA 2,MMTBQ ; CORE ADDRESS LDA 1,.DOB ADD 0,1 STA 1,.+1 0 ; DOB 2,0 LDA 2,MTBQ ; TAPE BUFFER ADDRESS MOVZL 2,2 ; TTyAPE BUFFER BYTE POINTER STA 2,MTBP ; SET IT TO BEGINNING SUB 2,2 LDA 1,.DOAS ADD 0,1 STA 1,.+1 0 ; DOAS 2,0 LDA 1,.SKBZ ADD 0,1 STA 1,.+1 0 ; SKPBZ DEVICE JMP .-1 ; WAIT FOR COMPLETION LDA 1,.DICA ADD 0,1 STA 1,.+1 0 ; DIAC 2,0 INTEYN ; ENABLE NOW MOVL 2,2,SNC ; ANY ERRORS ? RTRN ; NO INTDS ; YES, DISABLE AGAIN DSZ TMP,3 ; TRIED ENUF ? JMP .+2 ; NO JMP TAPER ; YES, TAPE ERROR ADC 2,2 ; -1 LDA 1,.DOC ADD 0,1 STA 1,.+1 0 ; DOC 2,0 LDA 2,SBCMD ; SPACE BACKWARD COMMAND LDA 1,.DOAS ADD 0,1 STA 1,.+1 0 ; DOAS 2,0 LDA 1,.SKBZ ADD 0,1 STA 1,.+1 0 ; SKPBZ DEVICE JMP .-1 JMP RCDLP RTYCN: 12 ; RETRY CONSTANT .DOC: DOC 2,0 .DOB: DOB 2,0 .DOAS: DOAS 2,0 .DICA: DIAC 2,0 .SKBZ: SKPBZ 0 TAPER: LDA 2,TAPEM J^|SR MSG HALT JMP .-1 ; NO RECOVERY TAPEM: MSG4 .MTBUF: MTBUF SBCMD: 40 READ: RSAVE 0 NEG 1,1 ; BYTE COUNTER RDLP: LDA 3,MTBP ; MAG TAPE BYTE POINTER MOV 1,1,SNR ; MORE BYTES WANTED? RTRN MOVZR 3,3 ; YES, FORM ADDRESS POINTER ISZ MTBP ; AND BUMP THE BYTE POINTER LDA 2,0,3 ; GET WORD FROM BUFFER MOV 2,2,SNC ; WHICH BYTE? MOVS 2,2 ; LEFT LDA 3,BOTM ; MASK AND 3,2 ; CORRECT BYTE, RIGHT ADJUSTED MOVZR 0,3 ; ADDRESS POINTER LDA 0,0,3 ; GET WORD FROM OUTPUT BUFFER MOV 0,0,SNC ; WHmICH BYTE HERE? MOVS 2,0,SKP ; PUT IN LEFT BYTE ADD 2,0 STA 0,0,3 ; PUT IT IN OUTPUT MOVL 3,3 ; REFORM BYTE POINTER INC 3,0 ; BUMP INTO AC0 INC 1,1 ; BUMP BYTE COUNT LDA 3,MTBP ; NEXT SOURCE BYTE POINTER LDA 2,@.MTBUF ; EMPTY BUFFER POINTER ADCZ# 3,2,SZC ; ANY BYTES LEFT? JMP RDLP+1 ; YES JSR @RDIN ; NO, READ NEXT RECORD JMP RDLP DVTAB: PTRDC: PTR RDTT PTRIN MTADC: MTA RDRCD MTIN CASDC: CAS RDRCD CASIN TTIDC: TTI RDTT TTRIN MC1: MCAR MCARD MCAIT MC2: MCAR1 MCARD MCAIT -1 . .SETMOD: SETMOD .QUENT: QUENT .WAIT: WAIT .MDCB: MDCB WRITE: RSAVE 0 STA 1,BQCA,2 ; LOGICAL DEVICE ADDRESS SUB 1,1 STA 1,BQCA1,2 ;ZERO HIGH ORDER ADDRESS STA 1,BQST,2 LDA 3,@.MDCB ; MASTER DCB LDA 1,DCBDC,3 ; MASTER DCT STA 1,BQDCT,2 ; MASTER DEVICE DCT LDA 1,DCBUN,3 ;MASTER UNIT NUMBER STA 1,BQUN,2 ;EXACT SAME DEVICE AS MASTER JSR @.SETMOD JSR @.QUENT ; TRANSFER JSR @.WAIT ; FINISH I/O JMP MDTO ; MASTER DEVICE TIMEOUT JMP MDDE ; MASTER DEVICE DATA ERROR RTRN MDTO: JSR @.PNIC PNMDT MQDDE: JSR @.PNIC PNMDD ; ROUTINE TO PRINT A MESSAGE TERMINATED BY A NULL ; INPUTS: AC2 - WORD POINTER MSG: STA 3,MSRTN LDA 0,MASK MOVZL 2,3,SKP MSGLP: MOVZR 3,2 ; FORM WORD POINTER LDA 1,0,2 ; GET WORD INC 3,3,SNC ; BUMP POINTER - TEST CARRY MOV2S 1,1 ; LEFT BYTE - SWAP THE WORD AND 0,1,SNR ; MASK & TEST FOR NULL JMP @MSRTN ; NULL BYTE, RETURN SKPBZ TTO ; WAIT FOR IDLE DEVICE JMP .-1 DOAS 1,TTO JMP MSGLP MSRTN: 0 MASK: 177 BOTM: 377 NAME:.BLK 12 TNAME: .BLK 12 .NOLOC 1 DU1: .TXT /<15)><12>YOU LOADED / DU2: .TXT / TAPE# / DU3: .TXT /; I WANT / DU4: .TXT / - TRY AGAIN<15><12>/ .NOLOC 0 .DU1:DU1 .DU2:DU2 .DU3:DU3 .DU4:DU4 .CKSER:CKSER TAPENO:0 TTNO:0 PNAME:NAME*2 .NAME:NAME PTNAME: TNAME*2 .TNAME: TNAME ;AC0 BYTE POINTER, AC1 RETURNED BYTE GTBYT: RSAVE MOVZR 0,2 ;WORD POINTER LDA 0,0,2 MOV# 0,0,SNC ;WHICH BYTE MOVS 0,0 ;HIGH ORDER LDA 1,BOTM AND 1,0 STA 0,OAC1,3 ;RETURN IT RTRN ; BYTE POINTERS TO STRINGS ARE IN AC0, AC1 ; RETURN TO CALL+1 IF NO COMPARE, CALL+2 IF COMPARE =CP0=TMP CP1=CP0+1 CPSTR: RSAVE 2 STA 0,CP0,3 STA 1,CP1,3 CPLP: LDA 0,CP0,3 ;BYTE POINTER IN FIRST STRING ISZ CP0,3 ; & INC IT JSR GTBYT ; & GET A BYTE MOV 1,2 ; & SAVE IT LDA 0,CP1,3 ISZ CP1,3 JSR GTBYT ; & LIKEWISE WITH OTHER STRING MOV# 1,1,SN4R ;NULL? JMP CPEND ;YES - RESOLVE THE LAST SUB# 1,2,SNR JMP CPLP ;EQUAL AND NON-NULL, KEEP GOING RTRN ;NOT EQUAL, DONE CPEND: SUB# 1,2,SNR ;ONE IS NULL, ARE BOTH? ISZ ORTN,3 ;YES RTRN ;AC0 HAS BINARY 1-OCTAL-DIGIT NUMBER PRNUM: RSAVE LDA 1,.0 ABDDS 1,0 ;CONVERT TO ASCII IN HIGH ORDER BYTE STA 0,PRN LDA 2,.PRN ; & TYPE IT JSR MSG RTRN .0: "0 .PRN: .+1 PRN: 0 0 .REED: READ SMSG: MSG ; READ STRING TERMINATED BY NULL - AC0 = BYTE POINTER TO BUFFER RDSTR: RSAVE RSLP: SUBZL 1,1 ;READ A BYTE J=SR @.REED ; AT JSR GTBYT ; A INC 0,0 ; TIME MOV# 1,1,SZR ; & STOP ON NULL JMP RSLP RTRN SEGBLK: LDA 1,C2 JSR @.REED ;PSEUDO ATTTRIBUTES LDA 2,@ITBUF COM# 2,2,SZR ;MUST BE -1 JMP @.CKSER ;CHECKSUM ERROR JSR @.REED ;READ TAPE NUMBER LDA 2,@ITBUF w STA 2,TTNO ; & SAVE IN CASE ERROR LDA 0,PTNAME JSR RDSTR ; & READ NAME ISZ SEGSW ;INC SWITCH, ONCE EACH AT LDA 1,SEGSW ; BEGINNING & END OF EACH TAPE MOVZR 1,1,SZC ;HALVE & SEE IF BEGINNING OR END JMP LOEOT ;END STA 1,TAPENO ;SAVE TAPE NUMBER SUB#Gx 2,1,SZR ;SAME AS ONE READ? JMP WRONG ;TUT TUT LDA 1,PNAME JSR CPSTR ;SAME NAME AS ONE WE STARTED WITH? JMP .+2 ;NOPE JMP LOOP ;OK, WE CAN READ THIS SEGMENT LDA 1,TAPENO MOVZR 1,1,SNR ;FIRST TAPE? JMP LOOP ;YES - NAMES DON'T HAVE TO MATCH WRONG: "DSZ SEGSW ;BACK UP LDA 2,.DU1 ;TYPE THE HAIRY MESSAGE JSR @SMSG LDA 2,.TNAME JSR @SMSG LDA 2,.DU2 JSR @SMSG LDA 0,TTNO JSR PRNUM LDA 2,.DU3 JSR @SMSG LDA 2,.NAME JSR @SMSG LDA 2,.DU2 JSR @SMSG LDA 0,TAPENO JSR PRNUM LDA 2,.DU4 JSR @SMSG LOEOT: JSR PTERR ;MAKE THE WORLD IDLE LDA 3,@..DVINI INTDS JSR 0,3 ;RESTART INPUT DEVICE INTEN JMP LOOP SEGSW:0 C2:2 C6:6 CC4:4 ..DVINI:.DVINI C377: 377 C371:371 C370:370 ITBUF: TBUF NMBLK: LDA 1,CC4 JSR @.REED ;SKIP ATTRIBUTES & NBR OF BLOCKS LDAA~ 0,PNAME JSR RDSTR ;SAVE THE NAME JMP LOOP TIMBLK: LDA 1,C6 ;3 WORDS JMP .+2 LNKATR: LDA 1,C2 JSR @.REED ;SKIP IT JMP LOOP ; READ OVERLAYS TOP: LDA 0,.BQ MOVZL 0,0 STA 0,.PQ STA 0,PQ,3 ;INITIALIZE BUFFER POINTER LDA 1,BUFSZ ADD 1,0 STA 0,BTOP ;BUFFER LIMIT SUB 0,0 STA 0,EXTRA,3 ; I DID AND I'M GLAD SUBZL 0,0 STA 0,SEGSW ;INITIALIZE SEGMENT COUNTER LOOP: LDA 0,.TBUF SUBZL 1,1 ;ONE BYTE JSR @.RED LDA 2,TBUF ;LOAD THE BYTE MOVS 2,2 LDA 3,C376X SUB# 3,2,SNR ;DATA BLOCK? JMP DATA LDA 3>,C377 SUB# 3,2,SNR ;NAME BLOCK? JMP NMBLK LDA 3,C373 SUB# 3,2,SNR ;TIME BLOCK? JMP TIMBLK LDA 3,C371 SUB# 3,2,SNR ;LINK ATTRIBUTE BLOCK? JMP LNKATR LDA 3,C370 SUB# 3,2,SNR ;SEGMENT BLOBK? JMP SEGBLK LDA 3,C374 SUB# 3,2,SZR ;END BLOCK? JMP LOOP ;KEEP TRYING END: LDA 3,CSP LDA 0,PQ,3 LDA 1,.PQ SUB# 0,1,SZR ;INCOMPLETE BUFFER STILL AROUND? JSR @.EMPTY ;WRITE IT LDA 3,RWCMD ; REWIND COMMAND LDA 1,SCIDV ;BOOTSTRAP DEVICE CODE LDA 0,@.MTADC ; MTA DEVICE CODE SUBZ# 0,1,SZR ; MAGNETIC TAPEm/ INPUT ? JMP CTACK ; NO TRY CTA DOAS 3,MTA ; YES, REWIND 9 TRACK RTRN CTACK: LDA 0,@.CTADC SUB# 1,0,SZR JMP MCACK ;NO - TRY MCA DOAS 3,CAS RTRN MCACK: LDA 0,@.MC1 #SUBZ 0,1,SNR ; WELL ? JMP .+4 ; NOT PRIMARY LDA 0,@.MC2 ; TRY SECONDARY #SUBZ 0,1,SZR JMP DEQ ; TRY PAPER TAPE LDA 0,.DICC ADD 0,1 ; MAKE INSTRUCTION STA 1,.+1 0 INTDS LDA 0,CMSK LDA 2,@.MCMS ; GET DEVICE CLEAR MASK COM 2,2 AND 2,0 ;CLEAR MCA INHIBIT BIT, IF WE STA 0,CMSK ; SET IT MSKO 0 ;RESTORE MCA INTERRUPTS * INTEN LDA 0,M377 ;UNIT IS IN AC1 FROM THE DIC - AND 0,1 ; GET UNIT NUMBER FOR CLIBT LDA 2,SCIDV ADD 2,1 ;PACK IT IN HIGH ORDER BYTE STA 1,SCIDV ; OF DEVICE CODE WORD RTRN PTERR: RSAVE 0 ; PAPER TAPE ERROR ENTRY DEQ: LDA 2,@.INDCT ; GET PTR OR TTR DCT ADDR SUB 0,0 ;DO A CLOSE: INTDS ; DISABLE INTS STA 0,DCTDP,2 ;CLEAR DEVICE POINTER STA 0,DCTPP,2 ;& PROGRAM POINTER LDA 0,DCTQS,2 ;STATUS LDA 1,LPMSK ;MASK OFF LAP BITS AND 1,0 STA 0,DCTQS,2 LDA 1,DCTBD,2 ;BEAD COM# 1,1,SZR JSR @.DEͻQUE INTEN RTRN TBUF: .BLK 3 ;BUFFER C376X: 376 C374: 374 C373:373 .BQ: BQ2 .PQ: 0 BUFSZ: 1000 ;BYTES BTOP: 0 .TBUF: TBUF*2 .EMPTY: EMPTY .INDCT: INDCT .DEQUE: DEQUE .CTADC: CASDC .MTADC: MTADC .MC1: MC1 .MC2: MC2 XTTIDC: TTIDC LPMSK: -BSLPD-1 .MCMS: MbCMS .DICC: DICC 1,0 RWCMD: 10 M377: 17*400 C4:4 .RED:READ PQ =TMP RCHX =PQ+1 WRDC =RCHX+1 CHEXM =WRDC+1 EXTRA =CHEXM+1 DATA: LDA 1,C4 ;4 BYTES JSR @.RED ;READ BYTE COUNT AND CHECKSUM LDA 1,TBUF+1 STA 1,CHEXM,3 ;KEEP CHECKSUM IN SAFE PLACE LDA 1,TBUCF STA 1,RCHX,3 LDA 0,PQ,3 ;CURRENT BUFFER POSITION CKBUF: LDA 2,BTOP ;TOP OF BUFFER SUB 0,2 ;BYTES LEFT ADCZ# 2,1,SNC ;ENOUGH ROOM FOR BLOCK? JMP FILL ;OK SUB 2,1 STA 1,EXTRA,3 ;HANG ONTO LEFTOVER COUNT MOV 2,1 FILL: MOVZR 1,2 STA 2,WRDC,3 ;WORD COUNT FOR CHECKSUM JSR @.RED ADD 0,1 STA 1,PQ,3 ;UPDATE CURRENT BUFFER POINTER MOV# 2,2,SNR JMP F2 ;ZERO WORD COUNT - DONT CHECKSUM LDA 1,RCHX,3 MOVZR 0,2 ;ADDRESS OF DATA LDA 0,0,2 ;GET CONTENTS ADD 0,1 ;TOTAL INC 2,2 ;NEXT WORD DSZ WRDC,e3 JMP .-4 STA 1,RCHX,3 ;KEEP RUNNING CHECKSUM F2: LDA 2,BTOP LDA 0,PQ,3 SUB# 0,2,SZR ;BUFFER FULL? JMP CKSUM ;NOT YET JSR EMPTY ;YES, PUSH IT OUT LDA 1,EXTRA,3 MOV# 1,1,SZR ;ANY LEFT OF TAPE BLOCK? JMP CKBUF ;YES, FINISH IT OFF FIRST CKSUM: LDA 1,RCHX,3 LDA 0,CHEXM,3 SUB# 1,0,SNR ; DO THEY MATCH JMP @.LOOP ;GO AFTER NEXT BLOCK JMP CKSER ;BRING IT DOWN EMPTY: RSAVE 0 LDA 2,@..BQ ;BUFFER ADDRESS LDA 1,WDADR ;DEVICE ADDRESS JSR @.WRT INC 1,1 STA 1,WDADR ;UPDATE DEVICE ADDRESS LDA 3,OSP,P3 MOVZL 2,2 STA 2,PQ,3 ;RESET BUFFER POINTER RTRN WDADR: 0 .WRT: WRITE .LOOP: LOOP CKSER: LDA 2,.CKMS JSR @.MSGX LDA 2,SCIDV ; BOOTSTRAP DEVICE CODE LDA 3,.MTDC ; MTA DEVICE CODE SUBZ# 3,2,SNC ; BOOTING FROM MAGNETIC TAPE ? JMP RETRY ; NO, RELTRY IS POSSIBLE HALT ; YES, NO RECOVERY (WRONG POSITION) JMP @.RESTAR RETRY: JSR PTERR ; RETURN WORLD TO IDLE STATE JMP @.RESTAR ; NOW RESTART OVERLAY LOAD ..BQ: .BQ .MTDC: MTA .RESTAR: RESTAR .CKMS: CKSMS .MSGX: MSG .TXTM 1 ; PACK 'EM LEFT TO RZIGHT .NOLOC 1 PTMSG: .TXT /<15><12>LOAD $PTR, STRIKE ANY KEY.<15><12>/ TTMSG: .TXT /<15><12>LOAD $TTR, STRIKE ANY KEY.<15><12>/ CASMG: .TXT /<15><12>LOAD CT0, STRIKE ANY KEY.<15><12>/ MSGI: .TXT /<15>TYPE ("0") FOR $TTR ("1") FOR $PTR ? / MSG4: .TXT /<t15><12>FATAL MAGNETIC TAPE ERROR.<15><12>/ MSG5: .TXT /<15><12>$PTR DRIVER NOT LOADED - SYSGEN ERROR.<15><12>/ MSG7: .TXT /<15><12>FATAL MCA TRANSMITTER ERROR<15><12>/ CKSMS: .TXT /<15><12>CHECKSUM ERROR IN SYSTEM OVERLAY FILE.<15><12>/ .NOLOC 0 .END  SCHED.SRB =: ; SYSTEM PROCESS SCHEDULER ; THIS MODULE GIVES CONTROL OF THE PROCESSOR TO A DESERVING ; PATH- EITHER A USER PROGRAM OR A SYSTEM TASK RTITLE SCHED .ENT SMON,SMON1 .ENT URSEX .ENT INTSK .ENT PRISW .ENT PTPRV,PTSWP .ENT CFPU .ENT UPQUE .ENT TACT=,TWINK,PENTR,SMNXT .ENT NOTSK .ENT TINA3 .ENT SACHN .ENT TSKPU .ENT FPUSV .IFN NSW .ENT STSAV ; CONTEXT FLAG .ENDC .IFN IOSW .ENT MPENT,MPEXT .ENT MPOFF .EXTD CMAPA,CMAPB .EXTD CMAPI .EXTD IMPST .EXTD ADMAP .EXTD VNIOC .EXTD IMPSL .EXiTN SYST .EXTN ISMAP .EXTN SMSZ DMSZ ;IOCS - STATIC AND DYNAMIC MAP SIZES .EXTN INDYM ;IOCS -INIT DYN MAP .ENDC .EXTN SYSFL ; SYSTEM FLAGS .EXTN ENVIR ; ENVIR WORD .EXTN SYSIN ; SYSTEM INHIBIT FLAG .EXTN SS .EXTN PT1,PT2 .EXTN OVLY1,OVLAY .EXTN MODOUT ; OUTPUT ONE MODIFIED BLOCK WITH NO STACK .EXTN SYSQ .EXTN RESCH .EXTN PS1 .IFN MSW .EXTD MFSTB .EXTD C31K .ENDC .IFN MNSW!MN3SW .EXTD MAPED .ENDC .IFN MBSW .EXTD CMAP,CLBLK .ENDC .EXTN SYSE2 .EXTN SQ1 .EXTN GCELL .EXTN SPRTN .EXTN TRTN .EXTN BRKP2 .EXTN FSYSF .EXTN TODS,TODI,TODH,RTCI .EXTN TUNE,TUSTK,TUPSTK ;TUNING STUFF .IFN NSW!MNSW!MN3SW .EXTN SRTN .ENDC  .NREL ; SYSTEM REQ PROC MONITER ; LOOKS AT TASK QUEUES IN PAGE 0 SMON: ISZ@ .SYN ;SET IN SYSTEM SMON1: INTEN LDA@ 0,.TODS ;SEE IF NUMB SEC CHANGED LDA 1,LTODS ;LAST TODS SUB 0,1,SNR ;SKP IF CHANGED JMP SMON8 STA 0,LTODS ;NEW LAST TODS SUBZL 1,1 ;DEC FOR TIME OUT SMON8: STA 1,TINK LDA 3,SACHN ;START AT SYSQ SMON3: STA 3,CQ LDA 1,QSTAT,3 ; STAZTUS OF Q MOVZL# 1,1,SNC ;READY TO RUN ? JMP@ PPC,3 ;YES-HERE WE GO SMNXT: LDA 3,POLNK,3 ;NEXT COM# 3,3,SZR JMP SMON3 ;KEEP LOOKING ; SEE IF WE WERE JUST UPDATING COUNTS OF A SECONDS PASSAGE LDA 1,TINK SNEZ 1 JMP SEND ; IF NO THEN SKIP ELSE ; CHEDICK IF TIME TO SEE ABOUT OUTING A MODIFIED BLOCK DSZ IDLE ; IF HAVEN'T IDLED ENOUGH JMP SEND ; THEN LOOP ELSE ; TIME TO OUT A MODIFIED BLOCK JSR @.MODOUT SUBZL 1,1,SKP ; IF DIDN'T OUT ANYTHING THEN WAIT 1 LDA 1,CIDLE ; ELSE WAIT MORE FOR NEXT TRY STA 1,IDLE ; FOR BLOCK OUTPUT ; FAKE CLOCK IF DON'T HAVE ONE SEND: LDA 0,.RTCI ;SYSTM HAVE CLOCK ? COM# 0,0,SZR ;SKIP IF NO JMP SMON1 ; NO CLOCK- FAKE OUT TIMEOUT SEC INC DSZ RTCFK ;SECOND'S WORTH OF PASSES ? JMP SMON1 ;LOOP THRU AGAIN ISZ@ .TODS ;INC SEC JMP .+1 LDA 0,RTCFC ;RESTORE SEC DSZ COUNT STA 0,RTCFK JMP SMON1 IDLE: 5*60. ; WAIT 5 MINUTES FOR 1ST TIME CIDLE: 5. ; 5 SECONDS EACH TIME AFTER THAT .MODOUT:MODOUT .SYN: SYSIN .RTCI: RTCI RTCFK: -1 RTCFC: -1 TINK: 0 .TODH: TODH .TODS: TODz S .TODI: TODI LTODS: 0 SMON9: SUB 0,0 STA 0,UPQUE STA@ 0,.RESCH JMP SMON1 SACHN: SYSQ .IFN NSW STSAV: 0 .ENDC .FPESV: FPESV .PENT1: PENT1 ; ENTER A USER PROG ; AC1= STATUS,AC3= PTBL (MUST BE INTACT IF XFER TO SMNXT) PENTR: MOV# 1,1,SZR ;ANY RDOLS FLAGS ? JMP @.PENT1 ;YES PENT2: LDA 0,TINK ; CHECK, IF TIME OUT PASS MOV# 0,0,SZR ; CHECK THEN JUST GO ON JMP SMNXT ; LOOKING ELSE LDA 1,PRISW ;SEE IF SWAP PRI SET MOV# 1,1,SZR JMP PSWAP ;YES PSRTN: LDA 1,FPUSV MOV# 1,1,SZR ;SKIP IF NO STATE SAVE NEEDED JMP @.FPESV ;LOOK AT FPU STATE FPRTN: .IFN MNSW!MN3SW MOV 3,2 ;PTBL JSR MAPED ;MAP USER LDA 3,CQ LDA 1,PMLB,3 SMLB 1 ; MAP LAST BLOCK .ENDC .DO N3?MSW!BB?MSW XLDA 2,= -8. ; IF ANY DEVICES ARE ENABLED XLDA 1,= 377 ; FOR THE USE6R THEN WE DVLP: LDA 0,PDEV,3 ; MUST SET IN ENABLED FOR USER ANDO 1,0,SZR SEQ 1,0 JMP DVLP1 ; YES - DEVICE ENABLED INC 3,3 INCO 2,2,SZR ; ELSE LOOP TO JMP DVLP ; CHECK THE REST ; AT THIS POINT CARRY = 0 IF NO DEVICE ENABLED, = 1 IF IS DVLP1: XLDA 1U,= -MPSIO-1 ; I/O DEVICE ACCESS LDA 3,CQ ; RESTORE PT ADDRESS LDA 0,PMST,3 ; FOR THE USER IN HIS AND 1,0,SNC ; MAP STARTUP WORD ADC 1,0 ; AND STORE IT FOR STA 0,PMST,3 ; LATER USE .ENDC .IFN IOSW ; SEE IF USER CONTEXT IS STILL AROUND INTDS LDA 1r,PPRI,3 ;PRI LDA 2,CMAPA ;BG MOVZR# 1,1,SNR ;SKIP IF BG LDA 2,CMAPB ;FG SUB# 2,3,SNR ;SKIP IF LOAD NEEDED JMP PMPOK MOVZR# 1,1,SNR ; IS THIS BACKGROUND JMP X ; NO, SET FG MAP STA 3,CMAPA ; SET BG MAP TO USER CONTEXT JMP X1 ; GO ON X: STA( 3,CMAPB ; SET FG MAP TO USER CONTEXT X1: SUB 0,0 STA 0,CMAPI ; CLEAR CMAPI STA 3,CMAP MOV 3,2 ;PTBL .IFN NEWMAP ;INFOS:2.00 - IF NEW MAP MUST LDA 0,PMST,2 ;INFOS:2.00 - GET MAP SELECT WORD .ENDC ;INFOS - FOR THE LMP ADDI PMAP,2 ;MAP BASE QLDA 1,C32 ;32. SLOTS .IFN NEWMAP ;INFOS:2.00 - IF NEW MAP MUST DOC 0,BMAP ;INFOS:2.00 - SELECT THE MAP AND SUBC 0,0 ;INFOS:2.00 - CLEAR ACO FOR THE LMP .ENDC ;INFOS:2.00 LMP PMPOK: INTEN .ENDC .IFN MBSW LDA 2,0,3 ;MAP SELECT WD SBI 1,2 !;DO NOT TURN ON DOA 2,BMAP ;SELECT STA 3,CMAP ;SELECTED(WILL BE) .ENDC .IFE MSW LDA 2,PUSTP,3 ;UST POINTER STA 2,USTP ;SET UP IN PAGE 0 .ENDC NOSTA: .IFE MSW .IFN NSW!N3SW LDA 0,STSAV ; SEE IF USERS CONTEXT STILL AROUND LDA 3,CQ ; CURRENT QUEUE (PTBL) SUB# 0,3,SNR ; USERS CONTEXT STILL AROUND ? JMP NORST ; YES NOTHING TO DO MOV 0,1,SNR ; OTHER USERS CONTEXT IN ? JMP NOSVS ; NO SKIP SAVE LDA 0,.PSS ADD 1,0 ; AC0 -> SAVE AREA IN PROG TABLE LDA 2,.HRB ; FROM HARDWARE AREA (40)| LDA 1,CM10 ; 10 WORDS (40-47) JSR MOVIT ; MOVE TO PROGRAM TABLE NOSVS: LDA 2,CQ ; SHOW OUR PROG IS CURRENT STA 2,STSAV LDA 0,.HRB ; TO HRBEG LDA 1,.PSS ADD 1,2 ; FROM MY PROGRAM TABLE LDA 1,CM10 ; 40-47 JSR MOVIT ; MOVE MY INFO TO CORE NO#RST: .ENDC .IFN BSW LDA 2,.PSS ;OFFSET IN PT ADD 3,2 ;ABSOLUTE ADDRESS OF SAVE AREA LDA 3,.HRB ;WHERE IT GOES IN USER SPACE LDA 1,C10 ;NUMBER OF WORDS TO MOVE BLM ;MOVE RESERVED BIRD WORDS TO ; USER .ENDC LDA 2,USTP ;UST ADDR LDA 3,USTSA,2 ;SCHED ADDR LDA 0,-1,3 ;.SYSTM CALL PROC ADDR ; MUST SET 17 IN UNMAPPED SINCE SHARED WITH OTHER PROG STA 0,17 LDA 3,CQ ;RESTORE TO PTBL SUB 0,0 STA 0,PINTU,3 ;NO RESCH-WE'RE IT .ENDC .IFN MBSW LDA 0,ISP ;BASE OF INTERRUPT STK STA 0,SP ;FO=R SCL CALLS BACK LDA 0,ISL ;END OF SS STA 0,CSL .ENDC INTDS LDA 3,CQ ; RESTORE PT ADDRESS LDA 1,UPQUE ;LAST CHANCE FOR LUNCH LDA@ 0,.RESCH ADD 1,0,SZR ;SKIP IF NOT NEEDED JMP SMON9 ;LOOP THRU AGAIN LDA 0,PSTAT,3 ; SEE IF ANY PROGRAM FLAGS SE_sT WHILE MOV# 0,0,SZR ; DOING SETUP, IF WERE THEN JMP SMON9 ; DO RESHED STA@ 0,.SYN .IFN MSW LDA 1,PMAC1,3 ;AC1 MLDA 0,1 ; IN SCHED ? MOV# 0,0,SNR JMP PENT3 ;NO-NORMAL EXIT .ENDC .IFN USW LDA 0,@USTP ; IS USER WAS IN UMTI SCHED MOVZR# 0,0,SENR ; THEN WE LET IT RUN ELSE JMP PENT3 ; WE MUST GO TO SCHED START LDA 0,PMUSP,3 ; RESTORE USER USP STA 0,USP LDA 1,PMAC1,3 .ENDC ; USER WAS INTERRUPTED WHILE SCHED PROC-RETURN TO POINT OF INT .IFN N3SW LDA 2,@.ENVIR ; ENVIR WORD LDA 0,.ENUN3 ; NOVA3 BIT AND# 0,2,SNR ; IS THIS A NOVA3 ?? JMP NOST1 ; NO-- DONT RESTORE .ENDC .IFN N3SW!MN3SW LDA 0,PN3SP,3 MTSP 0 LDA 0,PN3FP,3 MTFP 0 NOST1: .ENDC LDA 0,PMAC0,3 ;RESTORE AC0 LDA 2,PMPC,3 ;PC+CARRY MOVZR 2,2 STA 2,UEXAD ;EXIT ADDR .IFN MNSW LDA 2,PMAC2,3 LDA 3,PMAC3,3 NIOS MAP ;BLOW IN BILL'S EAR .ENDC .IFN N3?MSW!B?MSW!BB?MSW LDA 2,PMST,3 ; USER MAP SMST 2 ; SET IT IN MAP .ENDC .IFN USW!MN3SW!MBSW LDA 2,PMAC2,3 LDA 3,PMAC3,3 .ENDC INTEN JMP@ UEXAD ;GO .IFN IOSW C32: 382. .ENDC .IFE MSW PENT3: LDA 1,@.ENVIR ; PUT ENVIR WORD IN USER PROG STA 1,USTRV,2 LDA 3,USTCT,2 ; RESTORE USER USP FROM LDA 0,TUSP,3 ; HIS TCB STA 0,USP .IFN N3SW LDA 0,.ENUN3 AND# 1,0,SNR ; NOVA 3 ? JMP NOTN3 ; NO LDA 0,TSP,3 ; GET STACK POINTER MTSP 0 LDA 0,TFP,3 ; GET FRAME POINTER MTFP 0 .ENDC NOTN3: LDA 1,USTSV,2 ;SEE IF EXTENDED SAVE EXIT LDA 3,USTSA,2 ;SCHED ADDR MOVL 1,1,SNC JMP URSEX ;NO MOVZR 1,1 STA 1,USTSV,2 MOV 1,3 ;EXIT ADDR ; ENTER UNMAPPED SCHED WITH INT OFF URSE(X: LDA@ 0,.TODH ;TELL USER TOD LDA@ 1,.TODS LDA@ 2,.TODI ;SUB SEC INC ; GO TO THE USER JMP 0,3 .ENDC .IFN MSW PENT3: LDA 2,.UST .IFN MN3SW MLDA 2,USTCT,2 ; GET CURRENT TCB MLDA 0,TSP,2 ; GET STACK POINTER MTSP 0 MLDA 0,TFP,2 ; GET FRAME POINNTER MTFP 0 LDA 2,.UST .ENDC LDA 1,@.ENVIR MSTA 1,USTRV,2 ; STORE REV WORD MLDA 1,USTSV,2 ;SAVE ROUTINE MOVL 1,1,SNC JMP URSEX ;NO ; GO TO USER EXTENDED SAVE RESTORE ADDRESS MOVZR 1,0 ; RESET MSTA 0,USTSV,2 JMP UEXIT URSEX: LDA 2,.UST ; GET U ST ADDRESS IN CASE CAME FROM MAPZ MLDA 0,USTSA,2 ; GET ADDRESS OF USER SCHEDULER UEXIT: STA 0,UEXAD ; FOR RESTART SUBZL 0,0 ; SET IN SCHED MSTA 0,1 ; IN MRDOS/ARDOS AC3= PTBL SUB 0,0 STA 0,PINTU,3 ;NO RESCH LDA@ 0,.TODH ;TELL USER TOD LDA@ 1,.TODjS LDA@ 2,.TODI ;SUB SEC INC .IFN N3?MSW!B?MSW!BB?MSW LDA 3,@CQ SMST 3 .ENDC .IFN MNSW NIOS MAP .ENDC INTEN JMP@ UEXAD ;EXIT .ENDC LPOOL .IFE MSW .PSS: PSSV1 .HRB: HRBEG C10: 10 .ENDC .IFE BSW!MSW MOVIT: STA 3,MOVSV ; SORRY ABOUT STORING6 IN HARD CORE MOV 0,3 ; TO ADDRESS MOVI1: LDA 0,0,2 ; GET A WORD STA 0,0,3 ; STORE A WORD INC 2,2 ; BUMP ADDRESSES INC 3,3 INC 1,1,SZR ; DONE ? JMP MOVI1 ; NO DO NEXT JMP @MOVSV ; YES RETURN MOVSV: 0 ; RETURN ADDRESS CM10: -10 .ENDC UPQUE: 0 PTPRV: -1 ; PT PRIVELEGEGED FLAG ; VALUE OTHER THAN -1 SAYS ; PROGRAM TABLE DEPICTED IN ; PTSWP IS ONE TO RUN NEXT PTSWP: 0 ;SWAP PT 0 PT2 1 PT1 .RESCH: RESCH CSBRK: PSBRK CSEO: PSEW+PSCP .UST: UST .SBREK: SBREK PRISW: 0 FPUSV: 0 UEwbXAD: 0 .IFN NSW .ENUN3: ENUN3 .ENDC .ENVIR: ENVIR ;SWAP PRI BETWEEN PT1 AND PT2 PSWAP: LDA 2,POLNK,3 ;SEE IF PT1 COM# 2,2,SNR JMP P2ENT ;NO- ENTER LDA 1,PSTAT,2 ;DOES PT2 WANT CONTROL ? SEQZ 1 JMP P2ENT ;NO LDA 1,PTSWP SNE 1,3 ;EVERY OTHER PTIME SKIP OVER PT1 JMP@ .SMNXT ;SKIP P2ENT: INTDS ; SHUT OFF INTS SO WE CAN'T RUIN PRIV LDA 0,PTPRV ; NO SKIP IF PRIVELDGED PT LDA 1,PTSWP ; GET PERSON NOT LAST PRIVILEGGED SEQ 1,3 ; SNEZ 0 ; SET UP BY CLOCK STA 3,PTSWP INTEN JMP @.+1 PSRTKN CMWT: -1B1-1 PENT1: LDA 0,CSEO ;EXEC OP SET ? AND# 1,0,SZR ;SKIP IF NOT EO JMP @.SMNXT ;IF NO LDA 0,CSBRK ;ABORT SET ? AND# 1,0,SZR JMP@ .SBREK ;YES-GO PROC ; MUST BE REQ TO WAIT 1 SEC (1B14) LDA 2,@.TINK MOV# 2,2,SNR ;SEC PASS ? JMP @.SMNXT ;NO LDA 0,CMWT ;RESET WAIT 1 SEC AND 0,1 ;RESET FLAG STA 1,PSTAT,3 ; WAIT 1 PASS IN CASE BOTH FG AND BG IN THIS STATE JMP @.SMNXT ;ENTER .TINK: TINK ; SEE IF CURRENT FLOATING POINT CONTENTS CORRECT FOR USER ; IF NOT, SWAP STATES FPESV: LDA 2`,CFPU ;CURRENT CONTENTS SUB# 2,3,SNR JMP@ .FPRTN ;NO SWAP NEEDED- RTN ; SAVE CURRENT STAE OF FPU STA 3,CFPU ;NEW CURRENT- OK TO DO BEFORE ; SWITCH ;UNLESS INTERRUPT WORLD USES FPU LDA 1,CPFPSV ;PTBL OFFSET (DIFFERENT IN ; MRDOS) ADD 1,2 ;BUMP ADDR .IFE BSW!MBSW DOBS 2,FPU2 ;DUMP FPMAC TO PTBL LDA 0,C4 ADD 0,2 ;BUMP ADDR BY 4 SKPBZ FPU ;WAIT ON FPU JMP .-1 NIOC FPU2 ;TEMP TO FPMAC SKPBZ FPU ;WAIT ON FPU JMP .-1 DOBS 2,FPU2 ;FPMAC TO PTBL SKPBZ FPU ;WAIT ON FPU JMP .-1, DIAC 1,FPU ;STATUS SKPBZ FPU ;WAIT ON FPU JMP .-1 STA 1,4,2 ;TO PTBL ; PUT REQ STATE INTO FPU LDA 2,CPFPSV ;PTBL OFFSET ADD 3,2 ADD 2,0 ;ADDR TMP DOBP 0,FPU2 ;TMP TO FPMAC SKPBZ FPU ;WAIT ON FPU JMP .-1 NIOP FPU2 ;MOVE FPMAC TO TEMP SKP4BZ FPU ;WAIT ON FPU JMP .-1 DOBP 2,FPU2 ;SET FPMAC LDA 1,10,2 ;STATUS SKPBZ FPU ;WAIT ON FPU JMP .-1 DOA 1,FPU ;SET STATUS JMP@ .FPRTN ;EXIT C4: 4 .ENDC .IFN MBSW!BSW ADD 3,1 ;STATE ADDR TO INSTALL IF FPU ADCZR 0,0 STA 0,CSL ;NO OVERFL@LOW CHECK... ; SET UP FAKE SP = PTBL FPU SAVE AREAS SO POP/PUSH WORK STA 2,SP ;PUSH SP FPSH ;SAVE CURRENT ADDI 18.,1 ;= END ADDR STA 1,SP ;POP SP FPOP ;NEW STATE JMP@ .FPRTN ;BACK TO EXIT PATH .ENDC CFPU: 0 .IFN MBSW CPFPSV: PFPSV-1 .ENDC1F .IFE MBSW CPFPSV: PFPSV .ENDC .FPRTN: FPRTN .TENTR: TENTR ; SYSTEM TASK IS ACTIVE-SEE IF A TIME OUT HAS OCCURRED OR ; IF IT IS READY TO RUN TACT: MOVZR 1,1,SZC ;PENDED ? JMP TOUTC ;YES-LOOK FOR TIME OUT LDA 0,@.TINK ; IF DOING TIMEOUT UPDATE PASSc MOV# 0,0,SZR ; THEN HAVE DONE TIMEOUT UPDATE JMP @.SMNXT ; SO GO TRY FOR NEXT UPDATE MOVR# 1,1,SZC ;ACTVE ? JMP @.TENTR ;YES-GO TO IT ; TASK IS INACTIVE - CHECK ITS QUEUE TINACT: LDA 2,QLNK,3 ; LINK COM# 2,2,SNR ; ANY ENTRY JMP SDEQ ; NO (-1) tDELETE QUEUE FROM ; CHAIN JSR TSKPU ;GET A FREE STACK JMP@ .SMNXT ;NONE AVAILABLE-LOOP AROUND LDA 0,CLNK,2 ; POP QUEUE STA 0,QLNK,3 DSZ QCNT,3 ;DEC ON QUEUE COUNTER JMP .+1 STA 2,QCURR,3 ;CELL TO QUEUE STA 2,CC TINA3: LDA 1,QACT STA 1,QSTATK,3 ; ACTIVE STAT .IFN IOSW LDA 2,CC ;MIOCS - GET CURRENT PROCESS CELL LDA 0,CPROG,2 ;MIOCS - GET FLAGS & PRI ADDZL# 0,0,SNC ;MIOCS - SKIP IF TO BE MAPPED JMP NOTSK ;MIOCS - NOT TO BE MAPPED ANDI -1-1B1,0 ;MIOCS- CLEAR IOCS MAP FLAG STA 0,CPROG,2 ;MIOCS- UPDATE FLAGS LDA 2,CQ ;IOCS -GET QUEUE EJSR INDYM ;IOCS -INIT DYN MAP EJSR MPENT ;MIOCS - TURN ON MAP .ENDC NOTSK: LDA 3,CC LDA 1,CENT,3 ; TASK ENTRY LDA 0,CENT2,3 ;IN CASE DOUBLE QUEUE SET UP ; NEXT ENT STA 0,CENT,3 LDA 2,CSP STA 1,TMP,2 ; ADDR TO STK LDA 2,.OVLY1 ;ASSUME OVLAY CALL NEEDED MOVL# 1,1,SNC ;SKP IF TRUE MOV 1,2 ;ADDR TO GO DIRECTLY TO ; RESIDENT CODE .IFE BSW!MBSW STA 2,RLOC ;SAVE EXIT .ENDC .IFN BSW!MBSW PSH 2,2 .ENDC JSR LDUSP LDA 3,CC LDA 0,CAC0,m3 LDA 1,CAC1,3 LDA 2,CAC2,3 LDA 3,.TRTN ISZ INTSK .IFE BSW!MBSW JMP@ RLOC .ENDC .IFN BSW!MBSW POPJ .ENDC ;CHECK FOR A TIMEOUT TOUTC: LDA 0,QTIME,3 ;TIME OUT COUNTER COM# 0,0,SNR ;= -1? JMP@ .SMNXT ;YES - KEEP LOOKING LDA 2,@.TINK ;0 OR 1  SUB 2,0,SNR ;SKIP IF NO TIMEOUT JMP STOUT STA 0,QTIME,3 JMP@ .SMNXT .SMNXT: SMNXT ; UNLINK A QUEUE FROM THE ACTIVE CHAIN THAT IS NO LONGER ACTIVE SDEQ: LDA@ 2,.SACHN ;ACTIVE CHAIN START SUB# 2,3,SNR JMP SDEQ1 ;REMOVING FIRST SDEQ2: MOV 2,1 ;SAVE AS LAST LDA 2,POLNK,2 ;TO NEXT COM# 2,2,SNR ;FOUND ? JMP . SUB# 2,3,SZR ;MATCH ? JMP SDEQ2 ; FOUND POSITION LDA 3,POLNK,2 ;FORWARD LINK SUB 0,0 INTDS ;IN CASE UNPEND CALLED BY INTERRUPT STA 0,POLNK,2 ;COVER TRACKS MOV 1,2 ;PREVIOUS QUEUEX INTEN STA 3,POLNK,2 ;LINK IN JMP@ .SMON3 SDEQ1: LDA 3,POLNK,2 STA@ 3,.SACHN ;NEW START IN LIFE SUB 0,0 STA 0,POLNK,2 ;COVER JMP@ .SMON3 .SMON3: SMON3 .SACHN: SACHN ; TASK THAT WAS PENDED HAS TIMED OUT ; AC1=STATUS SHIFTED RIGHT 1 , AC3=QUEUE OSTOUT: LDA 2,QSTK,3 ;STACK POINTER .IFE BSW!MBSW DSZ RTLOC,2 ;BAD RETURN .ENDC .IFN BSW!MBSW DSZ ORTN,2 ;BAD RETURN .ENDC MOVZL 1,1 STA 1,QSTAT,3 JMP TACT ;GO TO TASK ; ENTER A TASK THAT WANTS TO BE TURNED ON TWINK: MOVR# 1,1,SZC ;PENDED ? J8MP@ .SMNXT ;YES JSR TSKPU ;GET A STACK JMP@ .SMNXT ;NONE-TRY LATER LDA 0,QSTAT,3 ;SET ACT FLAG MOV# 0,0,SZR ;SKIP IF NOT UNPENDED DSZ @.UPQUE JMP .+1 LDA 2,MQACT AND 2,0 ADC 2,0 STA 0,QSTAT,3 ; RETURN THE STATUS LDA 0,.TACT ;PC = ACTIVE PATКH STA 0,PPC,3 LDA 2,QCNT,3 ;PROC ADDR LDA 3,CSP STA 2,TMP,3 ;MUST BE AN OVERLAY ADDR LDA 3,.WRTN ;ADDR SHORT RETURN ISZ INTSK JMP@ .OVLY1 ;CALL IN .TACT: TACT QACT: TSACT MQACT: -TSACT-1 .WRTN: SPRTN ; PICK UP A FREE STACK ; IF NO STACK BAD RTNI ; ON RTN (GOOD ONLY) CSP= STACK POINTER TSKPU: STA 3,TRET JSR @.TUNE ;COUNT STACK REQUESTS TUSTK LDA 3,.PS1 ;ADDR FIRST TSRH: LDA 1,0,3 ;LOOK AT ONE MOVZL# 1,1,SNC ;FREE ? JMP TSFND ;EITHER A FIND OR THE END COM# 1,1,SNR ;END ? JMP TSKNO ;EͧXIT WITH BAD RTN INC 3,3 JMP TSRH TSFND: ADDOR 1,1 ;RESERVE IN PS TABLE  STA 1,0,3 ADDOR 1,1 ;FOR STACK SWITCH NO 1B0 MOV 3,0 ;ADDR OF STACK POINTER LDA 3,CQ ;CALLER QUEUE STA 0,QSTKC,3 ;SAVE FOR STK RELEASE LATER .IFE MBSW!BSW STA 1,CSP .ENDC .IFN MBSW!BSW STA 1,SP ;SET SP SBI 2,1 ;INIT FP TO SP-2 MOV 1,3 LDA 1,1,3 ;STK END MAGICALLY APPEARS IN ; AC1... STA 1,CSL STA 3,CSP ;FP .ENDC ISZ TRET ;GOOD RTN JMP TSKEX TSKNO: JSR @.TUNE ;COUNT TIMES STACK NOT FREE TUPSTK TSKEX: LDA 3,CQ JMP@ TRET TRET: 0 .TUNE: TUNE ; WAITED TASK IS NOW READY TO ENTER TENTR: LDA@ 1,.UPQUE MOV# 1,1,SZR DSZ@ .UPQUE ;DEC TO PROC COUNT JMP .+1 LDA 1,QSTK,3 ;STACK STA 1,CSP ;NEW STACK POINTER .IFN BSW!MBSW LDA@ 2,QSTKC,3 ;BASE OF STACK LDA 2,-1,2 ;STACK LIMIT STA 2,CSL .ENDC LDA 2,QCURR,3 ;CURRENT CELL STA 2,CC ISZ INTSK LDA 2,QCRSG,3 ;CURRENT SEG ADDR STA 2,CRSEG .IFN IOSW STA 1,SP ;FP=SP FOR MPENT SAVE.... LDA 0,CNMPB ;MAP BIT SET ? SZB 3,0 JSR MPENT ;YES-ENTER MAPPED MOI7DE .ENDC TENT1: JSR LDUSP ;RESTOER USTP .IFE BSW!MBSW JMP @.SRTN .SRTN: SRTN .ENDC .IFN BSW!MBSW RTRN .ENDC .OVLY1: OVLY1 .TRTN: TRTN .UPQUE: UPQUE INTSK: 0 .PS1: PS1 LDRTN: 0 ; RESTORE USTP FROM PTBL LDUSP: STA 3,LDRTN LDA 3,CC ;CELL COM# 3,3,SNR JMP@ LDRTN LDA 2,CPTAD,3 .IFE MSW LDA 1,PUSTP,2 ;UST ADDR STA 1,USTP .ENDC .IFG MSW-MBSW JSR MFSTB .ENDC .IFN MBSW LDA 1,PMAP,2 ;BLK 0 STA 1,CLBLK DOB 1,BMAP ;SET .ENDC JMP@ LDRTN SBREK: JSR@ .GCELL JMP@ .SMN1 SUB 0,0 LDA 3,CQ S)/TA 0,CQ ;PRETEND THIS IS A .SYSTM CALL STA 0,PSWD,3 ;CLEAR ANY BACKUP ADC 0,0 STA 0,CTMP2,2 LDA 1,CPSEW ;SET EO IN STATUS STA 1,PSTAT,3 STA 3,CPTAD,2 ;ASSUME BG LDA 0,PPRI,3 ;PRI STA 0,CPROG,2 LDA@ 1,.SYF1 ;ASSUME BG MOVZR# 0,0,SNR ;SKIP IF mTRUE LDA@ 1,.FSYSF STA 1,CTEMP,2 ;PASS STA 2,CC MOV 3,0 ;PTBL ADDR FOR COMPARE LDA@ 2,.SACHN SBR2: LDA 1,QSTAT,2 ;SEE IF ACTIVE MOV# 1,1,SNR JMP SBR1 ;NO LDA 3,QCURR,2 ;SEE IF CURRENT CELL COM# 3,3,SNR JMP SBR1 LDA 1,CPTAD,3 ;PTBL IN CELL SUBc# 1,0,SZR ;MY KIND OF GUY ? JMP SBR1 ;NO LDA 3,QSTAT,2 MOVR 3,3 ;SHIFT FOR UNPEND LDA 1,CAMSK ;SHIFTED ABORT COMPLEMENT AND 1,3 ADCZL 1,3 ;WOW STA 3,QSTAT,2 ;UNPENDED WITH ABORT SET SBR1: LDA 2,POLNK,2 ;TO NEXT ; STOP AT END OF ACTIVE SYSTEM TA.SK QUEUES LDA 1,PPRI,2 ;PRI OF 0 KEEP GOING MOV# 1,1,SNR JMP SBR2 ;NO LDA 2,.BRKP2 ;PROC ADDR FOR CENT JMP@ .SQ1 ;PUT ON QUEUE .BRKP2: BRKP2 CPSEW: PSEW CAMSK: -TSAB+1 .FSYSF: FSYSF .SYF1: SYSFL .SMN1: SMON1 .SQ1: SQ1 .GCELL: GCELL .IFN IOSW ; ENUTER MAPPED MODE ; ROUTINE WILL LOAD MAP AND SET MAPPED STATUS BIT MPENT: RSAVE 0 INTDS LDA 0,IMPSL ;A/B MAP SELECT BIT LDA 3,ADMAP ;MAP IOCS IS USING LDA 2,0,3 ;CONTENTS MOVL# 2,2,SZC ;SKIP IF NOT STATIC SYSTEM JMP MPEN1 ; LOAD UP STATIC SYSTEM -PORTION SUBC 2,2 ; CLEAR CMAPI STA 2,CMAPI LDA 2,.ISMAP ;BASE ADDR LDA 1,.ISMSZ ;SIZE .IFN NEWMAP ;INFOS:2.00 - IF NEW MAP DOC 0,BMAP ;INFOS:2.00 - SELECT THE MAP AND SUBC 0,0 ;INFOS:2.00 - CLEAR AC0 FOR THE LMP .ENDC ;INFOS:2.00 - LMP L+DA 2,.ISMAP ;IOCS - GET MAP BASE AGAIN ADDOR 2,2 STA 2,0,3 ;TO CMAPA OR CMAPB MPEN1: STA 2,CMAP ;SET AS SELECTED MAP LDA 2,CQ ;QUEUE LDA 1,CNMPB BTO 2,1 ;SET IN MAPPED MODE ADDI QIMAP,2 ;TO DYNAMIC START LDA 1,CMAPI ;MAPPED NOW ? SUB# 1,2,SNR JMP MPEN2 LDA 1,.IDYSZ ;DYNAMIC SIZE STA 2,CMAPI .IFN NEWMAP ;INFOS:2.00 - IF NEW MAP LDA 0,IMPSL ;INFOS:2.00 - GET MAP SELECT BIT DOC 0,BMAP ;INFOS:2.00 - SELECT THE MAP SUBC 0,0 ;INFOS:2.00 - AND CLEAR AC0 FOR THE LMP .ENDC ;INFOS:2.00 K)LMP MPEN2: INTEN LDA 1,IMPST ;MAP STAT DOA 1,BMAP RTRN .ISMSZ: SMSZ .IDYSZ: DMSZ CNMPB: BTSMP .ISMAP: ISMAP ; ; EXIT MAPPED MODE- ; ; MPOFF= TURN OFF MAP, LEAVE QSTAT SET. ; ASSUMES STACK IS NOT SS. ; RETURNS AC3 = CSP, ION = 1 ; ; MPEXT= IF THERE IS A CURRENT SYSTEM QUEUE, BE SURE ITS ; MAP STATUS IS RESET. ; TURN OFF MAP, SO RDOS CAN USE PAGE 31. ; RETURNS AC0,1,2 ION = 1 ; MPEXT: STA 1,MPS1 ; WILL USE AC1, AC2 STA 2,MPS2 LDA 2,CQ ; CLEAR INFOS MAP BIT LDA 1,CNMPB ; IN QSTAT IF THERE MOV 2,2,SZR ; IS A QUEUE. BTZ 2,1 LDA 2,MPS2 ; RESTORE AC1, AC2 LDA 1,MPS1 MPOFF: INTEN ; RETURN ENABLED STA 3,MPS3 NIOP BMAP ; TURN OFF MAP LDA 3,CSP ; ABSORB POSSIBLE TRASH LDA 3,CSP ; RETURN FRAME POINTER IF J;MP @MPS3 ; THERE IS ONE. MPS1: 0 MPS2: 0 MPS3: 0 .ENDC PSPACE.SRII 3 RTITLE PSPACE ; THIS MODULE PROVIDES PATCH SPACE IN UNMAPPED RDOS. ; 10 (OCTAL) WORK BLOCKS ARE GENERATED AND A .LIMT IN ; SYSGEN DETERMINES HOW MANY OF THESE ARE LOADED. THE ; SYSGEN LOCATION NBLKS CONTAINS THE NUMBER OF BLOCKS ; LOADED. THE ARGUMENT TO THE MACROS M1 AND M2 SPECIFY ; HOW MANY BLOCKS ARE GENERATED IN PSPACE.RB. ; ; CARE SHOULD BE TAKEN WHEN LOCATING THIS MODULE IN A ; LIBRARY. THE WORD FOLLOWING THIS MODULE SHOULD ALWAYS ; BE NON-ZERO TO ALLOW FOR PATCH SPACE OVERFLOW DETECTION. ; THIS' METHOD SAVES US A WORD BY NOT HAVING TO APPEND A ; NON-ZERO WORD ONTO THE END OF THIS CODE. .MACRO M2 ; GENERATE ENTRY POINTS PL000 THRU PL0^1 ; ASSUMED IS THAT <100 (OCTAL) OF THESE BLOCKS ARE REQUESTED. ; THIS MODULE SHOULD BE PLACED IN A LIBRARY S$O THAT THE ; WORD FOLLOWING IS NON-ZERO. ; ; ; ; CREATE BLOCKS OF WORDS (10 OCTAL WORDS LONG), EACH LABLED ; PL000 THRU PL0^1. THIS WILL ENABLE US TO USE THE .LMIT ; PSUEDO OP FROM SYSGEN TO DYNAMICALY ALLOCATE PATCH SPACE. .NOMAC 1 K=^1 J=K-1 .D{O K .ENT PL\J J=J-1 .ENDC J=0 .DO K PL\J: .BLK 10 J=J+1 .ENDC % .ENT PATCH .NREL PATCH: .+1 M2 100  .END SYMOD.SRB% @ ; THIS IS A GROUP OF MODULES THAT DO CORE RESIDENT .SYSTM CALL ; PROCESSING RTITLE SYMOD .ENT FILDQ .ENT BRKP1 .ENT SDNCK,SDNKA .ENT QCHK1 .ENT BLKCA,BLKCB .ENT TTYG,TTYP .ENT SOPNCK .ENT CLCHK .ENT RDCK0,RDCK1,RDCK2 .ENT WRCK .ENT MTCHK .ENT FOPE,DTER .IFN MSW .ENT BLKEW,BLKER .ENT CPNT .ENT LDOV .ENT REMAP .ENDC .ENT TIMEQ .ENT BRKP2 .EXTN SYSTR ; START OF SYSTEM .EXTN SYSFL ; SYSTEM FLAGS .EXTN DIVI ; INTEGER DIVIDE .EXTN STATUS .EXTN DSKC ; DISK FILE CLOSE .EXTN SETMOP ; SET BLOCK MODIFIED .EXTN PT1,PT2 .EXTN OVLY1,OVLAY .EXTN TTOQ .EXTN TTIQ .EXTN FCELL .EXTN DSQ1,DSQ2 .EXTN SMNXT .EXTN NOTSK .EXTN DNCK .EXTN OPNCK .EXTN SYSFG,SFGNP .EXTN SPOLQ .EXTN RDBNO ; DON'T DELETE-IT LOADS BLKIO.... .EXTN FSYSF ; FG SYSFL .EXTN NTO1Q,NTI1Q .EXTN INDSK .EXTN INFND .EXTN TRTN3 .EXTN SQ2 .EXTN INXTA,INXTB .EXTN SYSER .EXTN QWAIT .EXTN BRKWT .EXTN DTOTL .IFN MSW .EXTD C31K .EXTD TRPRT .EXTD UEBL .EXTN GTRTN .ENDC .IFE MSW!BSW ; UNMAPED NOVA ONLY x7 .EXTN STSAV ; PROG FLAG .EXTN MVWD .ENDC .NREL BRKP1: LDA 1,.+2 ; REAL PROCESSING ADDR JMP PESET .+1 SUBZL 1,1 ; SET BREAK FLAG LDA 2,CC STA 1,CTEMP,2 ; PASS IT ON LDA 2,CPROG,2 LDA 3,.SFLG ; ASSUME BG MOVZR# 2,2,SNR LDA 3,.FSF2 ; FG iO STA 1,0,3 ; SET FLAG BRKP2: .IFE MSW!BSW ; UNMAPED NOVA ONLY JSR PTCON ; SEE ABOUT PTABLE CONTEXT .ENDC JSR @.OVA1 ; GO SEE IF READY TO BREAK BRKWT JMP @.TR3A ; SET UP BLOCK IO CALL BLKCA: ADC 0,0,SKP ; FLAG READ BLKCB: SUB 0,0 ; WRITE STA 0!,RLOC ; SAVE FLAG LDA 2,CC ; GET CELL ADDRESS BLKCM: LDA @3,CC ; TCB LDA 1,TAC1,3 ; FIRST RELATIVE BLOCK STA 1,CTEMP,2 ; PASS IN CELL LDA 2,CCHAN,2 ; CHECK THE CHANNEL MOVL# 2,2,SZC ; OPEN ? JMP FOPE ; NO... LDA 0,UFTAT,2 ; GET ATTRIBUTES LDA io2,RLOC ; ENT FLAG SEQZ 2 ; SKIP IF WRITE JMP BKRD ; READ... MOVR# 0,0,SZC ; SKIP IF OK JMP WRER0 ; WRITE PROTECTED JMP BKCMN ; COMMON CODE BKRD: MOVL# 0,0,SZC ; READ PROTECTED ? JMP RDER1 ; YES BKCMN: LDA 0,CL377 ; MASK FOR # BLOCKS LDA 1,TnAC2,3 ; NUMBER OF BLOCKS + CHANNEL ANDS 0,1 ; # OF BLOCKS ISZ RLOC ; ONLY DO END TEST IF REG READ JMP BLKC1 ; WRITE LDA 3,CC ; CURRENT CELL LDA 0,CAC0,3 MOVS 1,3 ADD 3,0 LDA 3,USTP ; CHECK IT LDA 3,USTNM,3 ; AGAINST NMAX USLE 0,3 ; WELL? JXMP RDER0 BLKC1: LDA 3,CC ; CURRENT CELL STA 1,CAC1,3 ; SAVE AS AC1 # OF BLOCKS LDA 2,CCHAN,3 ; UFT STA 2,CAC2,3 ; SAVE AS AC2 LDA 0,UFTDC,2 ; DCT FOR QUEUE JMP @.INXTA ; ENQUEUE .IFN MSW ; EXTENDED READ/WRITE DIRECTLY TO BLK ARRAY ; CORE ADDR IS j$OFFSET+BLK # ; OFFSET = 0 THRU 3 WHICH = 0,400,1000,1400 RESP. ; TAC0=OFSET(LH),BLOCK #(RH) ; TAC1=RELATIVE BLOCK # ; TAC2=# BLOCKS(LH),CHANNEL #(RH) BLKER: SUBZL 0,0,SKP ; READ BLKEW: SUB 0,0 ; WRITE STA 0,RLOC LDA @2,CC ; TCB LDA 1,TAC0,2 ; COREG4 ADDR LDA 0,CNRB ; 377 AND 1,0 ; BLK # LDA 3,CNOFT ; OFFSET MASK TEST AND# 3,1,SZR ; CHECK FOR OFSET > 3 JMP MPER ADDOR 1,1 ; BIT 0 IN CA FLAGS TYPE FOR ; RWBLK LDA 3,CC STA 1,CAC0,3 ; FOR RWBLK LDA 3,CPTAD,3 ; PTBL LDA 2,TAC2,2 ; # DISK'k BLKS IN LB LDA 1,CL377 ANDS 1,2 ; GET IT INCZR 2,2 ; DIV BY 4 INCZR 2,2 ; =# OF 1K BLOCKS ADD 0,2 ; = LAST 1 K BLK (MAP START ; REL) LDA 1,PEDMP,3 ; DATA MAP START ADD 1,0 ; REAL STARTING BLK LDA 1,.PEMAP ; MAP START OFFSET ADD 1,0 ADD* 3,0 ; PTBL ADDR LDA 3,PEDCT,3 ; # BLKS IN EXTENDED MAP SUBZ# 2,3,SNC ; IF LAST BLK TOO BIG ERROR JMP MPER LDA 2,CC STA 0,CTMP3,2 ; FOR RWBLK (ADDR FIRST SLOT IN ; PTBL) JMP BLKCM ; COMMON CODE CNRB: 377 .PEMAP: PEMAP CNOFT: 377*2000 ; 2000=1K, THIS IS A K MASK .ENDC .IFE MSW!BSW ; UNMAPED NOVA ONLY PTCON: RSAVE 0 ; SAVE THE WORLD LDA 2,CC ; CELL ADDRESS LDA 2,CPTAD,2 ; PTABLE LDA 1,@.STSAV ; CURRENT CONTEXT SUB# 1,2,SZR ; AM I IN ? RTRN ; NO NOTHING TO DO SUBC 0,0 ; YES -> BUT NOT FOR LONG STA 0,@.STSAV ; FOR CORE IMAGE LOAD ETC. LDA 0,.SSV ; DISP TO SAVE AREA IN PTBL ADD 0,1 ; ADDRESS OF SAVE AREA IN PTBL LDA 0,.HRB ; START OF SAVE AREA LDA 2,C10 ; NUMBER OF WORDS TO SAVE JSR @.MVWD ; MOVE 40-47 TO PTBL RTRN X; THATS ALL FOLKS .HRB: HRBEG C10: 10 .MVWD: MVWD .SSV: PSSV1 .STSAV: STSAV .ENDC .IFN BSW!MBSW RLOC: 0 .ENDC CL377: 177400 .OVA1: OVLAY .SFLG: SYSFL .IQFN: INFND .TR3A: TRTN3 .FSF2: FSYSF QCHK1: LDA 1,.+2 ; PUT REAL POCESSING ADRESS IN ; AC1 JMP PESET .+1 ;COME HERE AFTER EVERYTHING IS ENQUEUED TO SYSQ .IFE BSW!MSW ; UNMAPED NOVA ONLY JSR PTCON ; MAKE SURE MY CONTEXT IS IN PTBL .ENDC JSR @.OVA1 ; CALL WAIT QWAIT JMP FILDQ ; QUEUE TO DSQ1 ; SET PROG STATUS TO NOT RUNNABLE PESET: LDA 2,CC LDA 2,CPTAD,2 ; PTBL LDA 3,CMEO ; RESET EO ONLY LDA 0,PSTAT,2 AND 3,0 ADC 3,0 JMP STRT CMEO: -PSEW-1 .IFN MSW .PT2: PT2 CCPF: PSCP CEO: PSEW CPNT: LDA 2,.PT2 INTDS ; NO SURPRISES LDA 0,PSTAT,2 ; SET CP BIT LDA 3,CEO ; RESET ALL BUT\ EO AND 3,0 LDA 3,CCPF ADD 3,0 ; CP INTEN .ENDC STRT: STA 0,PSTAT,2 LDA 3,CC ADCZ 0,0 ; FLAG AS QWAIT TYPE STA 0,CTMP2,3 ; CARRY = NON-DEVICE REQUEST ;AC1 = PROCESSING ADDR JMP @.+1 SQ2 FOPE: JSR @.SER1 ERFOP ; TTY GET CHAR - LOAD TTIQ AN;D JUMP TO COMMON LOGIC TTYG: LDA 2,.TTIQ LDA 3,CC ; SEE IF FG LDA 1,CPROG,3 MOVZR# 1,1,SZR JMP TTYP1 ; NO- USE TTY LDA @2,.T1I ; USE TTY1 JMP TTYP2 ; TTY CHAR PUT - LOAD TTOQ AND JUMP TO COMMON LOGIC TTYP: LDA 2,.TTOQ LDA 3,CC LDA 1,CPROG,3 ;@N SEE IF FG MOVZR# 1,1,SZR JMP TTYP1 LDA @2,.T1O ; FG- USE SECONF TTY TTYP2: COM# 2,2,SNR ; SECOND DEV DEF ? JMP TTYER ; NO TTYP1: LDA 1,QDCT,2 ; GET DCT ADDR STA 1,CAC2,3 ; PASS TO TTY OVLYS MOVZ 2,2 ; FLAD AS A NON-DEV REQ JMP @.IQFN .TTIQ: T&sTIQ .TTOQ: TTOQ .T1O: NTO1Q .T1I: NTI1Q .INDSK: INDSK FILDQ: MOVZ 0,0 ; QUEUE AS NOT A DEV REQ JMP @.INDSK TTYER: JSR @.SER1 ERICD WRER0: JSR @.SER1 ; WRITE PROTECT ERROR ERWPR RDER1: JSR @.SER1 ERRPR ; FILE READ PROTECTED RDER0: JSR @.SER1 ERRD ; NOT ENOUGH MEMORY RDER2: JSR @.SER1 ;RST- NO DIRECT I/O EROVA ;RST- (TO SEQUENTIAL FILES) ; AC1= UFT POINTER ; AC2= UFT ; CLOSE CHANNEL REQ CLCHK: MOV 1,3 ; UFT POINTER LDA 0,0,3 ; UFT MOVL# 0,0,SZC ; SEE IF OPEN NOW JMP FOPE ; IF NO LDA 0,UFTDC,2 ; DCT ADDR LDA 3,CC STA 2,CAC0,3 JMP @.INB1 .INB1: INXTB .INXTA: INXTA OVER1: JSR @.SER1 EROVN SDNCK: JSR @.OVA1 DNCK ; CHECK DEV NAME JMP @.INB1 ; GO QUEUE SDNKA: JSR @.OVA1 DNCK ; DEV NAME CHECK JMP @.NOTSK SOPNCK: JSR @ .OVA1 OPNCK ; CHECK FILE NAME JMP @.INB1 .NOTSK: NOTSK .IFN MSW MPER: JSR @.SER1 ERMPR .ENDC ; READ CHECKS ; INSURE AGAINST SYSTEM OVERWIRTES BY USER I/O TRANSFERS ; INPUT ; RDCK0: BYTE COUNT IN AC1, BYTE ADR IN USTA0 ; RDC BYTE COUNT "SCLLG", BYTE ADR IN USTA0 ; RDCK2: WORD COUNT "SCRRL", WORD ADR IN USTA0 ; THIS ROUTINE ALSO CHECKS FOR A OPEN CHANNEL AND QUEUES ; A CELL TO THE DEVICE QUEUE THAT WILL PROCESS THE REQUEST RDCK1: LDA 1,LNELG ; LINE LENGTH RDCKA: MOVZ 0,0 COMN: LDA 3,CC LDA 2,CCHAN,3 ; UFT LDA @3,CC ; TCB LDA 0,TAC0,3 ; USER AC0  MOV# 0,0,SZC MOVZL 0,0 ; TYPE REQUIRES BYTE POINTER ADDZR 1,0,SZC ; COMPUTE MAXIMUM TRANSFER INC 0,0 ; ADDRESS LDA 3,USTP LDA 1,USTNM,3 ; SEE IF READING BEYOND END COMN2: USLE 0,1 ; OVERWRITE POSSIBLE? JMP RDER0 ; YES JRDE1: JSR CHCK ; CHECK FOR OPEN CHANNEL LDA 0,UFTAT,2 ; GET ATTRIBUTES MOVL# 0,0,SZC ; READ PROTECTED? JMP RDER1 ; YES JMP WRCK1 ; GO TO QUEUEING LOGIC RDCK0: LDA @3,CC ; TCB LDA 1,TAC1,3 ; LOAD AC1 (BYTE COUNkT) JMP RDCKA RDCK2: LDA 1,RCD.2 ; RECORD LENGTH IN BYTES MOVO 0,0 ; SET CARRY TO MODE JMP COMN ; WRITE CHECK WRCK: LDA 3,CC LDA 2,CCHAN,3 ; UFT JSR CHCK ; CHECK FOR OPEN CHANNEL LDA 0,UFTAT,2 ; ATTRIBUTES MOVR# 0,0,SZC ; WRIE PROTECTED? EJMP WRER0 ; YES WRCK1: LDA 3,CC ; CURRENT CELL LDA 0,CENT,3 ; DEVICE COMMAND CODE LDA 2,UFTDC,2 ; DCT (AC2 = UFT ON ENTRY) LDA 3,DCTDT,2 ; DISPATCH ADDR ADD 0,3 ; DISPATCH ADDR LDA 1,0,3 ; SEE IF VALID COMMAND COM# 1,1,SNR ; -1 IF DEV CAN'T DO X JMP ICDER LDA 3,CC ; CURRENT CELL STA 1,CENT,3 ; STORE IN CELL ; CELL NOW HAS REAL PROCESSING ADDR - PUT ON QUEUE MOV 2,0 ; DCT ADDR LDA 1,CCHAN,3 ; UFT ADDR STA 1,CAC2,3 ; PASS IN CELL AS AC2 LDA @2,CC ; TCB LDA 1,TAC1,2 STA 1,CAC1,3 JMP @.IN XTA ;CHECK FOR AN OPEN CHAN AND NO DATA ERRORS ; AC2 = UFT, AC1 DESTROYED BY ROUTINE CHCK: MOVZL# 2,2,SZC ; SKP IF OPEN JMP FOPE LDA 1,UFTST,2 ; STATUS MOVZR# 1,1,SZC JMP DTER ; IF DATA ERROR JMP 0,3 .SER1: SYSER DTER: JSR @.SER1 ERFIL LNELG:c SCLLG RCD.2: SCRRL*2 FRST: STFWR LSTR: STRWD ; CHECK AN MTDIO FOR AN OPEN CHANNEL ; AC2= UFT ; AC1 DESTROYED MTCHK: LDA 3,CC LDA 2,CCHAN,3 MOVZL# 2,2,SZC ; OPEN XJMP FOPE ; YOU LOSE LDA 1,UFTST,2 ; GET UFT STATUS LDA 0,LSTR ; DIRECT I/O STATUS BI T AND# 0,1,SNR ; SET? JMP MTCER ; NO - ERROR LDA 0,UFTDC,2 ; YES - SET 0 TO DCT ADDRESS JMP @.INB1 ; GO ENQUE REQUEST ICDER: SUB 0,0 STA 0,CQ MTCER: JSR @.SER1 ERICD LPOOL .IFN MSW ; LOAD IN AN OVERLAY ; IF NODE IS VIRTUAL, DO IT NOW ; TACŎ0=NODE #(LH),OVERLAY #(RH) LDOV: LDA 2,USTP ; UST LDA 2,USTOD,2 ; OVLY DIR LDA 1,C31K ; OFSET TO BLOCK 31 ADD 1,2 ; CAN ADDR NOW LDA @3,CC ; TCB LDA 0,TAC0,3 ; NODE+ OVLY NUMBER LDA 3,C377L ; LEFT BYTE MASK ANDS 0,3 ; GET NODE # LDA Z 1,C377 ; TEST IF DIRECTORY ENTRY USLE 3,1 ; WILL BE OUTSIDE PAGE 31 JMP OVERR LDA 1,OVNDS,2 ; # NODES USLT 3,1 ; IS REQUESTED LEGAL? JMP OVERR ; GOTCHA STA 3,STBLK ; SAVE NODE # ISZ STBLK ; INC BY 1 SNO CAN USE AS COUNT ADDZL 3,3 ; TIMES 4 ADD 3,2 ; ADDR NOW FOR THIS NODE IN OVDIR STA 2,NEPTR ; SAVE NODE ENTRY POINTER LDA 1,OVNAD,2 ; NODE ADDR AND VIRTUAL FLAG MOVL# 1,1,SNC ; SKIP IF VIRTUAL JMP @.FILDQ ; REG OVLY LOAD LDA 3,C31K ; CONVERT "TO BLK IN MAP ANDS 3,1 ; MASK TO K #, CLEAR B0 MOVZR 1,1 ; DIVIDE BY 4=# 1K BLOCKS MOVZR 1,1 STA 1,BLKST ; SAVE IT LDA 3,C377 AND 3,0 ; OVLY # LDA 1,OVDIS,2 ; <# OVLYS>, LDA 3,C377L ANDS 3,1 ; # OVLYS USLT 0,1' ; TOO BIG ? JMP OVERR ; YUP LDA 1,OVRES,2 ; MOVS 1,1 ; POSITION AND 3,1 ; SAVE CNT ADDS 0,1 ; MERGE STA 1,OVRES,2 ; NEW OVERLAY IS CURRENT ADC 1,1 ; INIT COUNT OF DISPLACEMENT ; TO NEW MAP LDT0: STA 1,NBKS ; ENTRZIES FOR OVERLAY LDA 3,OVDIS,2 ; PICK UP SIZE OF OVERLAY LDA 1,C177 ; MASK TO RIGHT 7 BITS(SIZE) AND 1,3 INCZR 3,3 ; CONVERT TO SIZE IN 1K BLOCKS INCZR 3,3 SUB 1,1 ; ACCUMULATE THE DISPLAEMENT NEG 0,0,SNR ; -OVLY #-IF 0 WE'RE DONE JMP LDT1 ADD  3,1 ; BUILD UP FILE OFSET INC 0,0,SZR ; ADD IN FOR # JMP .-2 LDT1: LDA 0,NBKS ; ADD ANY PREVIOUS DISP CALC IN COM# 0,0,SNR ; IF FIRST TIME THEN STA 3,RMTMP ; SAVE SIZE OF REMAP AREA COM# 0,0,SZR ; IF FIRST TIME THEN DON'T ADD IN ADD 0,1 DSZ STBLK ; CHECK, IF GOT FINAL JMP .+2 ; THEN GO JMP LDOV1 ; USE IT ELSE LDA 0,C4 SUB 0,2 ; CALC POSITION O PRECEEDING NODE LDA 0,OVDIS,2 ; # OVERLAYS, SZIE LDA 3,C377L ; CALC # OF OVERLAYS IN IT ANDS 3,0 ; # OVERLAYS JMP LDT0 ; GO ADD IN THIS DISP C4: 4 NBKS: 0 NEPTR: .BLK 1 LDOV1: LDA 2,CC LDA 2,CPTAD,2 ; PTBL .DO BB?MSW LDA 0,PMST,2 ; GET USER MAP START WORD SBI MPSEN,0 ; SET SO WON'T ENABLE MAP SMST 0 ; SET IN TO ACCESS USER MAP .ENDC LDA 0,PEOMP,2 ; START SLOT FOR VIRTUAL OVERLAYS- ADD 0,1 LDA 3,RMTMP ; GET # OF 1K BLOCKS TO REMAP .IFN MBSW STA 3,LMP1 .ENDC ADD 1,3 ; SIZE+START LDA 0,CLSTS ; TOO BIG ? USLT 3,0 JMP OVERR ; YES LDA 3,BLKST ; START OF OUTPUT ADD 2,3 ; PTBL REL ADD 1,2 ; FROM ADDR ; AC2=PTR INTO EXTENDED MAP ; AC3=PTR INTO USER MAP OVLD2: LDA 1,PEMAP,2 ; FROM EXT MAP STA 1,PMAP,3 ; TO USER MAP .IFE MBSW SMBK 1 ; MAP IT, IF NOT BIRD .ENDC INC 2,2 ; TO NEXT MAP BLOCK INC 3,3 DSZ RMTMP ; DEC THE # BLOCKS REMAINING TO REMAP JMP OVLD2 ; ELMP IF BIRD .IFN MBSW LDA 1,LMP1 ; # WORDS SUB 1,2 ADDI PEMAP,2 ; IN EXTENDED MAP ; AN ASSUMPTION WAS JUST MADE THAT THE EXTENDED MAP IS SET UP ; WITH THE ENTIRE MAP WORD. THIS IS TRUE AS OF 10/14/77. RST. SUB 0,0 LMP ;THE ENTIRE MAP .ENDC LDA 2,NEPTR ; RETRIEVE NODE ENTRY PTR LDA 1,OVDIS,2 ; RESET LOADING FLAG LDA 3,CNRLD ; MASK FOR CLEARING CONDITIONAL LOAD AND 3,1 STA 1,OVDIS,2 ; REPLACE IT JMP @.GTRTN ; ALL DONE-EXIT C377: 377 C377L: 377*400 .FILDQ: FILDQ STBLK: 0 BLKST: 0 CNRLD: -J1-1B8 C177: 177 .SYSE: SYSER OVERR: LDA 2,NEPTR ; RETRIEVE NODE ENTRY PTR LDA 3,C377L STA 3,OVRES,2 ; FLAG NODE EMPTY JSR .SYSE EROVN .GTRTN: GTRTN CLSTS: (MPAPH&377)-7 ; LENGTH OF EXTENDED MAP SLOT AREA ; REMAP AN AREA ; CALLED VIA TRAP ; AC1= SpTART DATA MAP SLOT+ START WINDOW SLOT (0 REL) ; AC2 IN EBIRD= # SLOTS, AC3 IN 840 = # SLOTS ; DIFFERENCE DUE TO NIOC VS SCL DIFFERENCES ; ERROR RTN IF USER IS OUT OF BOUNDS (STROKE+DISTANCE) ; ALL LINES (OR CODE GROUPS) MARKED (RT1) ARE FIXES TO ; A COM.PLAINT THAT REMAP IS TO SLOW. WORK BEGAN ON 9/6/77. REMAP: .IFE MBSW MOV 3,2,SNR ;MAKE SAME AS BIRD .ENDC .IFN MBSW MOV# 2,2,SNR ;SKIP IF ANY REMAP TO DO .ENDC JMP RMGRT ;MUST JUST LIKE TO CALL ME... LDA 3,CQ ;PTBL STA 2,RMTMP ;CNT .IFN JMBSW ; IF IT'S A MAPPED BIRD... STA 2,LMP1 ; SAVE REMAP COUNT FOR .ENDC ; LMP. (RT1) LDA 0,PEDMP,3 ;START OF DATA MAP ADD 0,2 ;ADD CNT LDA 3,C377L ANDS 1,3 ;STARTING EXTENDED SLOT ADD 3,2 ;END SLOT FOR REMAP ADD 0,3 ;START OF REMAP LD A 0,CLSTS ;LAST ADDR IN EXTENDED MAP SUBZ# 0,2,SZC ;SKIP IF IN BNDS JMP MEMER LDA 2,C377 AND 2,1 ;START IN WINDOW LDA 2,CQ LDA 0,PMWIN,2 ;START OF WINDOW LDA 2,PMWSZ,2 ;SIZE OF WINDOW ADD 0,1 ;REAL START ADD 0,2 ;END SLOT LDA 0,RMTMP ;CMT nADD 1,0 ;END SLOT SUBZ# 0,2,SNC ;SKIP IF END IN WINDOW JMP MEMER LDA 2,CQ ADD 2,3 ADD 1,2 ;AC2= TO ADDR, AC3= FROM ; MOVE BLKS INTO MAP MPMV: LDA 0,PMAP,2 ;OLD BLK LDA 1,C377L AND 1,0 ;SAVE DOA HALF LDA 1,PEMAP,3 ;BLK MOV# 1,1,SNR ;DEFINED ?# .IFN MBSW ; IF MAPPED BIRD, THEN WE'RE ; WAITING TILL LATER TO DO LMP. ; WE CAN'T REPORT THE ERROR ; TILL WE'VE MAPPED AS MUCH AS ; POSSABLE. JMP LUMP .ENDC .IFE MBSW ; ELSE DO AS BEFORE. JMP MEMER ;NO .ENDC ; (RT1) ADD 1,0 STA 0,PMAP,2 ;TO MAP TBL .IFE MBSW SMBK 0 .ENDC ; IF NOT BIRD, DO MAPPING ; PAGE AT A TIME. ; (RT1) INC 2,2 ;TO NEXT INC 3,3 DSZ RMTMP ;DONE ? JMP MPMV ;NO ; THIS IS WHERE THE SETUP AND LMP IS DONE. (IF BIRD) (OBVIOUSLY). .IFN MBSW  LUMP: LDA 3,RMTMP ;RST- WILL BE ZERO IF ALL PAGES ;RST- REQUESTED WERE MAPPED. ;RST- THIS IS ACTUALLY THE NUMBER OF ;RST- PAGES NOT MAPPED. LDA 1,LMP1 ;RST- NUMBER OF PAGES IN ORIGONAL ;RST- REQUEST. SUB 3,1 ;RST- THIS IS THE NIMBERy4 OF PAGES WHICH ;RST- WERE MAPPED, AND THE NUMBER OF ;RST- WORDS TO SEND THE MAP. LDA 3,PMAP. ;RST- OFFSET INTO USER MAP. ADD 3,2 ;RST- AC2 POINTS TO LAST CHANGED ;RST- MAP SLOT. ;RST- NOTE THAT AC2 IS INCREMENTED AN EXTRA TIME (AFTER ;RST- THE FINAL MAP SLOT HAS BEEN CHANGED. TO HAVE AC2 POINT ;RST- TO THE RIGHT WORD IN PMAP, WE MUST DECREMENT IT. SUB 1,2 ;RST- THE FIRST PAGE TO BE CHANGED. SUB 0,0 ;RST- WE DON'T WANT AN ADDEND. LMP LDA 1,RMTMP ;RST- IF NONZERO, NOT ALL! REMAPPING ;RST- COULD BE DONE. SEQZ 1 JMP MEMER .ENDC ;RST- NUFF SAID (RT1) RMGRT: .IFN MBSW ISZ @SP ; GOOD RTN .ENDC J ISZ TRPRT [J] JMP UEBL ; ENABLE AND TURN ON MAP MEMER: LDA 2,.ERADR .IFN MBSW LDA 3,SP STA 2,OAC2,3 ; RTN VIA STK .ENDC JMP UEBL ; TURN ON MAP AND INTERUPTS .ERADR: ERADR ; THIS ENDS THE CONDITIONAL WHICH ; BEGAN AT LDOV RMTMP: 0 .ENDC .IFN MBSW ;RST- WE NEED THE LOCATION ONLY IF BIRD. ;RST- (RT1) LMP1: 0 PMAP.: PMAP ;RST- ADD. CONST. TO GET FTO USER MAP. .ENDC ; THIS ROUTINE PUTS A WAIT N CYCLE REQUEST ON QUEUE TIMEQ: LDA 2,CC LDA 2,CPTAD,2 ; PT ADDR MOV 2,0 ; SAVE LDA 1,.PDFR ; OFFSET FOR DEL CHAIN START ADD 1,2 STA 2,.TCBFR ; SAVE FOR INT USE INC 2,2 ; BUMP TO END POINTER STA 2,.TCBEN INC 2,2 STA 2,.TIMET ; TOTAL TIME ON QUEUE LDA @3,CC ; TCB QUEUED LDA 1,TAC1,3 ; NUMBER OF CYCLES TO WAIT MOV# 1,1,SNR ; 0 INC CHANGE TO 1 INC 1,1 STA 1,TAC1,3 ; ....... INTDS ISZ @.DTOTL ; INC DELAY COUNTER MOV 0,2 ; PTBL ISZ PDCNT,3n2 ; INC ON QUEUE CNT .IFN MSW LDA 0,PDINC,2 ; SET FIRST TCB = INC LDA @2,.TCBFR MOV# 2,2,SZR ; SKIP IF NONE STA 0,TAC1,2 .ENDC LDA @0,.TIMET ; TOTAL INC ON QUEUE NOW SUBZ 0,1,SNR ; COMPARE REQ TOTAL TO QUEUE ; TOTAL JMP TIME1 ; IF = MOV 0D,0,SZC ; SKP IF REQ INC < QUEUE TOTAL JMP TIME2 ; GO ADD TO END TO LIST ; LOOP THRU LIST LOOKING FOR INSERT POINT ; INSERT AT POINT WHERE QUEUE TOTAL TO POINT IS CLOSEST TO REQ ; INC BUT NOT > LDA 1,TAC1,3 ; RESTORE REQ INC SUB 3,3 ; INIT INTERMED +TOTAL STA 3,LTOT STA 3,LTCB LDA @2,.TCBFR ; START OF LIST TIME3: LDA 0,TAC1,2 ; INC IN FIRST/NEXT TCB ADD 0,3 ; TO INTERMED TOTAL SUBZ# 3,1,SNC ; IF 3<= 1 NOT AT POINT + 1 YET JMP TIME4 ; INSERT STA 3,LTOT ; SAVE LAST TOTAL AND LAST TCB STA 2,L'TCB LDA 2,TSYS,2 ; TP NEXT IN LIST MOVL# 2,2,SZC ; IF 1B0 ENTRY EQUIVALENT TO LAST JMP .-3 ; SKIP OVER THIS ENTRY-NO INC IN ; IT JMP TIME3 ; INSERT POINT REACHED - BACK UP ON TCB ON LIST AND INSERT TIME4: LDA 2,LTCB ; LAST TCB IN LIST (POINT -1) LDA @3,CC ; TCB TO ADD LDA 0,LTOT ; LAST TOTAL SUB 0,1 ; SUB QUEUE TOTAL TO INSERT POINT STA 1,TAC1,3 ; STORE AS INC FOR ADDED TCB MOV# 2,2,SNR ; SKP IF THIS IS NOT ADD TO HEAD ; OF CHAIN JMP TIME6 LDA 0,TSYS,2 ; FORWARD LINK FROM .-1 STA 3,TSYS,2 ; LINK .-1 TO . STA 0,TSYS,3 ; LINK . TO .+1 MOV# 1,1,SNR ; INC = 0 ? JMP TIME5 ; IF YES ; NEW TCB LINKED IN - NEXT TCB IN LIST MUST HAVE INC ADJUSTED ; FOR ADDED TCB'S INC MOV 0,2 ; NEXT TCB TIME7: LDA 0,TAC1,2 ; PRESENT INC SUB 1,0 ; DEC BY ADDED TCB'S INC STA 0,TAC1,2 ; NEW INC TO TCB JMP TEXIT ; DIFF IN INC = TIME5: LDA 0,TSYS,2 ; FORWARD LINK ADDOR 0,0 ; CHAINED LINK STA 0,TSYS,2 JMP TEXIT ; QUEUE TOTAL = REQ DIFFERENCE ; AC3 = TCB TIME1: ADDOR 3,3 ; SET 1B0 - EQUIVALENk^T ENTRY TIME2: STA 1,TAC1,3 ; INC TO TCB ADD 0,1 STA @1,.TIMET ; ADDED INC + OLD TIMET LDA @2,.TCBEN ; END OF CHAIN MOV# 2,2,SNR ; IF FIRST ADD TO QUEUE JMP TFIRQ ; IF FIRST QUEUE STA 3,TSYS,2 ; LINK OLD END TO NEW END TIME8: ADC 0,0 STA 0,TSYS,3 ֳ; END LINKED TO -1 STA @3,.TCBEN ; NEW END TCB TEXIT: INTEN JMP @.TR3 ; EXIT TIME6: LDA @2,.TCBFR ; START OF CHAIN STA @3,.TCBFR ; NEW START STA 2,TSYS,3 ; LINK OLD FIRST TO NEW FIRST .IFN MSW LDA 3,CC LDA 3,CPTAD,3 STA 1,PDINC,3 ; INC TO MUNCH ON .ENDC JMP TIME7 TFIRQ: STA @3,.TCBFR ; SET UP START OF LIST .IFN MSW LDA 2,CC LDA 2,CPTAD,2 ; PTBL STA 1,PDINC,2 ; INC .ENDC JMP TIME8 .TIMET: 0 .TCBFR: 0 .TCBEN: 0 .PDFR: PDFR LTOT: 0 LTCB: 0 .DTOTL: DTOTL .TR3: TRTN3 .END SYSTE.SRB& - ; SYSTE.SR ; SUPERVISOR TRAP DECODER RTITLE SYSTE .ENT SYST ; SYSTEM ENTRY .IFN MSW .ENT TCBAD .ENDC .ENT CFREE .ENT SYSER,SYSE2 ; SYSTEM ERROR RETURNS .ENT RETER,RETE2 ; SYSTEM ERROR RETURNERS .ENT GCELL ;GET CELL, DON'T SKIP IF NONE FREE  .ENT IGCELL ;INTERRUPTIBLE GCELL .ENT GETCELL ;ALWAYS GET CELL, PEND ETC IF NONE .ENT CREL ;RELEASE CELL .ENT CELCN .ENT INDSK .ENT INXTA .ENT GTRTN .ENT INFND .ENT TRTN3 .ENT SQ1,SQ2 .ENT CMER .ENT SPRTN .ENT SENQ ;***********************X**************************************** .ENT TRTN ; IOCS - FIND THE RETURN PATH .ENT CLINK ; IOCS - FIND THE CELL LINKER .ENT INXTB ; IOCS - FIND THE SYSTEM TASK ; QUEUE MAKER .IFN IOSW .EXTN IOCS ; IOCS - ENTRY FOR REGULAR CALLS .EXTN IOCOP/ ; IOCS - OPEN PROCESSOR .EXTN PREOP ; IOCS - PRE-OPEN PROCESSOR .EXTN HSTST ; IOCS - HISTOGRAM STOP .EXTN HSTRU ; IOCS - HISTOOGRAM START .EXTN LBINI ; IOCS - MAGTAPE LABELED INIT .IFN IOSW ; MIOCS .EXTD CMAPI ; MIOCS - CURRENT MAP .EXTN MPEXT ; MIOCS - MAP EXIT .EXTN INDYM ; MIOCS - INIT DYN MAP .ENDC .ENDC ;:************************************************************** .EXTN STK00 ; FORCE LOAD OF STKS .EXTN SYSIN ; SYSTEM INHIBIT FLAG .EXTN ENVIR ; SYSTEM ENVIRONEMENT FLAGS .EXKCTN CREATE,DELFIL .EXTN CRAND,CCONT .EXTN CONNT .EXTN CPART,CDIR .EXTN LINK,UNLNK .EXTN EQUIV .EXTN PT1,PT2 .EXTN OVLY1,OVLAY .IFN BSW!MBSW .EXTN SSOVF .ENDC .EXTN SYSQ,DSQ1 .EXTN RNAM .EXTN MEM,MEMI .EXTN RLSE,INIT .EXTN DDIR .EXTN SMON1,INTSK .EXTN SACHN .EXTN TSKPU .EXTN TINA3 .EXTN SYSFG .EXTN PRISW .EXTN FILDQ .EXTN BRKP1 .EXTN SDNCK,SDNKA .EXTN QCHK1 .EXTN BLKCA,BLKCB .EXTN TTYG,TTYP .EXTN SOPNCK .EXTN CLCHK .EXTN RDCK0,RDCK1,RDCK2 .EXTN WRCK .EXTN ENVIR .EXTN MTCHK .EXTN TIMEQ .EXTN RDSW .EXTN CMN .EXTN CEL01 .EXTN GDIRS,GSYS,GMDIR .EXTN UPDAT .EXTN GMCA .EXTN RETUR,ERTN .EXTN RSET .EXTN GCH,PCH .EXTN OPEN,CLS,OPNA .EXTN CHAT,GTAT,CHLAT .EXTN SECI .EXTN ABORT .EXTN QWAIT .EXTN GTIME,STIME .EXTN RDB,WRB .EXTN SDAY,GDAY .EXTN USRST,USRLST .EXTN ROPN,EOPN,ECLR .EXTN TOPN,TCRET .EXTN OVOPN,OVLDC .EXTN IDEF,IRMV .EXTN PEND,UNPEND .EXTN SPDIS,SPEBL,SPKIL .EXTN UCLI,UCLR,RTCF .EXTN CMNF .EXTN DTOTL .EXTN MTDIO .EXTN ICMN,WRCMN,RDCMN .EXTN FGND .EXTN RDOPR,WROPR .EXTN SFCP,GFCP .EXTN ODIS,OEBL .EXTN GCIN,GCOUT .EXTN NCEL .EXTN TCRND,TCCON .EXTN GCHN .EXTN HBOOT .EXTN OVRP .EXTN CHNST .EXTN DEBL,DDIS .EXTN TUON,TUOFF ; TUNING STUFF .EXTN TUNE,ITUNE,TUCEL,TUPCEL .EXTN INTAD .IFN MSW ` .EXTD MFSTB,C31K .EXTN CMNB .EXTN STMAP .EXTN WRPR,WREBL .EXTN GMEM,SMEM .EXTN BLKEW,BLKER .EXTN CPNT .EXTN MAPDF .EXTN VMEM .EXTN LDOV .ENDC .NREL ; THIS PATH PROCESSES A .SYSTM CALL (JSR@ 17) ; IF NOT MAP, AC2= TCB OR 0 OR 1 ; IF MAP, AC0= xbTCB OR 0 OR 1 ; USER FINDS THIS CODE BY A JMP@ 2 IN UNMAPPED WORLD ; OR BY NIOC MAP ON NOVA OR BY "SVC" AND "SCL" INSTRUCTIONS ; ON NOVA/3 AND BIRD ; THIS ROUTINE WILL EITHER QUEUE THE REQ OR PROC DIRECTLY ; INTERRUPS ARE OFF WHEN THIS PATH IS ENTERED SYS3_T: ISZ @.SYSN ; SET IN SYSTEM INTEN .IFN USW MOV 2,0 .ENDC .IFN MSW LDA 2,CQ ; MAP IN USERS FIRST JSR MFSTB ; BLOCK OF CORE .ENDC .IFN BSW LDA 3,CQ ; FIND THE PROGRAM TABLE ELEF 3,PSSV1,3 ; ADDRESS OF SAVE AREA ELEF 2,HRBEG ; ADDRESS OF HARWARE RESERVED AREA LDA 1,C10 ; EIGHT WORDS TO SAVE BLM ; SAVE THEM ELEF 1,SSOVF ; SET STACK OVERFLOW ADDR STA 1,CSO .ENDC .IFN USW!N3SW!MN3SW LDA 3,USTP ; GET ADDRESS OF LAST LDA 3,USTCT,3 ; ACTIVE TCB .IFN MSW LDA 2,C31K ADD 2,3 ; GET MAePPED TCB ADDRESS .ENDC .ENDC .IFN N3SW LDA 2,@.ENVIR LDA 1,.ENUN3 AND# 2,1,SNR JMP NON3 .ENDC .IFN N3SW!MN3SW MFSP 2 STA 2,TSP,3 MFFP 2 STA 2,TFP,3 NON3: .ENDC .IFN USW LDA 1,USP STA 1,TUSP,3 ; SAVE USER USP IN HIS TCB .ENDC MOVZR# 0,0,STNR ; SKIP IF >1 JMP SYST1 ; NOT A SYSTM CALL .IFN MSW LDA 3,C31K ; ADJUST ADDR TO END ADDZ 3,0,SZC ; IF OVERFLOW ERROR JMP @.TCBAD MOVL# 0,0,SZC ; IF OVERFLOWED INTO B0 BAD TOO JMP @.TCBAD .ENDC LDA @2,.CELCN LDA 1,C2 ; ENUF TO PROCESS ? SUBZ# 2,1,SNC SCWR1: JSR @.GCELL ; ENUF-GET ONE JMP SNOCL ; NO CELLS STA 2,CC ; CURRENT CELL STA 0,CATCB,2 ; TCB MOV 0,3 ; TCB ADDR SUB 0,0 STA 0,CERR,2 LDA 0,TAC0,3 ; USER AC0 TO CELL STA 0,CAC0,2 LDA 3,CQ ; PROG TABLE ADDR STA 3,CPTAD,2 ; SAVE IN CELL LDA 0,PPRI,3 ; PRI STA 0,CPROG,2 LDA @2,CC LDA 0,TSYS,2 ; USER REQ WORD LDA 1,CNMSK ; CHANNEL NUMBER MASK MOV 1,3 ; SPECIAL FILN NUMBER MASK AND 0,1 ; MASK IT OUT SUB# 1,3,SNR ; PASSED IN AN AC? LDA 1,TAC2,2 ; USER AC2 LDA 2,INSMS ; COMMAND CODE MASK ANDS 2,0 ; MASK AND RIGHT JUST LDA 2,CSCALL ; SEE IF A SCALL SUB# 2,0,SNR JMP SCALL ; YES .IFN IOSW ;*************************************************************** LDA 2,.IOCAL ; IOCS - SEE IF IOCS CALL SUB# 2,0,SNR ; IOCS C- WELL... JMP @.IOC ; IOCS - YES IT IS... ;***************************************************************** .ENDC LDA 2,USTP ; UST LDA 2,USTCH,2 ; CHANNELS IN RIGHT HALF LDA 3,C377 ; MASK OUT NUMB TCBS AND 3,2 AND 3,1 ; LOOK AT ONLY LOW BYTE bl ; MAKE SURE IN BOUNDS SUBZ# 2,1,SZC JMP ERS0 ; ERROR, GET OUT LDA 3,CQ LDA 2,PUFPT,3 ; UFPT ADDR MOV 2,3 ADD 1,2 ; INDEX UFT POINTER TABLE LDA 1,0,2 ; GET THE UFT ADDRESS ADDZL 1,1 MOVZR 1,1 ; CLEAR OPEN IN PROGRESS MOVR 1,1 ; LEAVE OPEN/CmLOSE BIT INTACT ADD 3,1 LDA 3,CC STA 1,CCHAN,3 ; SAVEUFT STA 1,CAC2,3 ; AC2 STA 2,CAC1,3 ; SAVE UFT POINTER LDA 1,MAXCO ; MAX VALID CODE SUBZ# 1,0,SZC ; TO HIGH JMP CMER ; IF YES LDA 2,.MCCT ; MCCT-1 ADD 0,2 ; SYST PROC ADDR LDA 1,CTLGT,2 ; NEXT PROC PATH ADDR LDA 2,0,2 ; NEXT PROC PATH COM# 2,2,SNR ; ILLEGAL COMMAND ? JMP CMER ; YES SQ1: SUB 3,3 STA 3,CQ ; FLAG AS SYST CALL LDA 3,CC ; CELL ADDR STA 1,CENT,3 ; ENTRY TO CELL STA 1,CENT2,3 ; IN CASE NOT A DIRECT CALL MOVL 2,0,SZC N1 ; SEE IF A DIRECT CALL JMP 0,2 ; YES MOVZR# 2,2,SNR ; IF FIRST ROUT=1, GO TO SEC SQ2: MOV 1,2 STA 2,CENT,3 ; MAY HAVE TO QUEUE ; CARRY = 0 FOR A NON-DEVICE REQ LDA 2,.SYSQ ; PUT ON SYSQ JMP @.INFN SYST1: LDA 3,CQ ; START SEARCH AFTER THIS PROG 8 INTDS ; PREVENT RACE COND LDA 1,PINTU,3 ; SEE IF INTS UNPENDED MOV# 1,1,SNR JMP SYST3 ; NO-PUT TO SLEEP SUB 0,0 STA 0,PINTU,3 JMP @.SMON1 ; WAIT FOR NEXT NULL PASS SYST3: SUBZR 1,1 ; SET NOT READY MOV# 0,0,SZR ; SEE IF QWAIT ACTIVE MOVZR 1,`1 ; SET QWAIT ACTIVE FLAG INSTEAD STA 1,PSTAT,3 JMP @.SMON1 C2: 2 .CELCN: CELCN .SCTBL: SCTBL .SMON1: SMON1 SCMAX: SCTLN .IFN MSW .TCBAD: TCBAD .ENDC ; AC1= SCALL CODE SCALL: LDA 3,SCMAX ; TOO BIG ? SUBZ# 1,3,SNC JMP CMER ; YUP LDA 2,.SCTBL ; BASE ADD 1,2 LDA 1,0,2 ; PROC ADDR COM# 1,1,SNR ; DEF ? JMP CMER SUBZL 2,2 ; FLAG FOR NEXT PATH JMP SQ1 ; COMMON PATH .IFN N3SW .ENVIR: ENVIR .ENUN3: ENUN3 .ENDC .IFN BSW C10: 10 .ENDC .SYSN: SYSIN .SYSQ: SYSQ .MCCT: MCCT MAXCO: CTLGT .INFNn: INFND .ERICM: ERICM .ERFNO: ERFNO CMER: LDA 2,.ERICM JMP ERS0+1 ; ILLEGAL C0MMAND ERS0: LDA 2,.ERFNO ; ILLEGAL CHANNEL SUB 0,0 ; CLEAR CQ STA 0,CQ JMP SYSE2 CNMSK: CPU ; CHANNEL NUMBER MASK INSMS: 177400 ; INSTRUCTION BITS MASK .IFN IOSW ;*************************************************************** .IOCAL: PIOCS-MCCT ; IOCS - FIGURE OUT THE SPECIAL OFFSET .IOC: IOCS ; IOCS - THIS IS HOW TO GET TO IOCS.. ;***************************************************************** .ENDC .GCELL: dGCELL SNOCL: JSR @.TUNE ; WE SIDE-STEPPED GCELL - TUCEL ; MUST LET TUNER KNOW WE JSR @.TUNE ; MADE A REQUEST, TUPCEL ; AN UNSUCCESSFUL ONE AT THAT LDA 3,CQ ; PROG TABLE MOV 0,2 ; TCB SUB 0,0 STA 0,TTMP,2 ; TERMINATE WITH 0 LDA 0,PSWD,3 ; &HEAD OF BACK UP CHAIN MOV# 0,0,SNR ; SKIP IF CHAIN EXISTS JMP SNOC1 SNCLK: .IFN MSW JSR TCBVL ; VALIDATE TCB ADDR .ENDC .IFE MSW MOV 0,3 .ENDC ; TCB ADDR IN AC3 LDA 0,TTMP,3 ; SEE IF END MOV# 0,0,SZR ; SKIP IF END JMP SNCLK STA 2,TTMP,3 ; LINNK TO OLD LAST JMP @.SMON1 SNOC1: STA 2,PSWD,3 ; START JMP @.SMON1 CSCALL: 42 C377: 377 SCWRT: .IFN MSW JSR MFSTB ; EL MAPPO .ENDC STA 2,CQ LDA 0,PSWD,2 ; HEAD OF CHAIN .IFN MSW JSR TCBVL ; VALIDATE TCB ADDR .ENDC .IFE MSW MOV 0,3 .ENDC ;N TCB ADDR IN AC3 LDA @0,.CELCN ; # FREE CELLS LDA 1,C2 ; 2 SUBZ# 0,1,SZC ; IF NOT 3 DON'T DEQUE IT JMP @.SMON1 ; NOT ENUF- WAIT LDA 0,TTMP,3 ; LIFT OFF OF CHAIN STA 0,PSWD,2 ; NEW FIRST OR 0 MOV 3,0 ; TCB .IFE MSW LDA 1,PUSTP,2 ; UST POINTER DSTA 1,USTP ; SET UP FOR WORLD .ENDC JMP @.+1 SCWR1 .IFN MSW ; VALIDATE TCB ADDR IS IN LAST BLK ; AC0= TCB ADDR, CQ= PTBL ; AC3= TCB ADDR ON RTN TCBVL: STA 3,TRET MOV 0,3 ; FOR CALLER LDA 1,C31K AND 1,0 ; GET BLK BITS SUB# 1,0,SNR ; SKIP IF BADQ JMP @TRET ; RTN TCBAD: LDA 3,CQ LDA 1,CNABT ; SET ABORT IN PSTAT STA 1,PSTAT,3 LDA 1,CNTRP ; PRETEND TRAP STA 1,PFLAG,3 ADC 1,1 STA 1,PMPC,3 ; TRAP PC = -1 JMP @.SMON1 CNTRP: 1B1 CNABT: PSBRK .ENDC ; SYSTEM ERROR RETURN ROUTINES ; CALLABLE BY JUMPS ; RETURN ERROR CODE POINTER TO BY AC3 SYSER: LDA 2,0,3 ; RETURN ERROR CODE IN AC2 SYSE2: LDA 3,CC ; CURRENT CELL STA 2,CTMP2,3 ; SAVE FOR LATER LDA 3,CRSEG ; CURRENT OVERLAY MOV# 3,3,SNR ; IS THERE ONE ? JMP TRTN LDA 3,0,3 ; BUFFER AYYDDR DSZ BQUSC,3 ; DEC USE JMP .+1 LDA 3,CQ SUB 0,0 MOV# 3,3,SZR ; SEE IF CQ = 0 (.SYSTM PATH) STA 0,QCRSG,3 ; CLEAR CURRENT OVERLAY JMP TRTN ; ROUTINE TO SAVE ERROR CODE IN CTMP2 OF CURRENT CELL & ; RETURN TO CALLER RETER: LDA 2,0,3 ; GET ERRORC! CODE RETE2: LDA 3,CC ; CURRENT CELL COM# 3,3,SZR ; MAKE SURE CELL EXISTS FIRST STA 2,CTMP2,3 ; SAVE IN TEMPORARY RTRN ; POP THE STACK .TUNE: TUNE .ITUNE: ITUNE ; IGCELL - GCELL CALLABLE FROM INTERRUPT WORLD ; AC0 & AC1 ARE LOST, & STACK POINTER IS NOT RETURNED IN AC3... IGCELL: MOV 3,1 ; SNEAK RETURN INTO A REENTRANT ; CUBBY HOLE THE TUNER WON'T BLOW JSR @.ITUNE ; CALL THE INTERRUPTIBLE TUNER TUCEL ; COUNT CELL REQUESTS MOVO 0,0 ; FLAG ENTRY TYPE JMP GCCMN ; GO TO COMMON PROCESSI8NG ; GET CELL FROM POOL ; ; JSR GCELL ; -- ERROR RETURN, NO CELLS FREE ; (NORMAL RETURN, AC2=CELL ADDRESS) ; GCELL: STA 3,TRET JSR @.TUNE ; COUNT CELL REQUESTS TUCEL MOVZ 0,0 ; FLAG NON-INTERRUPT ENTRY GCCMN: INTDS ; INTERRUPT WORLD CAN GET CELLS LDA 2,CFREE ; FIRST FREE CELL COM# 2,2,SNR ; NONE LEFT ? JMP GCLN LDA 3,CLNK,2 ; FORWARD LINK INTEN STA 3,CFREE ; NEW FIRST CELL DSZ CELCN ; DEC ON COUNT JMP .+1 MOV 1,3,SZC ; WHICH ENTRY TYPE? (& PULL ; POSSIBLE RETURN OUT OF HAT) JMP 1,3 ; INTERRUPTIBLE: SKIP, HOP ; & LET THE RABBIT RUN AWAY ISZ TRET ; JUST THE USUAL OLD HAT: SKIP GCLX: LDA 3,CSP ; (PLOD, PLOD) JMP @TRET ; & RETURN GCLN: INTEN MOV# 0,0,SZC ; TEST ENTRY TYPE JMP GCILN ; INTERRUPTIBLE RETURN JSR @.TUNE X ; COUNT TIMES CELL NOT FREE TUPCEL JMP GCLX GCILN: JSR @.ITUNE ; COUNT TIMES CELL NOT FREE TUPCEL MOV 1,3 ; RECOVER RETURN ADDRESS JMP 0,3 ; AND AWAY ; ; GETCELL - UNCONDITIONAL GET CELL ROUTINE ; ; JSR GETCELL ; (NORMAL RETURN - AC2=CELL ADDRESˌS) ; GETCELL: RSAVE GTCL: JSR GCELL ;TRY FOR ONE JMP NOCEL ;NONE FREE, MUST PEND STA 2,OAC2,3 ;RETURN CELL ADDRESS RTRN NOCEL: ADC 0,0 ;PEND FOREVER ADCZR 1,1 ;OUT-OF-CELLS PEND KEY INTDS ;MUST CLOSE THE BLINDS JSR @.PEND ;DOZE A BIT JMPzN .+1 JMP GTCL ;NOW TRY AGAIN ; RELEASE A CELL ; AC2=CELL CREL: .IFE BSW!MBSW STA 3,RLOC .ENDC .IFN BSW!MBSW PSH 3,3 .ENDC INTDS ; INT WORLD CAN RELEASE CELLS LDA 3,CFREE ; PRESENT FIRST STA 3,CLNK,2 ; LINK NEW TO OLD INTEN STA 2,CFREE> ; NEW FIRST CELL ISZ CELCN ; BUMP COUNT COM# 3,3,SZR ; SEE IF WE WERE OUT OF CELLS JMP CRELX ; IF NO ADCZR 0,0 ; UNPEND KEY JSR @.UNPEN ; UNPEND ANY WAITERS CRELX: LDA 3,CSP .IFE BSW!MBSW JMP @RLOC .ENDC .IFN BSW!MBSW POPJ .ENDC CFREE: CEL01 .PEND: PEND .UNPEN: UNPEN CELCN: .GADD NCEL,-1 ; # CELLS SYSGENED, LES 1 USED ; BY INIT TRET: 0 ; LINK A CELL INTO A TASK QUEUE ; AC0=PRIORITY ; AC1=CELL ; AC2=QUEUE ; CELL WILL BE LINKED AT END OF SAME PR1 ; AC0 DESTROYED ; IF PRISW=1 ALL GO TSHO END OF CURRENT QUEUE CLINK: STA 3,TRET ISZ QCNT,2 ; INC ON QUEUE COUNT JMP .+1 ; WELL, IT CAN SKIP...... STA 1,CELTM ; SAVE CELL ADDR LDA @3,.PRISW ; SEE IF BG=FG PRI MOV# 3,3,SZR ADC 0,0 ; YES-FORCE TO END LDA 1,FUDGE ; FAKE FIRST CELL ADD 1,2 LDA 1,C377 ; PRIORITY MASK AND 1,0 ; EL DROPPO CLNXT: STA 2,LAST LDA 2,CLNK,2 ; NEXT CELL COM# 2,2,SNR ; END OF CHAIN ? JMP CINSR ; YES- GO INSERT LDA 3,CPROG,2 ; PRI + FLAGS AND 1,3 ; DROP FLAG ADCZ# 0,3,SNC ; SKIP IF NEXT CELL PRIORITYAu JMP CLNXT ; > NEW CELL. CINSR: LDA 3,CELTM ; CELL TO INSERT LDA 2,LAST LDA 1,CLNK,2 ; LINK AT INSERT POINT STA 1,CLNK,3 ; LINK .-1 TO . STA 3,CLNK,2 JMP @TRET CELTM: 0 LAST: 0 ; HOLDER FOR PREVIOUS CELL ON Q FUDGE: QLNK-CLNK ; DISPLACEMENT OF F6#AKE FIRST CELL LINK ; TASK IS DONE TRTN: JMP TERTN ; BAD RTN GTRTN: .IFN IOSW ; MAPPED IOCS JSR @.MPEXT ; IOCS -TURN OF THE MAP .ENDC LDA @2,CC ; TCB IN CURRENT CELL MOV# 2,2,SNR ; IF 0 USER IS GONE... JMP TRTN3 TRTN1: LDA 3,CC ; CELL LD5A 0,CPROG,3 ; PR1 + FLAGS MOVZL# 0,0,SZC ; DEV REQ FLAG JMP TRTN5 TRTN4: LDA 0,TPRST,2 ; UNPEND TASK ADCZR 1,1 AND 1,0 ; RESET 1B0 STA 0,TPRST,2 LDA 2,CC LDA 2,CPTAD,2 LDA 0,PSTAT,2 ; RESET NOT READY IF SET MOVZR 1,1 ; MASK NOW IB0 AND 1B1 AND! 1,0 STA 0,PSTAT,2 ISZ PINTU,2 ; FORCE TASK RESCH TRTN3: LDA 2,CC LDA 3,CQ MOV# 3,3,SNR ; CURRENT Q? JMP NOQ ADC 0,0 ; NO CURRENT CELL STA 0,QCURR,3 JSR CREL WRTN: .IFN IOSW JSR @.MPEXT ; MIOCS - TURN OFF MAP LDA 2,CQ ; MIOCS - GET CURRENT "QUE ADDI QIMAP,2 ; MIOCS - INDEX QUE TO DYNAMIC MAP LDA 1,CMAPI ; MIOCS - GET CURRENT MAP SUB 2,1,SZR ; MIOCS -EQUAL? JMP WRTN2 ; IOCS - NO STA 1,CMAPI ; MIOCS - CLEAR CURRENT MAP LDA 2,CQ ; IOCS - GET QUEUE EJSR INDYM ; IOCS - INIT DYN MAP WRTN2: .ENDC LDA 3,CQ SUB 0,0 STA 0,QSTAT,3 ; CLEAR STATUS WRTN1: LDA 2,QSTKC,3 ; BASE OF STACK LDA 1,0,2 ; STACK ADDR ADDOR 1,1 ; RELEASE STACK STA 1,0,2 ; TO POINTER SUB 0,0 STA 0,@.INTSK ; CLEAR IN TASK FLAG STA 0,CRSEG LDA 2,.PT1 ; SEE IoF ANY WAITERS FOR CELLS LDA 0,PSWD,2 MOV# 0,0,SZR ; SKIP IF NO (0) JMP @.SCWRT LDA 2,PLNK,2 ; PT2 LDA 0,PSWD,2 MOV# 0,0,SZR ; ANY HERE ? JMP @.SCWRT ; YES JMP @.SMN1 ; TO SCHED .INTSK: INTSK NOQ: INTDS ; RELEASE CELL BY HAND LDA 3,CFREE ; POINTER STA 3,CLNK,2 ; LINK IN CHAIN STA 2,CFREE ; MAKE FIRST ON Q ISZ CELCN ; MAKE COUNT CORRECT JMP @.SMN1 ; JMP TO SMON1 SPRTN: LDA 3,CQ JMP WRTN1 .IFN IOSW .MPEXT: MPEXT CNMPB: BTSMP .ENDC .PT1: PT1 .SCWRT: SCWRT .PRISW: PRISW ; BAD RETURN FROM TASK TERTN: LDA 3,CC ; ANYBOBY HOME ? MOV# 3,3,SNR JMP WRTN ; NO LDA 0,CTMP2,3 ; ERROR CODE .IFN IOSW ; MAPPED IOCS JSR @.MPEXT ; IOCS -TURN IT OFF .ENDC LDA 2,@CC ; GET TCB MOV# 2,2,SNR ; IS IT GONE ? JMP TRTN3 ; YES STA 0,TAC2,2 ; PASS ERROR CODE DSZ TPC,2 ; GIVE USER BAD RTN DSZ TPC,2 JMP TRTN1 TRTN5: STA 1,TAC1,2 ; PASS AC1 (COUNT) TO USER LDA 3,CCHAN,3 ; UFT LDA 1,UFTCN,3 ; ACTIVE REQUEST COUNTER MOVZL# 1,1,SNR ; SKIP IF COUNT > 0 INC 1,1 NEG 1,1 COMZL 1,1,SZR MOVR 1,1 STA 1,UFTCN,3 JMP TRTN4 .SMN1: SMON1 ; THIS IS THE POINT WHERE A TASK QUEUE IS MADE BASED ON THE ; DCT ADDR IN AC0 INXTB: MOVZ 0,2,SKP ; CARRY = NOT A DEVICE REQ INXTA: MOVO 0,2 ; DEVICE REQ LDA 2,DCTDT,2 ; DISPATCH MOVL# 2,2,SZC ; SKIP IF NOT DISK JMP INDSK LDA 2,.SYQ1 ; LIST OF TASK QUEUES INXT: LDA 2,QNXT,2 ; QUEUE ADDR COM# 2,2,SNR ; DONE ? JMP INDSK ; MUST BE DISK QUEUE IF NO MATCH LDA 1,QDCT,2 ; DCT IN QUEUE SUB# 1,0,SZR ; DCT MATCH JMP INXT ; IF NO ; FOUND QUEUE WITH REQ DCT ; PUT CELL INTO QUEUE ; AC2 = Q INFND: JSR SENQ ; ADD TO ACTIVE CHAIN IF NOT IN LDA 3,CC ; USE CURRENT CELL FOR NEXT PATH LDA 0,CPROG,3 ; PROG PRI AND FLAGS ADDR 0,0 ; SET DEV REQ FLAG IF C =1 STA 0,CPROG,3 LDA 0,QSTAT,2 ; IF QUEUE FREE GO D[)IRECT... LDA 1,QLNK,2 ADC# 1,0,SNR ; SKIP IF ANYTHING GOING ON JMP INQDR INQD3: MOV 3,1 ; CELL LDA 0,CPROG,3 ; PRI JSR @.CLINK LDA 3,CQ ; SEE IF ENTRY FROM .SYSTM PROC MOV# 3,3,SNR JMP @.SMN1 ; IF YES NO CLEANUP JMP WRTN ; FINISH CLEANUP ; Q(UEUE TO ONE OF TWO DISK TASKS ; IF CHANNEL IS INACTIVE, QUEUE TO THE LEAST BUSY TASK ; IF CHANNEL IS ACTIVE QUEUE TO THE ACTIVE TASK QUEUE INDSK: LDA 2,.DSQ1 MOV# 0,0,SNC ; SKIP IF DEV REQ JMP INFND ; USE DSQ1 FOR ALL FILE STUFF LDA 3,CC LDA 3,CCHAN3a,3 ; UFT LDA 1,UFTCN,3 ; ACTIVE COUNT MOV# 1,1,SNR ; SKIP IF ACTIVE JMP INDS1 ; GO Q TO LEAST ACTIVE MOVL# 1,1,SZC ; SKIP IF ACTIVE TASK IS DS1 LDA 2,QNXT,2 ; TO DSQ2 INDS2: ISZ UFTCN,3 ; INC COUNT OF ACTIVE REQ IN UFT JMP INFND INDS1: LDA 1,QCN=aT,2 ; DSQ1 ON QUEUE COUNT ; IF THERE IS A FG AND IT HAS PRI, ONLY FG GETS TO USE DSQ2 ; FG WILL USE DSQ1 IF IT IS IDLE LDA @0,.SYSFG MOV# 0,0,SNR JMP INDS4 ; NO FG LDA @0,.PRISW MOV# 0,0,SZR JMP INDS4 ; = PRI ; FG HAS PRI LDA 2,CC LDA 0,CPROG,2 LDA 2,.DSQ1 MOVZR# 0,0,SZR JMP INFND ; CALLER IS BG- HE ONLY CAN USE ; DSQ1 LDA 0,POLNK,2 ; DSQ1 IDLE ? MOV# 0,0,SNR ; SKIP IF NOT IDLE JMP INFND ; YES- USE IT INDS3: LDA 0,C1B0 LDA 2,QNXT,2 ; TO DSQ2 JMP INDS5 INDS4: LDA 2,QNXT,2 ; DSQ2 LDv A 0,QCNT,2 ; DSQ2 COUNT LDA 2,.DSQ1 SUBZ# 0,1,SNC ; IF DSQ2 HAS MORE USE DSQ1 JMP INDS6 SUB# 1,0,SZR ; SAME ON QUEUE ? JMP INDS3 ; NO-USE DSQ2 LDA 1,QSTAT,2 ; SEE IF 1 IS ACTIVE MOV# 1,1,SZR ; SKIP IF FREE-ELSE USE DSQ2 JMP INDS3 ; YES-USE DSQa2 THEN INDS6: SUBC 0,0 INDS5: STA 0,UFTCN,3 ; STORE EITHER 0 OR 100000(DSQ2) JMP INDS2 C1B0: 100000 .DSQ1: DSQ1 .SYSFG: SYSFG ; AC0=0 INQDR: STA 3,QCURR,2 ; CELL TO QUEUE LDA 3,CQ STA 2,CQ ; NEW QUEUE MOV# 3,3,SNR ; ON .SYSTM CALL PROC PATH ? JMP INQD1 ; YES-GET STACK STA 0,QSTAT,3 ; 0 STATUS LDA 0,QSTKC,3 ; USE SAME STACK SYSQ USED STA 0,QSTKC,2 INQD2: MOV 2,3 JMP @.+1 TINA3 ; YUMP IN INQD1: JSR @.TSKPU JMP INQD4 ; NO STACK AVAILABLE-QUEUE JMP INQD2 ; CONTINUE INQD4: LDA 3,QCURR,2 ; CELL FOR QUEUE ADC 0,0 ; -1 STA 0,QCURR,2 ; FLAG AS NO CURRENT AGAIN SUB 0,0 ; NO STACK- FLAG AS .SYSTM PATH ; AGAIN STA 0,CQ JMP INQD3 ; GO PUT ON QUEUE .TSKPU: TSKPU ; ADD A QUEUE TO THE ACTIVE CHAIN IF NOT ALREADY IN SENQ: STA 3,SRET LDA؏ 3,POLNK,2 ; LINK IN QUEUE NOW MOV# 3,3,SZR ; SKIP IF NOT IN QUEUE NOW JMP @SRET INTDS ; MAKE ENQUEUE SAFE LDA @3,.SACHN ; START OF CHAIN STA @2,.SACHN ; ADD TO START INTEN STA 3,POLNK,2 JMP @SRET .SACHN: SACHN .SYQ1: SYSQ .CLINK: CLINK SRET: 0V ; DUMMY SYSTM CALL SYSI= TRTN+1 ; GOOD RTN ; MONITOR CALL CONTROL TABLE MCCT: @FILDQ ; CREATE @FILDQ ; DELETE @FILDQ ; RENAME @FILDQ ; MEMORY AVAILABLE @BRKP1 ; BREAK SDNCK ; DEVICE RELEASE SDNCK ; CHANGE DEFAULT DIRECTORY @QCHK1 ; EXECUTE SDNCK ; DEVICE INIT @QCHK1 ; RETURN 1 ; I/O RESET @BLKCA ; BLOCK READ @BLKCB ; BLOCK WRITE @QCHK1 ; ERROR RTN @FILDQ ; CREATE RANDOM @TTYG ; TTY GET CHARACTER @TTYP ; TTY PUT CHARACTER @TIMEQ ; DELAY @FILDQ ; MEMORY INCREMENT =SOPNCK ; OPEN FOR READING SOPNCK ; INIT OVLYS SOPNCK ; OPEN FOR APPENDING 1 ; CHANGE ATTRIBUTES 1 ; GET ATTRIBUTES SOPNCK ; OPEN FILE CLCHK ; CLOSE FILE @RDCK0 ; READ SEQUENTIAL @RDCK1 ; READ LINE @RDCK2 ; READ RANDOM @WRCK ; WRITE SEQUENTIAL @WRCK ; WRITE LINE @WRCK ; WRITE RANDOM .IFE MSW @FILDQ ; OVERLAY REQUEST CHECK .ENDC .IFN MSW @LDOV ; OVLY LOAD CHK FOR VIRTUAL NODE .ENDC @FILDQ ; CREATE CONT 0 ; NULL ENTRY FOR SCALL 1 ; EXECF .IFE IOSW -1 -1 .ENDC .IFN IO*SW ;*************************************************************** PIOCS: 0 ; IOCS - REGULAR PROCESS CALL 1 ; IOCS - OPEN CALL DIRECT PATH ;***************************************************************** .ENDC @MTCHK ; MTDIO 1 ; SET FILE POSITION 1 ; GET FILE POSITION SOPNCK ; EOPEN SOPNCK ; TOPN 1 ; CHANGE LINK ACCESS ATTRIBUTES 1 ; GET CHANNEL STATUS .IFE MSW -1 .ENDC .IFN MSW @CPNT ; CP INITIAL PROC .ENDC CLCHK ; UPDATE FILE SIZE INFO .IFE IOSW -1 .ENDC .IFN IOSW ;******|********************************************************* 1 ; IOCS - GO DIRECTLY TO PRE-OPEN ; CALL ;***************************************************************** .ENDC -1 ; RESERVED 60B7 .IFN MSW @BLKEW ; EXTENDED MEM WRITE @BLKER ; EXTENE%DED MEM READ .ENDC .IFE MSW -1 ; EXTENDED WRITE -1 ; EXTENDED READ .ENDC CTLGT= .-MCCT ; LENGTH OF DISPATCH TABLE ; MONITOR CALL SYSTEM DISPATCH TABLE MCSDT: CREATE ; CREATE DELFIL ; DELETE RNAM ; RENAME MEM ; AVAILABLE MEMORY BRKP1 ; BREAK RLSE ; DEVICE RELEASE DDIR ; DIRECTORY DEFAULT CMN ; EXECUTE INIT ; DEVICE INIT RETUR ; RETURN RSET ; I/O RESET RDB ; READ BLOCK WRB ; WRITE BLOCK ERTN ; ERROR RETURN CRAND ; CREATE RANDOM GCH ; TTY GET CHARACTER PCH ; TTY PUT (CCHARACTER 1 ; QUEUE TIME WAIT MEMI ; MEMORY INCREMENT ROPN ; OPEN FOR READING OVOPN ; INIT OVLYS OPNA ; OPEN FOR APPENDING CHAT ; CHANGE ATTRIBUTES GTAT ; GET ATTRIBUTES OPEN ; OPEN CLS ; CLOSE RS RL RR WS WL WR OVLDC ; LOAD OVLY 1K CCONT ; CREATE CONTIG 0 ; NULL ENTRY FOR SCALL CMNF ; EXECF .IFN IOSW ;*************************************************************** 0 ; IOCS - THESE PARE PCKED OFF ; EARLIER IOCOP ; IOCS - THE IOCS OPEN PROCESSOR ;*************************S**************************************** .ENDC .IFE IOSW -1 -1 .ENDC MTDIO SFCP ; SET FILE POS GFCP ; GET FILE POS EOPN ; EOPEN TOPN ; TRANSPARENT OPEN CHLAT ; CHANGE LINK ACCESS ATTRIBUTES CHNST ; GET CHANNEL STATUS .IFE MSW 0 ; PLACER' HOLDER IN RDOS .ENDC .IFN MSW CMNB ; EXBG .ENDC UPDAT ; UPDATE FILE SIZE INFO .IFN IOSW ;*************************************************************** PREOP ; IOCS - PRE-OPEN IOCS PROCESSOR ;****************************************************lv************* .ENDC .IFE IOSW  -1 .ENDC -1 ; RESERVED 60B7 .IFN MSW WRB ; EXTENDED WRITE RDB ; EXTENDED READ .ENDC .IFE MSW -1 ; EXTENDED WRITE -1 ; EXTENDED READ .ENDC ; SCALL TABLE SCTBL: RTCF ; 0- GET FREQ RTC UCLI ; 1- SET USER CLOrCK UCLR ; 2- REMOVE USER CLOCK GTIME ; 3- GET TOD STIME ; 4- SET TOD SDAY ; 5- SET DAY GDAY ; 6- GET DAY IDEF ; 7- DEV INTERRUPT DEFINE IRMV ; 10-INTERRUPT REMOVE SPKIL ; 11- KILL A SPOOLING OUTPUT SPDIS ; 12-DISABLE SPOLLING TO A DEV SPEBL ; 13- ENABLE SPOOLING TO A DEV USRLST ; 14- RSTAT, STATUS OF ; RESOLUTION ENTRY CPART ; 15- CREATE PARTITION CDIR ; 16- CREATE DIRECTORY LINK ; 17- CREATE DIRECTORY LINK ENTRY EQUIV ; 20- REASSIGN LOGICAL DIRECTORY ; SPECIF GDIRS ; 2-1- GET DIRECTORY SPECIF SYSI ; 22- SOS COMPATIBILITY -1 ; 23- RTOS .WCHAR CALL ICMN ; 24- DEF COMMON WRCMN ; 25- WRITE TO COMMON RDCMN ; 26- READ FROM COMMON ODIS ; 27- DISABLE PROG CONT A OEBL ; 30- ENABLE CONT A DEBL ; 31- ENABLE MAPPED DWEV DDIS ; 32- DISABLE MAPPED DEV RDOPR ; 33- READ OP MSG WROPR ; 34- WRITE OP MSG .IFE MSW SYSI ; NOOP IF NOT MAPPED .ENDC .IFN MSW STMAP ; 35-SET MAP FOR USER DCH .ENDC GCIN ; 36- GET CONSOLE INPUT DEV GCOUT ; 37- GET CONSOLE OUTPUT DEV ȗ USRST ; 40- STATUS OF FILE ECLR ; 41- CLEAR TCRET ; 42- TRANSPARENT CREATE TCRND ; 43- TRANSPARENT CRAND TCCON ; 44- TRANSPARENT CCONT FGND ; 45- SEE IF FG .IFE MSW -1 ; 46- ILLEGAL IN UNMAPPED -1 ; 47- ILLEGAL IN UNMAPPED .ENDC .IFN MSW,Z GMEM ; 46- GET MEM PARTITION SMEM ; 47- SET MEM PARTITON .ENDC HBOOT ; 50- INVOKE HIPBOOT GMDIR ; 51- GET MASTER DIR. SPECIFIER GCHN ; 52- GET A FREE CHANNEL UNLNK ; 53- DESTROY A LINK ENTRY .IFE MSW -1 ; 54- -1 ; WRITE EBL- .SCALL 55 .c2ENDC .IFN MSW WRPR ; 54- WRITE PROTECT WREBL ; 55- WRITE ENABLE .ENDC GSYS ; 56- GET SYSTEM NAME OVRP ; 57- REPLACE OVERLAY ABORT ; 60- ABORT A TCB CALL GMCA ; 61- WHAT MCA AM I ? SECI ; 62- REQUEST TO RESCHEDULE ; EVERY SECOND .IFN IOSW ;*************************************************************** HSTRU ; IOCS - 63 - RUN HISTOGRAM HSTST ; IOCS - 64 - STOP HISTOGRAM ;***************************************************************** .ENDC .IFE IOSW -1 -1 .ENDC RDSW ; 65- READ SWITCHES .IFE MSW -1 ; VMEM -1 ; MAP DEF .ENDC .IFN MSW VMEM ; 66- VMEM MAPDF ; 67- VIRTUAL DATA MAP DEF .ENDC TUOFF ; 70 - TURN TUNING OFF TUON ; 71 - TURN TUNING ON INTAD ; 72- WAIT FOR CONT A OR CONT C .IFN IOSW LBINI ; 73- IOCS LABELED MAGTAPE INIT .ENDC .IFE IOSW -1 ; PLACE HOLDER FOR NON-IOCS .ENDC CONNT ; 74- CREATE CONTIGUOUS NOT DATA INIT SCTLN= .-SCTBL-1 .END PXXDB.SRB  ; PXXDB.SR ; SPARE DCB'S USED FOR SUBDIRECTORYS AND SUB-PARTITIONS RTITLE PXXDB .NREL ; THE FOLLOWING ENTRY POINTS ARE USED FOR DEBUGING ; WITH THE EXCEPTION OF P00DB WHICH IS NEEDED BY INIT1 ; AND TABLE .ENT P64DB,P63DB,P62DB,P61DB,P60DB .ENT P5.9DB,P58DB,P57DB,P56DB,P55DB .ENT P54DB,P53DB,P52DB,P51DB,P50DB .ENT P49DB,P48DB,P47DB,P46DB,P45DB .ENT P44DB,P43DB,P42DB,P41DB,P40DB .ENT P39DB,P38DB,P37DB,P36DB,P35DB .ENT P34DB,P33DB,P32DB,P31DB,P30DB .ENT P29DB,P28DB,P27DB,P26DB,P25DB .ENT P24DB,^?P23DB,P22DB,P21DB,P20DB .ENT P19DB,P18DB,P17DB,P16DB,P15DB .ENT P14DB,P13DB,P12DB,P11DB,P10DB .ENT P09DB,P08DB,P07DB,P06DB,P05DB .ENT P04DB,P03DB,P02DB,P01DB,P00DB ; THE FOLLOWING ENTRY POINTS ARE USED FOR ; LIMITING THE LOAD OF THIS MODULE. .ENT Ph64DL,P63DL,P62DL,P61DL,P60DL .ENT P59DL,P58DL,P57DL,P56DL,P55DL .ENT P54DL,P53DL,P52DL,P51DL,P50DL .ENT P49DL,P48DL,P47DL,P46DL,P45DL .ENT P44DL,P43DL,P42DL,P41DL,P40DL .ENT P39DL,P38DL,P37DL,P36DL,P35DL .ENT P34DL,P33DL,P32DL,P31DL,P30DL .ENT P29DLh,P28DL,P27DL,P26DL,P25DL .ENT P24DL,P23DL,P22DL,P21DL,P20DL .ENT P19DL,P18DL,P17DL,P16DL,P15DL .ENT P14DL,P13DL,P12DL,P11DL,P10DL .ENT P09DL,P08DL,P07DL,P06DL,P05DL .ENT P04DL,P03DL,P02DL,P01DL,P00DL .DDCB P00DB,0,0,P01DB,,P00DL .EJECT ** .NOMAC 41 .DDCB P01DB,0,0,P02DB,,P01DL .DDCB P02DB,0,0,P03DB,,P02DL .DDCB P03DB,0,0,P04DB,,P03DL .DDCB P04DB,0,0,P05DB,,P04DL .DDCB P05DB,0,0,P06DB,,P05DL .DDCB P06DB,0,0,P07DB,,P06DL .DDCB P07DB,0,0,P08DB,,P07DL .DDCB P08DB,0,0,P09DB,,P08DL .DDCB P09DB,0,0,P10DB,,P09DL .DDCB P10DB,0,0,P11DB,,P10DL .DDCB P11DB,0,0,P12DB,,P11DL .DDCB P12DB,0,0,P13DB,,P12DL .DDCB P13DB,0,0,P14DB,,P13DL .DDCB P14DB,0,0,P15DB,,P14DL .DDCB P15DB,0,0,P16DB,,P15DL .DDCB P16DB,0,0,P17DB,,P16DL .DDCB P17DB,0,0,P18DB,,P17DL P .DDCB P18DB,0,0,P19DB,,P18DL .DDCB P19DB,0,0,P20DB,,P19DL .DDCB P20DB,0,0,P21DB,,P20DL .DDCB P21DB,0,0,P22DB,,P21DL .DDCB P22DB,0,0,P23DB,,P22DL .DDCB P23DB,0,0,P24DB,,P23DL .DDCB P24DB,0,0,P25DB,,P24DL .DDCB P25DB,0,0,P26DB,,P25DL .DDCB P26DB,0,0,P27DB,,P26DL .DDCB P27DB,0,0,P28DB,,P27DL .DDCB P28DB,0,0,P29DB,,P28DL .DDCB P29DB,0,0,P30DB,,P29DL .DDCB P30DB,0,0,P31DB,,P30DL .DDCB P31DB,0,0,P32DB,,P31DL .DDCB P32DB,0,0,P33DB,,P32DL .DDCB P33DB,0,0,P34DB,,P33DL .DDCB P34DB,0,0,P35DB,,P34qDL .DDCB P35DB,0,0,P36DB,,P35DL .DDCB P36DB,0,0,P37DB,,P36DL .DDCB P37DB,0,0,P38DB,,P37DL .DDCB P38DB,0,0,P39DB,,P38DL .DDCB P39DB,0,0,P40DB,,P39DL .DDCB P40DB,0,0,P41DB,,P40DL .DDCB P41DB,0,0,P42DB,,P41DL .DDCB P42DB,0,0,P43DB,,P42DL .DDCB P43DB,} 0,0,P44DB,,P43DL .DDCB P44DB,0,0,P45DB,,P44DL .DDCB P45DB,0,0,P46DB,,P45DL .DDCB P46DB,0,0,P47DB,,P46DL .DDCB P47DB,0,0,P48DB,,P47DL .DDCB P48DB,0,0,P49DB,,P48DL .DDCB P49DB,0,0,P50DB,,P49DL .DDCB P50DB,0,0,P51DB,,P50DL .DDCB P51DB,0,0,P52DB,,P51DLs .DDCB P52DB,0,0,P53DB,,P52DL .DDCB P53DB,0,0,P54DB,,P53DL .DDCB P54DB,0,0,P55DB,,P54DL .DDCB P55DB,0,0,P56DB,,P55DL .DDCB P56DB,0,0,P57DB,,P56DL .DDCB P57DB,0,0,P58DB,,P57DL .DDCB P58DB,0,0,P59DB,,P58DL .DDCB P59DB,0,0,P60DB,,P59DL .DDCB P60DB,0,h0,P61DB,,P60DL .DDCB P61DB,0,0,P62DB,,P61DL .DDCB P62DB,0,0,P63DB,,P62DL .DDCB P63DB,0,0,P64DB,,P63DL .DDCB P64DB,0,0,-1,,P64DL ; NEVER LOADED NEEDED FOR .LIMIT .NOMAC 0 .END OVLAY.SRB c;f; ; OVERLAY PROGRAM FOR SYSTEM SEGMENTS. ; ; JSR OVLAY (OVLY1) ; OVERLAY#,,ENTRY WORD OFFSET (THIS IN OTMP WITH OVLY1) ; -ERROR REUTRN ; -NORMAL RETURN ; ; VIRTUAL ADDRESS SPACE IS 32K ; ON CALL - 8 BITS SEGMENT NUMBER, 7 BITS SEGMENT OFFSET ADDR ; ON RETURN - 8 BITS SEGMENT NUMBER, 8 BITS OFFSET ; THUS, ALL OVERLAY ENTRY POINTS MUST BE IN THE ; FIRST 128. WORDS OF THE OVERLAY ; RTITLE OVLAY .ENT OVBA1,OVBAS .ENT FLAKE .ENT OVLAY .ENT OVLY1 .ENT OVCHN .ENT OICAL .ENT LDRTN .ENT PREOV .ENT FLAK1 ;OVERLAY CALL FROM FIXED CODE ;WITH ADDR FOLLOWING CALL ;**************************************************************** .ENT OVCH1 ;IOCS - CHAIN WITH CALL IN TMP .ENT USGDN ;RETURN FROM USAGE MEASUREMENT .EXTN OVUSG ;USAGE MEASUREME*NT ROUTINE ;**************************************************************** .NREL .EXTN WAIT,OVTAB,ASBUF,SYSTM,RELB,QUENT .EXTN MDCB .EXTN PEND,UNPEN .EXTN TUNE ;TUNING ENTRY OVLY1: RSAVE 10 .IFE BSW!MBSW LDA 0,OTMP,3 ;SEGMENT ADDRESS JMP OLCOMb ;JOIN COMMON CODE .ENDC .IFN BSW!MBSW LDA 2,OSP,3 ;GET OLD CSP LDA 0,TMP,2 ;SEGMENT ADDRESS JMP OLCOM ;JOIN COMMON CODE .ENDC ; CALL AN OVERLAY FROM FIXED CODE THAT HAS BEEN CALLED BY AN OV FLAK1: RSAVE 10 .IFE BSW!MBSW LDA @0,ORTN,3 ;LOAD FbROM BEHIND THE CALL NOVA STYLE .ENDC .IFN BSW!MBSW LDA 2,ORTN,3 ;GET THE RETURN ADDR LDA 0,0,2 ;AND LOAD THIS WAY CAUSE NO @ ALLOWED .ENDC ISZ ORTN,3 ;BUMP OVER ARGUMENT JMP FLAK4 ;GO ON LIKE REGULAR FLAKE CALL FLAKE: RSAVE 10 .IFE BSW!MBSW LDZA 0,OTMP,3 ;OVLAY TO LOAD .ENDC .IFN BSW!MBSW LDA 2,OSP,3 ;OLD CSP LDA 0,TMP,2 ;OVLAY TO LOAD .ENDC FLAK4: SUB 2,2 ;FLAG AS UNCHAINED LOAD STA 2,CHNFL,3 LDA 1,ORTN,3 ;FLIP RTN TO POST PROC FOR ; FIXED CALL STA 1,OVRTN,3 ;HOPE NOT AN OVLY CALLING... LDA 1,.OFRTN ;POST PROC STA 1,ORTN,3 LDA 2,CRSEG STA 0,SEGSV ;SAVE JSR VTUNE ;COUNT OVERLAY REQUESTS -1 MOV# 2,2,SNR ;SKIP IF A CURRENT OVLAY JMP OVLY4 ;NO TRICKS NEEDED LDA 2,0,2 ;BUFFER JSR @.RELB ;BYE LDA 1,OVRTN,3 ; GET RETURN JADDRESS JMP FLAK8 ; GO CCHECK IF WIHTIN OVERLAY ; FIND THE CALL OUT OF CURRENT OVLY IN PAST FRAMES ; YOU'LL LOVE THE ASSUMPTIONS MADE IN THE FOLLOWING CODE FLAK3: LDA 3,OSP,3 LDA 1,ORTN,3 ;RTN FLAK8: .IFN BSW!MBSW MOVL 1,1 MOVZR 1,1 ;MAKE 1B0 = 0 m .ENDC SUBZ 2,1,SNC ;SEE IF RTN > BASE JMP FLAK3 ;NO-KEEP GOING LDA 0,C377 SUBZ# 1,0,SNC ;SKIP IF OVLY ADDR JMP FLAK3 FLAK9: LDA 2,.OVTB ; MAKE INTO VERTUAL LDA 0,CRSEG SUBS 2,0 ; RETURN ADDRESS ADD 0,1 STA 1,OVRTN,3 ; AND STORE LDA 0,.OORTN Ÿ STA 0,ORTN,3 LDA 2,CRSEG ; RESTORE OVERLAY NUMBER LDA 2,0,2 LDA 3,OSP,3 LDA 1,ORTN,3 ;RTN .IFN BSW!MBSW MOVL 1,1 MOVZR 1,1 ;MAKE 1B0 = 0 .ENDC SUBZ 2,1,SNC ;SEE IF RTN > BASE JMP OVLY4 ; ALL DONE LDA 0,C377 SUBZ# 1,0,SNC ;SKIP IF OVLY ADC RTITLE OPPRO .IFN MNSW!MN3SW .EXTD CLSTB .ENDC .IFN MSW .EXTN MBLK .ENDC .IFN MBSW .EXTD CLBLK .ENDC .EXTN CHAR,TTDCT,INLIN,LABEL .EXTN FINP,PT1,PT2,DEQUE,XIBUF,CREL,UPQUE .ENT OPPRO .NREL .IFN MSW .BLKSV: BLKSV .ENDC FFD: 14 T.TDCT: TTDCT .XX: XX GAK: JSR @.PNIC PNIDA .TEXCP: TEXCP C133: 133. .CH1: CHAR .OUT4: OUT4 .TSTFB: TSTFB DRQCNT: SUBZL 1,1 ; GENERATE +1 STA 1,RQCNT,3 ; DUMMY UP BEAD COUNT STA 1,DCTOF,2 ; SET CR FLAG JMP SVQP OPPRO: STA 0,@.CH1 ; SAVE CHARACTER .IFN MS4W SUB 2,2 STA 2,@.BLKSV .ENDC LDA 2,@T.TDCT ; GET DCT ADDRESS LDA 3,DCTOP,2 ; SEE IF ANY MESSAGE COM# 3,3,SNR ; TEST JMP@ .XX ; SEE IF ! IN CLOUMN ONE LDA 0,DCTT3,2 ; GET STATUS MOVL# 0,0,SNC ; TEST FOR "!" JMP @.TEXCP ; DONT HAVE ONE MOVR$# 0,0,SNC ; HAVE ONE TRY FOR "F" OR "B" JMP @.TSTFB ; TEST FOR "F" OR "B" LDA 1,C133 ; HAVE 1 SEE WHICH BEAD IS ; ACTIVE ZK: LDA 0,RQCNT,3 SUB# 0,1,SZR ; SEE WHICH BEAD JMP TSTTR ; GOT IT LDA 3,RQLK,3 ; TRY AGAIN COM# 3,3,SNR ; TEST LINK J< MP GAK ; END OF QUEUE - BAIL OUT JMP ZK ; TRY AGAIN TSTTR: LDA 0,@.CH1 ; TEST FOR TERMINATOR LDA 1,CR SUB# 0,1,SNR JMP DRQCNT ; IT IS LDA 1,FFD ; GET A FORM FEED SUB# 0,1,SNR ; IS IT A FORM FEED ? JMP DRQCNT ; YEP MOV# 0,0,SNR ; NO, HOW 'BOmUT A NULL ? JMP DRQCNT ; YES LDA 1,RUB ; IS CHAR A RUB OUT SUB# 0,1,SZR ; IS IT A RUBOUT ? JMP ZVZ ; NO LDA 1,C132 ; HAS ONLY AN F OR B BEEN ; RECIEVED ? LDA 2,RQCNT,3 #SUBZ 1,2,SZR ; WELL ? JMP ZVZ ; IT'LL BE CAUGHT LATER LDA 0,@.BA ;J GET BACK ARROW STA 0,@.CHAR ; ECHHO BACK ARROW ISZ RQCNT,3 ; UP COUNT TO SHOW NO F OR B LDA 2,@.TTDCT DSZ DCTT3,2 ; CLEAR DCT F OR B RECIEVED ; STATUS JMP @.OUT4 ; ECHO BACK ARROW ZVZ: LDA 1,RQCNT,3 ; TEST FOR BUFFER OVERFLOW MOVZR# 1,1,SZR 4JMP .+2 ; NOT LAST @.CHARACTER SVQP: ISZ RQCNT,3 ; KEEP BEAD FROM 0 LDA 2,@.TTDCT LDA 1,DCTQP,2 ; GET REGULAR QUEUE POINTER STA 1,QPSV ; SAVE DCTQP STA 3,DCTQP,2 ; DUMMY UP DCTQP .IFN MSW STA 3,CELTMP ; SAVE BEAD ADDRESSS .IFN MNSW LDA 1,CLSTB ADDOR 1,1 INTDS DOA 1,MAP INTEN DIC 1,MAP LDA 0,C377 AND 0,1 .ENDC .IFN MN3SW LDA 1,CLSTB INTDS DOA 1,MAP1 INTEN DIA 1,MAP1 .ENDC .IFN MBSW LDA 1,CLBLK ;CURRENT .ENDC STA 1,BLKSV LDA 0,RQPTR,3 ; GET BYTE POINTER MOVZR 0,0 ; MAKE ADDRER7SS LDA 1,RQST,3 ; GET "F" OR "G" LDA 2,FTST AND 2,1,SZR SUBZL 1,1 ; FOREGROUND JSR @.MBLK JMP .+1 ;CAN'T GET ERROR.... LDA 0,.PPT1 ;ASSUME FG MOV# 1,1,SNR LDA 0,.PPT2 ;BG PTBL STA 0,PTSV ;SAVE MOV 2,0 LDA 3,CELTMP LDA 1,RQPTR,3 ; TO GET BYTE IN WORD MOVZR 1,1 MOVL 0,0 ; PUT IN POINTER STA 0,RQPTR,3 ; PUT IN BEAD LDA@ 2,.TTDCT ;RESTORE LDA@ 0,.CHAR .ENDC JSR @.EFINP ; FINISH INPUTTING TO USER ; BUFFER LDA 2,DCTQP,2 ; GET BEAD ADDRESS LDA 0,RQP1,2 ; GET UNMAPPED BYTE POINTER , JMP @.TRUB ; TEST FOR RUBOUT KXV: INC 0,0 ; UP BYTE POINTER STA 0,RQP1,2 ; SAVE POINTER ISZ RQBCT,2 ;IS CNT KX: STA 0,RQPTR,2 ; PUT UNMAPPED ADDRESS BACK IN LDA 0,RQCNT,2 ; GET COUNT MOVZR# 0,0,SZR ; DONE? JMP RESET ; NO LDA 2,@.TTDCT LDA 1,DCcTQP,2 LDA 0,DCTOP,2 STA 0,DCTQP,2 ; PUT OP Q IN QP FOR DEQUE STA 1,CELTMP ; DEQUE MESSES UP REGISTERS JSR @.DEQUE ; GET OFF QUEUE .IFN MSW LDA 2,PTSV ;PBLT ADDR LDA 1,PMAP,2 ;MAP .IFE MBSW LDA 3,C377 AND 3,1 ;GET BLK LDA 3,CLSTB ADD 3,1 ;LAST BLK DOA .ENDC .IFN MBSW STA 1,CLBLK ;NEW LAST .ENDC SMLB 1 .ENDC LDA 2,CELTMP ; RESTORE CELL ADDRESS LDA 0,RQBCT,2 ;COUNT LDA 1,RQCC,2 ; TCB ADDRESS OF REQUEST MOV 1,3 ; TCB STA 0,TAC1,3 ; FOR USER LDA 0,RQST,2 ; "F" OR "B" JSR@ .CREL MOV 1,2 LDA 1,TPRST,2 ;TO CLEAR PEND BIT IN TCB MOVZL 1,1 MOVZR 1,1 STA 1,TPRST,2 ; RESTORE LDA 1,FTST ; SEE IF "F" OR"B" LDA 2,.PPT2 ; BACKGROUND AND 0,1,SZR ; TEST LDA 2,.PPT1 ; FOREGROUND LDA 0,PSTAT,2 ; GET PROG STSTUS MOVZL 0,0 MOVZR 0,_0 STA 0,PSTAT,2 SUBZL 2,2 STA@ 2,.UUPQUE ;RESCHD LDA 2,@.TTDCT ; GET TCB ADDRESS LDA 0,DCTQP,2 ; GET OP STA 0,DCTOP,2 ; RESTORE LDA 0,QPSV ; GET OLD DCTQP STA 0,DCTQP,2 ; RESTORE PTCH: SUB 0,0 STA 0,DCTT3,2 ; CLEAR STATUS INC 0,0 ; TOSET CR FLAG STA 0,DCTOF,2 ; SAVE IT LDA 0,CR LDA 2,DCTPR,2 ; GET DCT FOR ECHO JSR @.EIBUFF JMP .+1 LDA 0,.LF ; OUTPUT LINE FEED JMP OUT4 .IFN MSW BLKSV: 0 .MBLK: MBLK PTSV: 0 .ENDC .DEQUE: DEQUE CR: 15 QPSV: 0 RUB: 177 .TTDCT: TTDCT .EFINP: FINP .PPT1: GePT1 .PPT2: PT2 .INLIN: INLIN C377: 377 CELTMP: .BLK 1 .TRUB: TRUB .CHAR: CHAR .BA: BKAR C132: 132. TEXCP: LDA 0,@.CHAR LDA 1,DCTOF,2 ; GET CR FLAG MOV 1,1,SNR ; WAS CR LAST CHAR ? JMP @.INLIN ; NOT FIRST LETTER LDA 1,EXCP SUB 0,1,SZR ; TEST JMP @.INLIN ; NOT ! MOVOR 1,1 ; SET STATUS BIT LDA 2,@.TTDCT ; GET TCB ADDRESS STA 1,DCTT3,2 ; SAVE LDA 0,DEXCP ; ECHO "! STA 0,@.CHAR JMP OUT FTST: BSFOP TSTFB: LDA 0,@.CHAR ; TEST FOR F OR B LDA 1,FF SUB# 0,1,SNR JMP FSET  ; ITS AN F LDA 1,CB NrSUB# 0,1,SNR ; TRY B JMP BSET ; ITS A B LDA 1,RUB ; SEE IF RUB SUB# 0,1,SZR ; TEST JMP OUTM2 ; ILLEGAL CHAR LDA 1,@.BA ; ECHO BACK ARROW STA 1,@.CHAR JMP PTCH FSET: LDA 0,FTST ; BIT SET FOR F JMP .+2 BSET: LDA 0,BTST ; BIT SET FOR B LDA  3,DCTOP,2 ; GET RIGHT BEAD WST: COM# 3,3,SNR JMP OUTM2 ; NEITHER LDA 1,RQST,3 ; TEST STATUS AND# 0,1,SNR JMP WT ; NOT THIS ONE DSZ RQCNT,3 ; SHOW THIS IS ACTIVE BEAD LDA 1,DCTT3,2 INC 1,1 ; SHOW F OR B WAS RECIEVED STA 1,DCTT3,2 ; SAVE JMP OUTP ; ECHO WT: LDA 3,RQLK,3 ; GET NEXT BEAD JMP WST ; TRY AGAIN RESET: LDA 0,QPSV ; GET REAL DCTQP LDA 2,@.TTDCT ; GET DCT STA 0,DCTQP,2 ; RESTORE JMP OUT ; ECHO IT OUTM2: LDA 0,ABELL ; NO REQUEST FOR OP MES RECIEVED JMP OUT4 OUT: LDA 2,@.TTDCT ~SUB 0,0 ; CLEAR CR FLAG STA 0,DCTOF,2 ; SAVE LDA 0,@.CHAR ; GET CHAR TO ECHO OUT4: LDA 2,@.TTDCT ; GET DCT ADDRESS LDA 2,DCTPR,2 ; GET DCT FOR ECHO .IFN MSW LDA 1,BLKSV MOV 1,1,SNR JMP@ .LABEL .IFN MNSW LDA 3,CLSTB ADD 3,1 .ENDC .IFN MBSW 7STA 1,CLBLK ;NEW LAST .ENDC SMLB 1 .ENDC JMP @.LABEL ; RETURN FF: "F CB: "B .EIBUF: XIBUF EXCP: "E-100 ; CONTROL E FOR OP MESSAGE .LABEL: LABEL BTST: BSBOP .CREL: CREL .UUPQUE: UPQUE ABELL: "G-100 .LF: 12 DEXCP: "! ; FOR ECHO XX: LDA 3,DCTOF,2 ;MOV# 3,3,SNR ;CR ? JMP@ .INLIN ;NO LDA 1,EXCP ;COL = 1 ? SUB# 1,0,SZR JMP@ .INLIN ;NOY ! JMP OUTM2 ; DING DING TRUB: LDA 1,@.CHAR LDA 3,RUBO #SUBZ 1,3,SZR ; IS IT AA RUB OUT ? JMP @.KXV ; NO ISZ RQCNT,2 ; GET RID OF RUB OUT ISZ RQCNT,2 ; GET RID OF PREVIOUS CHAR DSZ RQP1,2 ; ADJUST OTHER POINTER LDA 0,RQP1,2 ; GET UNMAPPED BYTE POINTER DSZ RQBCT,2 ; ADJUST COUNT RETURNED BY ; PREVIOUS CHAR JMP .+1 ; NEED IT LDA 1,BKAR ; ECHO BACK ARROW STA 1,@.CHAR JMP @.KX ; GIET AROUND UPDATING CELL .KXV: KXV .KX: KX RUBO: 177 BKAR: 137 .END z TTY1D.SRB e  ; TTY1D.SR ; SECOND TELETYPE CONTROLLER DCT RTITLE TTY1D .NREL .ENT TTI1D,TTI1Q ; SECOND TTI ENTRIES .ENT TTR1D,TTR1Q ; SECOND TTR ENTRIES .ENT TTO1D,TTO1Q ; SECOND TTO ENTRIES .EXTN TTIDT,TTRDT,TTODT ; DISPATCH TABLES .EXTN TTIEX,TTOEX ; EXECbUTE .EXTN CISER,COSER,TTIS; INTERRUPT SERVICE .EXTN XNIOS,STOUT ; NIOS,START OUTPUT OF CHARACTER TTI1D: 0 ; TTI1 DCT MKTTI ; MASK TTIS ; INTERRUPT SERVICE ROUTINE DCKEY+DCLTU ; CHARACTERISTICS TTI1 ; DEVICE CODE TTIEX ; EXECUTE IO TTIDT; ; DISPATCH TO COMMAND ENABLE DRTN TTISZ*2 ; BYTES IN BUFFER TTIBF*2 ; BYTE POINTER TO START .BLK 5 ; PC,PP,RQLK,DP,DC BSUPC+BSFCD+BSDON+BSLPA ; STATUS - DONE,UNPEND ON COMPLETEION .-4 ; BEAD ADDRESS -1 ; Q POINTER INITIAL .BLK 2 ; DEVIGCE TEMPS -1 ; LONG TIMEOUT TOECH-DCTBC ; PAIR FOR ECHO MODE TTR1D ; LINK TO TTR .BLK 3 ; FILLER USE DCTOF FOR CR FLAG -1 ; QUEUE STARTING ADDRESS FOR OP MESSAGE 0 ; TEMP FOR OP STATUS MESSAGE TTISZ=72. TTIBF: .BLK TTISZ ; BUFFER TTI1Q: .ٵBLK 2 ; TTI1Q 1B0 TTI1D .BLK SQLN-.+TTI1Q TTO1Q: .BLK 2  1B0 TTO1D .BLK SQLN-.+TTO1Q TTR1Q: .BLK 2 1B0 TTR1D .BLK SQLN-.+TTR1Q DRTN: JMP 0,3 TTR1D: 0 ; TTR1 DCT MKTTI ; MASK CISER ; INTERRUPT SERVICE DCIDI+DCPCK ; CHARACTERISTICS TTI1 ; DEVICE CODE TTIEX ; EXECUTE IO TTRDT ; COMMAND ENABLE DISPATCH XNIOS ; SETAR DEVICE TTRSZ*2 ; BUFFER SIZE TTRBF*2 ; BYTE POINTER TO BUFFER .BLK 5 ; PC,PP,RQLK,DP,DC BSUPC+BSDON+BSLPA ; INIT STATUS .-4 ; BEAD ADDRESS -1 ; STAR5TING Q POINTER .BLK 2 ; DEVICE TMPS 3 ; TIME OUT IN SECODSN .BLK 1 @TTI1D TTRSZ=5 TTRBF: .BLK TTRSZ TTO1D: 0 ; TTO1 DCT MKTTO ; MASK COSER ; INTERRUPT SERVICE ROUTINE DCCGN+DCCNF+DCTO+DCPCK+DCLAC+DCC80+DCSPO+DCSPC TTO1 ; DEVICE CODE T~TOEX ; EXEC IO TTODT ; COMMAND ENABLE DISPATCH STOUT ; START DEVICE TTOSZ*2 ; BUFFER SIZE TTOBF*2 ; BUFFER BYTE POINTER .BLK 5 ; PC,PP,RQLK,DP,DC BSUPC+BSDON+BSLPA ; DONE,UNPEND,LAPPABLE .-4 ; BEAD ADDRESS -1 ; Q POINTER .BLK 2 ; DEVICE TEMPS -1 ; NEGATIVE TIME IN  .BLK 2 ; COL COUNTER AND LINE COUNTER .BLK 3 ; SPOLLER INFO TTOSZ=40 TTOBF: .BLK TTOSZ TOECH: ECHBZ*2 ECHBP*2 .BLK 5 BSDONT .-4 TTO1D ; LINK TO DCT .BLK 2 "_ ; RUBOUT CHARACTER ECHBZ=12 ECHBP: .BLK EC +HBZ .END TTYDR.SRB RTITLE TTYDR .ENT TTIS ;TTY INTERRPUT SERVICE .ENT TTIEX .ENT TTOEX .ENT TTIDC,TTIQ,TTIDT ;TTI ENTRIES .ENT TTODC,TTOQ,TTODT ;TTO .ENT TTRDC,TTRQ,TTRDT ;TTR .ENT NOPPRO .ENT CHAR,TTDCT,INLIN,LABEL .ENT DEBAD ; HOLDS DEBUGGER ADDRESS  .EXTN OPPRO .EXTN OPNI,OPNO ;OPEN ENTRIES .EXTN CLSI ; CLOSE INPUT .EXTN CLSO,TOO ; CLOSE OUTPUT .EXTN FSYSF .EXTN TIRS ;TTI RDS .EXTN TIRL ;TTI RDL .EXTN RDS ;TTR RDS .EXTN RDL ;TTR RDL .EXTN XIBUF ; INPUT TO BUFFER .EXTN WRS ; WRITE SEQUENTIAL  .EXTN WRL ; WRITE LINE .EXTN DISMIS ; INTERRUPT DISMISSAL .EXTN SYSFL ; SYSTEM FLAGS .EXTN PT1,PT2,UPQUE .EXTN COSER,XNIOS ;COMMON I/O REQUESTS .EXTN STOUT .EXTN FINP ;FINISH A INPUT .EXTN CISER,XDIAC .EXTN SYSFG .EXTN FINP .EXTN ENQUE ;ENQUE REQUEST TO DEVICE .EXTN CREL ; RELEASE A CELL .EXTN DEQUE .TXTM 1 .NREL ; TTY IN KEYBOARD DCT TTIDC: 0 MKTTI ; MASK TTIS ;INT SERVICE DCKEY+DCLTU ; CHARACTERISTICS TTI ;DEVICE CODE TTIEX ;EXECUTE IO INSTRUCTION TTIDT ; DISPATwOCH TABLE ADDRESS TTIEX+1 ;NOOP FOR TTI START ROUTINE TTISZ*2 ; BUFFER SIZE TTIBF*2 ; BUFFER FIRST BYTE ADDRESS .BLK 1 ;PROGRAM BYTE COUNT .BLK 1 ;PROGRAM BYTE POINTER .BLK 1 ;DEVICE REQUEST CHAIN WORD .BLK 1  ;DEVICE DATA POINTER .BLK 1 ;,DEVICE DATA COUNT BSUPC+BSBCD+BSDON+BSLPA ;BEAD STATUS .-4 ;BEAD ADDRESS -1 ;DEVICE REQUEST QUEUE .BLK 2 ;DEVICE TEMPS -1 ;TIME OUT CONSTANT (LONG) TOECH-DCTBC ;PAIR POINTER FOR ECHO MODE TTRDC ;LINK TO TTRDCT ADDRESS .BLK 3 ; FILLER USEA DCTOF FOR CR FLAG -1 ; QUEUE STARTING AD FOR OP ; MESSAGES 0 ; TEMP FOR OP STATUS MESSAGE TTISZ= 72. ; BUFFER SIZE TTIBF: .BLK TTISZ ; RESERVE THE BUFFER SPACE ; TELETYPE IN READER TTRDC: 0 MKTTI ; MASK CISER ;INT SERVICE DCIDI+DC6PCK ; CHARACTERISTICS .TTI: TTI ;DEVICE CODE TTIEX ;EXECUTE I.O INSTRUCTION TTRDT ; DISPATCH TABLE ADDRESS XNIOS ; START READER ADDRESS TTRSZ*2 ; BUFFER SIZE TTRBF*2 ; BUFFER FIRST BYTE ADDRESS .BLK 1 ;PROGRAM BYTE COUNT .BLK 1 ;PROGgRAM BYTE POINTER .BLK 1 ;DEVICE REQUEST CHAIN WORD .BLK 1 ;DEVICE DATA POINTER .BLK 1 ;DEVICE DATA COUNT BSUPC+BSDON+BSLPA ;BEAD STATUS .-4 ;BEAD ADDRESS -1 ;DEVICE REQUEST CHAIN .BLK 2  ;DEVICE TEMPS 3 ;TIMEOUT CONSTANT IN SECONDS .BLK 1 @TTIDC TTRSZ= 5 ; BUFFER SIZE TTRBF: .BLK TTRSZ ; RESERVE THE BUFFER SPACE TTIEX: 0 JMP 0,3 JMP 1,3 ;FOR SKIPS SIGNL: MOV# 0,0,SNC ; WHICH? SUBZR 0,0,SKP ; INT (1B0) SUBZL 0,0 ; BRK (1B15) LDA 1,DCTQS,2 ; STATUS XLDA 3,= BSFCD ; ENABLED\ FOR FG ? AND# 3,1,SNR ; SKIP IF YES JMP SIG2 SIG1: XLDA 3,SYSFG ;FG RUNNING ? SNEZ 3 ;SKIP IF YES XXJMP DISMIS XLDA 3,= FSYSF ; ADD FG WORD XXLDA 2,= PT1 JMP SIG3 SIG2: XLDA 3,= BSBCD ; ENABLED FOR BG ? AND# 3,1,SNR XXJMP DISMIS ; NO BAG IT  XLDA 3,= SYSFL XXLDA 2,= PT2 SIG3: LDA 1,0,3 ; SEE IF ONE QUEUED NOW SEQZ 1 XXJMP DISMIS ; ONE'S ENOUGH LDA 1,PFLAG,2 ; SEE IF USER INHIBIT MOVL# 1,1,SZC ; SKIP IF NO XXJMP DISMIS ; IGNORE INT STA 0,0,3 ; TO CNTL WORD LDA 3,PSTAT,2 ;SET ABORT@ XLDA 1,= PSCP ;CP GOING ON ? AND# 1,3,SZR XXJMP DISMIS ;IGNORE DURING CP LOAD XLDA 1,= PSBRK ; SET INT REQD ADD 1,3 MOVL 3,3 ;UNPEND IF PENDED MOVZR 3,3 STA 3,PSTAT,2 SUBZL 2,2 XSTA 2,UPQUE XXJMP DISMIS ; YES, DISMIS SIGFG: ADC 0,0 ; CONT6 F FLAG JMP SIG1 TCR: LDA 0,CHAR ; CHECK FOR CR ON RDS XLDA 1,= 15 SUBZ 1,0,SZR ; TEST JMP .+2 INC 0,0,SKP CTIEX: SUB 0,0 ; TO CLEAR CR FLAG LDA 2,TTDCT STA 0,DCTOF,2 XXJMP DISMIS LPOOL CHAR: .BLK 1 ;SAVE INPUT CHAR SQP: .BLK 1 ;SAVE INTERRUPTING BEAD ADDRESS TTDCT: .BLK 1 ;SAVE DCT ADDRESS ON INTERRUPT .DCLCD: DCLCD ;6053 (LCD) CHARACTERISTIC BIT ; TELETYPE INTERRUPT SERVICE TTIS: XSTA 2,TTDCT ;SAVE DCT ADDRESS LDA 3,DCTLK,2 ; GET ADDR OF READER DCT LDA 3,DCTQP,3 ; GET READER BEAD38 ADDRESS COM# 3,3,SNR ; IF NO BEAD QUED JMP TTIS0 ; ON READER THEN GO TTI ELSE LDA 3,RQST,3 ; GET STATUS MOVR# 3,3,SZC ; IF READER NOT GOING THEN JMP TTIS0 ; THEN IS TTY CHAR ELSE LDA 2,DCTLK,2 ; GET READR DCT AND XXJMP CISER ; GO USE COMMON IN\T SERVICER TTIS0: XXJSR XDIAC ;DIA CLEAR XLDA 1,= 177 ;MASK TO AND 1,0 ;SEVEN BITS ;CHECK MODE WORD BEFORE DETERMINING HOW TO INTERPRET CURRENT ;CHARACTER (APPLIES TO 6053 ONLY). THE POSSIBLE STATES OF THE ;MODE WORD ARE: ; 0: NOTHING SPECIAL IN PXROGRESS ; 1: USER HAS JUST HIT A FUNCTION KEY. CURRENT ; CHARACTER IS THE FUNCTION CODE ; 1B0+1B1:THE TERMINAL IS RESPONDING TO A CONTROL-E ; (SEND CURSOR POSITION). CURRENT CHARACTER AND ; NEXT ARE THE CURSOR COORDINATES ; 1B0: CURRENT CHARACTER IS SECOND CURSOR COORDINATE ;FOR REFERENCE, THE MODES ARE DEFINED AS FOLLOWS: ; MODE 0: MODE WORD IS 0 ; MODE 1: MODE WORD IS 1 ; MODE 2: MODE WORD IS 1B0 OR 1B0+1B1 LDA 1,DCTON,2 ;MODE WORD MOVZR# 1,1,SNC ;SKIP IF MODE 1 JMP NMD1 SUB 1,1 STA 1,DCTON/h,2 ;SET MODE 0 INC 1,1 ;GEN 1 (PRINT FUNCTION) SNE 0,1 ;SKIP IF NOT PRINT JMP PRTC XLDA 1,= 21 ;OTHER PRINT FUNC CODE SNE 0,1 ;SKIP IF NOT PRINT JMP PRTC ;REGULAR FUNCTION CODE -- PUT <36> IN INPUT BUFFER ;AND DISMIS XSTA 0,CHAR ;SAVrrE CURRENT CHAR XLDA 0,= 36 ;FUNC HEADER CODE XJSR FINP ;PUT IN BUFFER XLDA 0,CHAR ;CURRENT CHAR AGAIN XJSR FINP ;PUT IN BUFFER XXJMP DISMIS ; AND DISMIS (NO ECHO) ;WAS PRINT CODE -- PUT IN ECHO BUFFER AND DISMIS PRTC: LDA 2,DCTPR,2 ;$TTO DCT XXJSR XIBUF ;PUT IN BUFFER XXJMP DISMIS ;IGNORE IF FULL XXJMP DISMIS ; OR NOT NMD1: MOVZL 1,1,SNC ;SKIP IF MODE 2 JMP NOMOD STA 1,DCTON,2 ;SET NEW MODE (MAY STILL BE 2) XJSR FINP ;PUT CHAR IN INPUT BUFFER XXJMP DISMIS ; AND DISMIS NOMOD: XLDA 1,=+ "C-100 ; BREAK CHARACTER XLDA 3,= "A-100 ; INTERRUPT CHARACTER SUBZ 0,1,SZR ; IS IT EITHER? SUBO 0,3,SNR JMP SIGNL ; YES, MAGIC CODE XLDA 1,= "S-100 ; IF IS STOP OUTPUT CODE SNE 0,1 ; THEN GO STOP XJMP YSTOP ; TTY OUTPUT ELSE XLDA 1,= "Q-100 ;tN IF IS START CODE THEN SNE 0,1 ; GO START THE XJMP YSTRT ; TTY OUTPUT LDA 1,DCTCD,2 ; CONTL F ON TTI ONLY XLDA 2,.TTI SEQ 1,2 ; TTI ? JMP INLIN ; NO - DON'T LOOK XLDA 1,= "F-100 SNE 0,1 JMP SIGFG ;STOP FORE GROUND ; CHECK TO SEE IF USER IS CALLING THE SYSTEM DEBUGGER XLDA 1,= "X-100 ; GET CALL CHAR(CONTROL-X) READS 3 ; GET SWITCHES SUB# 0,1,SNR ; IF NOT CORRECT CHAR OR COM# 3,3,SZR ; IF SWITCHES ARE ALL UP JMP TTS1X ; THEN NOT DEBUG REQUEST LDA 3,DEBAD ; GET DEBUGGER ADDRESS COM# 3g,3,SNR ; IF NO DEBUGGER IN SYSTEM JMP TTS1X ; THEN TREAT AS ORDINARY CHAR XXLDA 1,= DISMIS ; ELSE LOAD DISMISS AS PLACE TO STA 1,@-1,3 ; HAVE DEBUGGER RESTART AND JMP 0,3 ; GO TO DEBUG DEBAD: -1 ;DEBUG ADDR STORED HERE BY INIT TTS1X: LDA 2,NOPPRO ; SEE IF OP MES SUPPORT MOVL# 2,2,SNC JMP @NOPPRO ; CHECK FOR OPERATOR QUEUE INLIN: XLDA 2,TTDCT ; NO, ADDRESS OF KEYBOARD DCT LDA 3,DCTQP,2 ;ACTIVE REQUEST CHAIN COM# 3,3,SZR ;ANYTHING ACTIVE ? JMP .+4 ;YES LDA 2,DCTPR,2 ;ECHO = BELL XLDA 0,>= "G-100 JMP LABEL XSTA 3,SQP ;SAVE REQUEST ADDRESS XSTA 0,CHAR ;SAVE INPUT CHARACTER ;IF INPUT DEVICE IS A 6053 (LCD), CHECK FOR SPECIAL ;CHARACTERS. THESE CHARACTERS ARE DEFINED IN CTAB BELOW. LDA 1,DCTCH,2 ;CHARACTERISTICS WORD LDA 3,.DCLCD ALND 1,3,SNR ;SKIP IF 6053 JMP NOLCD XLDA 3,= 37 SEQ 0,3 ;SKIP IF CURSOR COORD HEADER JMP CTEST ;WAS CURSOR COORDINATE HEADER -- FLAG NEXT 2 CHARACTERS AS ;THE COORDINATES SUBZR 0,0 ;GENERATE 1B0+1B1 (MODE 2 FLAG) MOVOR 0,0 STA 0,DCTON,2 ;SAVE IT >JMP CLP2 ; INPUT TO BUFF AND DISMIS CTEST: XLDA 3,= 36 SEQ 0,3 ;SKIP IF FUNCTION HEADER JMP CTST2 ;WAS FUNCTION HEADER CODE -- FLAG NEXT CHAR AS FUNCTION CODE SUBZL 1,1 ;GENERATE A 1 (MODE 1) STA 1,DCTON,2 ;SAVE IT XXJMP DISMIS ; AND DISMIS ;LOOP mTHROUGH TABLE OF SPECIAL CHARACTERS FOR LCD CTST2: XLDA 3,CTAB CLP: LDA 1,0,3 ;GET ENTRY COM# 1,1,SNR ;SKIP IF NOT END OF TABLE JMP NOLCD ;EOT -- TREAT AS REGULAR CHAR SNE 0,1 JMP CLP2 ;IF MATCH, INPUT AND DISMIS INC 3,3 JMP CLP ;LOOP TILL MAjTCH OR EOT LPOOL CLP2: XLDA 0,CHAR ;CURRENT CHAR AGAIN XJSR FINP ;INPUT TO BUFFER XXJMP DISMIS ; AND DISMIS (NO ECHO) NOLCD: XJSR FINP ;FINISH INPUTTING TO BUFFER XLDA 3,SQP ;RELOAD BEAD ADDRESS LDA 1,RQST,3 ;STATUS WORD XLDA 3,= BSECH ; ECHO FLAG AND# 3,1,SNR ; WELL? JMP @.TCR ; NO, JUST DISMISS LDA 2,DCTPR,2 ; YES, GET TTO DCT XSTA 2,SQP XLDA 3,= 177 XLDA 0,CHAR ;INPUT CHARACTER AGAIN SNE 3,0 ; IS IT RUBBOUT? JMP RUB ; YES - GO HANDLE IT ORB: XXJSR XIBUF ;STUFF INTO PARIED BUFFE&R XXJMP DISMIS ;FULL - DISMIS XLDA 0,CHAR ;INPUT CHARACTER XLDA 2,SQP XLDA 1,= 134 ; LINE DELETE SEQ 0,1 JMP TTIS3 ; NO XLDA 0,= 15 ; YES, ECHO CR, LF XXJSR XIBUF XXJMP DISMIS ; DISMISS IF FULL XLDA 0,= 12 ;FORCE LINE FEED XLDA 2,SQP XXJSR XIBUF XXJMP DISMIS ;DISMIS IF FULL JMP @.CTIEX ;RST- DO NOT CAUSE DCTOF TO BE SET. ;RST- THIS CAUSES PROBLEMS WITH .RDOP . TTIS3: XLDA 1,= 15 SNE 0,1 ;RST-IS IT A ? JMP TTIS4 ;RST-YES, GO DO GOOD THINGS. XLDA 1,= 14 SEQ 0,1 ;RST-IS IT A ? JMP @.CTIEX ;RST-IF NOT A OR ;RST-THEN DISMISS NOW. TTIS4: XLDA 2,SQP ;INPUT DCT ADDRESS SUB 0,0 LDA 3,DCTQP,2 ;DEVICE DCT ADDRESS STA 0,DCTCC,3 ;CLEAR COL COUNTER FOR CL INC 0,0 ; TO SET CR FLAG XLDA 3,TTDCT ; PUT IN DCT STA 0,DCTOF,3 XLDA 0,= 12 ; YES, ECHO LINE FEED LABEL: XXJSR XIBUF XXJMP DISMIS XXJMP DISMIS ; AND GET OUT YSTOP: LDA 2,DCTPR,2 ; GET ECHO BEAD LDA 2,DCTQP,2 ; GET OUTPUT TTO DCT LDA 0,DCTQS,2 ; GET Q STATUS XLDA 1,= -BSCTS-1 ; AND STOP IT AND 1,0 ; OR IT IN TO THE WORD ADC 1,0 STA 0,DCTQS,2 ; AND STORE IT BACK XXJMP DISMIS YSTRT: LDA 2,DCTPR,2 ; GET ECHO BEAD LDA 2,DCTQP,2 ; GET OUTPUT TTO DCT LDA 0,DCTQS,2 ; START IT ONLY IF STOPPED XLDA 1,= -BSCTS-1 AND 0,1 SNE 0,1 ; IF WAS NOT STOPED XXJMP DISMIS ; THEN FORGET IT ELSE STA 1,DCTQS,2 ; START IT UP AGAIN XJMP COSER ; GO START IT NOPPRO: OPPRO .CTIEX: CTIEX .TCR: TCR LPOOL ** .NOLOC 1 KILL: .+1*2 ; RUBOUT STRING .TXT /<31><32><27><32><27><40><31><32><27><32><27>/ ** .NOLO C 0 RUB: LDA 0,DCTTO,2 ;RUBOUT CHAR MOVL# 0,0,SNC ;CRT? JMP ORB ;NO - JUST ECHO "_" LDA 0,KILL ; KILL STRING STA 0,TKILL RUBNX: LDA 0,TKILL ; GET CURRENT STRING POINTER ISZ TKILL .DO ?ANSW XLDA 1,= 177 ; LOAD BYTE ROUTINE MOVZR 0,3,SNC ; LEFHFT HALF ? MOVS 1,1 ; YES SWAP MASK LDA 0,0,3 AND 1,0,SNC ; MAKE IT SEVEN BITS MOVS 0,0 ; SWAP IF LEFT HALF .ENDC .DO ?ABSW LDB 0,0 .ENDC XLDA 2,SQP ; POINT TO DCT MOV 0,0,SZR ; DONE ? XXJSR XIBUF ; NO PUT IN BUFFER XXJMP DISMIS ; EITHER DONE OR BUFFER FULL GET OUT JMP RUBNX ; DO NEXT CHARACTER TKILL: 0 ; TEMP STORAGE FOR BYTE POINTER LPOOL ;TABLE OF SPECIAL-PURPOSE CHARACTERS USED BY 6053-TYPE TERMINAL. ;THE TABLE DOES NOT INCLUDE THE FOLLOWING SPECIAL CHARACTERS, ;WHICH ARE NOT SUPPORTED, OR ARE HANDLED SEPARATELY: ; 3 :BLINK ENABLE ; 23 :ROLL DISABLE ; 36 :FUNCTION HEADER ; 37 :CURSOR COORDINATE HEADER CTAB: .+1 4 ;BLINK DISABLE 5 ;READ CURSOR POSITION 11 ;TAB 16 ;START BLINK 17 ;END BLINK 20 ;SET CURSOR POSITION 22 ;ROLL ENABLE 24 ;START UNDERSCORE 25 ;END UNDERSCORE 34 ;START DIM 35 ;END DIM -1 ;END OF TABLE ; DEFINE THE TELETYPE IN DISPATCH TABLE TTIDT: OPNI ; TTI OPEN CLSI ; TTI CLOSE TIRS ; TTI READ SEQUENTIAL TIRL ; TTI READ LINE -1 ; READ RANDOM -1 ; WRITE SEQ -1 ; WRITE LINE -1 ; WRITE RANDOM -1 ; OPEN FOR APPENDING OPNI ; OPEN FOR READING ONLY OPNI ; EXCLUSIVE READ/WRITE OPEN -1 ; TRANSPARENT (EXCLUSIVE) OPEN ; TTY IN (READER) DISPATCH TABLE TTRDT: OPNI ;TTtY READER OPEN CLSI ;TTY READER CLOSE RDS ; TTY READER READ SEQUENTIAL RDL ; TTY READER READ LINE -1 ; READ RANDOM -1 ; WRITE SEQ -1 ; WRITE LINE -1 ; WRITE RANDOM -1 ; OPEN FOR APPENDING OPNI ; OPEN FOR READING ONLY OPNI ; EXCWLUSIVE READ/WRITE OPEN -1 ; TRANSPARENT (EXCLUSIVE) OPEN ; TELETYPE OUT SERVICE ; TELETYPE OUT DEVICE CONTROL TABLE TTODC: 0 MKTTO ; MASK COSER ;INTERRUPT SERVICE DCCGN+DCCNF+DCTO+DCPCK+DCLAC+DCC80+DCSPO+DCSPC; CHARACTERISTICS TTO ;DCVIGCE CODE TTOEX ;EXECUTE TTODT ; DISPATCH TABLE ADDRESS STOUT ; TTO START ADDRESS TTOSZ*2 ; BUFFER SIZE TTOBF*2 ; BUFFER FIRST BYTE ADDRESS .BLK 1 ;PROGRAM BYTE COUNT .BLK 1 ;PROGRAM BYTE POINTER .BLK 1  ;LINK TO NEXT DEVICE REQUEST .BLK 1 ;DEVICE DATA POINTER .BLK 1 ;DEVICE DATA COUNT BSUPC+BSDON+BSLPA ;BEAD STATUS .-4 ;BEAD ADDRESS -1 ;DEVICE REQUEST CHAIN .BLK 2 ;DEVICE TEMPS -1 ;NEGATIVE TIME IN .BLK 1 ;COLUMN COUNTER .BLK 1 ;LINE COUNTER .BLK 3 ;SPOOLER INFO TTOTSZ= 40 ; BUFFER SIZE TTOBF: .BLK TTOSZ ; RESERVE THE BUFFER SPACE TTOEX: 0 JMP 0,3 JMP 1,3 TOECH: ECHBZ*2 ;BUFFER SIZE ECHBP*2 ;BUFFER BYTE ADDRESS .BLK 5 ;PC,PP,RQLK,DP,DC BSDON ;INITIAL DONE STATUS .-4 ;BEAD ADDRESS TTODC ;LINK TOH REAL DCT ADDRESS .BLK 2 ;TEMPS "_ ;RUBOUT ECHO ECHBZ=12 ECHBP: .BLK ECHBZ ; DEFINE THE TELETYPE OUT DISPATCH TABLE TTODT: TOO ; TTO OPEN CLSO ; TTO CLOSE -1 -1 -1 WRS ; TTO WRITE SEQUENTIAL WRL ; TTO WRITE LINE -1 TOO ; TTO O'-PEN FOR APPENDING TOO ; OPEN FOR READING ONLY TOO ; EXCLUSIVE READ/WRITE OPEN -1 ; TRANSPARENT (EXCLUSIVE OPEN TTIQ: .BLK 2 100000 TTIDC .BLK SQLN-.+TTIQ TTOQ: .BLK 2 100000 TTODC .BLK SQLN-.+TTOQ TTRQ: .BLK 2 100000 TTRDC .BLK SQLN-.+ FGTTRQ .END DPMOD.SRDCZ$ RTITLE DPMOD .NREL .NOCON 1 DEBSW = 0 ;NON-DEBUGGING VERSION .ENT DGRAB ;MAKE OTHER SIDE GIVE UP A BLOCK .ENT DLOCK ;KEEP A BLOCK AWAY FROM OTHER SIDE .ENT DUNLOCK ;LET HIM HAVE IT .ENT DVLOCK ;GRAB & LOCK A DEVICE .ENT DVUNLOCK ;& UNLOCK4 A DEVICE .ENT DMPLOCK ;LOCK A MAP ON THE OTHER SIDE .ENT DMPUNLOCK ;UNLOCK MAP ON THE OTHER SIDE .ENT IPINIT ;INITIALIZE ROUTINE .ENT IPBDC ;IPB - SYSTEM LINK .ENT IPBQ ;IPB PROCESS .ENT DPIDC,DPODC ;DPI & DPO - USER LINK .ENT DPIQ,DPOQ .ENT] IVTINT ;INTERFACE WITH INTD FOR INTERVAL TIMER .EXTN IPCEL ;FROM SYSGEN: MAX NMBR OF CELLS ; IPB INTERRUPT WORLD CAN USE .EXTN GETCELL,CREL ;GET & RETURN CELL .EXTN IGCELL ;INTERRUPTIBLE GCELL .EXTN TRESP ;ZEBRA TRESPASSER .EXTN EITHER .EXTN DISMIS,PEND,UNPEND,QUENT,WAIT,BQ,DIRR,TACT .EXTN RDS,RDL,WRS,WRL,OPNO,OPNI,CLSO,CLSI .EXTN COSER,CISER,STOUT,XNIOS .ENT LOCKQ,OTHER,NFREE,IPSTK,CELIP ;FOR DEBUGGING .ENT .SENTC,.RSPTC SENTC=3 ;HOW LONG TO WAIT FOR SEND TO COMPLETE BEFORE ; ASSUMING OTHER SIDE IS DOWN RSPTC=2 ;HOW LONG TO WAIT FOR RESPONSE BEFORE RE-ASKING ** .IFN DEBSW .ENT IPQIMS,IPQOMS,IPQSLK,IPQRLK,IPQPLK,IPQLLK,IPQST,IPQUC .ENT QSRCV,QSDONE,QSLKWT,QSLKIN,QSCLIDE,QSSEND,QSTRY,QSCRAP,PSRCV,PSSEN .ENT ZLOCK,ZDVLOCK,ZRLS,ZFOIL,ZPASS,ZHEY .ENT ZMPLOCK,ZMPUNL,ZMPRMIT,ZGRANT,ZBOOT,ZPANIC .ENT IPBST,IPBSQ,IPBRQ,IPBCP,IPBCT,IPBCC,RCVWD,SENWD .ENT LKSEND,FOILED,SEND,TIMOUT,SRLKQ,IPZAP,LKLIZN,ZCLIZN,STALL .ENT IPRLS,IPSEN,IPNEXT,IPSNORE,IPSCAN,IPDO,IPGO,IJMLP,IPPC .ENT ILOCK,IDVLOCK,IMP?RMIT,IMPLOCK,IMPUNLOCK,FINDMP,RKEY,KEYFIND .ENT IPBIS,WHAT,THERE,ENDSEND,SDONE,SDEQUE,RCVING,REQUEST .ENT RESPONSE,STASH,ENDRCV,WAKE,PULSE,PENQ,IPENQU,SETLEN,CTRYSEN,TRYSENDQ .ENT TRET,TSWCH,SENSETUP,IPSTART,ITSW,IPTIMOUT,TAKEDOWN,CLRQUS,FIRSSW ** .ENDC DPIDC: 0 ; BS AREA MKDPI ; MASK CISER ; INTERRUPT SERVICE 0 ; CHARACTERISTICS DPI ; DEVICE CODE  DPIEX ; EXECUTE I/O DPIDT ; DISPATCH TABLE XNIOS ; START INPUT DPISZ*2 ; BYTES IN BUFFER DPIBF*2 ; BYTE POINTER TO START .BLK 5 ;o PC,PP,RQLK,DP,DC BSUPC+BSDON+BSLPA ; DONE,UNPEND ON COMPLERION LAPABLE .-4 ; BEAD ADDRESS -1 ; INITIAL QUEUE POINTER .BLK 2 ; DEVICE TEMPORARIES -1 ; TIME OUT IN SECONDS DPISZ=10. DPIBF: .BLK DPISZ ; BUFFER DPIQ: .BLK 2 1B0 ; NEEDS A STA,CK DPIDC ; DCT ADDRESS .BLK SQLN-.+DPIQ DPIEX: 0 JMP 0,3 JMP 1,3 DPIDT: OPNI ; OPEN CLSI ; CLOSE RDS ; READ SEQ RDL ; READ LINE -1 ; READ RANDOM -1 ; WRITE SEQ -1 ; WRITE LINE -1 ; WRITE RANDOM -1 ; OPEN FOR APPENDING OPNI ; READ ONLY OPEN OPNI ; EXCLUSIVE OPEN -1 ; TRANSPARENT OPEN DPODC: 0 ; BS AREA MKDPO ; MASK COSER ; INTERRUPT SERVICE DCSPO+DCSPC ; CHARACTERISTICS DPO ; DEVICE CODE DPOEX ; EXECUTE I/O DPODT ; DISPATCH TABLE STOUT ; STqMART OUTPUT DPOSZ*2 ; BUFFER SIZE DPOBF*2 ; BUFFER BYTE POINTER .BLK 5 ; PC,PP,RQLK,DP,DC BSUPC+BSDON+BSLPA ; DONE UNPEND ON COMP. LAPABLE .-4 ; BEAD ADDRESS -1 ; INITIAL QUEUE POINTER .BLK 2 ; DEVICE TEMPS -1 ; NEGATIVE TIME IN .BLK 2 v ; COLUMN/LINE COUNTERS .BLK 3 ; SPOOL CONTROL WORDS DPOSZ=10. DPOBF: .BLK DPOSZ DPOEX: 0 JMP 0,3 JMP 1,3 DPOQ: .BLK 2 1B0 DPODC .BLK SQLN-.+DPOQ DPODT: OPNO ; OPEN CLSO ; CLOSE -1 ; READ SEQ -1 ; READ LINE -1 ; READ RANDOM WRS  ; WRITE SEQUENTIAL WRL ; WRITE LINE -1 ; WRITE RANDOM OPNO ; OPEN FOR APPENDING OPNO ; READ ONLY OPEN OPNO ; EXCLUSIVE OPEN -1 ; TRANSPARENT OPEN ; ; QUEUE ENTRY (LIVES IN A CELL, SOMETIMES A BUFFER) ; MAXML=4 ;MAX MESSAGE LENGTH I IPQIMS=0 ;START OF INCOMING MESSAGE. REFERENCED ; NON-SYMBOLICALLY BY INTERRUPT HANDLER. IPQOMS=IPQIMS+MAXML ;START OF OUTBOUND MESSAGE IPQSLK=IPQOMS+MAXML ;LINK FOR SEND QUEUE IPQRLK=IPQSLK+1 ;LINK FOR RECEIVE QUEUE IPQLLK=IPQRLK+1 ;LINK FOR LOCK QU`EUE IPQPLK=IPQLLK ;ALSO USED FOR IPB PROCESS QUEUE IPQST=IPQLLK+1 ;STATUS IPQUC=IPQST+1 ;USE COUNT FOR ENTRIES ON THE LOCK QUEUE ; ; QUEUE ENTRY STATUS BITS - ; QSRCV=1B0 ; =1: SEND & GET RESPONSE, =0: JUST SEND QSSENDING=1B1 ;SEND OUTSTANDING - I.CE., CELL IS ON SEND QUEUE QSDONE=1B2 ;REQUEST COMPLETE (INCL. RECEPTION OF RESPONSE) QSTRY=1B3 ;RE-TRANSMIT - OTHER SIDE HAD NO CELL QSCRAP=1B4 ;OTHER SIDE TIMED OUT DURING SEND - ; INCOMING MESSAGE IS INVALID QSLKING=1B5 ;LOCK IN PROGRESS (IT'S NOT IN EFFECT YET) QSCLIDE=1B6 ;THERE HAS BEEN A LOCK COLLISION (I.E., ; BOTH SIDES TRIED TO LOCK AT THE SAME TIME). QSLKWTG=1B7 ;THE IPB PROCESS, ON BEHALF OF OTHER SIDE, ; IS WAITING FOR UNLOCK. QSOKCLIDE=1B8 ;DON'T RESOLVE LOCK COLLISIONS ; ; MISCELLANEOWUS ; BOTM=377 HI=400 TOP=BOTM*HI .MACRO NOT ;MAC DOESN'T DO COMPLEMENTS (-(^1)-1)% ; ; A QUEUE MESSAGE LOOKS LIKE THIS, IN BYTES. ; (EVEN BYTE DISPLACEMENTS REFER TO HIGH ORDER BYTE OF WORD) ; (NOTE: IF YOU CHANGE MESSAGE FORMAT, YOU WILL HAVE TO CHANGE ; STUFF MACRO, AND MAY HAVE TO CHANGE MAXML & GET MACRO. ; NOT ALL REFS TO TYPE & KEY BYTES ARE THROUGH QMTYPE & QMKEY, ; BUT MUST BE FOUND BY LOOKING UP IPQOMS & IPQIMS IN XREF ; AND FINDING INTERRUPT HANDLER'S NON-SYMBOLIC REFS). ; QMTYPE = 0 ;TYPE BYTE QMKEY = 1 ;RESPONSE KEY QMUNIT = 2 ;UNIT NUMBER QMDEV = 3 ;DEVICE CODE ;(BYTE 4 CURRENTLY UNUSED) QMHI = 5 ;HIGH ORDER OF DISK ADDRESS QMLO = 6 ;LOW ORDER OF DISK ADDRESS IS A WORD ; (BYTES 6 & 7) ; THE MESSAGE TYPE BYTE IS LAID OUT AS FOLLOWS: .DUSR RQ=1B8 ;A BIT THAT IDENTIFIES IT AS A REQUEST .DUSR RS=0B8 ; OR A RESPONSE, C=4+8. ;4 BITS FOR TYPE CODE, L=7+8. ;3 BITS FOR LENGTH OF MESSAGE. ;A REQUEST IS SENT TO THE IPB PROCESS IN THE DESTINATION ; PROCESSOR. A RESPONSE IS THE RETURN MES SAGE FROM THE ; IPB PROCESS IN THE SOURCE PROCESSOR TO THE SENDER ; OF THE LAST REQUEST IN THE DESTINATION PROCESSOR. ; THE INTERRUPT HANDLER REFERENCES THE REQUEST/RESPONSE BIT ; NON-SYMBOLICALLY (AS THE HIGH ORDER BIT OF 1ST MESSAGE WORD) ZLENMK = 7BL*HI ;LENGTH IS 3 BITS (INTERRUPT HANDLER ASSUMES ; LENGTH IS AT LOW END OF THE BYTE). ZTRYMK = 1B8 ;RETRY BIT SITS AT THE TOP OF THE KEY BYTE. ;THIS BIT APPEARS ONLY IN COMMUNICATIONS ACROSS THE ; BUS AND REFERS TO THE PREVIOUS TRANSMISSION. IT IS ; CLEARED & MOVED TO QSTRY BY THE INTERRUPT HANDLER. ZKEYMK = 1B8-1 ;MASK FOR KEY FIELD ; ; MESSAGE TYPE BYTES. ; ; CURRENTLY, EACH TYPE BYTE DIFFERS FROM ALL OTHERS IN AT LEAST ; TWO BITS, SO ANY SINGLE BIT ERROR IN THE TYPE BYTE WILL TURN ; A VALID CODE 7INTO AN INVALID ONE. NOTE ALSO THAT THE ALL-ZEROES ; AND ALL-ONES CODES ARE UNUSED (INVALID); THUS, HOPEFULLY, SOME ; OF THE MORE COMMON HARDWARE FAILURES ARE CAUGHT RATHER THAN ; ALLOWED TO CAUSE CONFUSION. NOTE: 0 & -1, WHILE NOT USED FOR ; THE FIRST WOR2D OF USER MESSAGES, ARE USED AT INTERRUPT ; HANDLER LEVEL. THE BUS IS SET TO ZERO ON RECEPTION OF EACH ; WORD OF A MESSAGE TO SIGNAL THE SENDER TO KEEP SENDING ; (AS OPPOSED TO THE CANCEL MESSAGES ZBOOT & ZPANIC). ; THE BUS IS SET TO -1 WHEN THE OTHER SIDEK GOES DOWN. ; ZLOCK = RQ+1BC+4BL ;GRAB REQUEST ZDVLOCK = RQ+3BC+3BL ;DEVICE LOCK REQUEST ZMPRMIT = RQ+4BC+4BL ;INTERLOCK A MAP LOCK SEQUENCE ZMPLOCK = RQ+2BC+4BL ;LOCK A MAP ZMPUNLOCK = RQ+7BC+4BL ;UNLOCK A MAP ZRLS = RS+7BC+1BL ;RESOURCE RELEASED, I.E., GO AHEAD, ; LOCK REQUEST SUCCESSFUL ZFOILED = RS+10BC+1BL ;UNSUCCESSFUL - LOCK ATTEMPT MUST BE ;RE-TRIED DUE TO POTENTIAL DEADLOCK CONDITION ;(OTHER SIDE HAD LOCK IN PROGRESS ON THE REQUESTED ;RESOURCE). NOT TO BE CONFUSED WITH BASE-LEVEL ;RE-TRANܟSMISSION CONDITION (FLAGGED BY QSTRY STATUS ;BIT) CAUSED BY NO CELL AVAILABLE TO RECEIVE ;A TRANSMISSION. ZGRANT = RS+4BC+1BL ;PERMISSION GRANTED (COLLISIONS ; TENTATIVELY RESOLVED) - YOU MUST NOW LOCK ZHEY = RS+2BC+1BL ;NULL MESSAGE SENT BY A REQUESTOR TO ; MAKE SURE THE OTHER SIDE IS STILL THERE. ZPASS = RS+1BC+1BL ;PASS UP THIS OPPORTUNITY TO SEND. ;I.E., PASS THE SEND PRIVILEDGE TO THE OTHER SIDE. ;(HE SENT TO ME & I HAVE NOTHING TO SEND, ;SO I SEND PASS, ALLOWING HIM TO SEND AGAIN.) ;USED ONLY FOR COMMUNICATION BETWEEN INTERRUPT HANDLERS. ZBOOT = RS+13BC+1BL ;INITIAL MESSAGE TO ANNOUNCE OUR EXISTENCE. ;HANDLED BY DESTINATION INTERRUPT HANDLER. ZPANIC = RS+15BC+1BL ;THE OTHER SIDE SAYS "GO TO HELL" ;GENERATED BY THE INTERRUPT HANDLER ON OTHER SmIDE, ; EXECUTED BY RECEIVING INTERRUPT HANDLER. ; ; MACRO FOR SYMBOLIC ACCESS TO MESSAGES ; ; GET DEST.ACC, BYTE.LABEL, I/O, CELL.ACC ; ; WHERE THE BYTE OF NAME 'BYTE.LABEL' (E.G., 'UNIT') OF THE ; INPUT ('I') OR OUTPUT ('O') MESSAGE IN THE CELL POINTE~D ; TO BY CELL.ACC IS LOADED INTO ACCUMULATOR DEST.ACC. ; IF 'BYTE.LABEL' IS 'LO', A WORD IS LOADED. ; NO ACCUMULATORS DESTROYED. ; NOTE - NOT ALL REFERENCES TO THE TYPE & KEY BYTES ARE ; SYMBOLIC THROUGH THIS MACRO (IN FACT NONE IN THE ; INTERRUPT HANDLER), BUT GO THROUGH IPQIMS OR IPQOMS. ; .MACRO GET ** .PUSH .NOMAC ** .NOMAC 1 ?WD=QM^2/2 ;WORD DISPLACEMENT ?BY=QM^2-(?WD*2) ;WHICH BYTE, 0=HI, 1=LO LDA ^1,IPQ^3MS+?WD,^4 ;PICK A WORD .DO ('^2'=='LO')!('^2'=='HI') ;IF LOOKING FOR A WORD, .ENDC Z ; YOU'VE GOT IT .IFN BSW!MBSW ;GOT A BIRD? .DO ?BY ;YES - CAN DO IT NICE WAY HXL 2,^1 ;LOW BYTE - SHIFT TO HIGH .ENDC HXR 2,^1 ;BYTE TO LO OF WORD & CLEAR HI .ENDC Z ;SKIP OUT STA ^4,RLOC ;FREE AN ACCUMULATOR .DO ?BY LDA ^4,LIT[BOTM] ;LO BYjTE - AND ^4,^1 ; MASK IT .ENDC S LDA ^4,LIT[TOP] ;HI BYTE - ANDS ^4,^1 ; MASK & SWAP [S] LDA ^4,RLOC ;GET ACC BACK [Z]** .NOMAC .POP % ; ; MACRO TO BUILD AN OUTPUT MESSAGE ; ; STUFF TYPE [,BQ/DB, 2/3 [,CA/FA]] ; ; WHERE TYPE IS THE NAME OF THE  TYPE (E.G., LOCK), ; 2/3 SPECIFIES WHERE TO GET THE MESSAGE PIECES, AND ; 'DB' MEANS THE PIECES ARE FROM A DCB, 'BQ' MEANS FROM ; MEANS FROM A BUFFER. 'CA' OR 'FA' MEAN STUFF ADDRESS, ; WHETHER CA OR FA (OTHERWISE JUST UNIT & DEV CODE). ; A POINTER TO THE jCELL TO BE STUFFED IS ASSUMED TO BE ; TO BE IN AC2; ALL OTHER AC'S ARE LOST (THAT INCLUDES 3). ; .MACRO STUFF ** .PUSH .NOMAC ** .NOMAC 1 LDA 0,LIT[Z^1*HI] ;TYPE STA 0,IPQOMS,2 ;STORE 1ST WORD (KEY = 0) .DO '^2'=='' ;IS THAT ALL? .ENDC Z .DO '^4'<0>'' LDA 0,^2^4,^3 ;WANT ADDRESS - PICK UP LO ORDER STA 0,IPQOMS+(QMLO/2),2 LDA 0,^2^41,^3 ;HI ORDER OF ADDR .ENDC S ADC 0,0 ;DEVICE LOCK: HI ORDER=-1 FOR CSRLKQ [S] STA 0,IPQOMS+(QMHI/2),2 ;HI ORDER TAKES A WORD LDA 0,^2UN,^3 ;PICK UP UNIT MOVS 0,0 ;MOVE TO HIGH BYTE LDA 3,^2DCT,^3 LDA 1,DCTCD,3 ;GET DEVICE CODE ADD 1,0 ;2ND WORD = UNIT & DEV CODE STA 0,IPQOMS+1,2 ;STORE [Z] ** .NOMAC .POP % DBFA=DCBFA ;MAKE CONSISTENT NAMES DBUN=DCBUN DBDCT=DCBDCT ** .IFE DEBSW ** .PUSH .NOLOC ** .NOLOC 1F .MACRO ZISZ % .MACRO SNAP % .MACRO CKDN % .MACRO CKDZ % .MACRO DISTMON % ** .NOLOC .POP ** .ENDC ENDEBMAC ; DEBUGGING MACROS .MACRO PNIC HALT ;*********************** % .MACRO ZISZ ;INC COUNT FOR MONITORING ;**ZISZ ^1 ;***MONITOR******** ** b.PUSH .NOMAC ** .NOMAC 1 .ENT ^1 ISZ ^1 JMP ^1+1 ISZ ^1-1 ;DOUBLE WORD COUNTS JMP ^1+1 PNIC ;OVERFLOW 0 ^1: 0 ** .NOMAC .POP % .MACRO SNAP ;^1=ACC TO DUMP, ^2=NAME ;**SNAP ^1,^2 ;***SNAP******** ** STA ^1,^2 ** .ENT ^2 ** JMP .+2 **^2: 111111GY % .MACRO CKDN SKPDN IPB ;***CHECK******* ** PNIC % .MACRO CKDZ SKPDZ IPB ;***CHECK******* ** PNIC % .MACRO DISTMON ;**DISTMON ^1,^2 ;***MONITOR MAP.DR & SYS.DR TRAFFIC******** ** .PUSH .NOMAC ** .NOMAC 1 .ENT ^1,^2 XJSR .DISTMON 0 ;MONITOR MAPI.DR TRAFFIC................ ^1: 0 0 ;MONITOR SYS.DR TRAFFIC............ ^2: 0 ** .NOCON 1 .DO .MCALL==0 JMP .DIOVER .DISTMON: .IFN BSW!MBSW PSH 3,3 .ENDC S STA 3,@CSP [S] LDA 3,BQDCB,2 MOVL# 3,3,SZC ;OVERLAY? JMP .DIRET ;YES, IGNORE ;NOTE. FOLLZOWING CODE DOESN'T WORK FOR ANY BUFFERS ; GOTTEN WITH FAKE DCB'S (E.G., BY BLKIO) LDA 0,DCBFA,3 LDA 3,DCBDR,3 LDA 1,DCBFA,3 SUB# 1,0,SNR ;DIRECTORY DCB OR COPY OF ONE? JMP .DISY ;YES LDA 3,SFLK,3 LDA 1,DCBFA,3 SUB# 1,0,SZR ;MAP DCB OR COPY? JMP .DIRET ;NO SUB 0,0,SKP .DISY: LDA 0,.2 .IFN BSW!MBSW POP 1,1 .ENDC S LDA 1,@CSP [S] MOV 1,3 ADD 0,3 ISZ 1,3 JMP .DIT ISZ 0,3 JMP .DIT PNIC .DIRET: .IFN BSW!MBSW POP 1,1 .ENDC S LDA 1,@CSP [S] .DIT: LDA 3,.4 ADD 1,3 .IFN BSW!MBSW PSH 3,3 LDA 3,CSP POPJ .ENDC S STA 3,@CSP LDA 3,CSP JMP @0,3 [S] .2:2 .4:4 LPOOL .DIOVER: .ENDC ** .NOMAC .POP % ; ; DEBUGGING/MONITORING WIDGETS. ; THESE LISTS NOT GUARANTEED TO BE ACCURATE OR COMPLETE! ; ; ; SNAPS. ; ALL ARE INITIALIZED TO 111111 SO YOU CAN TELL IF THEY'VE BEEN USED. ; ;GRAB & VARIOUS LOCK ROUTINES: ; YUCREL LAST CELL RELEASED BY UNLOCK (OR DVUNLOCK) ; YMLK0 DCB MPLCK WORD BEFORE LAST DMPLOCK STARTED (MUST BE -1) ; YMLK1 DCB MPLCK WORD AFTER LAST MPRMIT ; YMLS1 CELL STATUS AFTERd LAST MPRMIT ; YMLS2 CELL STATUS AFTER MPLOCK ; YMULK DCB MPLCK WORD AFTER LAST MPUNLOCK ; YFOIL LAST CELL/BUFFER LKSEND RECEIVED FOIL MESSAGE ; YTOUCHE LAST CELL/BUFFER LKSEND FOUND QSCLIDE SET ; YLOFOIL LOW ORDER OF DISK ADDRESS THAT HAD LAST COLLISION ; (EITHER FOIL OR TOUCHE IN LKSEND) ; YSCRAP CELL IN WHICH SEND FOUND CRAP BIT SET BEFORE SENDING ;IPB PROCESS: ; YPCES LAST CELL PROCESSED BY IPB PROCESS ; YPCREL LAST CELL RELEASED BY IPB PROCESS ; YPTYP TYPE BYTE OF LAST REQUEST RESPONDED TO BY ?;IPB PROCESS ; YPLO LOW OF DISK ADDRESS OF LAST RESPONSE ; YPRSP IPB PROCESS' LAST RESPONSE ; YWUSE LOW ORDER OF LAST DISK ADDR FOUND IN USE ; YWIO LOW ORDER OF LAST DISK ADDR WAITED FOR I/O ; YDESTROY LOW ORDER OF LAST DISK ADDR BUFFER DESTROYED ; YPAFOIL BUFFER IPB PROCESS LAST FOUND ANY COLLISION ; YPLOFOIL LOW ORDER OF DISK ADDRESS THAT HAD LAST COLLISION ; YPFOIL BUFFER - FOUND COLLISION & SET COLLISION BIT ; YAFOIL BUFFER - FOUND COLLISION BIT ALREADY SET ; YMILZ LAST DCB LOCKED BY OTHER SIDE ON MOPRMIT ; (I.E. MPLCK WORD WAS 0) ; YMILP MPLCK WORD (CELL POINTER) ON LAST MPRMIT ; THAT FOUND LOCK IN PROGRESS ; YMLUW MPLCK WORD ON LAST MPLOCK/MUNLOCK ; YMLUT 1 IF IT WAS LOCK, 0 IF UNLOCK ;INTERRUPT HANDLER: ; YIREQ LAST CELL ENQUEUED ON RECEIVE QUEUE ; YISDQ LAST CELL DEQUEUED FROM SEND QUEUE ; YIRDQ LAST CELL DEQUEUED FROM RECEIVE QUEUE ; YIWAKE LAST UNPEND KEY ; YRQ CELL OF LAST REQUEST, -1 IF NO CELLS FREE ; YIPEQ LAST CELL ENQUEUED TO IPB PROCESS ; YISET LAST CELL FOR WHICH A SEND WASg SET UP ; YILEN LENGTH OF LAST MESSAGE SET UP ; YISTASH LAST STASH, I.E., LAST WORD OF LAST RECEIVED MESSAGE ; YLSRCV LAST WORD RECEIVED (DIA) WHILE NOT SENDING ; YLSSEN LAST WORD SENT (DOA) OF LAST MULTI-WORD MESSAGE ; YLSIN RETURN A-REGISTER (DIA) BEFORRE YLSSEN'S DOA ; YLESEN LAST WORD SENT BY SENSETUP (=1ST WORD OF THAT MESSAGE) ; YLTSEN LAST WORD SENT BY TRYSENDQ ; YLPRCV ADDRESS WHERE YLSRCV WORD WENT TO ; YLPSEN ADDRESS WHERE YLSSEN WORD CAME FROM ; YLIRCV LOC 0 CONTENTS AT TIME OF YLSRCV ; YLISEN LOC 0 CONTENTS AT TIME OF YLSSEN ; YISBUSY CELL AT TIME IPSTART WENT TO START & FOUND BUS BUSY ; YTSBUSY CELL AT TIME TRYSENDQ " " " ; YTSDQ CELL LAST DEQUEUED FOR BEING DONE (SEE NTSDQ) ;TIMEOUT STUFF: ; YCLSQ HEAD OF SEND QUEUE AT TIME OF LAST CLRQUS CALL ; YCLRQ HEAD OF RECEIVE QUEUE, LAST CLRQUS CALL ; YCLPQ DITTO IPB PROCESS QUEUE ; YZS LAST CELL ON SEND QUEUE CLRQUS SET CRAP BIT ; YZR DITTO RECEIVE QUEUE ; YZP DITTO IPB PROCESS QUEUE ; YCLRET RETURN ADDRESS FOR LAST CLRQUS CALL ; YTKKRET RETURN ADDRESS & CARRY FOR LAST TAKEDOWN CALL ; YTKMP LAST MAP DCB UNLOCKED BY TAKEDOWN ; YTKCREL RECEIVING CELL QUEUED BY TAKEDOWN TO IPB PROCESS TO RELEASE IT ; YIPZQ LAST CELL RELEASED BY IPB PROCESS DUE TO CRAP BIT SET ; ; COUNTS (ZISZ'S). ALi^L ARE DOUBLE-WORDS. THE LABEL REFERS TO ; THE LOW ORDER WORD, WHICH IS PRECEDED BY HIGH ORDER. ; WHILE COUNTS CAN BE USEFUL IN DETERMINING RELATIVE ; FREQUENCIES OF USE OF CERTAIN PATHS, THEY HAVE TURNED OUT ; TO BE MOST IMPORTANT IN FIGURING OUT WHAT CAUSHED A BUG: ; IF SUCH AND SUCH A COUNT IS ZERO, THEN THAT CONDITION ; DIDN'T HAPPEN & THUS COULD NOT HAVE BEEN RESPONSIBLE. ; ;RELATED TO GRAB: ; NGR NUMBER OF CALLS TO DGRAB ; NSYGR COUNTS UNKNOWN FRACTION OF GRABS FOR DIRECTORY BLOCKS ; NMPGR DITTO FLOR MAP BLOCKS (SEE DISTMON) ; NGRLK # TIMES GRAB FINDS THE BLOCK ALREADY LOCKED ;IPB PROCESS: ; NZAP # TIMES REQUESTED BLOCK IS FOUND (WITH NO LOCK IN PROGRESS) ; NDESTROY # BUFFERS IPB PROCESS DESTROYED IDENTITY ; NSBLKW # TIMES LOCK WAITING SET - BUFF]ER ; NCBLKW # TIMES LOCK WAITING CLEARED - BUFFER ; (DOES NOT INCLUDE CLEARS DONE BY BUFFER RELEASE ROUTINES) ; NSYZAP HOPEFULLY THE # OF ZAPS OF DIRECTORY BLOCKS ; NMPZAP DITTO MAP BLOCKS ; NSYUSE # TIMES IPB PROCESS FOUND SYS.DR BLOCK IN USE ; NMPUSE DeITTO MAP BLOCK ; NSYSTALL # PENDS FOR I/O - DIRECTORY BLOCKS ; NMPSTALL DITTO MAP BLOCKS ; IWUSE # TIMES IPB PROCESS ENCOUNTERS BUFFER IN USE ; IWLK IPB PROCESS ENCOUNTERS POSTED LOCK ;RELATED TO LOCK ROUTINES: ; NLK # CALLS TO DLOCK ; NSHLK # TIMES .,LOCK IS SHARED (2 TASKS LOCK SAME BLOCK) ; NVLK # CALLS TO DVLOCK ; NMPLOCK # CALLS TO DMPLOCK ; ML2 # TIMES NEED BOTH MPRMIT & LOCK TO LOCK A MAP ; MLFOIL IPB PROCESS FINDS LOCK IN PROGRESS ; MAFOIL DITTO BUT IT'S ALREADY COLLIDED ; NSMLKW # TIMES LOCK  mWAITING SET - MAP ; NCMLKW # TIMES LOCK WAITING CLEARED - MAP ; (NOTE: ONLY COUNTS CLEARS BY WDCBK, DOES NOT ; INCLUDE CLEARS BY WDBLK OR DEBLK) ;RELATED ONLY TO IPB PROCESS: ; NRESCAN # TIMES IPB PROCESS RESCANS DUE TO PEND FOR I/O ; NPR # RESPONSES" SENT ; NPDQ # REQUEST CELLS DEQUEUED ;RELATED TO LKSEND: ; NFOIL # COLLISION RETRIES ; IFOIL # COLLISIONS IPB PROCESS DETECTED NOT ALREADY COLLIDED ; AFOIL DITTO & ALREADY COLLIDED ; ILFOIL COLLISIONS DETECTED DUE TO A LOCK ; ALFOIL DITTO & ALREADY WCOLLIDED ; NTHEY # TIMES TRY TO SEND HEY ; NHEY # TIMES HEY MESSAGE SENT ;RELATED TO SEND: ; NSCRAP # TIMES SEND CALLED WITH MESSAGE TO NON-EXISTENT MATE (CRAP BIT SET) ; NRETRY # RETRIES MADE ; ESQ # TIMES ENQUEUE MADE TO EMPTY SEND QUEUE ; MSQ # TIL,MES ENQUEUE MADE TO NON-EMPTY SEND QUEUE ; NOFFQ MUST WAIT FOR CELL TO COME OFF SEND QUEUE ; NSTAR # CALLS TO IPSTART ; STWB # TIMES IPSTART WAITS FOR BUSY TO GO AWAY ; STWTM # TIMES IPSTART TIMES OUT WAITING FOR BUSY ; STWMX LONGEST WAIT (MEASURED INe # TIMES THRU LOOP) ; STWTOT GLOBAL TOTAL # TIMES THRU WAIT LOOP ; NISBUSY DIDN'T START BECAUSE OTHER SIDE WAS SENDING ;RELATED TO IPTIMOUT: ; NTMOUT # TIMES IPTIMOUT CALLS TAKEDOWN ; NIALREDY DOESN'T CALL TAKEDOWN BECAUSE CELL SHOWS CRAP BIT ; NDOWN # LCALLS TO TAKEDOWN ; NSTCLR # TIMES IPSTART CALLS CLRQUS ; NTALREDY TAKEDOWN CALLED WHEN OTHER = 0 (ALREADY TAKEN DOWN) ; NZS # CELLS TAKEN DOWN FROM SEND QUEUE ; NZR DITTO RECEIVE QUEUE ; NZP DITTO IPB PROCESS QUEUE ; NTUNMP # MAP DCB'S UNLOCKED BY TAKE-DOWN ; NIPZQ # TIMES IPB PROCESS RELEASES CELL DUE TO CRAP BIT SET ;RELATED TO INTERRUPT HANDLER: ; NINT # INTERRUPTS HANDLED ; NS # SEND MESSAGES COMPLETED ; NR # RECEIVE MESSAGES COMPLETED ; NRQ # REQUESTS RECEIVED ; FLASH 1ST WORD FROM OTHER SIDE AFTER WE COMPLETE A SEND ; IS BEGINNING OF SEND BY HIM (RATHER THAN PASS) ; NOCEL WE COULD NOT RECEIVE BECAUSE OUT OF CELLS ; (& THUS TOLD OTHER SIDE TO RETRY) ; EIPQ # REQUESTS ENQUEUED TO EMPTY IPB PROCESS QUEUE ; MIPQ # REQUESTS ENQUEUED TO NON7-EMPTY IPB QUEUE ; NTSBUSY TRYSENDQ TRIES TO START A SEND & DOESN'T ; BECAUSE OTHER SIDE IS ALREADY SENDING ; NTSDQ CELL DEQUEUED WITHOUT SENDING BECAUSE IT'S ; ALREADY DONE (RECEIVED ITS RESPONSE) ; NBOOZAP OTHER SIDE BOOTS UP & WE DIDN'T KNOW HE WENT DOWN ; NCSBOOZAP OTHER SIDE CANCELS OUR SEND TO TELL US HE'S BOOTING UP ; NINBUSY SENSETUP FINDS BUSY TAKEN WHEN SENDING INITIAL MESSAGE (MUST BE 0 OR 1) ; NINBTM TIMEOUT WAITING FOR BUSY, INITIAL MESSAGE [ENDEBMAC]** ; ; DGRAB - SEND LOCK REQUEST FOR AC BLOCK TO OTHER SIDE, ; GIVEN IN AC2 A BUFFER WITH BQCA&CA1,BQUN,BQDCT SETUP ; USES THE BUFFER DATA AREA TO SEND THE REQUEST. ; RETURNS WHEN THE BLOCK CAN BE READ - OTHER SIDE ; EITHER HAS GIVEN IT UP OR IS DOWN. ; DGRAB: RSAVE ** .IFN DEBSW ;****************MONITORING***************** ** ZISZ NGR ** DISTMON NMPGR NSYGR ;*************************************************** ** .ENDC SUB 0,0 ;INITIALIZE "CELL" STATUS STA 0,IPQST,2 ; (IPB PROCESS MAY SET QSCLIDE) LDA 0,BQST,2 ;SET LOCK IN PROGRESS LDA 1,7LIT[QTLKING] ** .IFE DEBSW AND# 1,0,SNR ** .ENDC S AND# 1,0,SZR PNIC [S]** ADD 1,0 STA 0,BQST,2 JSR @.BSRLKQ ;SEARCH LOCK QUEUE JMP GRAB ;NOT LOCKED - MUST ASK OTHER SIDE ** ZISZ NGRLK JMP GDONE ;ALREADY LOCKED - IT'S OURS ;(WE ASSUME BSRLKQ ONLjY MATCHES BLOCK LOCKS, AND ; BLOCK LOCKS ARE ON THE QUEUE ONLY IF EFFECTIVE ; I.E., THERE IS NO LOCK-IN-PROGRESS TRANSITIONAL PERIOD.) GRAB: STUFF LOCK,BQ,2,CA ;SET UP THE MESSAGE JSR @.LKSEND ;SEND & GET A RESPONSE JMP GDONE ;OTHER SIDE GONE GDONE:5 LDA 0,BQST,2 LDA 1,NLKING ;LOCK NO LONGER IN PROGRESS AND 1,0 STA 0,BQST,2 RTRN ;CAN READ THE BLOCK NOW LPOOL NLKING: NOT[QTLKING] .BSRLKQ: BSRLKQ ; ; DLOCK - POST A LOCK ON A BLOCK TO HOLD UP FURTHER ; LOCK REQUESTS FROM THE OTHER SIDE, ; GIVEN IN AC2 A BUFFER WITH BQCA&CA1,BQUN,BQDCT SET UP. ; RETURNS UNLOCK KEY (=CELL ADDR) IN AC0. ; DLOCK: RSAVE ** ZISZ NLK JSR @.BSRLKQ ;SEE IF ALREADY ON LOCK QUEUE JMP PUTON  ;NO - PUT IT ON STA 0,OAC0,3 ; RETURN UNLOCK KEY MOV 0,2 ISZ IPQUC,2 ;YES -5 UP USE COUNT ** ZISZ NSHLK RTRN ;THAT'S ALL PUTON: JSR @.GETCELL STA 2,OAC0,3 ;RETURN UNLOCK KEY LDA 3,OAC2,3 ;BUFFER ADDRESS STUFF LOCK,BQ,3,CA ;STUFF THE CELL SUB 0,0 ;LOCK NOT IN PROGRESS, STA 0,IPQST,2 ; AMONG OTHER THINGS SUBZL 0,0 STA 0,IPQUC,2 ;INITIAL USE COUNT = 1 LDA 0,LOCKQ ;LOCK QUEUE POINTER STA 0,IPQLLK,2 ;MIGHT AS WELL PUT IT STA 2,LOCKQ ; AT THE BEGINNING RTRN LOCKQ: -1 ;POINTER TO LOCK QUEUE, INITIALLY EMPTY ; ; DUNLOCK - TAKE DOWN A DLOCK LOCK, ; GIVEN IN AC0 THE KEY (=CELL ADDR) RETURNED BY DLOCK. ; DUNLOCK:RSAVE XLDA 2,= @LOCKQ MOV 2,1 ;INITIALIZE PREVIOUS CELL POINTER LDA 2,0,2 ;POINT TO FIRST CELL JMP UNLIN UNLP: MOV 2,1 ;SAVE PREVIOUS CELL ADDR LDA 2,IPQLLK,2 ;NEXT UNLIN: COM# 2,2,SNR ;END? JMP UNF3]OUN ;NOT FOUND............ SUB# 0,2,SZR ;GOT IT? JMP UNLP ;NOT YET DSZ IPQUC,2 ;DOWN THE USE COUNT RTRN ;STILL IN USE VNLOK: LDA 0,IPQLLK,2 ;USED UP - DEQUEUE MOV 1,3 ;PREVIOUS CELL ON QUEUE MOVL# 3,3,SZC ;WAS IT FIRST ON QUEUE? STA 0,0,3 ;y;YES - CHANGE QUEUE POINTER MOVL# 3,3,SNC STA 0,IPQLLK,3 ;NO - REMOVE FROM MIDDLE OR END LDA 1,IPQST,2 LDA 3,LIT[QSLKW] LDA 0,UIPBQ ;UNPEND KEY = IPBQ, IN CASE... AND# 1,3,SZR ;LOCK WAITING? JSR @UUNPEND ;YES, UNPEND IPB PROCESS ** SNAP 2,YUCREL Xe!JSR CREL ;GIVE THE CELL AWAY RTRN ** .IFN DEBSW LPOOL ** .ENDC .GETCELL:GETCELL .LKSEND: LKSEND ; ; DVLOCK - SEND DEVICE LOCK REQUEST, ; GIVEN IN AC2 POINTER TO A DCB WITH DCBDCT,DCBUN SET UP. ; SKIPS IF OTHER SIDE HAS IT INIT'ED OR LOCKED. ; IT IS A}SSUMED RDOS WILL NOT ALLOW MORE THAN ONE PATH TO ; CONCURRENTLY PURSUE A FULL INIT IN THE SAME PROCESSOR. ; DEVICE LOCKS ARE NOT SHARED; THEY ARE ARE INDEPENDENT ; OF ALL BLOCK LOCKS & OTHER DEVICE LOCKS. ; DVLOCK: RSAVE ** ZISZ NVLK JSR @.GETCELL LDA 0P,LIT[QSLKING+QSOKCLIDE] STA 0,IPQST,2 ;LOCK IN PROGRESS, ; AND INGORE LOCK COLLISIONS LDA 3,OAC2,3 ;CALLER'S DCB STUFF DVLOCK,DB,3 ;STUFF THE OUTBOUND MESSAGE LDA 0,LOCKQ ;LOCK QUEUE POINTER STA 0,IPQLLK,2 ;MIGHT AS WELL PUT IT STA 2,LOCKQ ; e7AT THE BEGINNING JSR @.LKSEND ;SEND LOCK REQUEST JMP VDONE ;OTHER SIDE GONE, WE CAN HAVE IT LDA 0,IPQST,2 LDA 1,LIT[QSCLIDE] AND# 1,0,SZR ;LOCK COLLISION? JMP VTOUCHE ;YES, GIVE ERROR GET 0,TYPE,I,2 LDA 1,LIT[ZFOILED] SUB# 1,0,SZR ;LOCK COLLISION ON OTHER SIDE? JMP VDONE ;NO, DO SUCCESSFUL COMPLETION VTOUCHE:ISZ ORTN,3 ;YES, GIVE CALLER ERROR LDA 2,OAC2,3 ;PASS DCB JSR DVUNLOCK ;UNDO THE MESS WE GOT IN RTRN VDONE: LDA 0,IPQST,2 LDA 1,NQLKING AND 1,0 STA 0,IPQST,2 ;LOCK COMPLETE RT}RN ; ; DVUNLOCK - DEVICE UNLOCK, ; GIVEN IN AC2 PTR TO A DCB WITH DCBDC,DCBUN SET UP ; DVUNLOCK: RSAVE XJSR DSRLKQ ;SEARCH LOCK QUEUE JMP UNFOUN ;NOT FOUND?? MOV 0,2 ;POINTER TO CELL JMP VNLOK ;GO TAKE IT DOWN UNFOUN: JSR @.PNIC PNIPB [ LPOOL NQLKING:NOT[QSLKING] UIPBQ: IPBQ UUNPEND: UNPEND ; ; DMPLOCK - LOCK A MAP ON BOTH SIDES, ; GIVEN AC1 PTR TO DCB WITH DCBDC,DCBUN,DCBFA&FA1 SET UP, ; AC2 POINTER TO A CELL (CONTENTS OF WHICH ARE DESTROYED). ; MUST BE CALLED WHEN THE MAP IS UNLOCKED ON THIS SIDE. ; DMPLOCK: RSAVE ** ZISZ NMPLOCK MOV 1,3 ** .IFN DEBSW LDA 0,MPLCK,3 ** SNAP 0,YMLK0 ** .ENDC STA 2,MPLCK,3 ;CELL POINTER IN DCB MAP LOCK ; WORD SIGNALS LOCK IN PROGRESS LDA 0,LIT[QSLKING] STA 0,IPQST,2 ;STATUS STUFF MPRMIT,DB,3,FA ;GET PERMISSION TO LOCK THE MAP, JSR LKSEND ; RESOLVING CONFLICTS IF BOTH NOP ; SIDES TRY AT SAME TIME LDA 3,OAC1,3 ;DCB POINTER ** .IFN DEBSW LDA 0,MPLCK,3 MOVL# 0,0,SZC PNIC ** SNAP 0,YMLK1 LDA 0,IPQST,2 ** SNAP 0,YMLS1 ** .ENDC ADC 0,0 ;GOT IT - LOCK IT ON THIS SIDE STA 0,MPLCK,3 GET 0,TYPE,I,2 LDA 1,LIT[ZRLS] SUB# 1,0,SNR ;WAS HE ABLE TO LOCK IT? RTRN ;YES STUFF MPLOCK,DB,3,FA ;NO, GO LOCK IT ON OTHER SIDE ** ZISZ ML2 JSR LKSEND NOP ** .IFN DEBSW LDA 0,IPQST,2 ** SNAP 0,YMLS2 ** .ENDC RTRN ** .IFN DEBSW LPOOL ** .ENDC ; ; DMPUNLOCK - UNLOCK A MAP ON THE OTHER SIDE, ; GIVEN AC0 PTR TO DCB WITH DCBDC,DCBUN,DCBFA&FA1 SET UP, ; AC2 POINTER TO CELL (CONTENTS OF WHICH ARE DESTROYED). ; CALLER MUST NOT UNLOCK THIS SIDE TILL OTHER SIDE IS ; UNLOCKED (I.E., TILL THIS ROUTINE RETURNS). ; DMPUNLOCK: RSAVE MOV 0,3 STUFF MPUNLOCK,DB,3,FA ;TELL OTHER SIDE SUB 0,0 ; HE CAN UNLOCK STA 0,IPQST,2 JSR LKSEND NOP LDA 2,OAC0,3 ;GET DCB ADDRESS ** .IFN DEBSW LDA 0,MPLCK,2 ** SNAP 0,YMULK ** .ENDC XLDA 1,= STLKW LDA 0,DCBST,2 AND# 1,0,SNR ;LOCK WAITING? RTRN ** ZISZ NCMLKW LDA 0,UIPBQ ;YES, WAKE UP IPB PROCESS JSR @UUNPEND RTRN ;THAT'S ALL ;(DON'T NEED TO CLEAR LOCK WAITING SINCE CELL WILL BE GIVEN ; AWAY. EVEN IF IT I[qSN'T, THE WORST THAT CAN HAPPEN IS THE ; IPB PROCESS WILL SCAN ITS REQUESTS UNNECESSARILY.) LPOOL ; ; IPINIT - INITIALIZE IPB WORLD. ; MUST BE CALLED BEFORE INTERRUPTS ARE TURNED ON BY INIT - ; OR, MORE PRECISELY, THIS ROUTINE MUST BE CALLED BEFORE ; THE FIRST IPB INTERRUPT IS TAKEN. (THE BOOT MESSAGE MUST ; BE THE FIRST WE SEND. IF THE OTHER SIDE INTERRUPTS US ; FIRST, OUR RESPONSE WILL VIOLATE THIS CONDITION AND WE ; WILL PANIC.) INTERRUPTS ARE TURNED ON (BY SEND). ; IPINIT: RSAVE ** .IFN DEBSW $ SKPBZ CPU ;INTERRUPTS BETTER NOT BE ON ** PNIC ** .ENDC XLDA 2,= CELIP ;GET A CELL, LEAVING INTERRUPTS SUB 0,0 ; OFF STA 0,IPQST,2 ;MUST INITIALIZE STATUS STUFF BOOT ;MESSAGE TO ANNOUNCE OUR EXISTENCE XJSR SEND STUFF HEY ;SET UP FOR HEY MESSAGE,S RTRN ;OUR OWN CELL PRE-ALLOCATED, TO GUARANTEE CELIP: .BLK CLN ; NOT TURNING INTERRUPTS ON WHILE GETTING IT. ; ALSO USED BY LKSEND FOR SENDING HEY MESSAGES. LPOOL ; ; ROUTINE TO SEND A REQUEST & GET A RESPONSE, ; ; GIVEN IN AC2 A CELL WITH THE OUT-MESSAGE STUFFED ; AND STATUS INITIALIZED. RETURNS IMMEDIATELY FOLLOWING ; CALL IF OTHER SIDE ISN'T COMMUNICATIVE, ELSE SKIPS. ; UPON RETURN, CELL IS KNOWN TO BE OFF ACTIVE I/O QUEUES. ; RESOLVES LOCK COLLISIONS UNLESS QSOKCLIDE IS SET. ; LKSEND: Rz SAVE XLDA 0,OTHER ;KNOCK, KNOCK MOV# 0,0,SNR ;YOU THERE? RTRN ;I GUESS NOT LDA 0,RKEY ;ALLOCATE RESPONSE KEY ALOKEY: INC 0,0 XLDA 1,= ZKEYMK ;WRAP AROUND AND 1,0,SNR JMP ALOKEY XJSR KEYFIND ;MUST GUARANTEE UNIQUENESS SKIP JMP ALOKEY ;I3N USE, TRY AGAIN STA 0,RKEY LDA 2,OAC2,3 ;RESTORE CALLER'S CELL LDA 1,IPQOMS,2 ; (KEYFIND MAY HAVE BLOWN) ADD 1,0 ;PUT KEY IN FIRST WORD OF MESSAGE STA 0,IPQOMS,2 ;NON-SYMBOLIC REFERENCE TO KEY BYTE LAGAIN: LDA 0,IPQST,2 LDA 1,LKCLRS AND 1,0 ;CAN'T ALREADY BE DONE LDA 1,NQSRCV ;WE WANT A RESPONSE ADC 1,0 ;SET THE BIT STA 0,IPQST,2 ** .IFE DEBSW LHEY: JSR SEND ** .ENDC S LHEY: XJSR SEND [S]** LTES: LDA 2,OAC2,3 ;LOOK AT CALLER'S CELL XLDA 1,= QSDONE!QSCRAP INTDS ;MUST TEST DONE & PEND IND'IVISIBLY LDA 0,IPQST,2 ;LET'S SEE WHAT HAPPENED AND# 1,0,SZR ;DID HE RESPOND OR CRASH? JMP LDONE ;YES LPEND: LDA 1,OAC2,3 ;ALWAYS WAIT ON CALLER'S CELL LDA 0,.RSPTC ;RESPONSE TIME OUT CONSTANT ** .IFE DEBSW JSR @.PEND ** .ENDC S XJSR PEND [S]** SJ,KIP ;NO RESPONSE - TRY AGAIN JMP LTES ;UNPENDED - TEST STATE ** ZISZ NTHEY XLDA 2,= CELIP ;NO RESPONSE - SEND HEY MESSAGE XLDA 1,= QSSENDING ; TO MAKE SURE OTHER SIDE IS INTDS ; STILL THERE LDA 0,IPQST,2 AND 1,0,SZR ;ALREADY SENDING IT? JMP L~PEND ;YES, GO BACK TO SLEEP INTEN ** ZISZ NHEY STA 0,IPQST,2 ;CLEAR QSCRAP JMP LHEY ;GO SEND HEY MESSAGE ** .IFN DEBSW LPOOL ** .ENDC ** .IFE DEBSW ** .ENDC LDONE: INTEN ;CELL IS OFF QUEUES NOW ** .IFN DEBSW LDA 0,IPQOMS,2 XJSR KEYFIND ;MAKE SURE SKIP PNIC LDA 2,OAC2,3 ;RESTORE ACCS LDA 0,IPQST,2 ** .ENDC LDA 1,LIT[QSCRAP] AND# 1,0,SZR ;OTHER SIDE CRAPPED OUT? RTRN ;YES - DONE LDA 1,LIT[QSOKCLIDE] AND# 1,0,SZR ;HANDLE LOCK COLLISIONS? JMP LRTRN ;NO GET 1,TYPE,I,2 ;CHECK FOR L$OCK COLLISIONS XLDA 3,= ZFOILED SUB 1,3 ;DID WE GET TURNED BACK FOR XLDA 1,= QSCLIDE ; MEDDLING WHILE OTHER SIDE MOV# 3,3,SNR ; WAS LOCKING (FOIL) ? JMP FOILED ;YES, COOL OFF THEN CHARGE BACK IN THERE LDA 3,CSP ;OTHER SIDE MEDDLE WHILE WE AND# 1Q,0,SZR ; WERE LOCKING (QSCLIDE) ? JMP TOUCHE ;YES, RECOVER & RETRY LRTRN: ISZ ORTN,3 ;NO, OTHER RETURN ** .IFE DEBSW RTRN ** .ENDC S GET 1,TYPE,I,2 ;VALIDATE THE MESSAGE JSR VALLP ;POINTER TO TABLE IN AC3 ZRLS ZGRANT ZFOIL ;FOIL IS VALID IF LQSOKCLIDE IS SET -1 ;TERMINATE TABLE VALLP: LDA 0,0,3 INC 3,3 SUB# 1,0,SNR ;IS WHAT WE GOT IN THE TABLE? RTRN ;YES, GOOD RETURN COM# 0,0,SZR ;END OF TABLE? JMP VALLP ;NO JSR @.PNIC ;?? YES? PNIPB [S]** .RSPTC: RSPTC RKEY: 0 LKCLRS: NOT[Q?SDONE+QSRCV] NQSRCV: NOT[QSRCV] ** .IFN DEBSW LPOOL ** .ENDC ** .IFE DEBSW ** .ENDC FOILED: AND# 1,0,SNR ;SET COLLISION BIT ADD 1,0 ; (EFFECTIVELY CANCELS LOCK STA 0,IPQST,2 ; IN PROGRESS AS FAR AS ; IPB PROCESS IS CONCERNED) ** ZISZ NFOIL ** SpNAP 2,YFOIL LDA 0,0 ;PICK A RANDOM NUMBER MOVR 0,0 SUBCL 0,0 ;MAKE THAT A BIT INC 0,0 ;OFFSET IT, MUST BE POSITIVE INTDS ;INTRODUCE SOME SKEW BETWEEN JSR @.PEND ; THE SIDES - OPEN A WINDOW TO NOP ; GIVE THE OTHER SIDE A CHANCE LDA 0,IPQST,2 LDA 1,LIT[QSCLIDE] ** .IFN DEBSW JMP TCH1 TOUCHE: ** ZISZ NTOUCHE ** SNAP 2,YTOUCHE TCH1: SUB 1,0 ;CLEAR COLLISION BIT ** .ENDC S TOUCHE: SUB 1,0 ;CLEAR COLLISION BIT [S]** STA 0,IPQST,2 ** .IFN DEBSW GET 0,LO,O,2 ** SNAP 0,YLOFOIL ** .ENDC XJMP L AGAIN ;REJOIN THE MELEE .PEND: PEND LPOOL ; ; BASE LEVEL ENQUEUE ROUTINE ; ; GIVEN CELL IN AC2 WITH EVERYTHING SET UP. ; PUTS CELL ON SEND QUEUE, HANDLES RETRIES & TIMEOUTS. ; RETURNS WHEN CELL IS OFF THE SEND QUEUE. ; SVMSK=TMP SEND: RSAVE 1 ** .mIFN DEBSW JMP IN AGAIN: ** ZISZ NRETRY IN: ** .ENDC S AGAIN: [S]** ** .IFN DEBSW LDA 0,IPQST,2 LDA 1,LIT[QSSENDING] AND# 1,0,SZR PNIC ** .ENDC LDA 1,NIPBMK INTDS LDA 0,CMSK STA 0,SVMSK,3 ;SAVE INTERRUPT MASK AND 1,0 ADC 1,0 ;SET IPB & IVT INHIB%CIT BIT STA 0,CMSK ;DISABLE IPB INTERRUPTS MSKO 0 ;(IPSTART ISN'T ALWAYS QUICK) INTEN ;LET NON-IPB INTERRUPTS IN LDA 0,IPQST,2 XLDA 1,= QSCRAP AND# 1,0,SZR ;SHOULD WE TRY? ** .IFE DEBSW  JMP SMPEN ;NO ** .ENDC S JMP SZMPEN [S]** LDA 1,LIT[QSKSENDING] AND# 1,0,SNR ADD 1,0 ;SHOW AS ON SEND QUEUE LDA 1,NQSTRY AND 1,0 ;CLEAR RETRY BIT STA 0,IPQST,2 XLDA 3,= IPBDC LDA 0,IPBSQ,3 ;IPB SEND QUEUE POINTER COM# 0,0,SZR ;QUEUE EMPTY? JMP S.ENQU ;NO STA 0,IPQSLK,2 STA 2,IPBSQ,3 ** ZISZ ESQ  v JSR @DCTST,3 ;START UP INTERRUPT WORLD JMP SMPEN ;(DEQUEUES & SETS QSCRAP ; IF OTHER SIDE NOT THERE) ** .IFN DEBSW LPOOL ** .ENDC S.ENQU: MOV 0,3 LDA 0,IPQSLK,3 COM# 0,0,SZR ;FIND END OF QUEUE JMP S.ENQU STA 0,IPQSLK,2 STA 2,IPQSLK,3 ** ZISZ MSQ SMPEN: LDA 3,CSP LDA 3,SVMSK,3 INTDS STA 3,CMSK ;RESTORE PREVIOUS MASK MSKO 3 SENPEN: LDA 0,IPQST,2 LDA 1,LIT[QSCRAP] AND# 1,0,SZR ;OTHER SIDE GONE? JMP SIRET ;YUP, MIGHT AS WELL NOT WAIT FOR HIM MOV 2,1 ;PEND KEY = CELL LDA 0,.SENTC ;SEND TIMEOUT CONSTANT JSR @.PEND ;WAIT FOR SOMETHING TO HAPPEN JMP TIMOUT ; MAKE SURE CELL IS OFF SEND QUEUE ; (WE COULD HAVE BEEN UNPENDED BY A RECEIVE COMING HOME) LDA 1,LIT[QSSENDING] INTDS LDA 0,IPQST,2 AND# 1,0,SZR ;STILL SENDING? ** .IFE DEBSW JMP SENPEN ;YES, WAIT SOME MORE ** .ENDC S JMP SZOFFQ [S]** INTEN ;NO, IT'S OFF THE QUEUE LDA 1,LIT[QSTRY] AND# 1,0,SZR ;DID HE ASK US TO TRY AGAIN? JMP AGAIN ;YES, SEND AGAIN RTRN ;NO, ALL DONE ** .IFN DEBSW SZOFFQ: ** ZISZ NOFFQ JMP SENNPEN SZMPEN: ** SNAP 2,YSCRAP ** ZISZ NSCRAP JMP SMPEN ** .ENDC TIMOUT: XJSR IPTIMOUT RTRN SIRET: INTEN RTRN .SENTC: SENTC NIPBMK: NOT[IPMKB] NQSTRY: NOT[QSTRY] LPOOL ; ROUTINES TO SEARCH THE LOCK QUEUE TO SEE IF SOMETHING ; IS LOCKED, GIVEN A DdESCRIPTION OF THAT SOMETHING. ; RETURN FOLLOWING CALL IF NO MATCH FOUND, ELSE SKIP WITH ; AC0 POINTING TO THE MATCHING CELL, AC1 POINTING TO MATCH ; CELL'S PREDECESSOR ON THE QUEUE (SIGN BIT SET & ; POINTING TO LOCKQ IF MATCH CELL IS FIRST ON QUEUE). ; ; BSRLKQ: AC2 POINTS TO A BUFFER WITH BQCA&CA1, BQUN, & BQDCT ; SET UP. MATCH A BLOCK LOCK OF SAME DESCRIPTION. ; DSRLKQ: AC2 POINTS TO A DCB WITH DCBUN,DCBDC SET UP; ; MATCH A DEVICE LOCK WITH THE SAME UNIT & DEV CODE. ; CSRLKQ: AC2 POINTS TO CELL WITH EITHER A LOCK OR DEVICE LOCK ; REQUEST IN THE INPUT MESSAGE. IF EITHER THE CELL OR THE ; QUEUE HAS A DEVICE LOCK, MATCH ANY RELEVANT BLOCK LOCK. ; INDEV=TMP INUN=INDEV+1 INHI=INUN+1 INLO=INHI+1 LASTC=INLO+1 NXMCH=LASTC+1 ;1=EXACT MATCH, 0=MATCH RELEVA NT DEV LOCKS SLQTEMS=NXMCH-TMP+1 BSRLKQ: RSAVE SLQTEMS ;ENTRY WITH BUFFER LDA 0,BQCA,2 ;SHOVE THE BUFFER INFO STA 0,INLO,3 ; ONTO THE STACK LDA 0,BQCA1,2 STA 0,INHI,3 LDA 0,BQUN,2 STA 0,INUN,3 LDA 2,BQDCT,2 LDA 0,DCTCD,2 STA 0,INDEV,3 JMP XSRL6KQ DSRLKQ: RSAVE SLQTEMS ;ENTRY WITH DCB - DEVICE LOCK LDA 0,DCBUN,2 STA 0,INUN,3 ;MOVE TO STACK LDA 2,DCBDC,2 LDA 0,DCTCD,2 STA 0,INDEV,3 ADC 0,0 ;FLAG AS DEVICE LOCK STA 0,INHI,3 XSRLKQ: SUBZL 0,0 ;EXACT MATCH ONLY SRLKQ: STA 0,NXMCH,3 ;SAVE MjATCH FLAG XLDA 2,= @LOCKQ STA 2,LASTC,3 ;INITIAL PREVIOUS CELL LDA 2,0,2 ;FIRST CELL JMP LQIN ;JUMP IN THE BEGINNING LQFI: ADC 0,0 LDA 1,INHI,3 LQF: DSZ NXMCH,3 ;EXACT MATCHING? JMP LQFOUND ;NO, THIS IS GOOD ENOUGH ISZ NXMCH,3 ;RESTORE FLAG SWUB# 1,0,SNR ;NOW COMPARE - EXACTLY EQUAL? JMP LQFOUND ;YES - GOT IT LQSCAN: STA 2,LASTC,3 ;CURRENT BECOMES LAST CELL LDA 2,IPQLLK,2 ;NEXT BECOMES CURRENT LQIN: COM# 2,2,SNR ;END OF QUEUE? RTRN ;YES - NOT FOUND GET 0,UNIT,O,2 LDA 1,INUN,3 SUB# 1, 0,SZR ;UNIT NUMBERS JMP LQSCAN GET 0,DEV,O,2 ; & DEVICE CODES LDA 1,INDEV,3 SUB# 1,0,SZR ; MUST ALWAYS MATCH JMP LQSCAN GET 0,HI,O,2 LDA 1,LIT[BOTM] SUB# 0,1,SNR ;QUEUE DEVICE LOCK? JMP LQFI ;YES - SKIP OUT LDA 1,INHI,3 COM# 1,1,SNR ;IS INPpUT A DEVICE LOCK? JMP LQF ;YES - SKIP OUT SUB# 1,0,SZR ;NO - HIGH ORDER MATCH? JMP LQSCAN ;NO GET 0,LO,O,2 LDA 1,INLO,3 ;LOW ORDER? SUB# 1,0,SZR JMP LQSCAN ;NO LQFOUND:STA 2,OAC0,3 ;YES - RETURN MATCHING LOCK CELL LDA 0,LASTC,3 STA 0,OAC1,3 ;R+9ETURN PREDECESSOR ISZ ORTN,3 ;OTHER RETURN RTRN CSRLKQ: RSAVE SLQTEMS ;ENTRY WITH CELL GET 0,DEV,I,2 ;UNPACK ONTO STACK STA 0,INDEV,3 GET 0,UNIT,I,2 STA 0,INUN,3 GET 0,HI,I,2 LDA 1,LIT[BOTM] SUB# 0,1,SNR ;DEVICE LOCK? ADC 0,0 ;YES, MAKE TESrT EASIER ;(WE ASSUME DEV LOCK MESSAGES ; INCLUDE -1 FOR HIGH ORDER...) STA 0,INHI,3 GET 0,LO,I,2 STA 0,INLO,3 SUB 0,0 ;DEVICE LOCKS MATCH BLOCK LOCKS JMP SRLKQ LPOOL ; ; IPB PROCESS ; ; SERVICES REQUESTS FROM THE OTHER SIDE. SENDS RLS MESSAGE ; WHEN THE RESOURCE IS FREED, OR SENDS FOIL MESSAGE IF THE ; REQUEST CANNOT BE HONORED (E.G., THERE IS A LOCK COLLISION). ; HANDLES ALL OUTSTANDING REQUESTS IN PARALLEL. ; NOTE THAT THERE IS NO TIME LIMIT FOR COMPLETION OF A REQUEST - ; CREATE CONTIGcUOUS LOCKS THE DIRECTORY BLOCK FOR THE DURATION ; OF THE INITIALIZATION OF THE FILE; FOR A 64K BLOCK FILE, ; THAT CAN BE 10-20 MINUTES. ; NOTE: VARIABLE STALLED MUST BE BUMPED EVERY TIME IPB PROCESS ; DOES ANYTHING THAT HAS A CHANCE OF PENDING, OR ELSE IT MAY ; LOSE NOTIFICATION OF AN EVENT, WHICH COULD CAUSE EVERYTHING ; TO COME TO A GRINDING HALT, WAITING FOR IPB PROCESS RESPONSE. ; RQDEV = TMP RQUNIT = RQDEV+1 RQHI = RQUNIT+1 RQLO = RQHI+1 JMPT = RQLO+1 LASDCB = JMPT ;FOR FINDMP DVSTLL = JMPT IPPREV = JMPT+1 IPCUR = IPPREV+1 ;VARIABLE STALLED IS DIRTY BECAUSE IPZAP NEEDS TO REFER... IPTEMS=IPCUR+1 ; ; DEFINE THE STACK FOR IPB PROCESS ; ** .NOCON 0 NFRM=5 ;NUMBER FRAMES IPB PROCESS NEEDS ;(TOP LEVEL CALLS IPZAP CALLS WAIT CALLS PEND) ,;NOTE: QUENT GOES AS DEEP AS WAIT... IPSTK = .+1 .IFN BSW!MBSW  SZ=6*NFRM+IPTEMS+10+10 ;EACH FRAME HAS 4 AC'S & PC & VRTRN ;LET WAIT TAKE 10; EXTRAS - 10 .+SZ+1 ;STACK LIMIT .BLK SZ+10 ;EXTRAS FOR OVERFLOW .ENDC .IFE BSW!MBSW ** .PUSH .NOLOC  .DO NFRM ** .NOLOC 1 .+1 .BLK SLGT-1 .ENDC 1B0+IPSTK ** .NOLOC .POP .ENDC ** .NOCON 1 ; ; IPB PROCESS PROGRAM TABLE ; IPBQ: .BLK QSTKC-QSDCP .IPSTK ;OUR OWN STACK 0 ;DCT TSACT ;INITIAL STATUS - READY 0 ;QALNK, MUST BE 0 FOR SENQ 0 ;PRI tIPPC ;INITIAL STARTING ADDR .LOC IPBQ+QCURR -1 ;SYSTEM CALL REQUEST LINKS .LOC IPBQ+QLNK ; MUST BE -1 -1 ; FOR ABORT TO WORK... .LOC IPBQ+QSTK IPSTK ;STACK ADDRESS .LOC IPBQ+SQLN ;THE REST PQLNK = .-IPBQ ;REQUEST QUEUE LINK -1 .IPSTK: IPSTK IPPC: XLDA 2,= IPBQ ;FIRST TIME ONLY - LDA 3,QSTK,2 STA 3,CSP ;SCHEDULER DOESN'T GIVE STACK ** .NOCON 0 .IFN BSW!MBSW XLDA 0,= IPTEMS ADD 3,0 ;ALLOCATE OUR STACK TEMPORARIES STA 0,SP .ENDC ** .NOCON 1 XLDA 0,= TACT STA 0,PPC,2 ;PATCH If T UP BY HAND JMP IPPIN LPOOL ; USE CURRENT CELL TO SEND RELEASE TO OTHER SIDE IPRLS: LDA 2,IPCUR,3 STUFF RLS IPSEN: SUB 0,0 STA 0,IPQST,2 GET 0,KEY,I,2 ;TRANSFER INPUT KEY LDA 1,IPQOMS,2 ; TO OUTPUT MESSAGE ADD 1,0 STA 0,IPQOMS,2 ;NON-SYMBOLIC a/REF TO KEY BYTE ** .IFN DEBSW LDA 0,IPQOMS,2 ** SNAP 0,YPRSP GET 0,LO,I,2 ** SNAP 0,YPLO GET 0,TYPE,I,2 ** SNAP 0,YPTYP ** .ENDC XJSR SEND ** .IFE DEBSW ISZ STALLED ;GOT PENDED - DON'T FORGET IT! ** .ENDC S XISZ STALLED ;GOT PENDED - DON'T FORGET IVT! [S]** ** ZISZ NPR ; DEQUEUE THE REQUEST CELL ** .IFE DEBSW IPDEQ: ** .ENDC S JMP IPD0 IPDEQ: SNAP 2,YIPZQ ** ZISZ NIPZQ IPD0: [S]** ** ZISZ NPDQ LDA 2,IPCUR,3 LDA 0,IPPREV,3 STA 0,IPCUR,3 ;SET PREV AS CUR SO IPNEXT WORKS MOV 0,3 INTDS LDA 0,IPQPLK,2 MOVL# 3,3,SZC ;FIRST OF QUEUE? STA 0,0,3 ;YES, CHANGE PQLNK POINTER MOVL# 3,3,SNC STA 0,IPQPLK,3 ;NO, CHANGE LINK IN PREVIOUS CELL INTEN ** SNAP 2,YPCREL XJSR CREL ;RELEASE CELL XISZ NFREE ;ANOTHER AVAILABLE FOR MORE ; PROCESS NEXT REQUEST IN QUEUE IPNEXT: LDA 2,IPCUR,3 ;CURRENT CELL STA 2,IPPREV,3 ; BECOMES PREVIOUS INTDS ;INTERRUPT HANDLER CAN ADD REQUESTS MOVL# 2,2,SZC LDA 0,0,2 ;IN CASE WE DEQUEUED FIRST CELL MOVL# 2,2,SNC LDA 0,IPQPLK,2 ;POINTER TO NEXT CELL MOV 0,2 CUOM# 2,2,SZR ;IS THERE ANOTHER REQUEST? JMP IPDO ;YES, GO DO IT DSZ STALLED ;SHOULD WE RESCAN? JMP IIPSCAN ;YES IPSNORE: XXLDA 2,= TRESP LDA 0,0,2 SNE 0,2 ;IS TRESP REALLY THERE? JSR 1,2 ;YES, GO DO IT IPND: LDA 1,CQ ;DON'T RESCAN, WAIT FOR KSOMETHING SUBZL 0,0 ;WAIT 1 SEC, PLEASE XJSR PEND SKIP ;IGNORE TIMEOUT ** .IFE DEBSW ;(WE DON'T JUMP AROUND THE FOLLOWING INTEN ONLY ; BECAUSE IT'S NOT WORTH THE EXTRA WORD) ** .ENDC S JMP IPSCAN LPOOL [S]** IIPSCAN: INTEN ** ZISZ NRESCAN IPPIɂN: IPSCAN: SUBZL 0,0 ;SWITCH THAT TELLS IF WE MADE IT STA 0,STALLED ; WITHOUT A HITCH (PEND) XLDA 2,= @IPBQ+PQLNK STA 2,IPPREV,3 INTDS LDA 2,0,2 COM# 2,2,SNR ;QUEUE EMPTY? JMP IPSNORE ;YES, NOTHING TO DO IPDO: INTEN STA 2,IPCUR,3 ; SEE IF REQldUEST IS REAL. ;(NOTE: IF OTHER SIDE GOES DOWN BETWEEN NOW AND THE TIME WE ; TRY TO SEND A MESSAGE, SEND WILL CATCH THE CRAP BIT AND ; RETURN WITHOUT SENDING. WE TEST CRAP NOW TO AVOID TYING UP ; THE CELL FOR A POSSIBLY LONG TIME, AND ALSO BECAUSE TAKEDOWN ; CAN'T CALL CREL, SO IT QUEUES THE CELL (CONTAINING GARBAGE) ; TO THE IPB PROCESS IN ORDER TO GET IT RELEASED...) XLDA 1,= QSCRAP LDA 0,IPQST,2 ;STRAGGLER FROM NO-LONGER- AND# 1,0,SZR ; EXISTING SIDE? JMP IPDEQ ;YES, THROW IT OUT ** SNAP 2,YPCES ; SEE IF REQUEST IS COVERED BY A LOCK. ;(CURRENTLY, NO ONE LOCKS MAP BLOCKS, SO ; MAP LOCK/UNLOCK REQUESTS SHOULD FALL THROUGH) XJSR CSRLKQ ;SEARCH LOCK QUEUE JMP IPGO ;NOT FOUND - DECODE REQUEST MOV 0,2 ;FOUND MATCHING CELL INTDS ;CELL COULD BEx ON I/O QUEUE LDA 0,IPQST,2 LDA 1,LIT[QSLKING] AND# 1,0,SZR ;LOCK IN PROGRESS? JMP LKLIZN ;YES - LOCK COLLISION LDA 1,LIT[QSLKW] AND# 1,0,SNR ;LOCK WAITING BIT ADD 1,0 ;SET IT STA 0,IPQST,2 INTEN ** ZISZ IWLK JMP IPNEXT ;THAT'S ALL WE CAN DO NOW LKLIZN: LDA 1,LIT[QSCLIDE] AND# 1,0,SZR ;ALREADY COLLIDED? JMP IIPRLS ;YES, IT'S FREE - GRAB IT QUICK ADD 1,0 ;NO - FLAG COLLISION STA 0,IPQST,2 INTEN ** ZISZ ILFOIL FOIL: LDA 2,IPCUR,3 ;USE CURRENT CELL STUFF FOIL ; TO SEND RETRY ** .IFE ~DEBSW JMP IPSEN ** .ENDC S XJMP IPSEN [S]** IIPRLS: INTEN ** ZISZ ALFOIL ** .IFE DEBSW JMP IPRLS ** .ENDC S XJMP IPRLS [S]** ** .IFE DEBSW ** .ENDC S [S]** LPOOL STALLED: 0 ;DIRTY BECAUSE IPZAP REFERS ; DECODE THE MESSAGE & JUMP TO APPROPRIATESf PROCCESSING CODE IPGO: LDA 2,IPCUR,3 GET 0,DEV,I,2 ;SPLIT OUT MESSAGE PIECES STA 0,RQDEV,3 ; ONTO STACK GET 0,UNIT,I,2 STA 0,RQUNIT,3 GET 0,HI,I,2 STA 0,RQHI,3 GET 0,LO,I,2 STA 0,RQLO,3 GET 1,TYPE,I,2 ;REQUEST TYPE LDA 0,.JMTAB ;FIGURE OUT WHE{RE TO GO STA 0,JMPT,3 IJMLP: LDA 0,@JMPT,3 ;PICK UP TABLE ENTRY TYPE ISZ JMPT,3 ;POINT TO HANDLER ADDRESS SUB# 1,0,SZR ;TYPE MATCH TABLE ENTRY? JMP IJMNX ;NO LDA 2,@JMPT,3 ;YES, GET HANDLER ADDRESS  JMP 0,2 ;GO TO IT IJMNX: ISZ JMPT,3 ;NO, SKIP A2DDRESS COM# 0,0,SZR ;END OF TABLE? JMP IJMLP ;NO JSR @.PNIC ;?? INVALID REQUEST PNIPB .MACRO CANDO ** Z^1 ;REQUEST TYPE ** I^1 ;LABEL OF HANDLER % .JMTAB: .+1 ;LIST THE THINGS WE CAN DO: CANDO LOCK ;LOCK (GRAB, ACTUALLY) A BLOCK CANDO MPRMIT ;TINTERLOCK A MAP LOCK SEQUENCE CANDO MPLOCK ;LOCK A MAP CANDO MPUNLOCK;UNLOCK A MAP CANDO DVLOCK ;LOCK A DEVICE -1 ;TERMINATOR ;BLOCK LOCK - ;SEE IF THE REQUESTED BLOCK IS IN CORE ILOCK: XLDA 2,= BQ ;FIRST BUFFER ADDRESS JMP .+2 BQNEXT: LDA 2,BQN)XT,2 COM# 2,2,SNR ;TRIED ALL BUFFERS? XJMP IPRLS ;YES - NOT THERE LDA 0,RQLO,3 LDA 1,BQCA,2 SUB# 0,1,SZR ;LOW ORDER ADDRESS MATCH? JMP BQNEXT ;NO LDA 0,RQHI,3 LDA 1,BQCA1,2 SUB# 0,1,SZR ;HIGH ORDER MATCH? JMP BQNEXT ;NO LDA 0,RQUNIT,3 LDAoM 1,BQUN,2 SUB# 0,1,SZR ;UNITS MATCH? JMP BQNEXT ;OH NO LDA 0,RQDEV,3 LDA 3,BQDCT,2 MOV 3,1,SZR ;****TEMP?? SOME DESTROY BUFFER ; IDENTITY BY ZEROING BQDCT... LDA 1,DCTCD,3 LDA 3,CSP ;STACK POINTER BACK SUB# 0,1,SZR ;DEVICE CODES MATCH? JM8P BQNEXT JSR IPZAP ;YES - KICK IT OUT XJMP IPNEXT ;PENDED - CAN'T GIVE RLS SINCE ; SOMEONE COULD HAVE POSTED ; A LOCK WHILE WE WERE PENDED. XJMP IPRLS LPOOL ; ; ROUTINE TO TRY TO GET RID OF A BUFFER ; ; AC2 - POINTER TO BUFFER ; JSR IPZA#

0 ) ** .IFE DEBSW JDISM: JMP @.DISMIS ** .ENDC S JDISM: JMP @.+1 DISMIS [S]** ; GOT A REQUEST - QUEUE IT TO IPB PROCESS PENQ: MOV 3,2 ;AC3 HAS CELL ADDRESS ** SNAP 2,YIPEQ SUB 0,0 STA 0,IPQST,2 ;MUST NOT LET QSCRAP BE SET JSR IPENQU ;ENQUEUE TO IPB PROCESS XLDA 3,= IPBQ JMP WAKE ;GO WAKE IPB PROCESS ; ROUTINE TO ENQUEUE A CELL TO IPB PROCESS ; AC2 - CELL. ACS 0 & 3Y LOST. IPENQU: STA 3,PQRET ;CAN'T USE STACK - WE'RE XLDA 3,= IPBQ ; CALLED BY TAKEDOWN LDA 0,PQLNK,3 COM# 0,0,SZR ;QUEUE EMPTY? ** .IFE DEBSW JMP PQLP ;NO ** .ENDC S JMP MPENQ [S]** STA 0,IPQPLK,2 ;NEW CELL IS NEW END STA 2,PQLNK,3 ;PUT OUR CELL ON THE QUEUE ** ZISZ EIPQ JMP @PQRET ** .IFN DEBSW MPENQ: ** ZISZ MIPQ ** .ENDC PQLP: MOV 0,3 LDA 0,IPQPLK,3 COM# 0,0,SZR ;IPB PROCESS QUEUE TRAVERSAL LOGIC JMP PQLP ; REQUIRES WE ENQUEUE AT END STA 0,IPQPLK,2 STA 2,IPQPLK,3 JMP @PQRET PQRET: 0. ** .IFN DEBSW LPOOL ** .ENDC ** .IFE DEBSW ** .ENDC S [S]** ; ROUTINE TO SET UP IPBCT, THE LENGTH OF THE MESSAGE, ; GIVEN IN AC0 THE FIRST WORD OF THE MESSAGE ** .NOCON 0 SETLEN: .IFN BSW!MBSW PSH 3,3 .ENDC S STA 3,@CSP [S] ** .NOCON 1 LDA 1,LIT[ZLENMK] XLDA 3,= MAXML ;MAX ALLOWED MESSAGE LENGTH ANDS 0,1,SZR ;EXTRACT LENGTH FROM TYPE BYTE USLE 1,3 ** .IFE DEBSW XJSR IPANIC ;MUST BE NONZERO & <= MAX ** .ENDC S PNIC [S]** ** SNAP 1,YILEN STA 1,IPBCT,2 ;SET LENGTH ** .NOCON 0 .IFN BSW!MBBSW POPJ .ENDC S LDA 3,CSP JMP @0,3 [S] ** .NOCON 1 ; ; ROUTINE TO SCAN RECEIVE QUEUE FOR CELL WITH GIVEN RESPONSE KEY. ; ; AC0 - KEY IN LOW ORDER BYTE ; JSR KEYFIND ; -- NOT FOUND ; FOUND: AC2 HAS CELL ADDRESS, ; AC1 HAS PREDECESSOR CELL ADDRESS KEYFIND: RSAVE XLDA 1,= BOTM AND 1,0 ;MASK OFF HIGH BYTE OF AC0 XLDA 2,= @IPBDC+IPBRQ STA 2,OAC1,3 LDA 2,0,2 KFLP: COM# 2,2,SNR RTRN ;NOT FOUND GET 1,KEY,O,2 SNE 1,0 JMP KFND STA 2,OAC1,3 LDA 2,IPQRLK,2 JMP KFLP KFND: STA 2,OAC2,3 ;FOUND: *QRETURN CELL ADDR ISZ ORTN,3 ;OTHER RETURN RTRN ** .IFN DEBSW LPOOL ** .ENDC ** .IFE DEBSW ** .ENDC S [S]** ;RECEPTION PROCESSING COMPLETE - SEE IF WE HAVE SOMETHING TO SEND. ;IF SEND QUEUE IS EMPTY, SEND PASS & POSSIBLE RETRY BIT (SENWD). CTRYSENDQ: ** CKDN NIOC IPB TRYSENDQ: XLDA 2,= IPBDC LDA 3,IPBSQ,2 COM# 3,3,SNR ;QUEUE EMPTY? JMP TRET ;YES, JUST RETURN LDA 0,IPQST,3 LDA 1,LIT[QSDONE] ;DONE BIT (SET = RECEIVE ; ALREADY CAME HOME) AND# 1,0,SZR ;EXTRANEOUS STRAGGLER? ** .IFE 2DEBSW XJMP TSDEQUE ;YES, JUST THROW HIM AWAY ** .ENDC S JMP TTSDEQ ;************** [S]** JSR SENSETUP ** .IFE DEBSW JMP JDISM ;DIDN'T GET BUSY - OTHER SIDE MUST BE ; SENDING, & WE MUST NOT HAVE SENWD ** .ENDC S JMP TSWCH ;**************** [S]** JMP JDISM ; & GO AWAY TRET: LDA 0,SENWD,2 MOV# 0,0,SNR ;DO WE HAVE SOMETHING TO SAY? JMP JDISM NIOS IPB ;YES, MUST COVER IT WITH BUSY ;(TO KEEP AN IPSTART ON OUR SIDE FROM ; INTERFERING BEFORE OTHER SIDE GETS IT). SKPBN IPB ** .IFE DEBSW ** .PNOCON 0 XJSR IPANIC ;THE FACT THAT WE HAVE SENWD IMPLIES ** .NOCON 1 ** .ENDC S PNIC [S]** ; WE ARE RESPONDING TO SOMETHING HE JUST SENT, ; WHICH IMPLIES HE STILL HAS SOMETHING ON HIS ; SEND QUEUE, WHICH IMPLIES HE WON'T ASYNCHRON- ; -OUSLY TRY F28OR BUSY (BY CALLING IPSTART); ; THEREFORE, WE MUST GET BUSY. ** CKDZ DOAP 0,IPB ** SNAP 0,YLTSEN ** .IFE DEBSW JMP JDISM ** .ENDC S XJMP JDISM [S]** ** .IFN DEBSW TSWCH: ZISZ NTSBUSY LDA 0,SENWD,2 ;**************** MOV# 0,0,SZR PNIC LDA 0,IPBSQ,2, ** SNAP 0,YTSBUSY ** .IFE DEBSW JMP JDISM ** .ENDC S XJMP JDISM [S]** TTSDEQ: ZISZ NTSDQ ** SNAP 3,YTSDQ XJMP TSDEQUE ** .ENDC LPOOL ; ROUTINE TO START A TRANSMISSION (SEND), GIVEN DCT POINTER ; IN AC2. ALL OTHER AC'S ARE LOST. THE MESSAGE TO BE SENT IS ; IN THE FIRST CELL ON THE SEND QUEUE. RETURN IS FOLLOWING ; THE CALL IF THE MESSAGE CANNOT BE SENT (OTHER SIDE HAS BUSY), ; ELSE SKIP WITH DCT POINTERS & STATUS SET UP AND THE ; FIRST WORD ON ITS WAY. ** .NOCON 0 SENSETUP: .IFN BSW!MBSW PSH 3,3  .ENDC S STA 3,@CSP [S] ** .NOCON 1 NIOS IPB ;TRY FOR THE BUSY BUS BIT SKPBZ IPB ;DID WE GET BUSY? ** .IFE DEBSW JMP SENGOT ;YES ** .ENDC S JMP SENGD ;YES [S]** LDA 0,FIRSSW MOV# 0,0,SZR ;NO. THIS OUR FIRST MESSAGE? ** .NOCON 0 .IFN BSW!MBSW POPJ ;NO - SO LONG .ENDC S JMP 0,3 [S] ** .NOCON 1 ** .IFN DEBSW LDA 0,@LIT[NINT] MOV# 0,0,SZR ;MUST NOT HAVE BEEN INTERRRUPTED ** PNIC ** ZISZ NINBUSY SUB 0,0 STA 0,SDSW ** .ENDC ; TRYING TO SEND INITIAL MESSAGE & OTHER SIDE HAS BUSY - ; WE CANCEL |HIS MESSAGE BY SENDING ANYWAY. TO DO THIS, ; OUR DOAP MUST FOLLOW HIS; THUS WE WAIT FOR OUR DONE TO BE ; SET BY HIS DOAP, THEN DO OURS (WHICH ALSO CLEARS OUR DONE). ; THIS WAIT CANNOT HURT ANYONE BECAUSE THIS PATH CAN BE TAKEN ; ONLY ONCE, AT THE BEGINNIN2EG OF SYSTEM INITIALIZATION. SENBLP: SKPDZ IPB ;DONE? JMP SENGOT ;YES, THE RACE IS OVER INC 0,0,SZR ;NO. TIMEOUT? (AC0 STARTED AT 0) JMP SENBLP ;NO, KEEP TRYING ;TIMEOUT - TRY IT ANYWAY (LET IVT & SEND BE THE ; OFFICIAL DETERMINERS OF OTHER SIDE'SJR EXISTENCE) ** ZISZ NINBTMOU SENGOT: SUBZL 0,0 STA 0,FIRSSW LDA 3,IPBSQ,2 ;GOT IT - STA 3,IPBCC,2 ; SET CURRENT CELL POINTER LDA 0,LIT[IPQOMS] ADD 3,0 ;POINT TO OUTGOING MESSAGE STA 0,IPBCP,2 ;CURRENT POINTER LDA 0,IPQOMS,3 ;PICK UP FIRST WORD OF MU ESSAGE ** SNAP 3,YISET LDA 1,SENWD,2 LDA 3,LIT[ZTRYMK] AND 3,1 ;OR IN RETRY BIT ADD 1,0 ; FROM PREVIOUS RECEPTION ** .IFN DEBSW DSZ SDSW ;FIRST MESSAGE? JMP SDSWJ ;YES, COULD BE DONE ** CKDZ SDSWJ: ** .ENDC DOAP 0,IPB ;THERE SHE GOES ** SNAP 0,YL:WESEN LDA 1,LIT[PSSENDING] STA 1,IPBST,2 ;OFFICIALLY SENDING, NOW ** .NOCON 0 .IFN BSW!MBSW POP 3,3 .ENDC S LDA 3,@CSP [S] INC 3,3 ;OTHER RETURN ** .NOCON 1 XJMP SETLEN ;SET LENGTH & RETURN ** .IFN DEBSW SENGD: SUBZL 0,0 STA 0,SDSW JMP SENGOT S+DSW:0 ** .ENDC FIRSSW: 0 ** .IFN DEBSW LPOOL ** .ENDC ; ; ROUTINE TO START UP INTERRUPT WORLD, ASSUMING IT IS IDLE ; (SEND QUEUE WAS EMPTY). THE MESSAGE TO START WITH IS IN ; THE CELL ON THE SEND QUEUE. ASSUMES IPB INTERRUPTS DISABLED. ; IF OTHER SIDE IS NOT THERE, THE CELL IS DEQUEUED AND THE ; CRAP & DONE BITS ARE SET. ; IPSTART:RSAVE ** ZISZ NSTAR XLDA 2,= IPBDC LDA 0,OTHER MOV# 0,0,SNR ;DO WE HAVE SOMEONE TO TALK TO? JMP IPSTCLR ;NO, TAKE IT DOWN ** .IFN DEBSW ADC 0,0 ;FLAG START ENTRY************** STA 0,RCVWD,2 ** .ENDC SUB 0,0 ;NO RETRY BIT STA 0,SENWD,2 ; FROM PREVIOUS RECEPTION ;WAIT FOR TAIL END OF PREVIOUS SEND TO GET THERE, IF NECESSARY. ; WE ASSUME, OF COURSE, HE DOES HIS DIA BEFORE CLEARING OUR BUSY. BUSTM = -5000. ;APPROX 25 MiTILLISEC ON 1200, 12 ON ECLIPSE LDA 0,LIT[BUSTM] IPSTLP: SKPBN IPB JMP IPSTST INC 0,0,SZR ;LOCK LOOP JMP IPSTLP ** ZISZ STWTM RTRN ;TIME OUT (LET IVT & SEND TIME OUT ; BE OFFICIAL DETERMINERS OF OTHER SIDE'S EXISTENCE. ; ALSO BECAUSE OTHER SIDE COULD BE TRYING TO ; SEND BOOT MESSAGE) IPSTST: ** .IFN DEBSW ;*************************** LDA 1,LIT[BUSTM] SUB 1,0,SNR JMP IPST2 ** ZISZ STWB LDA 1,STWTOT ADDZ 0,1,SZC ;ADD IN TO TOTAL WAIT COUNT ISZ STWTOT-1 SKIP PNIC STA 1,STWTOT LDA 1,5,STWMX USGE 1,0 STA 0,STWMX ;REMEMBER LONGEST WAIT JMP IPST2 .ENT STWMX,STWTOT 0 STWTOT: 0 STWMX: 0 IPST2: ;****************** ** .ENDC ** .IFE DEBSW JSR SENSETUP ;START 'ER UP ** .ENDC S XJSR SENSETUP ;START 'ER UP [S]** ** .IFE DEBSW RTRN ;DIDNP'T GET BUSY, JUST GET OUT: ** .ENDC S JMP ITSW ;DIDN'T GET BUSY, JUST GET OUT: [S]** ; OTHER SIDE MUST BE SENDING RTRN ** .IFN DEBSW ;******************:TEMP*********** ITSW: ZISZ NISBUSY LDA 0,IPBSQ,2 ** SNAP 0,YISBUSY RTRN ;**********************7***** ** .ENDC IPSTCLR: ** ZISZ NSTCLR JSR CLRQUS ;DEQUEUE & SET BITS ETC RTRN ;(IPB INTERRUPTS ALREADY DISABLED) ** .IFN DEBSW LPOOL ** .ENDC  ; ; IPTIMOUT - CALLED BY SEND WHEN A TRANSMISSION HAS NOT ; COMPLETED WITHIN THE ALLOWED TIME. CLEARS aINTERRUPT WORLD ; STATE & FLAGS NON-EXISTENCE OF OTHER SIDE, IF THIS HASN'T ; BEEN DONE ALREADY. THE CELL STATUS MUST BE TESTED TO ; DETERMINE THIS, SINCE DURING THE TIME SEND IS UNPENDED BUT ; NOT SCHEDULED IN, AN IVT INTERRUPT COULD BE TAKEN, THEN ; THE OTHER SIDE COULD REAPPEAR. ; ; INPUT: AC2 - CELL ADDRESS ; IPTIMOUT:RSAVE LDA 1,LIT[QSCRAP] INTDS ;IVT INTERRUPT CAN CHANGE IT LDA 0,IPQST,2 ** .IFE DEBSW AND# 1,0,SNR ;STRAGGLER FROM PAST TAKEDOWN? ** .ENDC S AND# 1,0,SZR ;STRAGGLER? JMP TMNAL ;YES ** ZISZ NTMOUT [S]** JSR TAKEDOWN ;NO, TAKE THE WORLD DOWN ** .IFN DEBSW TMALREDY: ** .ENDC INTEN ;INTERRUPTS BACK ON, NOW RTRN ** .IFN DEBSW TMNAL: ZISZ NIALREDY JMP TMALREDY ** .ENDC OTHER: 1 ; 1 IF OTHER SIDE IS THERE (HAS SENT A MESSAGjE) ; 0 IF OTHER SIDE IS NOT THERE LPOOL ; ; CLRQUS - ROUTINE TO CLEAR THE SEND & RECEIVE QUEUES. ; CALLED BY INTERRUPT HANDLER ON RECEPTION OF BOOT MESSAGE, ; BY IPSTART WHEN OTHER SIDE IS NOT THERE, AND BY TAKEDOWN. ; BECAUSE OF THE LATTER, CAN'T USER A STACK TILL NEXT REV. ; IPB & IVT INTERRUPTS MUST BE DISABLED, OF COURSE. ; ; INPUT: AC2 - DCT ADDRESS. ALL OTHER ACCUMULATORS LOST. ; CLRQUS: STA 3,CQRET ** SNAP 3,YCLRET LDA 0,IPBSQ,2 ;HEAD OF SEND QUEUE ** SNAP 0,YCLSQ ADC 1,1 STA 1,IPBSQ,2 ;VACANTE IT CQSLP: COM# 0,0,SNR ;NO MORE CELLS? JMP CQRQ ;GO DO THE RECEIVE QUEUE MOV 0,2 ;INDEX ON CELL ** .IFE DEBSW JSR TMZAP ;FLAG CRAP-OUT ** .ENDC S XJSR TMZAP ;FLAG CRAP-OUT [S]** ** SNAP 2,YZS ** ZISZ NZS LDA 0,IPQSLK,2 ;LINK TO NEXT JMP CQSLP7 CQRQ: XLDA 2,= IPBDC ;GET BACK DCT ADDRESS LDA 0,IPBRQ,2 ;HEAD OF RECEIVE QUEUE ** SNAP 0,YCLRQ ADC 1,1 STA 1,IPBRQ,2 ;AWAY IT GOES CQRLP: COM# 0,0,SNR ;END OF RECEIVE QUEUE? JMP CQPQ ;YES MOV 0,2 ;HELPS TO PUT IT IN THE RIGHT ACCUMULATOR ** .IFE1 DEBSW JSR TMZAP ;LEAVE SOME TRACKS ** .ENDC S XJSR TMZAP ;LEAVE SOME TRACKS [S]** ** SNAP 2,YZR ** ZISZ NZR LDA 0,IPQRLK,2 ;LINK TO NEXT JMP CQRLP CQPQ: XLDA 2,IPBQ+PQLNK ;HEAD OF IPB PROCESS QUEUE ** SNAP 2,YCLPQ CQPLP: COM# 2,2,SNR ;ALL DONE? \JMP CQRTN ;YES ** SNAP 2,YZP ** ZISZ NZP XLDA 1,= QSCRAP LDA 0,IPQST,2 AND# 1,0,SNR ;LEAVE SOME TRACKS ADD 1,0 STA 0,IPQST,2 LDA 2,IPQPLK,2 XLDA 3,= IPBQ ;UNPEND IPB PROCESS WITHOUT LDA 0,QSTAT,3 ; USING A STACK (IPB PROCESS MOVR 0,0 ; MAY BE SITTING ON ONLY AVAILABLE MOVZL 0,0 ; CELLS - IT MUST RELEASE THEM STA 0,QSTAT,3 ; IF OTHER SIDE IS TO BE ABLE TO JMP CQPLP ; COME BACK) CQRTN: XLDA 2,= IPBDC ;RETURN WITH DCT ADDRESS IN AC2 JMP @CQRET CQRET: 0 ** .IFN DEBSW LPOOL ** .ENDC ; ACGTUAL TAKE-DOWN ROUTINE, CALLED BY IPTIMOUT, ALSO CALLED ; ON EVERY INTERVAL TIMER INTERRUPT UNDER THE ALIAS IVTINT. ; BECAUSE OF THE LATTER, IT MUST PRESERVE THE ENTIRE STATE ; OF THE MACHINE, EXCEPT AC3, AND CANNOT USE A STACK. ; NOTE THAT "ENTIRE STATE" jINCLUDES INTERRUPT ENABLE STATE. ; IVT & IPB INTERRUPTS ARE ASSUMED DISABLED. IVTINT: ** .IFN DEBSW JMP 0,3 ;***NOP TO MAKE IT POSSIBLE TO DEBUG ** .ENDC TAKEDOWN:MOVL 3,3 ;SAVE CARRY & RETURN STA 3,TM.RET ;HOPE IVT INTERRUPTS NOT ENABLED.. STA 0,TM.0% STA 1,TM.1 STA 2,TM.2 LDA 0,OTHER MOV# 0,0,SNR ;ALREADY TAKEN DOWN? ** .IFE DEBSW JMP TMRTN ;YES ** .ENDC S JMP TNTREDY [S]** ** SNAP 3,YTKRET ** ZISZ NDOWN XLDA 2,= IPBDC LDA 0,IPBST,2 MOVR# 0,0,SNC ;CELL ALLOCATED DURING RECEIVE? JMP TMCL _J ;NO LDA 2,IPBCC,2 ;YES - ** SNAP 2,YTKCREL ** .IFE DEBSW XLDA 0,= QSCRAP ;FLAG STATUS ** .ENDC S ADC 0,0 [S]** STA 0,IPQST,2 XJSR IPENQU ; AND QUEUE TO IPB PROCESS XLDA 2,= IPBDC ; TO RELEASE IT ; (CREL TURNS ON INTERRUPTS) TMCL: DIB 0,IPB ;CLEAR OUR DONE & BUSY SUB 0,0 STA 0,OTHER ;FLAG HIS NON-EXISTENCE STA 0,IPBST,2 ;CLEAR OUT LEFT-OVER STATUS ADC 0,0 STA 0,IPBCP,2 DOA 0,IPB ;INVALIDATE A-REG (CAN'T ; CLEAR HIS DONE) (???) ** .IFE DEBSW JSR CLRQUS ;CLEAR OUT LEFT-OVER QUEUES *^* .ENDC S XJSR CLRQUS ;CLEAR OUT LEFT-OVER QUEUES [S]** XLDA 2,DIRR ;NOW LOOK FOR LOOSE ENDS JMP .+2 ; IN MAP LOCK WORLD TMMPLP: LDA 2,SFNX,2 COM# 2,2,SNR ;NO MORE DCB'S TO LOOK AT? JMP TMRTN ;YES LDA 3,SFLK,2 COM# 3,3,SNR ;THIS ONE HAVE A MJAP? JMP TMMPLP ;NO LDA 0,MPLCK,3 ;MAP LOCK WORD<>-1 BUT 1B0 SET, INCL# 0,0,SNC ; MEANING LOCKED FOR OTHER SIDE? JMP TMMPLP MOVL 0,0 MOVZR 0,0 ;YES, UNLOCK IT STA 0,MPLCK,3 ** SNAP 3,YTKMP ** ZISZ NTUNMP JMP TMMPLP TMRTN: LDA 0,TM.0 LDA 1,TM.1  LDA 2,TM.2 LDA 3,TM.RET MOVZR 3,3 JMP 0,3 ** .IFN DEBSW TNTREDY:ZISZ NTALREDY JMP TMRTN ** .ENDC ;ROUTINE TO RECORD IN CELL STATUS THAT ;TRANSMISSION/RECEPTION HAS BEEN CANCELED ; INPUT: AC2 - CELL ADDRESS TMZAP: LDA 0,IPQST,2 LDA 1,TMCLR AND xv1,0 ;CLEAR SENDING LDA 1,TMSET ADD 1,0 ;SET CRAP & DONE STA 0,IPQST,2 JMP 0,3 TMCLR: NOT[QSSENDING+QSCRAP+QSDONE] TMSET: QSCRAP+QSDONE TM.RET:0 TM.0:0 TM.1:0 TM.2:0 LPOOL .END RWBLK.SRB' RTITLE RWBLK .IFN IOSW .ENT IORDB IOWRB .ENDC .NREL .ENT RDB,WRB  .EXTN ASBUF ;ASSIGN BUFFER .EXTN RDBNO ;READ BLOCK NUMBER .EXTN GETCE ;ALLOCATE CELL .EXTN SETMOD ;SET MODIFIED BIT .EXTN MCLR ;CLEAR IN MAPPED ENVIRONMENT .EXTN QUENT ; QUEUE ENTRY FOR IO .EXTN WAIT ;WAIT FOR IO COMPLETION .EXTN FLAK1 ;CALL FLAKE WITH ADDR. ;FOLLOWING CALL INSTEAD OF IN ; TMP .EXTN RETER ;ERROR RETURN .EXTN RDNBK ;READ NEXT BLOCK .EXTN RELZT ;RELEASE BLOCK AND ZERO TLA .EXTN CREL ;RELEsASE A CELL .EXTN DIVI ;INTEGER DIVIDE .EXTN WDBLK ;WITHDRAW BLOCK FROM FREE ; STORAGE .IFN IOSW ;MAPPED IOCS .EXTN WMAPV ;IOCS -MAP VECTOR .ENDC .IFN MSW .EXTN CLEAR .EXTD MFSTB .EXTD C31K .IFE MBSW .EXTD CLSTB .ENDC .IFN MBSW .EXTD] CLBLK .ENDC .ENDC .EXTN WAIT ;WAIT FOR I/O ; ; READ/WRITE BLOCK- ; ROUTINE TO READ AND WRITE DIRECTLY TO/FROM ; USER AREA. ; ; ; STACK PARAMETERS ; WRCA=TMP ;RUNNING CORE ADDRESS BLKS=TMP+1 ;NUMBER OF BLOCKS TO TRANSFER BUFD1=TMP+2 ;BUFFER ADDRESUS WDSAV=TMP+3 ;RUNNING MAP INDEX DCBSV=TMP+4 ;DCB ADDRESS SAVED - SIGN BIT SET IF 3330 TMPBQ=TMP+5 ;FONEY BUFFER HEADER ADDRESS - SIGN BIT ; SET MEANS ERROR ENCOUNTERED LSTAD=TMP+6 ;LAST ADDRESS IN MAP INDEX BUFFER MODE=TMP+7 ;READ/WRITE MODE SW. WDSV1=LsSTAD ;WDSAV, HIGH ORDER ** .EJECT .IFN IOSW ; THIS PAGE ;IORWB AND IORDB ARE THE BLOCK I/O PROCESSORS FOR THE I/O SYSTEM ;THESE ROUTINES READ OR WRITE DIRECTLY TO THE I/O SYSTEM BUFFERS ;THE USER OF THESE ROUTINES SUPPLIES HIS OWN FAKE BUFFER HEADER :AND ;AND EMPTY ARRAY FOR HOLDING THE DISK BLOCK ADDRESSS POINTERS ; AC0 = FIRST LOGICAL BLOCK TO MOVE ; AC1 = UFT ADDRESS ; AC2 = POINTER TO BQUST IN FAKE BUFFER HEADER ; JSR IORDB,IORWB ; THE FAKE BUFFER HEADER IS A 16 WORD CELL. THE USER MUST FILL ; IQN THE FOLLOWING INFORMATION ..... ; BQADR - ADDRESS OF CORE BUFFER FOR TRANSFER ; BQUST - INITIAL USER STATUS (B1 - PEND, B15 DONE SET ON COMPLETION) ; BQNBK - NUMBER OF BLOCKS TO TRANSFER ; BQARD - POINTER TO AN EMPTY ARRAY OF WORDS FOR DISK ADDRESSES ; THE REMAINING LOCATIONS OF THE FAKE BUFFER HEADER ARE USED BY ; THIS ROUTINE AND THE DISK DRIVER AND INTERRUPT SERVICE WORLDS... IORDB: MOVO 0,0,SKP ;IOCS - SET THE CARRY FOR A READ IOWRB: MOVZ 0,0 ;IOCS - CLEAR FOR A WRITE RSAVE 10 ;IOCS - SAVE THE QhRETURN IN THE ; STACK STA 2,TMPBQ,3 ;IOCS - SAVE THE FAKE BUFFER ; HEADER STA 1,DCBSV,3 ;IOCS - SAVE THE UFT LDA 1,BQNBK,2 ;IOCS - GET THE NUMBER OF BLOCKS LDA 2,DCBSV,3 ;IOCS - GET THE DCB (UFT) STA 0,UFTBN,2 ;IOCS - SAVE THE STARTING BLOCK s ; NUMBER MOV# 1,1,SNR ;IOCS - SEE IF ANY BLOCKS JMP@ .RET1 ;IOCS - TAKE AN ERROR RETURN ON ; ZERO XFER STA 1,BLKS,3 ;IOCS - SAVE THE NUMBER OF ; BLOCKS SUBCL 0,0 ;IOCS - GET THE MODE BIT LDA 3,TMPBQ,3 ;IOCS - GET THE BUFFER HEADER LDA, 1,BQUST,3 ;IOCS - GET THE USER STATUS ; WORD MOVZR 1,1 ;IOCS - SHIFT OFF THE DONE BIT ADDZL 1,1 ;IOCS - CLEAR FOR SURE AND ; SHIFT LEFT MOVOR 1,1 ;IOCS - NOW SET THE IOCS TYPE ; BIT STA 1,BQUST,3 ;IOCS - SAVE IN THE BUFFER ; HEADE4ER  LDA 3,CSP ;IOCS - GET THE STACK BACK JMP IO1 ;IOCS - GO ON LIKE NORMAL .RET1: RET1 .TMPBQ: TMPBQ .ENDC ; ; ROUTINE TO READ/WRITE BLOCKS DIRECT TO/FROM ; USER AREA. ; IN EXTENDED I/O, AC0= @ OFFSET+STARTING BLK # IN EX DATA ARRAY ; CTMP3= PEDMP ADDR ; AC0: CORE ADDRESS (STARTING) ; AC1: NUMBER OF BLOCKS ; AC2: UFT ADDRESS ; JSR RDB/WRB ; ; CTEMP CONTAINS STARTING BLOCK NUMBER (LOGICAL) INTO FILE. ; CRATT: ATCON+ATRAN RDB: MOVO 0,0,SKP ;SET READ MODE WRB: MOVZ 0,0 ;SET WRITE MODE RSAVE 10 S.JTA 0,WRCA,3 ;STARTING CORE ADDRESS SAVED LDA 0,UFTAT,2 LDA 3,CRATT ;RST - CONT & RAN. ATRIB. BITS AND# 0,3 SNR ;RST - ARE EITHER SET? JMP RNER ;RST - NO, IT AIN'T FOR DIRECT ;RST - I/O LDA 3,CC ; CURRENT CELL LDA 0,CTEMP,3 ; STARTING BLOCK NU/MBER STA 0,UFTBN,2 ; SAVE IN UFT LDA 3,CSP ; RECOVER THE STACK POINTER STA 0,OAC1,3 ; RETURN AC1 FOR DSQ SEQZ 1 ; ZERO BLOCKS REQUESTED? JMP .+3 ISZ ORTN,3 ;YES RTRN ;JUST FINE WITH ME STA 1,BLKS,3 ; SAVE NUMBER OF BLOCKS .IFN IOSW ; IOCS - IHAVE TO SET UP TMPBQ LDA 1,.TMPBQ ;DUMMY UP THE IOCS BIT - ADD 3,1 ; MAKE IT LOOK LIKE NON-IOCS STA 1,TMPBQ,3 ; CALL UNTIL TMPBQ IS DEFINED ;TMPBQ MUST POINT TO WORD OF ;ZERO SIGN BIT - WHY NOT ITSELF .ENDC SUBCL 0,0 ;MODE TO AC IO1: STA 0,/MODE,3 ;SAVE ON STACK - 0 => WRITE ; 1 => READ LDA 0,UFTAT,2 ;LOOK AT ATTRIBUTES LDA 1,DCBOFF ; MAKE DCB ADDRESS ADD 1,2 STA 2,DCBSV,3 ; SAVE ON STACK LDA 1,CONAT ; CONTIGUOUS MASK AND# 0,1,SZR ;CONTIGUOUS ? JMP CELOK ; YES, IGNORE JUNK LDA 1,UDBBN,2 ;LOGICAL BLOCK NUMBER LDA 3,DCBDC,2 LDA 3,DCTCH,3 ;DEVICE CHARACTERISTICS MOVL 2,0 MOVL 3,3 ;IF 3330, MOVR 0,0 ; SET SIGN BIT LDA 3,CSP STA 0,DCBSV,3 ; OF DCB POINTER, & SAVE LDA 2,WPB2 ;INDICES PER BLOCK MOVL# 0,0,SZC MOVZR 2,2 ";3330 - HALF AS MANY JSR@ .IDIV ;DIVIDE LDA 2,DCBSV,3 ;DCB ADDRESS MOVL# 2,2,SZC ;3330? MOVZL 0,0 ;YES - 2-WORD INDICES STA 0,WDSAV,3 MOV 1,0 ;BLOCK NUMBER OF MAP BLOCK JSR@ .RDBNO ;READ BLOCK NUMBER .IFE IOSW RTRN ; RDOS - ERROR JUST RETURN .ENDC .IFN IOSW JMP SDONE ;IOCS - HAVE TO SET DONE BIT .ENDC STA 0,BUFD1,3 ;SAVE BUFFER ADDRESS LDA 2,WDSAV,3 ADD 0,2 STA 2,WDSAV,3 ;ADDRSS IN BUFFER TO START INDEX LDA 2,WPB2 ;WORDS PER BLOCK ADD 0,2 STA 2,LSTAD,3 ;SAVE FOR EOR CHECK LDA o2,DCBSV,3 MOVZL# 2,2,SZC ; BIG DISK ? DSZ LSTAD,3 ; YES ONE LESS PER BLOCK CELOK: .IFN IOSW LDA 2,TMPBQ,3 ;IOCS - GET THE BUFFER HEADER LDA 0,BQUST,2 ;IOCS - GET THE STATUS MOVZL# 0,0,SNC ;IOCS - SKIP IF IOCS TYPE JMP GETC ;IOCS - GO ON AN GET A CELL LDA 0,BQADR,2 ;IOCS - GET CORE BUFFER ADDR .IFN IOSW ;IOCS - IF MAPPED IORI 1B0,0 ;IOCS - MARK FOR EXTENDED I/O .ENDC STA 0,WRCA,3 ;IOCS - PUT IN THE STACK .IFE IOSW LDA 1,RANBQ ;STAT INIT .ENDC .IFN IOSW LDA 1,EXBST ;IOCS - GET 0THE EXTENDED I/O ATTRIBUTE .ENDC JMP IO3 ;IOCS - GO ON LIKE NORMAL .ENDC ; ; GET A CELL AND SET UP FAKE BUFFER HEADER ; GETC: JSR @.GETCE ; GET A CELL LDA 0,.CLN3 ;CELL LENGTH ADD 0,2 ;ADDRESS OF END OF CELL STA 2,TMPBQ,3 ;FONEY BQ ADDRESS 7LDA 0,WRCA,3 .IFN MSW MOVL# 0,0,SZC ;SKIP IF NOT EXTENDED I/O JMP EXBHD .ENDC LDA 1,RANBQ ;INDIRECT FLAG BHSUP: STA 0,BQADR,2 ; CORE ADDRESS OF BUFFER SUB 0,0 STA 0,BQUST,2 ; INITIAL USER STATUS IO3: STA 1,BQST,2 ;INIT STATUS LDA 3,DCBSV,3 ;DCB ATDDRESS LDA 0,DCBDC,3 ;DCT ADDRESS STA 0,BQDCT,2 ;SETUP BQ HEADER - DCT ADDRESS LDA 0,DCBUN,3 ;UNIT NUMBER STA 0,BQUN,2 ;... ; BUFFER ; SET FILE MODIFIED BIT IN UFD IF WRITING, THEN ; TAKE PROPER PROCESSING PATH (CONTIGUOUS/RANDOM) MOV 3,2 ;DCB ADDRESS TO AC2 LDA 3,CSP ;STACK POINTER LDA 0,UFTST-UFTDC,2 LDA 1,.MOD AND# 1,0,SNR ADD 1,0 ;OR IN MOD BIT TO FILE STATUS LDA 1,MODE,3 ;NOW SEE IF WE WANT IT MOVR# 1,1,SNC ;WRITING? STA 0,UFTST-UFTDC,2 ;YES, MUST SET FILE MODIFIED BIT LDA 0,UFTAT-UFTDC,2 ; GET ATTRIBUTES LDA 1,CONAT ; CONTIGUOUS ATTRIBUTE AND 0,1,SZR ; IS FILE CONTIGUOUS? JMP CONTIG ; YES- PROCESS CONTIGUOUS ; ; PROCESS RANDOM FILE REQUESTS ; LDA 0,BLKS,3 ; AC0 <= # BLOCKS REQUESTED NEG 0,0 ; AC0 <= # BLOCKS REQUESTED COM 0,0 ; -1. LDA 1,UDBBN,2 ; AC1 <= FIRST BLOCK TO XFER ADDZ 0,1 ; AC1 <= LB TO XFER ; SET CARRY ON OVERFLOW LDA 0,MODE,3 ; CHECK IF READ/WRITE SNEZ 0 ; IS IT WRITE ? JMP @.CKWR1 ; YES- CONTINUE DOWN WRITE PATH ; FINISH PROCESSING RdEAD REQUEST MOV# 1,1,SZC ; WAS REQUEST LEGAL ? JMP R2FAR ; NO- GO SET ERROR .IFN IOSW LDA 3,TMPBQ,3 ;IOCS - GET THE BUFFER HEADER LDA 3,BQUST,3 ;IOCS - GET THE STATUS WORD MOVL# 3,3,SZC ;IOCS - SKIP IF NOT IOCS JMP @.CH1 ;IOCS - DONT DO THESE TESTS LDA 3,CSP ;IOCS - GET THE STACK BACK .ENDC LDA 0,UDBBK,2 ; AC0 <= LAST BLOCK IN FILE USLE 1,0 ; LB REQUESTED .LE. LB IN FILE ? JMP RDEOF ; NO- END OF FILE ERROR SEQ 1,0 ; LB REQUESTED = LB IN FILE JMP @.CH1 ; NO- OK TO DO I/O LDA 0,BLKS,gk3 ; AC0 <= BLOCKS REQUESTED LDA 1,UFTBC-UFTDC,2 ; AC1 <= BYTES IN LAST BLOCK SNEZ 1 ; ARE THERE ANY ? JMP REOF1 ; NO- END OF FILE ERROR JMP @.CH1 ; YES- OK TO DO I/O ; HANDLE ILLEGAL ATTEMPT AT DIRECT BLOCK I/O RNER: JSR @.RETER ; TAKE SYSTEM ERR OR RETURN EROVA ; PASS THE ERROR CODE HERE .CLN3: CLN-3 DCBOFF: UFTDC WPB2: SCWPB .IDIV: DIVI .RDBNO: RDBNO .GETCE: GETCE RANBQ: QTIND .MOD: STMOD .CKWR1: CKWR1 .RETER: RETER .CH1: CH1 CONAT: ATCON .IFN IOSW RET1: LDA 2,CC ;IOCS - GET THE PROCESS CELL LDA 0,.IOZDX ;IOCS - ERROR CODE FOR ZERO ; XFER STA 0,CTMP2,2 ;IOCS - PUT INTO THE CELL SDONE: LDA 2,TMPBQ,3 ;IOCS - GET THE BUFFER HEADER ISZ BQUST,2 ;IOCS - SET DONE RTRN ;IOCS - NOW RETURN .IOZDX: IOZDX .ENDC .IFN MSW EXBHD: .IFEZ MBSW LDA 1,C1400 ;GET OFFSET AND 1,0 .ENDC .IFN MBSW ANDI 1400,0 .ENDC LDA 3,CC LDA 1,CTMP3,3 ;PEDMP ADDR STA 1,BQDCB,2 ;TO HDR FOR SWAMP LDA 1,EXBST ;STAT BITS LDA 3,CSP JMP BHSUP ;COMMON CODE EXBST: QTIND+QTEXI .ENDC ; ; PROCESS CONTIiGUOUS FILE BLOCK READ/WRITE. ; FIRST COMPUTE DOUBLE PRECISION DEVICE ADDRESS OF FIRST ; BLOCK TO TRANSFER. ; CONTIG: SUBZR 0,0 ; SET 1B0 TO SHOW STA 0,BUFD1,3 ; NO BUFFER TO RELEASE ON EXIT. LDA 0,UDBAD,2 ; AC0 <= DEV. ADD. (LO) OF 1ST BLOCK LDA 1,UDBBN,2 ; AC1 <= FIRST BLOCK TO TRANSFER ADDZ 1,0 ; AC0 <= LOW ORDER DEVICE ADDRESS STA 0,WDSAV,3 ; SAVE 1ST BLOCK LOW ORDER ADDRESS LDA 0,UDDL,2 ; EXTRACT HIGH ORDER 1ST BLOCK ADDRESS LDA 3,C377L ; AC3 <= MASK ANDS 3,0,SZC ; AC0 <= HIGH ORDER DEVICE# ADDRESS INC 0,0 ; PROPAGATE CARRY TO HIGH ORDER LDA 3,CSP ; RESTORE STACK POINTER STA 0,WDSV1,3 ; AND SAVE ON STACK. ; COMPUTE LAST BLOCK TO TRANSFER AND CHECK IF LEGAL LDA 0,BLKS,3 ; AC0 <= # BLOCKS REQUESTED NEG 0,0 ; AC0 <= # BLOCKS REQUESTED] COM 0,0 ; -1. ADDZ 0,1,SZC ; AC1 <= LB TO XFER JMP R2FAR ; ERROR- REQUEST BEYOND #177777 LDA 0,UDBBK,2 ; AC0 <= # OF LAST BLOCK IN FILE USLE 1,0 ; LB REQUESTED .LE. LB IN FILE ? JMP RDEOF ; NO- END OF FILE ERROR ; NUMBER OF BLOCKS TO TRANSF-ER DETERMINED- ; SET UP BUFFER HEADER CONT1: LDA 2,TMPBQ,3 ; GET BUFFER HEADER ADDRESS LDA 0,WDSAV,3 ; FIRST BLOCK DEVICE ADDRESS STA 0,BQCA,2 ; SET IN BUFFER LDA 0,WDSV1,3 ;HIGH ORDER, TOO STA 0,BQCA1,2 LDA 0,ICTST ;INITITAL CONTIGUOUS STATUS LDA Ə1,BQST,2 ;SET CONTIG BIT ADD 0,1 ;OK SINCE STAT INIT TO QTIND STA 1,BQST,2 ; TO BUFFER STATUS LDA 0,BLKS,3 ;NUMBER OF BLOCKS TO MOVE STA 0,BQNBK,2 ;PUT IN BUFFER HEADER DSZ MODE,3 ;READ OR WRITE? JSR @.SET1 ; WRITE, SET MODIFIED ; ; PERFORM BLOCՑK I/O AND EXIT ; IOX: JSR @.QUENT ; QUEUE IT .IFN IOSW LDA 3,TMPBQ,3 ;IOCS - GET THE FAKE BUFFER ; HEADER LDA 3,BQUST,3 ;IOCS - GET THE USER STATUS WORD MOVL# 3,3,SZC ;IOCS - SEE IF IOCS TYPE CALL JMP DONE ;IOCS - YES SO NO WAIT .ENDC JSR @ .WAIT ; & WAIT FOR IT JMP EDONE ;TIMEOUT ERROR JMP EDONE ;DATA ERROR - TAKE BAD RETURN JMP DONE ; CLEANUP & RETURN EDONE: LDA 0,TMPBQ,3 MOVL 0,0 MOVOR 0,0 ;SET ERROR BIT FOR RETURN STA 0,TMPBQ,3 DONE: LDA 3,CSP ;IOCS - GET THE STACK BACK .IFNR@ IOSW LDA 2,TMPBQ,3 ;IOCS - GET THE FAKE BUFFER ; HEADER LDA 0,BQUST,2 ;IOCS - GET THE USER STATUS WORD MOVZL# 0,0,SZC ;IOCS - SEE IF IOCS TYPE??? JMP IO2 ;IOCS - YES .ENDC LDA 2,BUFD1,3 ;BUFFER ADDRESS MOVL# 2,2,SNC ;DON'T RELEASE IF NOT THE:RE JSR@ .RLZT ;RELEASE IT FINALLY LDA 2,TMPBQ,3 ;CELL ADDRESS LDA 0,.CLN3 SUBL 0,2 MOVZR 2,2 ;CLEAR SIGN (ERROR) BIT JSR@ .CREL ;RELEASE CELL TO SYSTEM IO2: LDA 0,TMPBQ,3 MOVL# 0,0,SNC ;WAS THERE ERROR? ISZ ORTN,3 ;YES RTRN C377L: 377*400 Is5CTST: QTCT ; INITIAL CONTIGUOUS BUFFER STATUS .QUENT: QUENT .WAIT: WAIT .SET1: SETMOD .RLZT: RELZT .CREL: CREL EOFCD: EREOF*400 CKWRP: CKWR .IFN MSW .IFE MBSW C1400: 1400 CNMRS: 100377 .ENDC .ENDC ; ; PROCESS REQUESTS THAT WOULD EXTEND BEYOND BLOCK ##177777 ; OR ; READ REQUESTS THAT WOULD EXTEND BEYOND END-OF-FILE (NOT INFOS). ; ; COMPUTE NUMBER OF BLOCKS THAT CAN BE TRANSFERRED R2FAR: ADC 1,1 ; FORCE LB TO XFER = 177777 RDEOF: LDA 0,UDBBK,2 ; AC0 <= # OF LAST BLOCK IN FILE SUB 0,1 ; AC1 <= # BhLOCKS TOO MANY LDA 0,BLKS,3 ; AC0 <= # BLOCKS REQUESTED SUBZ 1,0,SBN ; AC0 <= # BLOCKS TO XFER JMP NOBLK ; NO BLOCKS CAN BE XFERRED LDA 1,UFTBC-UFTDC,2 ; AC1 <= BYTES IN LAST BLOCK SEQZ 1 ; IF THERE ARE BYTES IN LB JMP STERR ; GO SET EOF RETURN EQLSE REOF1: NEG 0,0 ; SET UP TO TRANSFER COM 0,0 ; ONE BLOCK LESS. JMP STERR ; NOW GO SET EOF CODE. ; HANDLE RANDOM FILE WRITE BLOCK REQUEST PAST BLOCK #177777 W2FAR: ADC 1,1 ; LAST BLOCK = 177777 LDA 0,UDBBN,2 ; AC0 <= FIRST BLOCK TO XFER SUB 0,1 ; AC1 <= # BLOCKS TO XFER -1 INC 1,0 ; AC0 <= # BLOCKS TO XFER JMP STERR ; GO SET EOF CODE. ; SET END-OF-FILE ERROR RETURN, PARTIAL BLOCK READ/WRITE ; COUNT AND PROCESS. NOBLK: SUB 0,0 ; SET 0 BLOCKS TO XFER STERR: STA 0,BLKS,3 ; SET # BLOCKS TO X'FER LDA 1,EOFCD ; AC1 <= END-OF-FILE CODE ADDS 0,1 ; AC1 <= PARTIAL COUNT/EOF LDA 3,CC ; AC3 => CURRENT CELL STA 1,CTMP2,3 ; RETURN ERROR CODE LDA 3,CSP ; RECOVER STACK POINTER LDA 1,TMPBQ,3 ; AC1 <= FAKE BUFFER HEADER ADDRESS MOVL 1,1 ; SET SIiGN BIT MOVOR 1,1 ; TO INDICATE ERROR STA 1,TMPBQ,3 ; AND PLACE BACK IN STACK. SNEZ 0 ; ANY BLOCKS TO TRANSFER ? JMP DONE ; NO- FINISH UP AND EXIT LDA 0,UDBAT,2 ; AC0 <= FILE ATTRIBUTES LDA 1,CONAT ; AC1 <= CONTIGUOUS BIT AND# 0,1,SZR ; CONTIGUOpLUS FILE ? JMP CONT1 ; YES- CONTINUE WITH CONTIGUOUS DSZ MODE,3 ; NO- CHECK RANDOM READ/WRITE JMP @CKWRP ; CONTINUE WRITE RANDOM ; ; PROCESS RANDOM FILE READ REQUESTS ; CH1: JSR BCHK CHEKI: LDA 0,@WDSAV,3 ;GET DISK POINTER, HIGH ORDER LDA 2,DCBSV,e73 MOVL 2,2,SNC ;IF NOT 3330, SUBC 0,0,SKP ; HIGH ORDER IS ZERO ISZ WDSAV,3 LDA 1,@WDSAV,3 ;LOW ORDER MOV# 0,0,SNC JMP .+3 STA 0,@MODE,3 ;3330 - STORE HIGH ORDER ISZ MODE,3 STA 1,@MODE,3 ;STORE LOW ORDER LDA 2,WRCA,3 ;POINTER TO CORE BUFFER MOVY# 0,0,SZR ;IS INDEX ZERO? JMP CHNZ MOV# 1,1,SZR ;ALL OF IT, NOW JMP CHNZ ;IOCS - DONT CLEAR IT .IFN MSW MOVL# 2,2,SZC ;EXTENDED I/O ? JMP ECLR ;YES-DO SPECIAL CLEAR .ENDC IO4: LDA 0,BLKSZ JSR @.MCLEAR ;YES, CLEAR HIS BUFFER CHNZ: LDA 0,BLKSZ ;MUST LOAD IN CASE DIDN'T CLEAR DSZ BLKS,3 ; DONE ? ADD 0,2,SKP ; NO, INCREMENT CORE ADDRESS JMP DAIO ; YES, GO DO READ .IFN MSW MOVL# 2,2,SNC ;EXTENDED I/O ? JMP CHNZ2 ;NO ; SEE IF INC CAUSED OFFSET OVERFLOW LDA 1,C31K AND# 1,2,SNR JMP CHNZ2 ;NO .IFN MBSW ANDI 100377,2 ;DROP OLD OFFSET .ENDC .IFE MBSW LDA 1,CNMRS AND 1,2 .ENDC INC 2,2 ;UP BLK # .ENDC CHNZ2: STA 2,WRCA,3 ; SAVE NEW CORE ADDRESS JSR NXTBL ; YES - GET NEXT INDEX BLOCK JMP CHEKI ; NO, CHECK NEXT ADDRESS .MCLEAR:<` MCLR .IFN MSW ECLR: .IFN IOSW ;MAPPED IOCS LDA 3,TMPBQ,3 ;IOCS -GET BQ LDA 0,BQUST,3 ;IOCS -GET USER STATUS MOVL# 0,0,SNC ;IOCS -IOCS TYPE CALL? JMP IO5 ;IOCS -NO MOVL 2,0 ;IOCS -DISPLACEMENT MOVZR 0,0 ;IOCS- CLEAR BIT 0 LDA 2,BQDCB,3 ;IO?CS -VECTOR EJSR WMAPV ;IOCS -MAP USER WINDOW MOV 0,2 ;IOCS -MAPPED ADDR LDA 0,BLKSZ ;IOCS -BLOCK SIZE JSR @.CLEAR ;IOCS -CLEAR IT JMP IO6 IO5: .ENDC LDA 1,C377 AND 2,1 ;BLK # LDA 3,CC LDA 3,CPTAD,3 LDA 0,PEDMP,3 ;DATA MAP START SLOT ADD 0,$3 ADD 1,3 ;BLK REL LDA 1,PEMAP,3 ;SLOT CONTENTS .IFE MBSW LDA 3,CLSTB ;LB CON ADD 3,1 SMLB 1 LDA 0,C31K LDA 1,C1400 AND 1,2 ADD 0,2 ;CLEAR ADDR .ENDC .IFN MBSW STA 1,CLBLK ;LAST BLK SMLB 1 ANDI 1400,2 ;GET OFFSET ADDI 76000,2 ;CLEAR ADDR .ENDC LDA 0,BLKSZ ;400 JSR@ .CLEAR ;UNMAPPED CLEAR LDA 2,CC LDA 2,CPTAD,2 ;PTBL JSR MFSTB ;MAP FIRST BLK AGAIN IO6: LDA 2,WRCA,3 ;RESTORE AC2 JMP CHNZ .CLEAR: CLEAR .ENDC WPBLK: SCWPB .SETMOD: SETMOD C377: 377 DAIO: LDA 2,BUFD1,3 ; MAP mINDEX BUFFER ADDRESS JSR@ .RELZT ; RELEASE IT LDA 2,TMPBQ,3 ; BUFFER HEADER ADDRESS LDA 0,BQARD,2 ;NEW ARRAY ADDRESS LDA 1,BQNBK,2 ;NUMBER OF BLOCKS MOVZR# 1,1,SNR ; =1 ? (CAN'T BE 0) ADDOR 0,0 ;YES- SET 1B0 IN BUFD1 STA 0,BUFD1,3 ;STORE FOR LATER RELEASE DIO2: LDA 0,@BQARD,2 ;GET FIRST DEV. ADDR. LDA 1,DCBSV,3 MOVL# 1,1,SNC SUB 0,0,SKP ;NON-3330 - HIGH ORDER ZERO ISZ BQARD,2 LDA 1,@BQARD,2 ;LOW ORDER SEQZ 0 ; ZERO? JMP .+3 SNEZ 1 JMP DIO1 ;YES - GET NEXT ONE STA 0,BQCA1,2 ;NO - PUT IN BUFFER STA 1,BQCA,2 JMP @.IOX ; DO I/O AND EXIT DIO1: ISZ BQARD,2 ;NEXT DEVICE ADDRESS LDA 0,BQADR,2 ;MUST UP DESTINATION CORE ADDRESS, TOO LDA 1,BLKSZ ADD 1,0 STA 0,BQADR,2 DSZ BQNBK,2 ;ONE LESS BLOCK JMP DIO2 ;GO CHECK IT .IFN IOSW ISZ B9QUST,2 ;IOCS - SET DONE IF NO TRANSFER .ENDC JMP @TDONE ;NO NON ZERO BLOCK NUMBERS .IOX: IOX TDONE: DONE BLKSZ: SCDBS ; GET AND INITIALIZE BUFFER BCHK: MOV 3,0 ;SAVE RETURN LDA 3,CSP .IFN IOSW LDA 2,TMPBQ,3 ;IOCS - GET THE BUFFER HEADER LDA 2KV,BQUST,2 ;IOCS - GET THE STATUS WORD MOVL# 2,2,SZC ;IOCS - SKIP IF NOT IOCS JMP CH4 ;IOCS - IOCS CASE SO HANDLE ; DIFFERENTLY .ENDC LDA 1,BLKS,3 ;NUMBER OF BLOCKS MOVZR# 1,1,SNR ;DOES BLKS = 1 (CAN'T BE 0) JMP CH3 ;YES - DON'T GET ANOTHER BUFkFER SUB 2,2 ;NO HEADER INIT FLAG (DCB=0) JSR@ .ASBUF ;GO GET BUFFER JMP CH2 CH3: LDA 1,WDSAV,3 ;FUDGE SO NO BUF NEEDED CH2: LDA 2,TMPBQ,3 ;FAKE BUFFER ADDR STA 1,BQARD,2 ;STORE ADDR OF ARRAY CH5: STA 1,MODE,3 ;RUNNING PTR TO NEW BUFFER LDA 1,BLKS,3 w0;GET NUMBER OF BLOCKS STA 1,BQNBK,2 ;AND PUT IN HEADER JMP NRET ;RETURN .IFN IOSW CH4: LDA 2,TMPBQ,3 ;IOCS - GET THE FAKE BUFFER ; HEADER LDA 1,BQARD,2 ;IOCS - GET THE CORE ADDR JMP CH5 ;IOCS - GO ON LIKE NORMAL .ENDC ; GET NEXT INDEX BLOCK  NXTBL: MOV 3,0 ;SAVE RETURN ADDRESS LDA 3,CSP ISZ WDSAV,3 ;INCREMENT RUNNING PTR ISZ MODE,3 ;INCREMENT NEW RUNNING PTR LDA 2,LSTAD,3 ;LAST ADDR IN OLD BUF LDA 1,WDSAV,3 SUB# 2,1,SZR ;END OF OLD BUF? JMP NRET ;JUST RETURN LDA 2,BUFD1,3 ;OLD BX(LOCK ADDR JSR@ .RELZT ;RELEASE IT LDA 2,DCBSV,3 ;DCB ADDRESS JSR @.RDNBK ;GET NEXT INDEX BLOCK JMP ER1 ;ERROR - CLEAN UP AND GO HOME STA 1,BUFD1,3 ;SAVE INDEX BLOCK BUF ADDR STA 1,WDSAV,3 ;RESET POINTER TO BEGINNING LDA 2,WPBLK ;WORDS/BLOCK ADDo 2,1 ;LAST ADDRESS STA 1,LSTAD,3 ;SAVE IN STACK LDA 2,DCBSV,3 MOVZL# 2,2,SZC ; BIG DISK ?? DSZ LSTAD,3 ; YES ONE LESS NRET: MOV 0,2 ;RETURN ADDRESS JMP 0,2 ;RETURN ; ; PROCESS RANDOM FILE WRITE REQUESTS ; CKWR: ADCZ 1,1 ; FORCE LB = 177777 kCKWR1: MOV# 1,1,SZC ; WAS WRITE REQUEST LEGAL ? JMP @.W2FAR ; NO- END OF FILE ERROR LDA 0,UDBBK,2 ; AC0 <= LAST BLOCK IN FILE USGE 1,0 ; LB REQUESTED .GE. LB IN FILE ? JMP CK4 ; NO- OK TO DO I/O STA 1,UDBBK,2 ; YES- SET LAST BLOCK LDA 1,K1000 ; lAC0 <= # BYTES IN FULL BLOCK STA 1,UFTBC-UFTDC,2 ; SET BYTES IN LAST BLOCK = 1000 ; ALLOCATE BLOCKS WHERE NECESSARY, THEN DO I/O CK4: JSR BCHK ;GET AND INIT BUF, IF NECESSARY CK2: LDA 2,DCBSV,3 LDA 0,@WDSAV,3 ;GET DISK POINTER MOVL# 2,2,SNC SUB 0,0f+,SKP ;NON-3330 - HIGH ORDER ZERO ISZ WDSAV,3 LDA 1,@WDSAV,3 ;LOW ORDER MOV# 0,0,SZR ;ZERO? JMP CNXT ;NO - CHECK NEXT BLOCK MOV# 1,1,SZR JMP CNXT ;LIKEWISE JSR @.FLAK1 ;ZERO - ALLOCATE A BLOCK WDBLK .IFE IOSW JMP ER0 .ENDC .IFN IOSW JMP .ERT .ENDC LDA 2,DCBSV,3 ; AND STORE IN INDEX MAP: MOVL# 2,2,SNC ;3330? JMP .+3 LDA 2,WDSAV,3 STA 0,-1,2 ;YES - HIGH ORDER STA 1,@WDSAV,3 ;LOW ORDER LDA 2,BUFD1,3 ; BUFFER ADDRESS OF MAP JSR @.SETMOD ;INDEX MAP HAS CHANGED CNXT: LDA 2,DCBSV,3 ;STOFRE INDEX IN BUFFER: MOVL# 2,2,SNC JMP .+3 STA 0,@MODE,3 ;3330 - HIGH ORDER ISZ MODE,3 STA 1,@MODE,3 ;LOW DSZ BLKS,3 ; DONE ? JMP CK5 ;NO LDA 2,TMPBQ,3 ;YES-SET DUMMY HEADER FOR WRITE JSR@ .SETMOD JMP DAIO ;GO DO WRITE CK5: JSR NXTBL ; YES, .GET NEXT INDEX BLOCK JMP CK2 ; NO, CHECK NEXT BLOCK .W2FAR: W2FAR K1000: SCDBS*2 .RDNBK: RDNBK .RELZT: RELZT .ASBUF: ASBUF .FLAK1: FLAK1 ER0: LDA 2,BUFD1,3 ; RELEASE INDEX BLOCK JSR @.RELZT ER1: LDA 2,TMPBQ,3 ; GET THE BUFFER HEADER LDA 1,BQNBK,2 ; AND THE NUMBER OF BLOCKS TO MOVE LDA 2,BQARD,2 ; ADDRESS OF BUFFER TO RELEASE #MOVZR 1,1,SNR ; UNLESS ONLY 1 BLOCK IS INVOLVED SUBZR 2,2 ; THEN SHOW NO BUFFER STA 2,BUFD1,3 .IFN IOSW .ERT: LDA 2,TMPBQ,3 ;IOCS - GET THE BUFFER HEADER ISZ BQUST,2 R ;IOCS - SET DONE .ENDC JMP @TERT ; CLEAN UP AND RETURN TERT: EDONE .END BLKIO.SRB + ; ; ; BLOCK I/O MANAGEMENT ; ; RTITLE BLKIO .NREL .ENT RDNBK,RDLBK,RDCBK .ENT RDBLK,RDBNO .EXTN GPATH,CPATH,FPATH ; GET/FREE PATH .EXTN CLEAR ;CORE CLEAR .EXTN SETMOD ;SET MODIFIED BIT .EXTN WDBLK,DEBLK ;WITHDRAW & DEPOSIT BLOCK .EXTN OVLAY .EXTN ASBUF ;ASSIGN BUFFER .IFE BSW!MBSW .EXTN ROX ;EXCLUSIVE OR .ENDC .EXTN RLMPB ;RELEASE MODIFIED,PREFERRED ; BUFFER .EXTN DIVI ;DIVIDE .EXTN RELMB,RELPB ;RELEASE BUFFERS CALLS .EXTN RELB ;RELEASE BUFFER .EXTN OVLY1 ;ALT OVERLAY CALL .EXTN BLKIN ;INPUT DISK BLOCK .EXTN RETER ;ERROR RETURNER .EXTN FLAKE,FLAK1 ;TRICK OVERLAY CALL .EXTN RELZT ;RELEASE BUFFER WITH ZERO TLA .EXTN DLOCK,DUNLOCK ;DUAL PROCESSOR STUFF FOR ; EXTENDING FILES ; ROUTINE TO READ THE CURRENT BLOCK OF A DISK FILE ; ; INPUTS: AC2 - DCB ADDRESS ; ; OUTPUTS: AC1 - BUFFER ADDRESS OF BLOCK ; ; RETURNS: CALL+1 - ERROR...CODE IN CTMP2 OF CURRENT CELL ; CALL+2 - GOOD RETURN ; NOTE - IF CALLED WITH CA = 0, IT MUST BE COVERED WITH A LOCK ; IN DUAL PROCESSOR WORLD, SINCE IT WITHDRAWS A BLOCK LNKAD=TMP RDCBK: RSAVE 1 LDA 0,DBCA1,2 ; HIGH ORDER OF ADDRESS LDA 1,DCBCA,2 ; LOW ORDER MOV# 0,0,SZR ; IS ACURRENT ASSIGNED ? JMP RDCIN ; YES MOV# 1,1,SNR ; LAST CHANCE JMP QDON ;NO - GO WITHDRAW RDCIN: JSR@ .BLKIN RTRN ;ERROR STA 0,OAC1,3 ;RETURN BUFFER ADDRESS JMP DOLNK ;GO SET LINKS QDON: JSR @.FLK1 ;ASSUME THE CALLER KNOWS WDBLK ; WHAT HE'S DOING RTRN ;ERROR........ RDCAL: STA 0,DBCA1,2 ; SET IN DCB STA 1,DCBCA,2 LDA 3,DCBCB,2 ; IS IT ASSIGNED MOV# 3,3,SZR JMP RDIN STA 0,DBFA1,2 STA 1,DCBFA,2 RDIN: JSR@ .ASBU ;ASSIGN A BUFFER LDA 0,BLKWZ ;WORDS PER BLOCK MOV 1,2 ;BUFFER ADDRESS STA 2,OAC1,3 ;RETURN BUFFER ADDRESS JSR@ .CLR ;CLEAR DATA PORTION OF BLOCK LDA 3,OAC2,3 ;DCB ADDRESS SUWB 1,1 STA 1,DCBNA,3 ;NEXT ADDRESS IS UNASSIGNED STA 1,DBNA1,3 ; NEXT ADDRESS =0 LDA 0,DBLA1,3 ; GET HIGH ORDER FOR LINK LDA 1,DCBLA,3 ;LAST ADDRESS LDA 3,DCBDC,3 ; DCT ADDRESS LDA 3,DCTCH,3 ; CHARACTERISITC MOVL 3,3 ; SET CARRY LDA 3,NXOFF ;NEX.T'S OFFSET ADD 2,3 STA 1,0,3 ; LINK = LA .XOR. 0 MOV# 0,0,SZC ; DOUBLE WORD LINK ? STA 0,-1,3 ; YEP JSR@ @.SETMO ;BUFFER IS MODIFIED LDA 0,BQST,2 ;BUFFER STATUS LDA 1,IOIP ;IO IN PROGRESS MASK AND 1,0 ;TURN IT OFF STA 0,BQST,2 ISZ ORTN,3 ;LjGOOD RETURN RTRN ;RETURN .CLR: CLEAR NXOFF: BQNXL .FLK1: FLAK1 .BLKIN: BLKIN .ASBU: ASBUF BLKWZ: SCWPB .SETMO: SETMOD IOIP: -QTIOP-1 DOLNK: ISZ ORTN,3 ; GOOD RETURN NOW LDA 1,NXOFF ;OFFSET TO BUFFER LINK ADD 0,1 ;ADDRESS OF LINK STA 1,LNKAD,3 ;h SAVE LINK ADDRESS MOV 1,3 LDA 1,0,3 ;LOAD LINK LDA 0,DBLA1,2 ;LAST ADDRESS COM# 0,0,SNR ;-1 ? JMP SLA ;YES - GOING BACKWARDS LDA 0,DCBLA,2 ; GET LOW ORDER LAST ADDRESS .IFE BSW!MBSW JSR@ .XOR .ENDC SKIP XOR 0,1 [SKIP] STA 1,DCBNA,2 ; SET LOW HALF OF NEXT ADDRESS LDA 3,DCBDC,2 ; DCT ADDRESS LDA 0,DCTCH,3 ; CHARACTERISITC MOVL# 0,0,SNC ; DOUBLE WORD ADDRESSING ? RTRN ; NO LDA 3,CSP LDA 3,LNKAD,3 ; LINK ADDRESS LDA 0,DBLA1,2 ; LAST ADDRESS LDA 1,-1,3 ; HIGH ORDER LINK WORD .IFE BSW!MBSW JSR @.XOR .ENDC SKIP XOR 0,1 [SKIP] STA 1,DBNA1,2 ; SET FIRST HALF OF NEXT ADDRESS RTRN SLA: LDA 0,DCBNA,2 .IFE BSW!MBSW JSR@ .XOR .ENDC SKIP XOR 0,1 [SKIP] STA 1,DCBLA,2 LDA 3,DCBDC,2 ; DCT LDA 0,DCTCH,3 ; CHARACTERISTIC MOVL# 0,0,SNC ; B%IG DISK ? JMP CLRLA ; CLEAR HIGH ORDER LAST ADDRESS LDA 3,CSP LDA 3,LNKAD,3 LDA 0,DBNA1,2 ; HIGH ORDER NEXT ADDRESS LDA 1,-1,3 ; LINK .IFE BSW!MBSW JSR @.XOR .ENDC SKIP XOR 0,1 [SKIP]SETLA:STA 1,DBLA1,2 ; SET LAST RTRN .IFE BSW!MBSW .XOR: ROZX .ENDC CLRLA: SUB 1,1 JMP SETLA ; ROUTINE TO READ THE NEXT BLOCK OF A DISK FILE ; ; INPUTS: AC2 - DCB ADDRESS ; ; OUTPUTS: AC1 - BUFFER ADDRESS OF BLOCK ; ; RETURNS: CALL+1 - ERROR...CODE IN CTMP2 OF CURRENT CELL ; CALL+2 - GOOD RETURN ; NOTE - IF RDNBK IS CALLED WITH CA = -1 AND NA = 0, ; IT MUST BE COVERED WITH A LOCK IN DUAL PROCESSOR ; WORLD, SINCE IT BLINDLY WITHDRAWS A BLOCK. ADTM1= TMP+2 ADTMP= TMP+1 ULKY=TMP RDNBK: RSAVE 3 LDA 0,DBNA1,2 ; NEXT ADDRESS HIGH ORDER MOV# 0,0,SZR ; IS ITo8 ASSIGNED JMP NBKOK ; IT SURE IS LDA 0,DCBNA,2 ;NEXT ADDRESS MOV# 0,0,SZR ;IS IT ASSIGNED ? JMP NBKOK ;YES LDA 1,DCBCB,2 ;CUR BLOCK NUMBER COM 1,1,SNR ;TRYING TO READ FIRST BLOCK? JMP RDN1 ;YES ; HAVE NO NEXT BLOCK, MAKE SURE NO ONE ELSE ON PATH BEFORE TRY FOR ONE JSR @.GPATH ; GET CONTROL OF PATH RDNFG ; PULL IN CURRENT BLOCK SO CAN SEE IF A LINK HAS BEEN INSERTED JSR RDCBK ;READ CURRENT ONE JMP YRET ;ERROR...... ; CHECK TO SEE IF GOT AN ADDR OF A NEXT BLOCK NOW LDA 0,DBNA1,2 ; IF NOW EHAVE ADDRESS OF MOV# 0,0,SZR ; NEXT BLOCK THEN JMP NBKOB ; GO USE IT LDA 0,DCBNA,2 ; MOV# 0,0,SZR JMP NBKOB ; DON'T HAVE A NEXT ADDRESS, SO LOCK BLOCK WHILE GET A NEXT MOV 1,2 ;BUFFER ADDRESS JSR @.DLOCK ;LOCK WHILE WE FIGURE OUT STA 0,ULKY,3 ; WHAT TO PUT IN IT JSR @.RELB ;MAKE ROOM FOR WDBLK LDA 2,OAC2,3 ;CALLER'S DCB JSR @.FLAK1 WDBLK ;GET A FREE BLOCK JMP URET ;ERROR - MUST UNLOCK CURR. BLOCK STA 0,ADTM1,3 ;REMEMBER ADDRESS STA 1,ADTMP,3 JSR RDCBK ;GET CURRENT BACK JMP ZRET ;ŴERROR - MUST GIVE BACK ; WITHDRAWN BLOCK & UNLOCK CURR. MOV 1,2 ;BUFFER ADDRESS STA 2,OAC1,3 LDA 1,NXOFF ;OFFSET OF LINK WORD ADD 1,2 ;ADDRESS OF LINK WORD LDA 1,0,2 ;BLOCK LINK WORD LDA 0,ADTMP,3 ;NEW BLOCK ADDR, LO .IFE BSW!MBSW JSR@ .XOR8 ;EXCLUSIVE OR WITCH LINK WORD .ENDC SKIP XOR 0,1 [SKIP] STA 1,0,2 ; PUT BACK LDA 3,OAC2,3 ; GET DCB ADDRESS LDA 3,DCBDC,3 ; DCT ADDRESS LDA 0,DCTCH,3 ; CHAR LDA 3,CSP ; RESTORE AC3 MOVL# 0,0,SNC ; WELL ? JMP OKSKP LDA 1,-1,2 ; NOW DO SECOND LINK WORD LDA 0,ADTM1,3 ; GET DISK ADDRESS .IFE BSW!MBSW JSR @.XOR .ENDC SKIP XOR 0,1 [SKIP] STA 1,-1,2 ; LINK IS SET OKSKP: LDA 2,OAC1,3 ;TEMP BUFFER ADDRESS SUB 1,1 STA 1,BQTLA,2 ;FLAG AS PREFERED JSR@ .RLMPB LDA 2,OAC2,3 ;DCB ADDRESS LDA 1,DCBCA,2 ;CURRENT ADDRESS LDA 0,DBCA1,2 JMP PRIN RDN1: SUB 0,0 ; ADVANCE ADDRESSES SUB 1,1 PRIN: STA 0,DBLA1,2 STA 1,DCBLA,2 LDA 0,ADTM1,3 ; GET DISK ADDRESS LDA 1,ADTMP,3 ISZ DCBCB,2 ;BUMP CURRENT BLOCK JMP RDN2 ; IS LINK TO PREVIOUS BLOCK JMP @.+1 ;WAS -1: MUST WITHDRAW QDON ;WITHDRAW & READ CURRENT ; GO SETUP ACCESS TO NEW BLOCK RDN2: JSR RDN3 ; IS REALLY A CALL TO RDCAL JMP .+1 ; NO ERROR POSSIBLE ; RETURN ADDRESS OF BUFER TO CALLER STA 1,OAC1,3 ; UNLOCK THE BLOCK THAT PRECEEDS THE NEW* BLOCK LDA 0,ULKY,3 JSR @.DUNLOCK ; & UNLOCK IT ; FREE THE GET NEXT BLOCK PATH FOR ACCESSS JSR @.FPATH RDNFG ; RETURN TO CALLER WITH NO ERROR ISZ ORTN,3 RTRN ; FAKE ENTRY TO RDCAL RDN3: RSAVE 1 JMP @.+1 RDCAL NBKOB: MOV 1,2 ; GET BUFFER ADDR FOR RELEASE JSR @.RLZT ; RELEASE IN ZERO TIME JSR @.FPATH ; FREE THE PATH RDNFG LDA 2,OAC2,3 ; PICK UP DCB ADDRESS NBKOK: LDA 0,DCBCA,2 ;CURRENT ADDRESS STA 0,DCBLA,2 ;GOES TO LAST ADDRESS LDA 0,DBCA1,2 ; CURRENT ADDRESS STA 0,DBLA1,2 ; GOES TO LASThl ADDRESS LDA 0,DCBNA,2 ;NEXT ADDRESS STA 0,DCBCA,2 ;GOES TO CURRENT ADDRESS LDA 0,DBNA1,2 ; NEXT ADDRESS STA 0,DBCA1,2 ; GOES TO CURENT ADDRESS ISZ DCBCB,2 ;BUMP CURRENT BLOCK NUMBER JMP .+1 JMP @.+1 RDCIN RDNFG: -1 ; CREATE NEXT SEQUENCIAL BLOCK2 PATH LOCK FLAG .RLMPB: RLMPB .RLZT: RELZT .DLOCK: DLOCK .DUNLOCK:DUNLOCK ZRET: LDA 1,ADTMP,3 ;GET BACK LO OF WITHDRAWN BLOCK JSR @.FLAK1 DEBLK ;RETURN BLOCK JMP .+1 URET: LDA 0,ULKY,3 JSR @.DUNLOCK ;UNLOCK CURRENT BLOCK ; FREE THE PATH ON ERROR YREPbT: JSR @.FPATH RDNFG ; RETURN TO CALLER WITH ERROR RTRN ; ROUTINE TO READ THE LAST BLOCK OF A DISK FILE ; ; INPUTS: AC2 - DCB ADDRESS ; ; OUTPUTS: AC1 - BUFFER ADDRESS OF BLOCK ; ; RETURNS: CALL+1 - ERROR...CODE IN CTMP2 OF CURRENT CELL ; CALL+2 - GOORvD RETURN RDLBK: RSAVE 1 LDA 0,DCBLA,2 ;LAST ADDRESS MOV# 0,0,SZR ;IS THERE ONE ? JMP TSTOK ; GOT ONE LDA 0,DBLA1,2 ; TRY BOTH WORDS MOV# 0,0,SNR JMP POUT ; ERROR - BEGINNING OF FILE TSTOK: LDA 0,DCBCA,2 ;CURRENT ADDRESS STA 0,DCBNA,2 ;GOES TO N}EXT ADDRESS LDA 0,DBCA1,2 STA 0,DBNA1,2 LDA 0,DBLA1,2 STA 0,DBCA1,2 LDA 0,DCBLA,2 ;LAST ADDRESS STA 0,DCBCA,2 ;GOES TO CURRENT ADDRESS ADC 0,0 STA 0,DCBLA,2 ;-1 GOES TO LAST ADDRESS STA 0,DBLA1,2 DSZ DCBCB,2 ;DEC. CURRENT BLOCK NUMBER JMP .+1 JMP @.+1 ; NOW READ AS CURRENT BLOCK RDCIN POUT: JSR @.PNIC PNIDA .GPATH: GPATH .FPATH: FPATH .RELB: RELB .FLAK1: FLAK1 ; ROUTINE TO READ A BLOCK FROM A DISK FILE ; ; INPUTS: AC2 - UFT ADDRESS ; ; OUTPUTS: AC0 - BUFFER ADDRESS OF BLOCK ; ; RETURNS : CALL+1 - ERROR...CODE IN CTMP2 OF CURRENT CELL ; CALL+2 - GOOD RETURN WDSAV=TMP ;WORD OFFSET IN MAP DCBSV=WDSAV+1 ;SAVE DCB ADDRESS TDCT=DCBSV+1 ;DCT ADDRESS TUN=TDCT+1 ;UNIT NO TCA1=TUN+1 ; DEVICE ADDRESS (HIGH ORDER) TCA=TCA1+1 ;DEVICE ADDRESSx (LOW ORDER) BUFSV=TCA+1 ; BUFFER ADDRESS SAVE RDBLK: RSAVE 7 LDA 1,DCBOFF ;OFFSET FROM UFT TO DCB ADD 1,2 ;DCB ADDRESS OF FILE LDA 1,UFTAT-UFTDC,2 ;FILE ATTRIBUTES LDA 0,CONAT ; CONTIGUOUS ATTRIBUTE AND# 1,0,SNR ; IS IT CONTIGUOUS? JMP NONCT p; NO LDA 0,UDBBN,2 ; REQUESTED BLOCK # LDA 1,UDBBK,2 ; LAST BLOCK # SUBZ# 0,1,SNC ; REQUEST MUST BE <= LAST JMP RCTER ; READ CONTIGUOUS ERROR LDA 3,UDDL,2 ; HIGH ORDER STARTING ADDRESS LDA 1,ADMSK ; ONLY GET SIGNIFICANT BITS ANDS 1,3 ; SET UP AS WORD LDA 1,UDBAD,2 ; STARTING ADDRESS OF FILE ADDZ 0,1,SZC ; LOGICAL ADDRESS OF REQUESTED(TEST OVERFLOW) INC 3,3 MOV 3,0 ; ALL SET NOW LDA 3,CSP ; RESTORE STACK POINTER JMP BLKOE ; GO GET IT RCTER: JSR @.RETER ; RETURN EOF CODE EREOF ADMSK:m ATMSK NOIP: -QTIOP-1 NONCT: LDA 0,RANAT ;RANDOM ATTRIBUTE BIT AND# 0,1,SNR ;IS IT A RANDOM FILE ? JMP RDSAL ;NO - ENTER SEQUENTIAL ; PROCESSING LDA 3,DCBDC,2 ; DCT ADDRESS LDA 1,DCTCH,3 ; GET CHARACTERISITCS TO SET BIG DISK FLAG LDA 3,CSP ; RESTORE STACK POINTER MOVZL 2,2 ; STORE FLAG IN DCB POINTER MOVL 1,1 ; GET BIT MOVR 2,2 ; SET IN ADDRESS STA 2,DCBSV,3 ;SAVE DCB ADDRESS LDA 1,UFTBN-UFTDC,2 ;BLOCK NUMBER LDA 0,WPB ; WORDS PER BLOCK MOVL# 2,2,SZC ; USING DOUBLE ADDRESSING ? MO}VZR 0,2,SKP ; YEP, HALF AS MANY ENTRIES PER BLOCK MOV 0,2 ; BLOCK SIZE IS OK NOW JSR@ .IDIV ;DIVIDE LDA 2,DCBSV,3 ;DCB ADDRESS MOVL# 2,2,SZC ; BIG DISK ? MOVOL 0,0 ; TWO WORDS PER ENTRY STA 0,WDSAV,3 ; REMAINDER IS OFSET OF REAL ADDRESS MOV 1,0zn ;DESIRED BLOCK NUMBER TO AC0 JSR RDSBK ;READ SEQUENTIAL BLOCK RTRN ;ERROR........ LDA 2,WDSAV,3 ;WORD OFFSET ADD 0,2 ;ADDRESS OF DEVICE ADDRESS STA 0,BUFSV,3 ; SAVE BUFFER ADDRESS STA 2,WDSAV,3 ;WORD ADDRESS IN BUFFER JMP NONC2 ; GO SEE IF GOT BLOCK ASSIGNED ; NO BLOCK ASSIGNED AND SOMEONE IS DOING AN ASSIGN, WAIT FOR THEM ; TO GET DONE NONC1: JSR @.GPATH ; WAIT FOR PATH TO BE FREE RDBFG JSR @.FPATH ; FREE PATH JUST GOTTEN RDBFG ; GET WORD ADDR IN BUFFER LDA 2,WDSAV,3 ; CHECK TO SEE IF ;BLOCK IS AASSIGNED NONC2: LDA 0,-1,2 ; GET FIRST WORD OF ADDRESS LDA 1,0,2 ; GET SECOND WORD OF ADDRESS LDA 2,DCBSV,3 ; GET DCB ADDRESS WITH TYPE FLAG BACK MOVL# 2,2,SNC ; DOUBLE PRECISION ? SUB 0,0 ; NO, HIGH ORDER IS ZERO MOV# 1,1,SZR ; IS IT A4MSSIGNED ? JMP BLKOK ; YES, GO READ IT MOV# 0,0,SZR ; TEST HIGH ORDER JMP BLKOK ; ASSIGNED LDA 2,DCBST,2 ; STATUS MOVL# 2,2,SZC ; READ OR WRITE? JMP READ ; NEED TO ASSIGN A BLOCK, MAKE SURE PATH IS FREE JSR @.CPATH ; IF PATH IS NOT RDBFG ; FR$EE THEN GO WAIT JMP NONC1 ; TILL NO ONE ASSIGNING BLK ELSE ; ASSIGN A BLOCK, KNOWING THAT NO ONE ELSE CAN DO SO AT SAME TIME LDA 2,DCBSV,3 ;DCB JSR @.FLAK1 WDBLK JMP RELBF ; ERROR...RELEASE THE BUFFER LDA 2,WDSAV,3 ;POINTER IN INDEX STA 1,0,2 ; SET LO ORDER ADDRESS IN INDEX LDA 3,DCBSV,3 MOVL# 3,3,SZC ;DOUBLE ADDRESSING? STA 0,-1,2 ;OF COURSE - PUT IN INDEX LDA 3,CSP JMP RAN ;SKIP RELEASE - HOLD ON TO INDEX ;TILL IT IS VALID (WE MAY BE IN ;DUAL PROCESSOR WORLD) - IF WE ;CAN HOLD IT & CALL WDBLK WITHOUT ;DEADLOCK, WE CAN HOLD & ASBUF RDBFG: -1 ; ASSIGN BLOCK PATH IN USE FLAG .CPATH: CPATH ; CHECK IF PATH IN USE ROUTINE READ: LDA 2,BUFSV,3 ; RECOVER BUFFER ADDRESS JSR @.RELPB RAN: LDA 2,DCBSV,3 ;DCB ADDRESS  STA 1,TCA,3 ;dSAVE THIS ADDRESS JSR@ .ABU ;ASSIGN A BUFFER MOV 1,2 ;BUFFER ADDRESS STA 0,BQCA1,2 ;SET DEVICE ADDRESS IN BUFFER LDA 0,TCA,3 ; GET LOW ORDER STA 0,BQCA,2 ; SET REST OF DEVICE ADDRESS IN BUFFER LDA 0,WPBLK STA 1,OAC0,3 ;RETURN BUFFER ADDRESS JSR@ 6.CLEAR ;CLEAR BUFFER ISZ ORTN,3 ; GOOD RETURN NOW LDA 0,BQST,2 ;BUFFER STATUS LDA 1,NOIP ;-IO IN PROGRESS BIT AND 0,1 STA 1,BQST,2 LDA 3,OAC2,3 ; UFT ADDRESS LDA 0,UFTST,3 ; STATUS MOVL# 0,0,SZC ; READ OR WRITE? RTRN ;READ JSR @SETM1 ; WRIrTE, SET MODIFIED BIT LDA 2,BUFSV,3 ;NOW WE CAN JSR @.RELMB ; RELEASE THE INDEX BLOCK JSR @.FPATH RDBFG ; FREE THE ASSIGN BLOCK PATH RTRN RELBF: LDA 2,BUFSV,3 ; BUFFER ADDRESS JSR @.RELZT ; RELASE THE BUFFER JSR @.FPATH ; FREE THE PATH RDBFEG RTRN ; RETURN TO CALL+1 .CLEAR: CLEAR WPB: SCWPB .IDIV: DIVI DCBOF: UFTDC RANAT: ATRAN CONAT: ATCON WPBLK: SCWPB+1 .TDCT: TDCT .RELMB: RELMB .RELPB: RELPB SETM1: SETMO .RETER: RETER .BLKN: BLKIN .ABU: ASBUF  BLKOK: LDA 2,BUFSV,3 ; BUFFER ADDRESS  JSR@ .RELPB ;RELEASE BUFFER LDA 2,DCBSV,3 ;DCB ADDRESS BLKOE: STA 0,TCA1,3 ; SAVE DEVICE ADDRESS ON STACK STA 1,TCA,3 ;SAVE DEVICE ADDRESS ON STACK LDA 0,DCBDC,2 ;DCT ADDRESS STA 0,TDCT,3 ;TO STACK LDA 0,DCBUN,2 ;AND UNIT STA 0,TUN,3 LDA 2,.TDCT  ADD 3,2 JSR@ .BLKN ;INPUT BLOCK RTRN ;ERROR....... STA 0,OAC0,3 ;RETURN BUFFER ADDRESS ISZ ORTN,3 ;GOOD RETURN RTRN ; ROUTINE TO READ A SEQUENTIAL BLOCK OF A DISK FILE ; ; INPUTS: AC2 - DCB ADDRESS ; ; OUTPUTS: AC0 - BUFFER ADDRESS OF BLOCK ;f ; RETURNS: CALL+1 - ERROR...CODE IN CTMP2 OF CURRENT CELL ; CALL+2 - GOOD RETURN TDCB=TMP+1 RDSAL: LDA 0,UFTBN-UFTDC,2 ;BLOCK NUMBER DESIRED JMP RDSIN RDBNO: RDSBK: RSAVE 2 RDSIN: LDA 1,DCBCB,2 ;CURRENT BLOCK NUMBER SUBZ 1,0,SNR ;ARE WE THERE? JMPW1 RDC ;YES - READ CURRENT COM# 1,1,SNR ; IF HAVE NOT READ ANY BLOCKS OF MOVO 1,1 ; SET THAT MUST READNEXT BLOCK STA 2,TDCB,3 ;SAVE DCB ADDRESS LDA 2,DCBDC,2 ;DCT ADDRESS LDA 1,DCTRL,2 ;READ LAST ADDRESS MOV# 0,0,SNC ;AHEAD OR BEHIND JMP RDB1 ;BEHIND NEG 0,0 LDA 1,DCTRN,2 ;READ NEXT ADDRESS RDB1: STA 1,TMP,3 ;SAVE ON STACK RDLP: LDA 1,TMP,3 ;ROUTINE ADDRESS LDA 2,TDCB,3 ;DCB ADDRESS RDLP1: LDA 3,.FLK ;OVLAY ROUTINE ADDRESS MOVL# 1,1,SNC ;OVERLAY OR FIXED CODE? MOV 1,3 ;FIXED - JUMP DIREC]T JSR 0,3 ;GO TO IT RTRN ;ERROR........ INC 0,0,SNR ;DONE ? JMP RETN ;YES MOV 1,2 JSR @.RELZT ;RELESE PREFERED JMP RDLP ;LOOP BACK RDC: LDA 3,DCBDC,2 ;DCT ADDRESS LDA 1,DCTRDB,3 ;DISPATCH ADDRESS LDA 3,CSP ;STACK POINTER STA 1,TMP,3 ;SAVE SEG ADDRESS IN TMP ADC 0,0 ;-1 JMP RDLP1 ;ENTER COMMON CODE RETN: STA 1,OAC0,3 ISZ ORTN,3 ;GOOD RETURN NOW RTRN .FLK: FLAKE .RELZT: RELZT .END FILIO.SRB&/ ; ; FILE MANAGEMENT MODULE RTITLE FILIO .NREL .ENT BLKIN ; BLOCK INPUT .ENT ASBUF ; ASSIGN A BUFFER .ENT FIDCB,FNDCB ; FULL INIT OF DCB .ENT IDCB ; PLAIN DCB INIT .ENT RELB ; RELEASE A BUFFER .ENT RELMB ; RELEASE A MODIFIED BUFFER .ENT RELPB ; RELEASE A PREFERRED BUFFER .ENT RELZT ; RELEASE BUF & ZERO TLA .ENT RELDB ; RELEASE & CLEAR DCT & STATUS .ENT RLMPB ; RELEASE MODIFIED PREFERRED .ENT SETMOD ; SET BUFFER MODIFIED BIT .ENT PSHRD ; READ IN PUSH DIRECTORY .ENT BMOVE ; INDREX CONDENSE FOR PUSH I/O .ENT FLUSH,BFLUSH ; FLUSH FILE BUFFER POOL .ENT WAIT ; WAIT FOR I/O TO COMPLETE .ENT WAITF ; WAIT FOREVER .ENT PEND,UNPEND ; TASK PEND,UNPEND .ENT PENDR .ENT GPATH,GPATJ ; GET USE OF PATH .ENT FPATH,FPATJ ; FREEE PATH FOR >USE .ENT CPATH,CPATJ ; CHECK IF PATH IN USE .ENT MODOUT ; FLUSH ONE BLOCK ; WITHOUT USING THE STACK .ENT QUENT ; Q AN I/O REQUEST .ENT GBLKNO ; BAD BLOCK MAPPER .ENT STCONT,ENCONT ;BAD BLOCK POOL GLOBAL VARIABLES .ENT STLINK,BLIST ; " .ENT DSqxKDT ; DISPATCH TABLE .IFN MSW .ENT SWAMP ; DATA CHANNEL MAPPER .ENDC .ENT XDIA,XIAC ; NOTE - IOBUF DEFINES ITS OWN .ENT XDIB,XDIBC ; XDIAC,XDIAP,XNIOC,XNIOS,XSKPB .ENT XDIC,XDICC .ENT XDOA,XOAS,XDOAP,XDOAC .ENT XDOB,XDOBS,XDOBP .ENT XDOC,XDOCS,XDOCP .ENT XNOC,XNOS .EXTN BQ ; BUFFER Q CHAIN START ADDRESS .EXTN BUFNT ; COUNT OF BUFFER WAITERS .EXTN SYSTM ; ADDRESS OF SYSTEM TIME .EXTN UPQUE ; Q DIRECTOR .EXTN INTSK .EXTN SMNXT ; SYSTEM MONITOR ENTRY .EXTN SMON1 ; SYSTEM MONITOR ENTZRY (TOP) .EXTN PS1 .EXTN SACHN ; ACTIVE CHAIN .EXTN TUNE,TUBUF,TUPBUF ; TUNING STUFF .EXTN STCOT,STLIK ;START & END OF BAD BLOCK POOL .EXTN RETER,DIRR .EXTN DGRAB,IPBQ ;IPB STUFF .EXTN DFRS,DFWS .EXTN DFRR,DFWR .EXTN DFRL,DFWL .EXTN DSKO,DSKC,DSYKA ; OPEN,CLOSE,APPEND .EXTN DFRO,DFEO,DFTO ; READ ONLY, EXCLUSIVE, TRANSPARENT OPENS .IFN MBSW .EXTN IUD .ENDC .IFN IOSW .EXTN MPOFF .ENT WAITS .ENDC .IFN MSW .EXTD C31K .EXTN PT2 .ENDC .IFE BSW!MBSW .EXTN SETFL ; LOGICAL OR ROUTINE .E XTN SRTN .ENDC ; ROUTINE TO ASSIGN A BUFFER ; ; INPUTS: AC2 - DCB ADDRESS ; - IF AC2 = 0 THEN SETUP AS A DATA BUFFER ; ; OUTPUTS: AC1 - BUFFER ADDRESS ( NOTE IOP IS SET ) ; ; RETURNS: CALL+1 ; ; NOTE: NO DUAL PROCESSOR INTERLOCKING IS PERFORMED; ; THUSu, IF YOU ASSIGN A BUFFER & WRITE IT TO A DISK, ; YOU MUST COVER YOURSELF WITH A LOCK. ; ROUTINE TO RETURN A GIVEN DISK BLOCK ; ; INPUTS: AC2 - DCB ADDRESS ( DCT TRIPLET ) ; ; OUTPUTS: AC0 - BUFFER ADDRESS ; ; RETURNS: CALL+1 - ERROR ; CALL+2 - SUCCESS ; BUFFR=TMP ; BUFFER BFTLA=BUFFR+1 ; BUFFER TIME LAST ASSIGNED ENTSW=BFTLA+1 ; ENTRY SWITCH BLKIN: MOVOL 2,2,SKP ; BLOCK IN ENTRY ASBUF: MOVZL 2,2 ; ASSIGN BUFFER ENTRY MOVZR 2,2 ; RESET 1B0 OF DCB ADDRESS RSAVE 3 SUBL 0,0 ; 0 = BLKIN STA 0,ENTSW,3 ; 1 = ASBUF JSR @.TUNE ; COUNT BUFFER REQUESTS TUBUF RETRY: SUB 0,0 ; +0 STA 0,BUFFR,3 ; INIT THE STACK VARIABLES STA 0,BFTLA,3 LDA 2,BQAD ; FWA OF BUFFER QUEUE JMP .+2 BUFLP: LDA 2,BQNXT,2 ; NEXT BUFFER MOVL# 2,2,SZC ; ANY LEFT ? JMP RHESLV ; NO, GO RESOLVE LDA 0,ENTSW,3 ; YES, GET ENTRY SWITCH MOV 0,0,SZR ; BLOCK IN SEARCH ? JMP ASBF1 ; NO LDA 3,OAC2,3 ; ADDRESS OF DCB QUAD LDA 0,DCBCA,3 ; CURRENT ADDRESS LDA 1,BQCA,2 ; & SAME FOR BUFFER SUB# 0,1,SZR ; MATCH ? JMP NOMAT ; NeOPE LDA 0,DBCA1,3 ; CURRENT ADDRESS (HIGH ORDER) LDA 1,BQCA1,2 ; AND SAME FOR BUFFER ? SUB# 0,1,SZR ; MATCH ? JMP NOMAT ; NO LDA 0,DCBUN,3 ; UNIT # LDA 1,BQUN,2 ; SAME FOR BUFFER SUB# 0,1,SZR ; MATCH ? JMP NOMAT LDA 0,DCBDC,3 ; DCT ADDRESS LDA-$ 3,CSP ; STACK POINTER LDA 1,BQDCT,2 ; BUFFER'S DCT SUB# 0,1,SNR ; MATCH THEM ALL ? JMP GOTIT ; BY JOVE! I THINK YOU'VE GOT ; IT ! NOMAT: LDA 3,CSP ; NO MATCH ASBF1: LDA 1,BQUSC,2 ; GET USER COUNT MOV 1,1,SZR ; IS THIS ONE IN USE ? JMP BUFLP L ; YES, CAN'T USE LDA 0,BQST,2 ; NO, GET BUFFER STATUS LDA 1,IOP ; GET I/O IN PROGRESS MASK AND# 0,1,SZR ; IS I/O IN PROGRESS JMP BUFLP ; YES, CAN'T USE THIS ONE LDA 1,.LKWTG ; LOCK WAITING BIT (DUAL PROCESSORS) AND# 0,1,SZR ; OTHER SIDE WAITING c>FOR THIS BLOCK? JMP BUFLP ; YES, CAN'T USE LDA 1,ERR ; ERROR MASK AND# 0,1,SZR ; IS BUFFER IN ERROR JMP ERGO ; YES, CORRECT ITS FAILINGS LDA 1,BQTLA,2 ; NO, GET TIME LAST ASSIGNED MOV 1,1,SZR ; IF TLA=0, USE ME FIRST ERGO: JMP OLDST ; NOT ZERO,@ TEST AGE MOVR# 0,0,SZC ; IS BUFFER MODIFIED ? JSR @.QUENT ; YES, START IT GOING OUT MOVR# 0,0,SZC ; SAME QUESTION JMP BUFLP ; WAS MODED, TRY SOME MORE LDA 0,ENTSW,3 ; NOT MODED, TEST ENTRY MOV 0,0,SZR ; BLKIN ENTRY ? JMP BFRTN ; NO, ASBUF, RE߂TRUN THIS ONE OLDST: LDA 0,@.STIM ; CURRENT SYSTEM TIME SUB 1,0 ; SUBTRACT TLA OF BUFFER LDA 1,BFTLA,3 ; PREVIOUS OLDEST TLA SUBZ# 1,0,SNC ; SKIP IF NEW ONE IS BETTER JMP BUFLP ; NOT QUITE STA 2,BUFFR,3 ; YES, SAVE THIS ONE STA 0,BFTLA,3 ; & TIME LAST ASSIGNED JMP BUFLP .LKWTG: QTLKW ERR: QTER BQAD: BQ .REB1: RELB .RETER: RETER .IFE BSW!MBSW .SETFL: SETFL ERMSK: STER .ENDC IOP: QTIOP .TUNE: TUNE RESLV: LDA 2,BUFFR,3 ; OLDEST BUFFER MOV# 2,2,SNR ; WAS THERE ONE ? JMP BFLP1 ; NO LDA 0,B\QST,2 ; BUFFER STATUS MOVR# 0,0,SNC ; IS IT MODIFIED ? JMP BFRTN ; NO, RETURN IT JSR @.QUENT ; YES, START IT GOING OUT JMP RETRY ; NO, KEEP LOOKING BFRTN: LDA 0,OAC2,3 ; YES, GET DCB ADDRESS LDA 1,ENTSW,3 ; ENTRY SWITCH MOV 1,1,SZR ; BLKIN ENTRY ? STA 2,OAC1,3 ; NO, ASBUF, RETURN ADDRESS IN ; AC1 MOV 1,1,SZR ; BLKIN ENTRY ? JMP BFAS1 ; NO, ASSIGN BUFFER AND GET OUT JSR BUFAS ; ASSIGN AND RETURN HERE JSR @.TUNE ; COUNT REQUESTS THAT PEND TUPBUF JSR @.DGRAB ; MUST MAKE SURE THE OTHE RR SIDE ; DOESN'T HAVE IT JSR @.QUENT ; START IT IN BLKRT: STA 2,OAC0,3 ; RETURN BUFFER ADDRESS IN AC0 JSR @.WAIT ; WAIT FOR IT JMP OUTTA ; TIME OUT - RELEASE & ERR RETURN JMP FILER ; ERROR ISZ ORTN,3 ; GOOD RETURN NOW RTRN FILER: JSR @.REBM1 ; DEC THE USER COUNT LDA 2,OAC2,3 ; DCB ADDRESS LDA 0,DCBST,2 ; DCB STATUS .IFE BSW!MBSW LDA 1,ERMSK ; ERROR MASK JSR @.SETFL ; SET THE ERROR FLAG .ENDC .IFN BSW!MBSW IORI STER,0 ; SET ERROR BIT .ENDC STA 0,DCBST,2 ; RESTORE STATUS JSR @.RETER ; ERROR RETURN TO SYSTEM ERFIL OUTTA: JSR @.REB1 ; RELEASE THE BUFFER RTRN ; ERROR RETURN GOTIT: LDA 0,BQST,2 LDA 1,.LKWTG ; LOCK WAITING (DUAL PROCESSORS) AND# 0,1,SZR ; OTHER SIDE WAITING FOR THIS BLOCK? JMP WTOTHR ; YES, MUST WAIT OUlR TURN LDA 1,.LKING ; NO, WE CAN HAVE THE BUFFER ISZ BQUSC,2 ; BUMP THE USER COUNT AND# 1,0,SZR ; LOCK IN PROGRESS? JSR LKWAIT ; YES, WAIT FOR IT TO COMPLETE LDA 0,BQDCB,2 ; PREVIOUS DCB ADDRESS MOVL# 0,0,SZC ; RESIDENT OVERLAY ? JMP NOCHG ; YENS, DON'T CHANGE OWNERS LDA 0,OAC2,3 ; DCB ADDRESS STA 0,BQDCB,2 ; DCB ADDRESS NOCHG: ISZ @.STIM ; BUMP THE SYSTEM TIME JMP .+1 LDA 0,@.STIM ; SYSTEM TIME STA 0,BQTLA,2 ; NEW TIME LAST ASSIGNED JMP BLKRT ; FINISH PROCESSING BFLP1: JSR @.TUNE ; OUT{ OF BUFFERS TUPBUF ; COUNTS AS PEND REQUEST SUBZL 1,1 ; +1 IS PEND KEY ADC 0,0 ; GO TO SLEEP FOREVER INTDS ; MUST DISABLE ISZ @.BUFNT ; BUFFER NOT THERE JSR @.PEND ; PEND JMP . ; TIME OUT IS A GOTCHA DSZ @.BUFNT ; UNCOUNT A WAITER JMP @.mRETRY JMP @.RETRY .QUENT: QUENT .BUFNT: BUFNT .RETRY: RETRY .STIM: SYSTM .WAIT: WAIT .PEND: PEND .DGRAB: DGRAB ; WAIT FOR THE OTHER SIDE TO GET THE BUFFER (IF WE DIDN'T, ; WE'D BE ALMOST GUARANTEED OF GENERATING A LOCK COLLISION), ; THEN RE-SCAN THE BbUFFER POOL. IF WE ARE BY OURSELVES ON THIS ; PATH, WE WILL SCAN THE POOL UNSUCCESSFULLY, ASSIGN A BUFFER, ; & ASK THE OTHER SIDE. HOWEVER, IF ANOTHER BLKIN IS ON THIS PATH ; SLIGHTLY AHEAD OF US, HE MAY HAVE ALREADY ASSIGNED A BUFFER, ; AND WE MUST SCAN THE ENTIRE BUFFER POOL TO ENSURE FINDING IT. WTOTHR: JSR LKWAIT JMP @.RETRY ; NOW START ALL OVER ; ROUTINE TO WAIT FOR A BIT TO GO AWAY, ; GIVEN MASK IN AC1, BUFFER ADDRESS IN AC2. LKWAIT: RSAVE LKWT: LDA 1,OAC1,3 INTDS ; LET'S BE ABSOLUTELY CERTAIN BEFORE PENDING LDA 0,BQST,2 AND# 1,0,SNR ; NOW, BIT STILL SET? JMP LKGONE ; NO MOV 2,1 ; KEY = BUFFER LDA 0,LKTIM ; HOW LONG TO WAIT JSR @.PEND JMP .+1 ; TIME OUT JMP LKWT ; MAKE SURE THIS IS FOR REAL LKGONE: INTEN RTRN LKTIM: 4 .LKIN_G: QTLKING BUFAS: RSAVE 0 BFAS1: LDA 3,BQDCB,2 ; DCB ADDRESS MOVL# 3,3,SZC ; SKIP IF OVERLAY STA 3,SGCA,3 ; SHOW AS NOT RESIDENT MOV 0,3,SNR ; INPUT DCB JMP BFAS2 ; NOT A DCB- INIT FOR DATA BUFF STA 3,BQDCB,2 ; CHANGE OWNERS LDA 0,DCBUN,3 ; UNITc # STA 0,BQUN,2 ; IS NEW LDA 0,DBCA1,3 ; CURRENT ADDRESS (HIGH ORDER) STA 0,BQCA1,2 ; IS NEW LDA 0,DCBCA,3 ; CURRENT ADDRESS STA 0,BQCA,2 ; IS NEW LDA 0,DCBDC,3 ; AND DCT ADDRESS STA 0,BQDCT,2 ; IS ALSO NEW LDA 0,IOP ; I/O IN PROGRESS STATUS STA P)0,BQST,2 ; IS NEW STATUS BFAS3: ISZ BQUSC,2 ; BUMP THE USER COUNT ISZ @.STIM ; BUMP THE SYSTEM TIME JMP .+1 LDA 0,@.STIM ; GET THE SYSTEM TIME STA 0,BQTLA,2 ; NEW TLA RTRN BFAS2: SUB 0,0 STA 0,BQDCB,2 ; INIT HEADER STA 0,BQDCT,2 STA 0,BQST,2 JM8P BFAS3 .IFE BSW!MBSW ; HOW TO GET INTO A RELEASE ROUTINE .MACRO RELIN ; NOVA - STORE RETURN ** STA 3,@CSP % .ENDC S .MACRO RELIN ; BIRD - PUSH RETURN ** PSH 3,3 % [S] RLMPB: RELMB: MOVZ 0,0,SKP SETMO: MOVO 0,0 RELIN ; SAVE RETURN LDA 3,BQSLwT,2 ; STATUS WORD .IFE BSW!MBSW MOVR 3,3 MOVOL 3,3 .ENDC .IFN BSW!MBSW IORI QTMOD,3 ; SET MODIFIED BIT .ENDC STA 3,BQST,2 MOV# 0,0,SZC JMP RTCOM ; GO RETURN JMP RELCM RELPB: RELB: RELIN ; JUST RELEASE BUFFER RELCM: DSZ BQUSC,2 ; DEC USER COUNT JMP RTCOM LDA 3,BQST,2 MOVL# 3,3,SNC ; LOOK AT LOCK WAITING BIT, SET? JMP RTBFW ; NO, SEE ABOUT BUFFER WAITERS .IFN BSW!MBSW PSH 0,0 ; YES, NEED AN ACCUMULATOR .ENDC S JSR @.SAV ; NOVA - PUSH FRAME & SAVE ACCUMULATORS [S] ; NOTE: RETURNZ IS ALREADY SAVED LDA 0,.IPBQ ; KEY JSR @.UNPEND ; WAKE UP IPB PROCESS INTDS LDA 0,BQST,2 ;MUST CLEAR LOCK WAITING BIT MOVL 0,0 MOVZR 0,0 STA 0,BQST,2 INTEN LDA 3,@BUFWC ; NOW SEE IF ANYONE WAITING MOV# 3,3,SNR JMP RTPOP ; NO, POP STACK & RETURN SUBZL 0,0 ; YES, BUFFER AVAILABLE KEY JSR @.UNPEND JMP RTPOP ; POP & RETURN RTBFW: LDA 3,@BUFWC ; HOW MANY ARE OUT OF BUFFER? MOV# 3,3,SNR ; ANY? JMP RTCOM ; NOPE .IFN BSW!MBSW PSH 0,0 ; NEED AN ACCUMULATOR .ENDC S JSR @.SAV ; JUMP TO SAOVE ACCUMULATORS [S] SUBZL 0,0 ; UNPEND KEY JSR @.UNPEND ; THE UNPEND ROUTINE PARASITES RTPOP: .IFE BSW!MBSW RTRN ; POP-&-RETURN .ENDC S POP 0,0 ; POP [S] RTCOM: LDA 3,CSP ; & RETURN .IFN BSW!MBSW POPJ .ENDC S JMP @0,3 [S] ;RELEASE A BUFFER jAND CLEAR THE TIME LAST ASSIGNED RELZT: RELIN SUB 3,3 STA 3,BQTLA,2 JMP RELCM ; RELEASE A BUFFER AND CLEAR IT'S DCT&STATUS RELDB: RELIN SUB 3,3 STA 3,BQCA1,2 STA 3,BQCA,2 STA 3,BQST,2 STA 3,BQTLA,2 ; ALSO ZERO TIME LAST ASSIGNED JMP RELCM BUFU"WC: BUFNT .UNPEND: UNPEND .IPBQ: IPBQ ; INITIALIZE A DCB, AC2 = DCB ADDRESS IDCB: MOVO 0,0 ; SET CARRY .IFE BSW!MBSW STA 3,@CSP ; SAVE RETURN ADDRESS LDA 3,CSP ; SAVE STATE STA 0,AC0,3 ; USE CURRENT FRAME STA 1,AC1,3 STA 2,AC2,3 .ENDC .IFN Bg1SW!MBSW PSH 3,2 .ENDC IDCB1: LDA 0,DBFA1,2 STA 0,DBNA1,2 ; SET CURRENT TO NEXT STA 0,DBCA1,2 ; SET CURRENT TO FIRST LDA 1,DCBFA,2 ; GET FIRST ADDRESS (LOW ORDER) STA 1,DCBNA,2 ; SET TO NEXT STA 1,DCBCA,2 ; AND TO CURRENT ADC 0,0 STA 0,DCBCB,2 ; CU\RRENT BLOCK SUBC 0,0 ; KEEP CARRY STA 0,DCBLA,2 ; CLEAR LAST ADDRESS STA 0,DBLA1,2 ; CLEAR LAST STA 0,DCBUC,2 ; & USER COUNT MOV# 0,0,SZC ; ADJUST NA JMP CLRCA STA 0,DCBCB,2 ; SET BLOCK # TO ZERO STA 0,DBNA1,2 ; CLEAR STA 0,DCBNA,2 ; BOTH HALVESZ JMP INLIN CLRCA: STA 0,DBCA1,2 ; ZERO CA FOR SEQUENTIAL FILE ON RDNBK STA 0,DCBCA,2 INLIN: LDA 0,DCBST,2 LDA 1,MSKI AND 1,0 STA 0,DCBST,2 ; STATUS CLEARED .IFE BSW!MBSW JMP @.SRTN .SRTN: SRTN .ENDC .IFN BSW!MBSW POP 2,0 LDA 3,CSP POPJ .ENDC t"MSKI: STDIU*2+STDIU+STINI+STCMK ; ; FULL INIT FOR DCB ; AC2: DCB ADDRESS, AC1: DCB ADDRESS OF SYS.DR ; TO USE - SET UP FA1&FA, THEN: ; FNDCB THEN BLKIN, OR ; FIDCB THEN RDNBK, OR ; FIDCB THEN SET UP CA1&CA THEN BLKIN FIDCB: MOVO 0,0,SKP ; SET CARRY FNDCB: MOVZ 0,0 ; CLEAR CARRY .IFE BSW!MBSW STA @3,CSP LDA 3,CSP ; SAVE STATE STA 0,AC0,3 ; USE CURRENT FRAME STA 1,AC1,3 STA 2,AC2,3 .ENDC .IFN BSW!MBSW PSH 3,2 .ENDC MOV 1,3 LDA 1,DCBDC,3 ; DCT ADDRESS STA 1,DCBDC,2 LDA 1,DCBUN,3 ; UNlIT NUMBER STA 1,DCBUN,2 LDA 1,DCBDR,3 ; SYS.DR POINTER STA 1,DCBDR,2 JMP IDCB1 ; THIS ROUTINE MOVES A SMALL DISK PUSH INDEX INTO ONE WORD ADDR ; AC2= FAKE BUFFER HEADER ; AC1= CALLER TO SOV6,SOV3 AC1 (=-1 IF PUSH) BMOVE: RSAVE 0 LDA 3,BQDCT,2 ; DCT r LDA 3,DCTCH,3 ; CHAR MOVL# 3,3,SZC ; SKIP IF SMALL DISK JMP BIGD COM# 1,1,SZR JMP BMV3 LDA 0,BQNBK,2 ; # BLKS STA 0,BMTMP LDA 2,BQARD,2 ; START OF INDEX (BUFFER) SUB 1,1 STA 1,BQDCT,2 ; I'D HATE TO GET THIS ON A ; BLKIN... MOV 2,3 BMV1: LDAZ 0,1,3 ; WD 2 OF NXT ADDR STA 0,0,2 ; CONDENSE INC 2,2 INC 3,3 INC 3,3 DSZ BMTMP ; DONE ? JMP BMV1 ; NO LDA 3,CSP LDA 2,OAC2,3 ; CELL HDR BMV3: LDA 3,BQARD,2 ; INDEX BLK LDA 1,0,3 ; ADDR SUB 0,0 ; WD 1 BMV2: STA 0,BQCA1,2 ; ADDR TO CELL HDRq STA 1,BQCA,2 RTRN BMTMP: 0 BIGD: LDA 0,@BQARD,2 ; HIGH ORDER ADDRESS ISZ BQARD,2 ; BUMP THE POINTER TO LOW ORDER LDA 1,@BQARD,2 ; GET LOW ORDER ADDRESS JMP BMV2 ; ROUTINE TO READ IN PUSH DIRECTORY AND SET FA TO REAL PUSH ADDR ; AC2= DCB WHICH HA7S BEEN SET UP WITH FA= DIRECTORY ADDRS PSHRD: RSAVE 0 JSR @.BLKIN ; READ IN DIR RTRN ; BAD NEWS ISZ ORTN,3 LDA 3,CC .IFN MSW LDA 1,CTEMP,3 ; =1B0 IF CPOINT .ENDC LDA 3,CPTAD,3 ; PTBL .IFN MSW MOVL# 1,1,SZC ; IF CPOINT USE PT2 LDA 3,.PT2 .ENDC LDA 3,PTSPN,3 ; PUSH LEVEL MOVZL 3,3 ; *2 (2 ADDR FOR EACH) ADD 0,3 ; TO BUFF REL ADDR LDA 1,0,3 ; ADDR WD 2 STA 1,DCBFA,2 ; TO DCB FA STA 1,DCBCA,2 ; SET CA LDA 1,-1,3 ; WORD 1 STA 1,DBFA1,2 STA 1,DBCA1,2 ; SET UP CA MOV 0,2 ; BUFFER JSR @.RELB RTRN .BLKIN: BLKIN .IFN MSW .PT2: PT2 .ENDC .RELB: RELB ; ROUTINES TO FLUSH ALL MODIFIED BUFFERS ; ; ENTRY POINT - FLUSH ; ; INPUTS: NONE ; ; OUTPUTS: NONE ; ; RETURNS: CALL+1 ; ; ENTRY POINT - BFLUS(H) ; ; INPUTS: AC0 - UNIT NUMBER ; AC1 -R DCT ADDRESS ; ; OUTPUTS: NONE ( IDENTITY OF BUFFER IS DESTROYED IF NOT IN USE ) ; ; RETURNS: CALL+1 - ERROR ; CALL+2 - SUCCESS ERC=TMP+1 BFLUS: MOVO 0,0,SKP FLUSH: MOVZ 0,0 ; SET SWITCH RSAVE 2 LDA 2,.BQ ; FIRST BUFFER ADDR SUBC 0,0 STA 0,ERC,3- ; RESET ERROR COUNT MOVR 0,0 FLP3: STA 0,TMP,3 ; SAVE SWITCH JMP .+2 FLP: LDA 2,BQNXT,2 ; NEXT ADDRESS BUFFERS LDA 3,CSP ; STACK POINTER MOVL# 2,2,SZC JMP DONE LDA 0,TMP,3 ; SEE IF BFLUSH MOVL# 0,0,SNC JMP FLP5 ; NO ;SEE IF BUF IS OURS BEFORE ZAPPING IT LDA 0,OAC1,3 ; DCT LDA 1,BQDCT,2 SUB# 0,1,SZR JMP FLP ; GET NEXT BUFFER FLP5: LDA 0,BQUSC,2 ; USER COUNT MOV# 0,0,SZR ; IS BUFFER IN USE ? JMP FLP1 ; YES LDA 0,BQST,2 ; STATUS WORD LDA 1,IOP2 ; IO IN PROGRESS MASK AND# 0,1,SZR ; SJET ? JMP FLP1 ; YES. MOVR# 0,0,SZC ; MODIFIED BIT BFLWT: JSR @QQUENT FLP1: LDA 0,TMP,3 MOV# 0,0,SNR JMP FLP ISZ BQUSC,2 ; LOCK BUFFER FOR I/O WAIT JSR WAIT ISZ ERC,3 ; TIME OUT ERROR ISZ ERC,3 ; DATA ERROR JMP .+1 JSR @.RELB ; UNLOCK - MUSTF USE RELB IN CASE ; IPB PROCESS SET LOCK WAITING LDA 0,BQST,2 ; GET STATUS MOVR# 0,0,SZC ; MODED AGAIN? JMP BFLWT ; YES, HANG IN THERE  LDA 3,BQDCB,2 ; DCB ADDRESS MOVL# 3,3,SZC ; IS IT AN OVERLAY ? JMP FLP ; YES - DONT DESTROY LDA 0,BQUSC,2 ; USER COUNT MOV# 0,0,SZR ; IS IT IN USE ? JMP FLP ; YES FLP4: STA 0,BQDCT,2 STA 0,BQTLA,2 ; SET USE IN NO TIME JMP FLP ; GO FOR NEXT BUFFER DONE: LDA 0,TMP,3 ; GET ENTRY SWITCH MOV# 0,0,SNR ; BFLUSH ENTRY ? RTRN ; NO, JUST RETURN LDA 0,ERC,3 ; YES, GET ERROR COUNT MOV# 0,0,SNR ; ANY ERRORS ? ISZ ORTN,3 ; NO, GOOD RETURN RTRN .BQ: BQ QQUENT: QUENT IOP2: QTIOP ; ROUTINE TO WAIT FOR DATA CHANNEL TRANSFER TO COMPLETE ; ; ENTRY POINTS: WAIT - WAIT 10 SECONDS (MAYBE 9) FOR I/O TO COMPLETE ; WAITF - WAIT FOREVER FOR I/O TO COMPLETE ; WAITS - WAIT FOR SECONDS SPECIFIED IN ; AC0 (INFOS ONLY) ; INPUTS: AC2 - BUFFER ADDRESS ; ; OUTPUTS: NONE ; ; RETURNS: CALL+1 - DEVICE TIME OUT ERROR ; CALL+2 - DEVICE DATA ERROR~ ; CALL+3 - GOOD RETURN TIMCN= TMP ; DEFINE THE STACK TOC= TIMCN+1 ; LONG TIME OUT .IFN IOSW WAITS: RSAVE 2 IORI 1,0 ; FORCE BIT 15 ON ISZ ORTN,3 ; ASSUME RETURN 2 JMP CMN ; JOIN COMMON CODE .ENDC WAITF: INCO 3,3,SKP ; WAIT FOREVER FOR I/O WAIT: INCZ 3,3 ; WAIT FOR APPOX 10 SEC RSAVE 2 LDA 0,TIMC2 ; ASSUME 10 SEC WAIT MOV 0,0,SZC ; IS IT? ADC 0,0 ; NO - WAIT FOREVER CMN: STA 0,TOC,3 ; SAVE ON STACK WAIT2: INTDS ; DISABLE TO LOOK AT CONDITION LDA 0,BQST,2 ; BUFFER STATUS WORD LDA 1,IOP2 ; IO IN PRGORESS BIT MASK AND# 0,1,SZR ; SET ? JMP WAIT1 ; YES - MUST PEND INTEN ; BUFFER OK - REENABLE LDA 1,QERR ; LOOK FOR ERROR BIT AND# 0,1,SNR JMP WAIT4 ; NONE - GOOD RETURN JSR @.RET ; ERROR - GIVE FILE DATA ERROR ERFIL WAIT4: ISZ ORTN,3 RTRN WAIT1: LDA 0,TIMC1 ; USE SHORT TIMEOUT UNTIL IN ; TOP OF Q WAIT7: STA 0,TIMCN,3 ; SAVE WHICH TYPE MOV 2,1 ; BUFFER IS KEY JSR @PWEND ; PEND JMP TIMOT ; DEVICE TIMEOUT WAIT6: JMP WAIT2 ; WE'VE UNPENDED, RECHECK ; 2ERROR + IOP TIMOT: INTDS ; DISABLE TO VALIDATE CONDITION LDA 0,BQST,2 ; GET BUFFER STATUS WORD LDA 1,IOP2 ; I/O IN PROGRESS MASK AND# 0,1,SNR ; STILL IN THE BAG ? JMP WAIT2 ; NOPE - FOOLED YOU, YOU RASCAL MOV 2,0 ; BUFFER ADDRESS TO AC0 LDA E2,BQDCT,2 ; GET DCT ADDRESS LDA 2,DCTPD,2 ; GET REAL ONE LDA 1,DCCRQ,2 ; AND REAL REQUEST TIMO1: MOVZ 0,2 ; BUFFER TO AC2 - CLEAR CARRY SUB# 0,1,SZR ; AM I CURRENT REQUEST? JMP WAIT1 ; NO, KEEP ON TRUCKIN' LDA 1,TIMCN,3 ; PREVIOUS TIMEOUT CONSTANT q LDA 0,TOC,3 ; POSSIBLE NEW TIMECONSTANT MOVZR 1,1,SNC ; FIRST TIMEOUT ?? JMP WAIT7 ; YES DO IT AGAIN SUB 0,0 STA 0,BQST,2 ; RESET BUFFER STATUS STA 0,BQCA1,2 ; DESTROY IDENTITY STA 0,BQCA,2 ; DESTROY IDENTITY DSZ ORTN,3 ; TIMEOUT RETURN JSR @.3.NOC ; TAKE DOWN HARDWARE LDA 1,BQQLK,2 ; LINK TO NEXT REQUEST LDA 2,BQDCT,2 ; DCT ADDRESS LDA 2,DCTPD,2 ; GET REAL ONE STA 1,DCCRQ,2 ; PUT NEXT ONE ON QUEUE COM# 1,1,SZR ; REAL REQUEST ? JSR @DCSTR,2 ; YES, START IT UP INTEN ; ENABLE NOW JSR @.RET ; GIVE TIMEOUT RETURN ERDTO .RET: RETER ..NOC: XNOC TIMC1: 2 ; MUST BE EVEN NUMBER TIMC2: 21 ; MUST BE ODD NUMBER PWEND: PEND QERR: QTER MXER: SCMER ; MAX ERROR RETRY COUNT ; ; QUEUE ONE MODIFIED BUFFER IN THE BUFFER POOL ; FOR OUTPUT. DO^NE WITHOUT THE USE OF A STACK ; OR ANY MIRRORS. FOR USE ONLY BY THE SYSTEM ; "SMON" CODE TO SLOWLY FLUSH OUT MODIFIED ; BLOCKS WHEN THE SYSTEM IS IDLE. ; ; CALL IS: JSR MODOUT ; (RETURN IF COULDN'T OUT MODIFIED BLOCK) ; (RETURN IF OUTPUT BLOCK OR WEREp NONE TO OUTPUT) ; MODOUT: INC 3,3 ; ASSUME OK RETURN STA 3,MDRTN ; SAVE RETURN TO SMON LDA 2,.BQ ; GET START OF BUFFER POOL SKIP ; SCAN MDO1: LDA 2,BQNXT,2 ; GET NEXT BUFFER IN CHAIN MOVL# 2,2,SZC ; IF ALL DONE THEN JMP @MDRTN ; RETURN TO SMSON LDA 0,BQUSC,2 ; IF BUFFER IN USE THEN SEQZ 0 ; GO TRY NEXT JMP MDO1 ; BUFFER ELSE LDA 0,BQST,2 ; GET BUFFER STATUS LDA 1,IOP2 ; IF I/O IN PROGRESS AND# 0,1,SZR ; THEN IGNORE BUFFER, GO JMP MDO1 ; GET NEXT ELSE MOVR# 0,0,SNC ; IF BUFFER NOT MODIFIED THEN JMP MDO1 ; GO TRY NEXT BUFFER DSZ MDRTN ; GOT BLOCK TO OUT, ASSUME CAN'T FIND LDA 3,.PS1 ; STACK CAN USE SKIP MDO4: INC 3,3 ; TO USE IN QUEING BUFF OUT LDA 1,0,3 ; LOOK AT NEXT STACK COM# 1,1,SNR ; IF ALL STACKS IN USE THEN JMP @MDRTN ; JUST RETURN TO SMON ELSE MOVZL# 1,1,SZC ; IF DON'T GOT IT THEN JMP MDO4 ; THEN LOOP ELSE .DO ANSW STA 1,CSP ; SET UP STACK .ENDC .DO ABSW STA 1,SP SBI 2,1 MOV 1,3 LDA 1,1,3 STA 1,CSL STA 3,CSP .ENDC JSR QUENT ; OUT THE BUFFER I/7SZ MDRTN ; DO OUTPUT DONE RETURN JMP @MDRTN ; RETURN TO SMON MDRTN: 0 .PS1: PS1 ; ; PLACE AN ENTRY INTO A DISK I/O QUEUE ; ; AC2: BUFFER ADDRESS ; MAXAD=TMP DEVAD=MAXAD+1 BLKCT=DEVAD+1 MXAD1=BLKCT+1 TYPE=MXAD1+1 QUENT: RSAVE 5 LDA 3,BQDCT,w2 ; DEVICE DCT ADDRESS LDA 0,DCNB1,3 ; MAX BLOCK COUNT HIGH ORDER LDA 1,DCNBK,3 ; MAX BLOCK COUNT LOW ORDER INC# 1,1,SNR ; IS MAX COUNT = 177777 ? JMP NOADT ; YES NO ADDRESS TEST LDA 2,DCTCH,3 ; GET DISK TYPE FLAG MOVL 2,2 ; MOVE INDICATOR TO CARRzY SUBC 2,2 ; ZERO AC AND SAVE CARRY MOVL 2,2 ; GET CHARACTERISTIC LDA 3,CSP STA 2,TYPE,3 ; NEED THIS LDA 2,PPA ; PRIMARY PARTITION OFSET ADDZ 2,1,SZC ; DOUBLE ADD INC 0,0 ; LOWER WORD OVERFLOW STA 0,MXAD1,3 ; SAVE IT STA 1,MAXAD,3 LDA 2,OAC2.,3 ; BUFFER ADDRESS LDA 0,BQST,2 ; BUFFER STATUS LDA 1,INDMD ; INDIRECT MODE FLAG AND# 0,1,SNR ; MUTIPLE BLOCK TRANSFER ? JMP ONLY1 ; NO LDA 1,CONMD ; YES, GET CONTIGUOUS MODE AND# 1,0,SNR ; IS IT CONTIGUOUS ? JMP RANDM ; NO, MUST BE RANDOM LDA 1,BQCA,2 ; GET LOW ORDER OF STARTING DISK ; ADDRESS LDA 0,BQCA1,2 ; HIGH ORDER LDA 3,BQNBK,2 ; BLOCK COUNT NEG 3,3 COM 3,3 ; BLOCK COUNT-1 ADDZ 3,1,SZC ; GET LAST BLOCK ADDRESS INC 0,0 ; OVERFLOW JMP CONT1 ; CHECK AGAINST MAX ADDRESS RANH DM: LDA 0,BQNBK,2 ; GET BLOCK COUNT MOVZR# 0,0,SNR ; ONLY 1 ? JMP ONLY1 ; NO STA 0,BLKCT,3 ; YES SAVE THE COUNT LDA 0,BQARD,2 ; GET INDEX POINTER STA 0,DEVAD,3 ; SAVE IT LDA 0,TYPE,3 MOV# 0,0,SZR ; SINGLE OR DOUBLE WORD ; ADDRESSING ? JMP BTN"EST ; DOUBLE LDA 1,MAXAD,3 ; MAX ADDRESS ADLUP: LDA 0,@DEVAD,3 ; GET AN ADDRESS ISZ DEVAD,3 ; BUMP THE POINTER ADCZ# 0,1,SNC ; IS IT LEGAL ? JMP ILDAD ; NOPE - YOUR'RE IN THE BAG DSZ BLKCT,3 ; YES, DEC THE COUNT JMP ADLUP ; TRY NEXT ADDRESS JMP NOADT ; EVERYTHING LOOKS SPIFFY ONLY1: LDA 1,BQCA,2 ; GET BLOCK ADDRESS LDA 0,BQCA1,2 ; HIGH ORDER CONT1: LDA 3,CSP LDA 2,MXAD1,3 ; TRY HIGH ORDER FIRST SUBZ# 2,0,SNC ; LEGAL ? JMP NOADT ; ITS OK SUBZ# 0,2,SZR ; NOW ? JMP ILDAD ; FORGET IT LDA 2,MAXAD,3 ; NEED TO TRY LOW ORDER ADCZ# 1,2,SNC ; THIS WILL DO IT JMP ILDAD ; TOO BIG NOADT: LDA 3,CSP ADC 0,0 ; YES, FORM -1 LDA 2,OAC2,3 ; GET BUFFER ADDRESS STA 0,BQQLK,2 ; Q LINK FOR END OF QUEUE LDA 0,MXER ; MAX RETRY COUNT STA 0,BQERC,27 ; SET IN Q ENTRY LDA 0,BQST,2 ; BUFFER STATUS LDA 1,ERBI3 ; ERROR BIT AND 1,0 ; TURN OFF LDA 1,IOP1 ; SET I/O IN PROGRESS ADD 1,0 STA 0,BQST,2 ; PUT PACK ; ; FOR DCH MAP ; .IFN MSW LDA 1,INDMD AND# 1,0,SNR ; INDIRECT MODE? JMP NOMP ; NOPE- iSYSTEM MAP LDA 1,.QTEX ; EXTENDED I/O ? AND# 1,0,SZR JMP NOMP ; YES-BQDCB ALL SET UP ALREADY LDA 3,CC ; GET CURRENT CELL ADDR LDA 3,CPTAD,3 ; CURRENT TABLE PTR LDA 1,.PMAP ; OFFSET FOR MAP WITHIN TABLE ADD 1,3 ; FIRST MAP WORD STA 3,BQDCB,2 ; &^STORE NOMP: .ENDC ; MOV 2,0 LDA 2,BQDCT,2 JSR @DCDST,2 INTDS ; DISABLE FOR INSERTION LDA 2,DCTPD,2 ; GET REAL DCT ADDRESS LDA 3,DCCRQ,2 ; CURRNET Q ENTRY COM# 3,3,SNR ; EMPTY NOW ? JMP QEMPTY ; YES. LDA 2,BQQLK,3 ; LINK OF NEXT COM# 2,2,SNR JMP .+3 MOV 2,3 JMP .-4 STA 0,BQQLK,3 ; BY SWITCHING LINKS JMP QUDN ; DONE QEMPTY: STA 0,DCCRQ,2 ; START OF Q JSR @DCSTR,2 ; GO START DEVICE QUDN: INTEN RTRN ILDAD: JSR @.PNIC PNIDA ERBI3: -QTIOP-QTER-1 INDMD: QTIND CONMD: QTCT IOP1: QTIOP PPAu: SCPPA ; ;MORE MAP STUFF .IFN MSW C37: 37B5 ; MASK FOR BITS 1-5 .PMAP: PMAP ; OFFSET IN PROGRAM TABLE FOR USER MAP .QTEX: QTEXI .ENDC ; THIS IS THE TWO WORD ADDRESSING TEST BTEST: DSZ DEVAD,3 ; BQARD POINTS TO WORD 2 OF INDEX LDA 1,MXAD1,3 ; HIsGH ORDER MAX ADDRESS BADLP: LDA 0,@DEVAD,3 ; GET AN ADDRESS ISZ DEVAD,3 ; POINT TO LOW ORDER PART SUBZ# 1,0,SNR ; FIRST PART OF ADDRESSES = ? JMP CADLU ; YES TRY SECOND HALF SUBZ# 0,1,SNC ; ADDRESS > MAX VALUE ? JMP ILDAD ; YEP, YOU CAN'T DO THATh CONT: ISZ DEVAD,3 ; GET BY SECOND HALF DSZ BLKCT,3 ; THROUGH ? JMP BADLP ; KEEP GOING JMP NOADT ; GET BACK IN LINE CADLU: LDA 1,MAXAD,3 ; GET LOW ORDER LDA 0,@DEVAD,3 ; GET SECOND HALF OF ADDRESS ADCZ# 0,1,SNC ; VALID ? JMP ILDAD ; BAG IT LD˱A 1,MXAD1,3 ; THIS ADDRESS IS OK JMP CONT ; TRYY NEXT ONE .IFN MSW ; ; SWAMP - DATA CHANNEL MAP ROUTINE FOR DEVICES ; ; CALLED WITH AC0: FIRST PAGE OF DCH MAP TO USE ; (IN FORMAT OF LOAD MAP COMMAND; RH=0) ; AC1: NUMBER OF PAGES TO MAP IF INDIRBECT (USER) MODE ; (MAPS TWO PAGES IF IN SYSTEM MODE) ; AC2: BUFFER ADDRESS ; ; RETURNS IN AC0 THE ADDRESS FOR THE DRIVER TO USE ; THE ROUTINE PARASITES OFF THE STACK ; AND DESTROYS AC'S 0 AND 1 ; .IFE MBSW OUT=AC2 CNT=AC1 TLP=AC0 SAC2=VRTN .ENDC .IFN MBSW OUT=OAC0 CNT=OAC1 TLP=TMP .ENDC SWAMP: .IFE MBSW STA @3,CSP LDA 3,CSP STA 2,SAC2,3 ; SAVE AC2 STA 1,CNT,3 ; REMEMBER NUMBER OF PAGES .ENDC .IFN MBSW RSAVE 1 .ENDC SMLD 3,MPSDC ; SET TO LOAD DCH MAP LDA 1,BQST,2 ; STATUS FhROM BUFFER LDA 3,INDMD AND# 1,3,SZR ; INDIRECT MODE? JMP USRMP ; YES - USE USER MAP LDA 1,C31K ; NO - SYSTEM MAP ANDS 2,1 ; LOGICAL PAGE NUMBER MOVZR 1,1 MOVZR 1,1 ; TO LOW ORDER BITS ADD 0,1 ; SET UP MAP COMMAND .IFN MNSW LDA 3,C37L ANDZLu 3,0 ; LOGICAL PAGE NUMBER MOVZL 0,0 ; TO HIGH ADDRESS BITS LDA 3,C1777 AND 3,2 ; OFFSET IN PAGE (10 BITS) .ENDC .IFN MBSW!MN3SW LDA 3,C31K AND 3,0 ; MAKE ADDR COM 3,3 AND 3,2 .ENDC ADD 2,0 ; FORM LOGICAL ADDRESS LDA 2,AOB SMBK 1 ; SET F`IRST PAGE IN MAP ADD 2,1 ; INCREMENT PHYS AND LOG PAGE ; NUMBER SMBK 1 ; SET SECOND PAGE IN MAP .IFE MBSW LDA 3,CSP LDA 2,SAC2,3 ; RECOVER BUFFER ADDRESS JMP @0,3 ; AND RETURN .ENDC .IFN MBSW LDA 3,CSP STA 0,OUT,3 ; PASS IT BACK RTRN ;b RETURN .ENDC USRMP: LDA 3,CSP .IFN MNSW MOVS 0,1 STA 1,TLP,3 ; DCH MAP TEMPLATE .ENDC .IFN MBSW!MN3SW STA 0,TLP,3 .ENDC LDA 1,C31K LDA 3,BQNXT,2 ; ACTUAL CORE ADDRESS ANDS 3,1 ; LOGICAL PAGE NUMBER MOVZR 1,1 ; TO LOW BITS MOVZR 1,1 LDA 2,BQDCB,2 ; MAP STARTING ADDR IN PT ADD 1,2 ; PLUS PAGE NUMBER .IFN MNSW LDA 1,C37L ANDZL 1,0 ; FAKE PAGE NUMBER MOVZL 0,0 ; TO HIGH BITS LDA 1,C1777 AND 1,3 ; OFFSET IN PAGE .ENDC .IFN MBSW!MN3SW LDA 1,C31K AND 1,0 ; MAKE ADDR COM 1,1 AND 1,3 .ENDC ADD 3,0 ; FORM FAKE ADDRESS LDA 3,CSP STA 0,OUT,3 ; SAVE FOR LATER RETURN SP1: LDA 0,0,2 ; ENTRY FROM PROGRAM TABLE MAP COM# 0,0,SNR ; END OF TABLE? .IFE MBSW JMP SP3 ; YES - RETURN .ENDC .IFN MBSW RTRN .ENDC .IFN MNSW LDA 1,C377 ANDS 1,0 ; PHYSICLA PAGE FROM PT MAP LDA 1,TLP,3 ; DCH TEMPLATE ADDS 1,0 ; COMMAND FOR MAP DOA 0,MAP ; SET IT UP ISZ TLP,3 ; NEXT SLOT IN MAP .ENDC .IFN MBSW!MN3SW LDA 1,C377 AND 1,0 LDA 1,TLP,3 ; BLK ADD 1,0 SMBK 0 LDA 0,C2000 ADD 0,1 ; NEXT STA 1,TLP,3 ; INC ADDR .ENDC INC 2,2 ; ALSO IN PROGRAM TABLE MAP DSZ CNT,3 ; DONE? JMP SP1 ; NO - GET NEXT PAGE .IFE MBSW SP3: LDA 0,OUT,3 ; YES - GET FAKE ADDRESS LDA 2,SAC2,3 ; RECOVER AC2 JMP @0,3 ; AND RETURN .ENDC .IFN MBSW L' RTRN .ENDC .IFN MNSW C377: 377 C37L: 37B7 C1777: 1777 AOB: 401 .ENDC .IFN MBSW!MN3SW AOB: 2001 C377: 377 C2000: 2000 .ENDC C2: 2 .ENDC ; ; FORMAT OF A BAD BLOCK TABLE AS IT RESIDES IN CORE. ; THE OVERFLOW LIST CONTAINS ENTRIES DYNAMICALLY ADDED4 TO THE TABLE. ; ; =============================== ; ! CORE HEADER, CONSISTING OF A ! ; ! POINTER TO THE UNIT DCT OF ! ; ! THE DEVICE OWNING THE TABLE ! ; =============================== ; ! IMAGE OF DISK-RESIDENT BAD ! ; ! BLOCK TABLE, CONSI^}STING OF ! ; ! A HEADER & A LIST OF DISK ! ; ! ADDRESS (SEE PARS) ! ; =============================== ; ! @LINK TO OVERFLOW LIST OR -1 ! ------. ; =============================== : ; : ; : ; .-----------------------------------------2------: ; : ; : =============================== ; :----> ! DISK ADDRESS (DOUBLEWORD) ! ; =============================== ; ! @LINK TO REST OF LIST OR -1 ! --> ETC ; =============================== ; ; ORGANIZATION OF GLOBAL BAD BLOCK POOL, CONTAINtING MULTIPLE TABLES. ; THE LABELS ARE NAMES OF VARIABLES CONTAINING POINTERS TO THE ; INDICATED LOCATIONS. ON RELEASE OF A DEVICE, THE CONTIGUOUS ; PART OF THE POOL IS COMPACTED, EXPANDING FREE SPACE. OVERFLOW ; LIST NODES ARE QUEUED TO THE FREE LIST,x WHOSE HEAD IS POINTED ; TO BY THE VARIABLE BLIST. LINK SPACE IS NEVER COMPACTED. ; ; =============================== ; STCONT: ! CONTIGUOUS PART OF A TABLE, ! ; ! CONSISTING OF CORE HEADER, ! ; ! DISK TABLE IMAGE, & LINK ! ; ===================Ʈ============ ; ! ANOTHER TABLE SEGMENT ! ; =============================== ; ! AND SO ON ! ; =============================== ; ENCONT: ! FREE SPACE, AVAILABLE FOR ! ; ! EXPANSION OF EITHER CONTIG ! ; ! SPACE OR LINK SPACE ! ; ============F=================== ; STLINK: ! LINK SPACE, CONTAINING THE ! ; ! OVERFLOW LISTS OF ALL TABLES ! ; ! & THE NODES ON THE FREE LIST ! ; =============================== ; GLOBAL POOL VARIABLES: STCONT: STCOT ;INITIALLY POINTING TO START OF POOL ENCONT: STCOT ;CONTIG SPACE HAS ZERO LENGTH INITIALLY STLINK: STLIK ;ZERO LINK SPACE IMPLIES INITIAL POINTER ; POINTS TO WORD FOLLOWING POOL BLIST: -1 ;LIST INITIALLY EMPTY ; ; GBLKNO - ROUTINE TO MAP A DISK BLOCK ADDRESS ACCORDING TO THE ; DEVICE BAD BLOCK TcABLE. CALLED BY DISK SETUP ROUTINE. ; WILL NOT DO MULTIPLE LEVELS OF MAPPING (I.E., A BLOCK ; MAPPED TO A BLOCK WHICH IS ITSELF MAPPED). CONTIGUOUS ; TRANSFERS ARE HANDLED BY RETURNING IN BQCYL THE MAXIMUM ; NUMBER OF BLOCKS THAT CAN BE CONTIGUOUSLY TRANSF=ERED ; (UP TO BQNBK), OR A ONE WHEN TRANSFERING A MAPPED BLOCK. ; ; INPUTS: AC2 - POINTER TO BUFFER WITH BQCA & BQCA1 SET UP ; ; OUTPUTS: AC0,AC1 - MAPPED BLOCK ADDRESS (TO REPLACE CA & CA1) ; BQCYL - MAX NUMBER BLOCKS CAN TRANSFER ; ; RETURNS: NO ERROR& RETURN ; GBUFP=OAC2 ADHI=OAC0 ADLO=OAC1 MAPSLOT=TMP NBLK=MAPSLOT+1 NTEMP=NBLK-TMP+1 GBLKNO: RSAVE NTEMP SUB 0,0 STA 0,MAPSLOT,3 ;START AT BEGINNING OF REALLOCATION SPACE LDA 0,BQST,2 ;BUFFER STATUS LDA 1,INHIBIT AND# 1,0,SZR ;MAPPING & REALLOCATING INHIBITED? JMP NONUTHN ;YUP, NUTH'N TO DO COM 0,0 LDA 1,CONTIG AND# 1,0,SZR ;BOTH INDIRECT & CONTIGUOUS BITS SET? SUBZL 0,0,SKP ;NO, SINGLE BLOCK TRANSFER LDA 0,BQNBK,2 ;YES, PICK UP INITIAL MAX COUNT STA 0,NBLK,3 ;REMEMBER THAT LDA 0,,BQCA1,2 ;PICK UP DISK ADDRESS LDA 1,BQCA,2 STA 0,ADHI,3 ;RETURN DEFAULT STA 1,ADLO,3 ; AND MAKE ACCESS EASIER LDA 2,BQDCT,2 ;UNIT DCT LDA 2,DCTBL,2 ;BAD BLOCK TABLE POINTER LDA 0,TOLIST ADD 2,0 ;POINT PAST HEADER TO START OF LIST COM# 2,2,SZR ;NO BAD BLOCK TABLE? (UNIT NOT ; INIT'D, E.G., WHILE SIZING) LINK: COM# 0,0,SNR ;END OF TABLE? JMP NOMAP ;YES MOV 0,2 ;POINT TO PIECE OF TABLE JMP PICKUP NEXT: INC 2,2 ;POINT TO NEXT BLOCK ADDRESS INC 2,2 ISZ MAPSLOT,3 ;KEEP TRACK OF HOW FAR WE ARE PICKUP: LDA 0,0,2 ;HIGH ORDER OF DISK ADDRESS, MOVL# 0,0,SZC ; OR @ CORE ADDR TO REST OF TABLE JMP LINK ;CORE ADDRESS LDA 1,ADHI,3 ;OUR ADDRESS, HIGH ORDER ADC 1,0 ;TABLE ADDR.HI - OUR ADDR.HI - 1 LDA 1,1,2 ;TABLE ADDR, LOW ORDER LDA 3,ADLOB,3 ;OUR ADDR, LOW SUBZ 3,1,SZC ;TABLE ADDR.LO - OUR ADDR.LO INC 0,0 ;COMPENSATE FOR PREVIOUS DECREMENT LDA 3,CSP ;AC0&1 HAVE TABLE ADDR - OUR ADDR MOV# 0,0,SZR ;DIFFERENCE < 0 OR > 65K? JMP NEXT ;YES, CAN'T BE RELEVANT LDA 0,NBLK,3 ;TABLE ENTRY +INSIDE OUR TRANSFER? USLT 1,0 ;LOGICAL SKIP (16 BITS, NOT 15 + SIGN) JMP NEXT ;NO MOV 1,0,SNR ;WHICH BLOCK IS BAD SUBZL 0,0 ;IF ZERO, MAKE ONE STA 0,NBLK,3 ;SET NUMBER BLOCKS CAN DO MOV# 1,1,SZR ;IS THE BAD BLOCK THE FIRST ONE? JMP NOMAP ;NO, ɎDO INTERVENING BLOCKS FIRST LDA 2,GBUFP,3 ;BUFFER LDA 2,BQDCT,2 LDA 2,DCTBL,2 ;BAD BLOCK TABLE ADDRESS LDA 0,BESTART,2 ;BASE OF REALLOCATION AREA LDA 1,BESTART+1,2 ;LOW ORDER, TOO LDA 2,MAPSLOT,3 ;DISPLACEMENT INTO AREA ADDZ 2,1,SZC INC 0,0 ;MAPPE{D DISK ADDRESS STA 0,ADHI,3 ;RETURN MAPPED ADDRESS STA 1,ADLO,3 NOMAP: LDA 0,NBLK,3 ;MAX BLOCK COUNT LDA 2,GBUFP,3 ; RETURN IT IN STA 0,BQCYL,2 ; BQCYL OF BUFFER NONUTHN:RTRN INHIBIT:QTNBAD CONTIG: QTCT+QTIND TOLIST: BELIST ; ; ROUTINE TO PEND A NWSYSTEM TASK ; (ASSUMES INTERRUPTS ARE DISBLED ON ENTRY) ; ; AC0: TIME OUT WAIT IN SECONDS ; AC1: PEND KEY ; PEND: INC 3,3 ; ASSUME GOOD RETURN .IFN BSW!MBSW RSAVE 0 .ENDC .IFE BSW!MBSW STA @3,CSP ; SAVE RETUNRN LDA 3,CSP STA 2,AC2,3 ; SAVE AC2 Oj!NLY .ENDC LDA 2,CQ ; CURRENT TASK Q ENTRY STA 1,QKEY,2 ; SET KEY STA 0,QTIME,2 ; SAVE TIME OUT ISZ QSTAT,2 ; SET PENDED BIT .IFN IOSW JSR @.MPOFF ; TURN OFF MAP IF ON & ; TURN ON INTERRUPTS .ENDC .IFE IOSW INTEN ; TURN ON INTERRUPTS .ENDC STA 3,QSTK,2 ; SAVE CSP ON Q LDA 0,CRSEG STA 0,QCRSG,2 ; SAVE OVERLAY SEG IF ANY. SUB 0,0 STA 0,@.INTSK ; NO LONGER IN TASK STA 0,CRSEG ; SHOW NO OVERLAY TO ACQUIRE JMP @.SMON1 ; GO TO TOP OF SCHEDULER PENDR: LDA 1,CSP LDA 3,CQ STA 1,QSTK,3 LDA 0,CRSEG ; CURRENT TASK OVERLAY STA 0,QCRSG,3 ; SAVE SUB 0,0 STA 0,@.INTSK ; CLEAR IN TASK STA 0,CRSEG ; COVER TRACKS JMP @.SMNXT .INTSK: INTSK .SMNXT: SMNXT .SMON1: SMON1 .IFN IOSW .MPOFF: MPOFF ; IOCS - TURN OFF THE MAP ROUTINE .ENDC ; ; ROUTINE TO UNPEND ALL WAITERS OF A KEY. ; ; AC0: KEY ; UNPEND: .IFE BSW!MBSW STA @3,CSP ; SAVE RETURN LDA 3,CSP ; LOAD STACK PINTER STA 0,AC0,3 ; SAVE AC0 STA 1,AC1,3 ; SAVE AC1 STA 2,AC2,3 ; AND AC2 .ENDC .IFN BSW!MBSW RSAVE 0 .ENDC MOVL 0,0 ; MAKE 15 BIT KEY MOVZR 0,0 LDA @2,.SACHN ; START OF OP LIST UPLP: LDA 1,QSTAT,2 ; TASK STATUS MOVR 1,1,SNC ; IS IT PENDED ? JMP NOTSK ; NO - FORGET THIS ONE LDA 3,QKEY,2 ; LOOK AT ITS PEND KEY SUBOL# 0,3,SZR ; A MATCH ? JMP NOTSK ; NO MOVZL 1,1 ; YES - UNPENDED BIT STA 1,QSTAT,2 ; SET STATUS BACK ISZ @.UPQUE ; SET SOMETHING TO DO FLAG JMP .+1 ; GEORGE CLAIMS THIS CAN'T ; HAPPEN, BUT.... NOTSK: LDA 2,POLNK,2 ; LINK TO NEXT Q COM# 2,2,SZR ; END ? JMP UPLP ; GO LOOK AT NEXT .2-IFE BSW!MBSW UPEX: JMP @..SRT ; PARASITE RETURN ..SRT: SRTN .ENDC .IFN BSW!MBSW UPEX: RTRN .ENDC .UPQUE: UPQUE .SACHN: SACHN ; GET CONTROL OF PATH ROUTINE. ROUTINE LOOKS AT FLAG ; WORD TO SEE IF PATH IS BUSY. -1 IN FLAG WORD SAYS PATH ; NOT BUSY. -o 0 SAYS BUSY. ANY OTHER NUMBER SAYS THE NUMBER ; OF PEOPLE WAITING FOR USE OF THE PATH. ; ; CALLING SEQUENCE ; ; JSR GPATH ; (ADDRESS OF FLAG WORD) ; (RETURN ADDRESS ON GOT USE OF PATH) ; ; LDA 2,(ADDRESS OF FLAG WORD) ; JSR GPATJ ; (RETURN ON GOT USE OF ^PATH) ; ; IF PATH IS NOT FREE THEN ROUTINE PENDS TILL IT IS FREE SO ; CALLER SHOULD BE SMART IN WHAT RESOURSES IT HOLDS ON TO ; WHEN DOES CALL TO THIS ROUTINE. ; ; FLAG THAT FLAG WORD ADDRESS IS IN REGISTER AC2 GPATJ: MOVO 0,0,SKP ; FLAG THAT FLAG WORD ADnDRESS IS IN WORD AFTER CALL GPATH: MOVZ 0,0 ; SAVE REGISTERS ON THE STACK RSAVE 0 ; CHECK TO SEE IF MUST PICK UP ADDRESS OF FLAG WORD MOV# 0,0,SZC ; IF ALREADY HAVE ADDR JMP GPAT2 ; IN AC2 THEN BRANCH ; PICK UP FLAG WORD ADDRESS FROM WORD AFTER CALL PGLDA 2,ORTN,3 ; PICK UP ADDR OF RETURN LDA 2,0,2 ; GET FLAG WORD ADDR ISZ ORTN,3 ; INC RETURN ADDRESS PAST FLAG WORD ; CHECK TO SEE IF PATH IS FREE TO USE GPAT2: INTDS ; DISABLE INTERRUPTS WHILE CHECKING ISZ 0,2 ; IF PATH IS IN USE THEN JMP GPAT4 T"; GO WAIT FOR IT ELSE ; RETURN TO CALLER WITH CONTROL OF THE PATH INTEN ; TURN INTERRUPTS BACK ON RTRN ; AND RETURN TO CALLER ; PATH NOT FREE TO USE, PEND TILL IT IS FREE GPAT4: MOV 2,1 ; PEND ON FLAG WORD ADDRESS ADC 0,0 ; FOR AS LONG AS WE CAN B JSR PEND ; WAIT JMP GPAT2 ; GO CHECK TO SEE JMP GPAT2 ; IF PATH NOW FREE ; ROUTINE TO FREE PATH FOR USE. ONCE PATH HAS BEEN ; GOTTEN FOR USE BUY EITHER THE GPATH OR CPATH ROUTINES ; IT MUST BE FREED WHEN USER IS FINISHED WITH IT. THIS ROUTINE ; QyDOES SO BY SETTING THE FLAG WORD TO SAY NOT IN USE (-1) AND ; UNPENDING ALL WAITERS ON THE FLAG WORD ADDRESS. ONE OF THE ; WAITERS WILL THEN GET CONTROL OF THE PATH. ; ; CALLING SEQUENCE ; ; JSR FPATH ; (ADDRESS OF THE FLAG WORD) ; (RETURN) ; ; LDA 2,(ADD'RESS OF THE FLAG WORD) ; JSR FPATJ ; (RETURN) ; ; SET FLAG THAT THE ADDR OF THE FLAG WORD IS IN AC2 FPATJ: MOVO 0,0,SKP ; SET FLAG THAT THE ADDRESS OF THE FLAG WORD IS IN WORD AFTER CALL FPATH: MOVZ 0,0 ; SAVE REGISTERS ON STACK RSAVE 0 ; CHECK TO SEE IFH ADDR OF FLAG WORD IS IN REGISTER AC2 MOV# 0,0,SZC ; IF ALREADY HAVE FLAG WORD JMP FPAT2 ; ADDRESS THEN BRANCH ELSE ; PICK UP ADDR OF THE FLAG WORD IN WORD AFTER CALL LDA 2,ORTN,3 ; PICK UP ADDRESS OF WORD AFTER CALL LDA 2,0,2 ; PICK UP ADDR OF FLAGM WORD ISZ ORTN,3 ; INC TO CORRECT RETURN ADDR ; INHIBIT INTERRUPTS WHILE FREEING THE PATH FPAT2: INTDS ; SET PATH FREE AND UNPEND ALL WAITERS ADC 0,0 ; SET THAT PATH STA 0,0,2 ; IS FREE AND MOV 2,0 ; UNPEND ALL WAITERS ON JSR UNPEND ; FLAG WORD AUDDR ; OK, PATH IS NOW FREE, TURN INTERRUPTS BACK ON INTEN ; AND WE IS DONE, PATH IS FREE RTRN ; ROUTINE TO CONDITIONALLY GET CONTROL OF A PATH. ; IF PATH IS FREE THEN GETS CONTROL OF IT. IF PATH IS BUSY ; THEN TAKES A BUSY RETURN. THIS ALLOWS CALLER |TO TAKE ; ALTERNATE ACTION IF PATH IS BUSY. ; ; CALLING SEQUENCE ; ; JSR CPATH ; (ADDRESS OF FLAG WORD) ; (RETURN ON PATH IS BUSY) ; (RETURN ON YOU GOT CONTROL OF PATH) ; ; LDA 2,(ADDRESS OF FLAG WORD) ; JSR CPATJ ; (RETURN ON PATH IS BUSY) ; (RETURN ON GOAT CONTROL OF PATH) ; ; SET FLAG THAT ADDR OF FLAG WORD IS IN REGISTER AC2 CPATJ: MOVO 0,0,SKP ; SET FLAG THAT ADDR OF FLAG WORD IS IN WORD AFTER CALL CPATH: MOVZ 0,0 ; SAVE REGS ON THE STACK RSAVE 0 ; CHECK TO SEE IF FLAG WORD ADDRESS IS ALREADY IN AC2 MOV# 0,0,SZC ; IF IS THEN JMP CPAT2 ; JUST BRANCH ELSE ; GET ADDRESS OF FLAG WORD FROM WORD AFTER CALL LDA 2,ORTN,3 ; GET ADDRES OF WORD AFTER CALL LDA 2,0,2 ; AND PICK UP FLAG WORD ADDR ISZ ORTN,3 ; AND INC TO PATH BUSY RETURN ; CHECK TO SEE IF PAqTH IS BUSY CPAT2: INTDS ; DIABLE INTERRUPTS WHILE LOOKING ISZ 0,2 ; IF PATH IS BUSY THEN JMP CPAT4 ; JUMP ELSE ; GOT CONTROL OF PATH, RETURN TO CALLER AT GOT PATH RETURN INTEN ; ENABLE INTERRUPTS AGAIN ISZ ORTN,3 ; INC TO GOT PATH RETURN RTRN ] ; AND RETURN TO CALLER ; PATH IS BUSY, RETURN TO CALLER AT PATH BUSY RETURN CPAT4: INTEN ; ENABLE INTERRUPTS AGAIN BUT DSZ 0,2 ; CORRECT COUNT OF # WAITING RTRN ; THEN RETURN TO RTRN ; CALLER ;EXECUTE I/O INSTRUCTIONS ; (DEVICE CODE OeBTAINED FROM DCT) ; AC2: BUFFER ADDRESS ; AC1 AND AC3 ARE DESTROYED XDOA: LDA 1,.DOA .IFE BSW!MBSW XEQ: STA 3,RLOC STA @2,CSP ; SAVE AC2 LDA 2,BQDCT,2 ; GET DCT ADDR FROM BUF LDA 3,DCTCD,2 ; GET DEVICE CODE ADD 3,1 ; MAKE I/O INSTRUCTԁION STA @1,DCTEX,2 JMP @DCTEX,2 ; GO DO IT .ENDC .IFN BSW!MBSW XEQ: PSH 3,3 ; SAVE RETURN LDA 3,BQDCT,2 ; GET DCT ADDRESS LDA 3,DCTCD,3 ; DEVICE CODE ADD 3,1 ; FORM INSTRUCTION XCT 1 ; WAHOO POPJ .ENDC XNOC: LDA 1,.XNOC JMP XEQ XDIBC: LDA @1,.XDBC JMP XEQ XNOS: LDA 1,.NXOS JMP XEQ XDICC: LDA 1,.DICC JMP XEQ XDOCS: LDA 1,.DOCS JMP XEQ XDOB: LDA 1,.DOB JMP XEQ XDOC: LDA 1,.DOC JMP XEQ XOAS: XDOAS: LDA 1,.DOAS JMP XEQ XDOAP: LDA 1,.DOAP JMP XEQ XDOBS: LDA 1,.DOBS JMP XEQ XDOBP: LDA 1,.DOBP JMP XEQ XDOCP: LDA 1,.DOCP JMP XEQ XIAC: XDIAC: LDA 1,.CDIA JMP XEQ XDIC: LDA 1,.DIC JMP XEQ XDIB: LDA 1,.DIB JMP XEQ XDIA: LDA 1,.DIA JMP XEQ XDOAC: LDA 1,.DOAC JMP XEQ .DOAC: DOAC 0,0 .DOAP: DOAP 0,0 .DOBP: DOBP 0,0 .DOBS: DOB)gS 0,0 .DOAS: DOAS 0,0 .DOC: DOC 0,0 .DOB: DOB 0,0 .DOCP: DOCP 0,0 .DOA: DOA 0,0 .CDIA: DIAC 0,0 .DIC: DIC 0,0 .DIB: DIB 0,0 .DIA: DIA 0,0 .DICC: DICC 0,0 .DOCS: DOCS 0,0 .NXOS: NIOS 0 .XNOC: NIOC 0 .XDBC: DIBC 0,0 ; DISK DISPATCH TABLE DSKDT: DSKO ; DISK FILE OPEN DSKC ; DISK FILE CLOSE DFRS ; READ BINARY DFRL ; READ ASCII DFRR  ; READ RANDOM DFWS ; WRITE BINARY DFWL ; WRITE ASCII DFWR ; WRITE RANDOM DSKA ; OPEN FOR APPENDING DFRO ; OPEN FOR READING ONLY DFEO ; OPEN FOR EEe&XCLUSIVE READ/WRITE DFTO ; TRANSPARENT (EXCLUSIVE) OPEN .END GSUB.SRB p { ; ; GENERAL SUBROUTINE UTILITY PACKAGE FOR RDOS. ; RTITLE GSUB .IFN NSW ; UNMAPPED NOVA ONLY .NREL .ENT SAVEM ;SAVE REGISTERS .ENT RETN ;RESTORE REGISTERS .ENT MVBYT ;MOVE BYTES .ENT MTMVB,MFMVB .ENT LDBT,LDCHR ;LOAD A BYTE .ENT STBT,STCHR \;STORE A BYTE .ENT MLDBT,MSTBT .ENT MVWD ;MOVE WORDS .ENT MBMVW,MFMVW,MTMVW .ENT CLEAR ;CLEAR CORE .ENT MCLR .ENT CMPWD ;COMPARE WORDS .ENT TSTNE,TSTEQ ;TEST ERROR CODES .ENT DIVI,DIVD ;DIVIDE .ENT MPY,MPYAD ;MULTIPLY .ENT ROX ;EXCLUSIVE OR .ENT/ SETFL ;SET BITS ON .ENT RSTFL ;SET BITS OFF .ENT SRTN ; ; SUBROUTINE LINKAGE. ; SAVEM: STA 3,RLOC ;SAVE RETURN IN TEMP. LOCATION LDA 3,CSP ;CURRENT STACK POINTER LDA 3,NSP,3 ;NEXT STACK POINTER MOVL# 3,3,SZC JMP STOUF STA 3,CSP ;PUSH STACK FRAM#E STA 0,OAC0,3 ;SAVE AC'S STA 1,OAC1,3 STA 2,OAC2,3 JMP@ RLOC ;ENTER SUBROUTINE RETN: LDA 3,CSP ;CURRENT STACK POINTER LDA 0,OAC0,3 ;LOAD AC'S LDA 1,OAC1,3 LDA 2,OAC2,3 LDA 3,OSP,3 ;POP STACK POINTER STA 3,CSP JMP@ RTLOC,3 ;RETURN TO CALLER STOgUF: MOV 3,2 ;SAVE OVERFLOW POINTER JSR @.PNIC PNCSO ; ; MOVE BYTES AROUND. ; ; ; AC0: FROM BYTE POINTER ; AC1: TO BYTE POINTER ; AC2: BYTE COUNT ; JSR MVBYT ; MTMVB: MFMVB: MVBYT: STA@ 3,CSP ;SAVE RETURN LDA 3,CSP ;SAVE STATE STA 0,AC0,3 ;USE CURRE:NT FRAME STA 1,AC1,3 STA 2,AC2,3 MOVR# 0,0,SZC JMP MB ;MOVE BYTES MOVR# 1,1,SZC JMP MB MOVR# 2,2,SNC JMP MW ;MOVE WORDS MB: STA 0,MVA0 STA 1,MVA1 MOV 0,1 NEG 2,2,SNR JMP SRTN MVLP: JSR LDBT ;LOAD A BYTE ISZ MVA0 ;BUMP FROM POINTER LDA 1,MVA 1 ;TO POINTER JSR STBT ;STORE BYTE ISZ MVA1 LDA 1,MVA0 INC 2,2,SZR ;DONE ? JMP MVLP ;LOOP BACK SRTN: LDA 3,CSP ;RESTORE STATE FROM CURRENT FRAME LDA 0,AC0,3 LDA 1,AC1,3 LDA 2,AC2,3 JMP@ 0,3 MW: MOVZR 0,0 MOVZR 1,1 MOVZR 2,2 JMP MVWD1 MVA0: 0 1MVA1: 0 ; ; BYTE ROUTINES. ; ; AC1: BYTE POINTER ; AC0: BYTE ;(CARRY IS DESTROYED) ; MLDBT: LDCHR: LDBT: STA 3,RLOC ;SAVE RETURN MOVZR 1,3 ;MAKE CORE ADDRESS FROM BYTE POINTER LDA 1,C377 ;MASK LDA 0,0,3 ;BYTE WORD MOV# 0,0,SNC MOVS 0,0 ;SWAP WORD zSAND 1,0 ;MASK TO GET BYTE MOVL 3,1 ;RESTIRE AC1 LDA 3,CSP ;GET CSP JMP@ RLOC ;RETURN C377: 377 MSTBT: STCHR: STBT: STA 3,RLOC ;SAVE RETURN LDA 3,CSP STA 2,STA2 STA 0,STA0 LDA 2,C377 ;HALF WORD MASK AND 2,0 ;MASK INPUT TO HALF WORD MOVZR 1,3,SZ}C ;MAKE CORE ADDRESS MOVS 2,2 ;SWAP LDA 1,0,3 ;BYTE WORD AND 2,1,SNC MOVS 0,0 ADD 1,0 ;ADD IN BYTE STA 0,0,3 ;PUT BACK MOVL 3,1 ;RESTORE AC0 LDA 3,CSP LDA 2,STA2 ;RESTORE AC0,AC2 LDA 0,STA0 JMP@ RLOC STA2: 0 STA0: 0 ; ; MOVE WORDS ; ; AC0: iFROM ADDRESS ; AC1: TO ADDRESS ; AC2: COUNT ; JSR MVWD ; MBMVW: MFMVW: MTMVW: MVWD: STA@ 3,CSP ;SAVE RETURN LDA 3,CSP ;SAVE STATE STA 0,AC0,3 ;USE CURRENT FRAME STA 1,AC1,3 STA 2,AC2,3 MVWD1: MOV 0,3 ;FROM NEG 2,0,SNR ;COUNT JMP SRTN MOV 1,2 ;TO fADDRESS LDA 1,0,3 STA 1,0,2 INC 2,2 INC 3,3 INC 0,0,SZR ;DONE ? JMP .-5 JMP SRTN ; ; CLEAR CORE ; ; AC0: COUNT ; AC2: ADDRESS ; JSR CLEAR ; MCLR: CLEAR: STA@ 3,CSP ;SAVE RETURN LDA 3,CSP ;SAVE STATE STA 0,AC0,3 ;USE CURRENT FRAME STA 1,AC1,3 t STA 2,AC2,3 NEG 0,0,SNR JMP SRTN SUB 1,1 ;CLEAR STA 1,0,2 ;STORE ZERO INC 2,2 INC 0,0,SZR JMP .-3 JMP SRTN ; ; COMPARE WORDS ; ; AC0: ADDRESS 1 ; AC1: ADDRESS 2 ; AC2: WORD COUNT ; JSR CMPWD ; -SUCESS RETURN ; -FAIL RETURN ; CMPWD: STA@ 3,CSP ;SAVE RETURN LDA 3,CSP ;SAVE STATE STA 0,AC0,3 ;USE CURRENT FRAME STA 1,AC1,3 STA 2,AC2,3 MOV 0,3 NEG 2,0,SNR JMP SRTN ;NONE STA 0,CMPTM ;COUNT MOV 1,2 CMPLP: LDA 0,0,2 LDA 1,0,3 SUB# 0,1,SZR JMP NOTEQ ;NOT THE SAME INC 2,2 INC 3,3 ISZ CMPTM- ;DONE ? JMP CMPLP JMP SRTN NOTEQ: LDA 3,CSP ISZ 0,3 ;TAKE FAIL RETURN JMP SRTN CMPTM: 0 ; ROUTINE TO TEST ERROR CODE IN CTMP2 OF CURRENT CELL ; FOR EQUALLITY/NON-EQUALLITY OF ERROR CODE AT CALL+1 ; ; RETURNS: CALL+1 - TEST FAILED ; CALL+2 - TEST TRUE TSTNE: MOVO 0,0,SKP ; TEST FOR NON-EQUALLITY TSTEQ: MOVZ 0,0 ; TEST FOR EQUALLITY STA 3,RLOC ; SAVE RETURN LDA 3,CSP STA 1,AC1,3 STA 2,AC2,3 LDA 2,CC ; CURRENT CELL LDA 2,CTMP2,2 ; CURRENT ERROR CODE LDA 1,@RLOC ; GET CODE TO BE TESTED IS+Z RLOC ; BUMP PAST CODE SUB# 1,2,SNR ; EQUAL ? MOVC 1,1 ; YES, COMPLEMENT THE CARRY MOV# 1,1,SZC ; NOW TEST CARRY ISZ RLOC ; TEST TRUE - RETURN TO CALL+2 LDA 1,AC1,3 LDA 2,AC2,3 JMP @RLOC ; ; DIVIDE R0,,R1 BY R2. ; QUOTIENT IN R1 AND REMAINDEwR IN R0. ; SET CARRY ON OVERFLOW. ; DIVI: SUB 0,0 ;INTEGER DIVIDE ENTRY POINT DIVD: STA 3,RLOC ;RETURN SUBZ# 2,0,SZC ;IS IT GONNA FIT? JMP DOFLO ;OUT YA GO LDA 3,MC20 MOVZL 1,1 D0: MOVL 0,0 SUB# 2,0,SZC SUB 2,0 MOVL 1,1 INC 3,3,SZR JMP D0 MOVZ 3r,3,SKP ;MADE IT - CLEAR CARRY DOFLO: MOVO 3,3 LDA 3,CSP JMP@ RLOC MC20: -20 ; ; MULTIPLY R1 BY R2 ; PRODUCT IN R0 R1 ; MPYAD ENTRY POINT RESULT IS R0+R1*R2 ; MPY: SUBC 0,0 ; CLEAR AC0, SAVE CARRY MPYAD: STA 3,RLOC ; SAVE RETURN LDA 3,MC20 ; STEP COUgNT .MP: MOVR 1,1,SNC ; CHECK NEXT MULTIPLIER BIT MOVR 0,0,SKP ; 0-SHIFT ADDZR 2,0 ; 1-ADD MULTIPLICAND AND SHIFT INC 3,3,SZR ; DONE ? JMP .MP ; TRY AGAIN MOVCR 1,1 ; GET THE LAST BUGGER JMP GOUT ; GOODBYE ; ; AC1 = AC0.XOR.AC1 ; ROX: STA@ 3,CSP ;SAVE REUTNR MOV 1,3 ;COPY AC1 ANDZL 0,3 ;CARRY BITS ADD 0,1 ;ADD SUB 3,1 ;SUBTRACT CARRYS LDA 3,CSP JMP@ 0,3 ; ; SET/RESET BITS ; AC0: WORD ; AC1: MASK ; RSTFL: MOVZ 0,0,SKP SETFL: MOVO 0,0 STA 3,RLOC ;RETURN COM 1,3 AND 3,0,SZC ADC 3,0 6GOUT: LDA 3,CSP JMP@ RLOC .ENDC .IFN BSW ; UNMAPPED BIRD GSUB .NREL .ENT CLEAR ;CLEAR CORE .ENT MVWD ;MOVE WORDS .ENT CMPWD ;COMPARE WORDS .ENT MVBYT .ENT SSOVF .ENT MAGIC .ENT DIVI,DIVD .ENT MTMVW,MFMVW .ENT MPY,MPYAD .ENT MTMVB,MFMVB5 .ENT MBMVW .ENT MCLR .ENT TSTEQ .ENT TSTNE ; ; STACK OVERFLOW HANDLER ; SSOVF: INTDS LDA 2,CSP ;STACK FOR THE USER JSR @.PNIC PNCSO ; ; UNDEFINED EXTENDED INSTRUCTION HANDLER ; MAGIC: JSR@ .PNIC ;SURPRISE! PNILL ; ; MOVE BYTES AROUNDq. ; ; ; AC0: FROM BYTE POINTER ; AC1: TO BYTE POINTER ; AC2: BYTE COUNT ; JSR MVBYT ; MTMVB: MFMVB: MVBYT: RSAVE 0 NEG 2,2,SNR ;MAKE COUNT NEG RTRN ;COUNT IS ZERO - JUST RETURN MVLP: LDB 0,3 ;GET A BYTE STB 1,3 ;STORE IT AWAY INC 2,2,SNR ;DONE? RTRN ;YES - RETURN INC 0,0 ;NO - INCREMENT BYTE POINTERS INC 1,1 JMP MVLP ;AND CONTINUE ; ; CLEAR CORE ; ; AC0: COUNT ; AC2: ADDRESS ; JSR CLEAR ; MCLR: CLEAR: RSAVE 0 ;SAVE STATE NEG 0,1,SNR ;PUT NEG COUNT IN AC1 RTRN ;COUNT IS ZERO - JUST RETURMN MOVL 2,2 ;MAKE SURE NO INDIRECT MOVZR 2,2 SUB 0,0 ;FIND A ZERO STA 0,0,2 ;PUT IN FIRST LOC TO BE CLEARED INC 2,3 ;PUT ADDR OF NEXT LOCATION IN AC3 COM 1,1,SZR ;PUTS ORIGINAL COUNT-1 IN AC1 BLM ;CLEAR REST OF SPACE RTRN ;RETURN (BLM IS SKIPPED I9F COUNT WAS 1) ; ; MOVE WORDS ; ; AC0: FROM ADDRESS ; AC1: TO ADDRESS ; AC2: COUNT ; JSR MVWD ; MBMVW: MFMVW: MTMVW: MVWD: RSAVE 0 MOVL 1,3 ;SET UP AC'S FOR BLM MOVZR 3,3 ;TURN 1B0 OFF MOV 2,1 MOVL 0,2 ;SOURCE ADDRESS CAN'T INDIRECT MOVZR 2,2 BLM RTRN ; ; COMPARE WORDS ; ; AC0: ADDRESS 1 ; AC1: ADDRESS 2 ; AC2: WORD COUNT ; JSR CMPWD ; -SUCESS RETURN ; -FAIL RETURN ; CMPWD: RSAVE 0 MOV 0,3 NEG 2,0,SNR RTRN ;NONE STA 0,CMPTM ;COUNT MOV 1,2 CMPLP: LDA 0,0,2 LDA 1,0,3 SUB# 0,1,SZR JMP NO@TEQ ;NOT THE SAME INC 2,2 INC 3,3 ISZ CMPTM ;DONE ? JMP CMPLP RTRN NOTEQ: ISZ @CSP ;TAKE FAIL RETURN RTRN CMPTM: 0 ; DIVIDE AC0,,AC1 BY AC2 ; QUOTIENT IN AC1 - REMAINDER IN AC0 ; ON OVERFLOW - SET CARRY DIVI: SUB 0,0 ;INTEGER DIVIDE DIVD: PSH 3b.,3 ;SAVE RETURN DIV ;DIVIDE LDA 3,CSP ;RETURN CSP POPJ ; MULTIPLY AC1 BY AC2 ; PRODUCT IN AC0,,AC1 - AC2 UNCHANGED ; MPYAD ENTRY - RESULT IS AC1*AC2+AC0 MPY: SUBC 0,0 ;CLEAR AC0 MPYAD: PSH 3,3 ;SAVE RETURN MUL ;DO THE MULTIPLY LDA 3,CSP ;RETURN Cx%SP POPJ ; ROUTINE TO TEST ERROR CODE IN CTMP2 OF CURRENT CELL ; FOR EQUALLITY/NON-EQUALLITY OF ERROR CODE AT CALL+1 ; ; RETURNS: CALL+1 - TEST FAILED ; CALL+2 - TEST TRUE TSTNE: MOVO 0,0,SKP ; TEST FOR NON-EQUALLITY TSTEQ: MOVZ 0,0 ; TEST FOR EQUALLITY RSAVE 0 LDA 2,ORTN,3 ; RETURN PC LDA 1,0,2 ; GET CODE TO BE TESTED ISZ ORTN,3 ; BUMP RETURN PAST CODE LDA 2,CC ; CURRENT CELL LDA 2,CTMP2,2 ; CURRENT ERROR CODE SUB# 1,2,SNR ; EQUAL? MOVC 1,1 ; YES, COMPLEMENT THE CARRY MOV# 1,1,SZC ; NOW TEST CARRY ISZ ORTN,3 ; TEST TRUE - TAKE SKIP RETURN RTRN .ENDC .IFN MSW ; MAPED GSUB .NREL .IFN MBSW .ENT SSOVF .ENDC .IFE MBSW .ENT MAPD MFSB MAPC .ENT LDBT,LDCHR ;LOAD A BYTE .ENT STBT,STCHR ;STORE A BYTE .ENT SRTN,RETN,SA>VEM .ENT SETFL,RSTFL .ENT ROX .ENDC .ENT CLEAR ;CLEAR CORE .ENT MVWD ;MOVE WORDS .ENT MPY,MPYAD .ENT CMPWD ;COMPARE WORDS .ENT DIVD,DIVI ;DIVIDE .ENT MSTBT,MLDBT .ENT MVBYT .ENT MTMVW,MFMVW .ENT MTMVB,MFMVB .ENT MCLR .ENT MBMVW .ENT TSTEQ,TSTNE .ENT MBLK .ENT GMBK,RMBK,GMBK2,RMBK2 .EXTD MAPCC .EXTN PT1,PT2 .EXTD C31K .EXTD FBLK1,BBLK1 .IFE MBSW .EXTD CLSTB,MFSTB .EXTD CMAP .ENDC .IFN MBSW .EXTD CLBLK .ENDC .IFE MBSW ; ; SUBROUTINE LINKAGE. ; SAVEM: STA 3,RLOC ;SAVE RETURN IN TEMP. LOCATION LDA 3,CSP ;CURRENT STACK POINTER LDA 3,NSP,3 ;NEXT STACK POINTER MOVL# 3,3,SZC JMP STOUF STA 3,CSP ;PUSH STACK FRAME STA 0,OAC0,3 ;SAVE AC'S STA 1,OAC1,3 STA 2,OAC2,3 JMP @RLOC ;ENTER SUBROUTINE RETN: LDA 3,CSP ;CURR ENT STACK POINTER LDA 0,OAC0,3 ;LOAD AC'S LDA 1,OAC1,3 LDA 2,OAC2,3 LDA 3,OSP,3 ;POP STACK POINTER STA 3,CSP JMP @RTLOC,3 ;RETURN TO CALLER STOUF: MOV 3,2 ;SAVE OVERFLOW POINTER JSR @.PNIC PNCSO SRTN: LDA 3,CSP LDA 0,AC0,3 LDA 1,AC1,3 LDA 2,AC2,3 JMP @0,3 .ENDC .IFN MBSW ; STACK OVERFLOW- PANIC SSOVF: INTDS LDA 2,CSP JSR @.PNIC PNCSO .ENDC ; ; MOVE BYTES AROUND. ; ; ; AC0: FROM BYTE POINTER ; AC1: TO BYTE POINTER ; AC2: BYTE COUNT ; JSR MVBYT ; .IFN MBSW MVBYT: RSAVE 0 NEG 2,2,S5NR RTRN MVB1: LDB 0,3 STB 1,3 ;MOVE A BYTE INC 2,2,SNR ;DONE ? RTRN INC 0,0 ;NXT BYTE INC 1,1 JMP MVB1 ;AGAIN SAM .ENDC .IFE MBSW MVBYT: RSAVE 2 ;SAVE RETURN SUB 0,0 ;FLAG AS A NORMAL MOVE .ENDC MVBY1: STA 0,MAPF,3 ;TYPE LDA 0,OAC0,3 ;RE`rSTORE AC0 MOVR# 0,0,SZC JMP MB ;MOVE BYTES MOVR# 1,1,SZC JMP MB MOVR# 2,2,SNC JMP MW ;MOVE WORDS MB: STA 0,MVA0 STA 1,MVA1 MOV 0,1 NEG 2,2,SNR RTRN MVLP: LDA 0,MAPF,3 ;MAP NEEDED ? MOVL# 0,0,SZC ;SKIP IF NO JMP MVBY3 .IFE MBSW JSR LDBT ;L/OAD A BYTE .ENDC .IFN MBSW LDB 1,0 .ENDC MVBY4: ISZ MVA0 ;BUMP FROM POINTER LDA 1,MVA1 ;TO POINTER LDA 3,MAPF,3 ;MAP NEEDED ? MOVR# 3,3,SZC JMP MVBY5 .IFE MBSW JSR STBT ;STORE BYTE .ENDC .IFN MBSW STB 1,0 LDA 3,CSP .ENDC MVBY6: ISZ MVA1 +LDA 1,MVA0 INC 2,2,SZR ;DONE ? JMP MVLP ;LOOP BACK RTRN MW: MOVZR 0,0 MOVZR 1,1 MOVZR 2,2 .IFE MBSW JMP MVWD1 ;TMP SET UP FOR MAPPING IN MVWD .ENDC .IFN MBSW LDA 3,TMP,3 ;TYPE FLAG MOVL# 3,3,SNC ;SKIP IF FROM MAPPED SPACE JMP .+3 JSR MFMbVW RTRN JSR MTMVW RTRN .ENDC MVA0: 0 MVA1: 0 ; MAPPED TO ADDR MTMVB: RSAVE 2 SUBZL 0,0 MVBY2: JSR MAPCC ;MAP IF NEEDED LDA 3,CSP LDA 1,OAC1,3 LDA 2,OAC2,3 JMP MVBY1 ;COMMON CODE ; MAPPED FROM ADDR MFMVB: RSAVE 2 SUBZR 0,0 JMP MVBY2 MAPF= TMP MVBY3: JSR MLDBT JMP MVBY4 MVBY5: JSR MSTBT JMP MVBY6 .IFE MBSW ; ; BYTE ROUTINES. ; ; AC1: BYTE POINTER ; AC0: BYTE ;(CARRY IS DESTROYED) ; LDCHR: LDBT: RSAVE 0 MOVZR 1,2 ;MAKE CORE ADDRESS FROM BYTE ; POINTER LDA 0,0,2 ;BYTE WORD LDBTC: LDA 1,C377 MOV# 0,0,SNC MOVS 0,0 ;SWAP WORD AND 1,0 ;MASK TO GET BYTE STA 0,OAC0,3 ;PASS BACK RTRN STBT: STCHR: RSAVE 0 LDA 3,C377 ;HALF WORD MASK AND 3,0 ;MASK INPUT TO HALF WORD MOVZR 1,2,SZC ;MAKE CORE ADDRESS MOVS 3,3 ;SWAP LDA 1,0N,2 ;BYTE WORD AND 3,1,SNC MOVS 0,0 ADD 1,0 ;ADD IN BYTE STA 0,0,2 ;PUT BACK RTRN .ENDC C377: 377 ; MAPPED LOAD BYTE MLDBT: RSAVE 1 MLDBA: JSR MAPCC ;SEE IF MAPPED LDA 3,CSP LDA 1,OAC1,3 ;RESTORE MOVZR 1,2 MLDA 0,0,2 ;MAPPED LOAD LDA 1,C37m7 MOV# 0,0,SNC MOVS 0,0 ;SWAP BYTES AROUND AND 1,0 ;DROP OTHER BYTE STA 0,OAC0,3 RTRN ;MAPPED STORE MSTBT: RSAVE 1 JSR MAPCC ;MAP IF NEEDED LDA 3,CSP LDA 1,OAC1,3 LDA 3,C377 AND 3,0 MOVZR 1,2,SZC ;WHICH BYTE ? MOVS 3,3 ;FLIP MASK MLDA 1,0,2 ;PRESENT CONTENTS AND 3,1,SNC ;MERGE HALVES MOVS 0,0 ADD 1,0 MSTA 0,0,2 ;STORE BACK RTRN ; ; AC1 = AC0.XOR.AC1 ; .IFE MBSW ROX: STA @3,CSP ;SAVE REUTNR MOV 1,3 ;COPY AC1 ANDZL 0,3 ;CARRY BITS ADD 0,1 ;ADD SUB 3,1 ;SUBTRACT CARRYS M LDA 3,CSP JMP @0,3 ; ; CLEAR CORE ; ; AC0: COUNT ; AC2: ADDRESS ; JSR CLEAR ; CLEAR: RSAVE 0 ;SAVE RETURN SUB 1,1 ;FLAG AS NO MAP CLR1: NEG 0,0,SNR RTRN SUB 3,3 CLR2: MOVL# 1,1,SZC ;MAP NEEDED ? MSTA 3,0,2 ;STORE ZERO INC 2,2 INC 0,0,SZR JM:P CLR2 RTRN ; MAPPED CLEAR MCLR: RSAVE 0 JSR MAPCC LDA 3,CSP LDA 2,OAC2,3 SUBZR 1,1 ;MAP FLAG JMP CLR1 .ENDC .IFN MBSW ; CLEAR CORE; AC2= SA, AC0= COUNT CLEAR: RSAVE 0 NEG 0,1,SNR ;ANY WORDS TO CLEAR RTRN ;NO MOVL 2,2 ;INSURE 1B0=0 MOVZR 2,2 SUB 0,0 STA 0,0,2 ;0 FIRST WORD INC 2,3 ;MOVE .-1(0) TO . COM 1,1,SZR ;ONLY ONE WORD ? BLM ;NO-DO REST RTRN ; CLEAR CORE IN USER SPACE ; AC2= SA, AC0= CNT, CELL CPTAD= PROG TO CLEAR MCLR: RSAVE 2 MOVZL 2,0 ;RESET B0 MOVZR 0,0 LDA 1,OAC^0,3 ;CLR CNT MCLR1: STA 0,MPAD,3 JSR MKADR ; AC2= MAPPED ADDR IN LB, AC0 = MAX CLR CNT SUBZ# 1,0,SNC JMP MCLBG ;TOO BIG A CLR FOR 1 MAP SUB 0,0 ;NO RESIDUE MCLR2: STA 0,RES,3 MOV 1,0 ;SAVE MAX CNT NEG 1,1,SNR ;NO WDS TO CLR ? JMP MPEXT ;MUST LI+KE TO JSR ALOT SUB 3,3 STA 3,0,2 ;0 FIRST WD INC 2,3 ;DESTINATION IS AC2+1 COM 1,1,SZR ;SKIP IF ONLY 1 WD IN THIS CLR BLM ;CLEAR REST LDA 3,CSP LDA 1,RES,3 MOV# 1,1,SNR JMP MPEXT ;NO RESIDUE LDA 2,MPAD,3 ;LAST MAPPED ADDR ADD 2,0 ;ADD TO ΪCLR CNT JMP MCLR1 ;AGAIN MCLBG: SUB 0,1 ;RESIDUE XCH 0,1 JMP MCLR2 ; MOVE WORDS TO MAPPED SPACE ; AC0= SOURCE, AC1= DESTINATION, AC2= CNT ; MTMVW: RSAVE 3 MOVL 0,0 ;INSURE B0 RESET MOVZR 0,0 STA 0,UMAD,3 ;INIT UNMAPPED ADDR MOVZL 1,0 ;ADDR TO MAP MOVZR 0,0 LDA 1,OAC2,3 ;WD CNT MTMVN: STA 0,MPAD,3 ;SAVE IT JSR MKADR ;MAKE IT A MAPPED ADDR ; AC2= MAPPED ADDR IN LBK ; AC0= # WDS FOR MAX BLM SUBZ# 1,0,SNC ;IF THIS BLM WILL DO IT, SKIP JMP MTBG ;TOO BIG SUB 0,0 ;NO RESIDUE MTMV1: STA 0,RES,3 ;RESIDUE LDA 3,UMAD,3 ;FROM ADDR XCH 2,3 ;FOR BLM MOV 1,0 ;SAVE CNT BLM LDA 3,CSP LDA 1,RES,3 ;RESIDUE MOV# 1,1,SNR JMP MPEXT ;EXIT- ALL DONE STA 2,UMAD,3 ;NEXT ADDR LDA 2,MPAD,3 ;ADDR TO MAP ADD 2,0 ;ADD TO CNT JUST BLM JMP MTMVN ;AGAIN MTBG: SUB 0,1 ;CNT WE CAN DO NOW XCH 0,1 JMP MTMV1 ; MOVE WORDS FROM MAPPED SPACE ; AC0= SOURCE, AC1= DESTINATION, AC2= CNT ; MFMVW: RSAVE 3 ADCZR 2,2 ;0777777 AND 2,1 AND 2,0 ;RESET B0 IF SET STA 1,UMAD,3 ;INIT UNMAPPED ADDR LDA 1,OAC2,3 ΍;WD CNT MFMVN: STA 0,MPAD,3 ;SAVE IT JSR MKADR ;MAKE IT A MAPPED ADDR ; AC2= MAPPED ADDR IN LBK ; AC0= # WDS FOR MAX BLM SUBZ# 1,0,SNC ;IF THIS BLM WILL DO IT, SKIP JMP MFBG ;TOO BIG SUB 0,0 ;NO RESIDUE MFMV1: STA 0,RES,3 ;RESIDUE LDA 3,UMAD,3 ;FKROM ADDR MOV 1,0 ;SAVE CNT BLM LDA 2,CSP LDA 1,RES,2 ;RESIDUE MOV# 1,1,SNR JMP MPEXT ;EXIT- ALL DONE STA 3,UMAD,2 ;NEXT ADDR LDA 2,MPAD,2 ;ADDR TO MAP ADD 2,0 ;ADD TO CNT JUST BLM LDA 3,CSP JMP MFMVN ;AGAIN MFBG: SUB 0,1 ;CNT WE CAN DO NO-W XCH 0,1 JMP MFMV1 ; CONVERT AN ADDR IN AC0 TO LBLK REL ADDR ; RTN MAPPED ADDR IN AC2, WDS MAX MOVE IN AC0 ; AC1 IS PRESERVED MKADR: PSH 3,3 MOV 0,2 LDA 3,CM10 LSH 3,0 ;BLK # LDA 3,CC LDA 3,CPTAD,3 ;PTBL ADD 0,3 ;BLK REL LDA 3,PMAP,3 ;CONTENΤTS STA 3,CLBLK ;LAST BLK DOB 3,BMAP ;TO MAP LDA 3,C31K ;76000 ANC 3,2 ;OFFSET ADD 3,2 ;MAGIC ADDR SUBZR 0,0 ;MAX BLK ADDR WHEN MAPPED +1 SUB 2,0 LDA 3,CSP POPJ CM10: -10. MPEXT: LDA 3,CC LDA 3,CPTAD,3 ;PTBL LDA 1,PMAP,3 ;FIRST BLK STA 1m,CLBLK ;RESTORE LBLK TO TCB DOB 1,BMAP RTRN RES= TMP MPAD= TMP+1 UMAD= TMP+2 ; RES AND MPAD MUST BE THE FIRST 2 TMP'S .ENDC  ; ; MOVE WORDS ; ; AC0: FROM ADDRESS ; AC1: TO ADDRESS ; AC2: COUNT ; JSR MVWD ; .IFN MBSW MVWD: RSAVE 0 MOVL 1,3 ;MO [VE FOR BLM AND RESET 1B0 MOVZR 3,3 MOV 2,1 MOVL 0,2 MOVZR 2,2 BLM ;MOVE WORDS RTRN .ENDC .IFE MBSW MVWD: RSAVE 2 ;SAVE RETURN SUB 0,0 .ENDC MVWD2: STA 0,MAPF,3 ;SAVE TYP MAP NEEDED LDA 0,OAC0,3 ;RESTORE MVWD1: STA 0,TMP+1,3 ;SAVE 0 NEG 2,0,SNR ;COUNT RTRN MOV 1,2 ;TO ADDRESS STA 0,MVCNT ;COUNT LDA 0,MAPF,3 LDA 3,TMP+1,3 ;FROM ADDR MVWD3: MOVL# 0,0,SZC  ;SKIP IF NO MAP MLDA 1,0,3 MOVR# 0,0,SZC ;SKIP IF NO MAP MSTA 1,0,2 INC 2,2 INC 3,3 ISZ MVCNT ;DONE ? JMP MVWD3 ;NO RTRN I.IFE MBSW ; MAPPED MOVE WORD TO MTMVW: RSAVE 2 SUBZL 0,0 ;FLAG MAP NEEDED MTMV1: JSR MAPCC LDA 3,CSP LDA 2,OAC2,3 LDA 1,OAC1,3 ;RESTORED JMP MVWD2 ; MAPPED FROM ADDR FOR MOVE WD MFMVW: RSAVE 2 SUBZR 0,0 JMP MTMV1 .ENDC ; REQ TO MOVE FROM A MAPPED SPACE TO A MAPPED SPACE MBMVW: RSAVE 2 SUBZR 0,0 INC 0,0 ;BOTH FLAGS SET JMP MTMV1 MVCNT: 0 ; ; COMPARE WORDS ; ; AC0: ADDRESS 1 ; AC1: ADDRESS 2 ; AC2: WORD COUNT ; JSR CMPWD ; -SUCESS RETURN ; -FAIL RETURN ; CMPWD: RSAVE 0 ;SAVE RETURN MOV 0,3 NEG 2,0,SNR RTRN ;NONE STA 0,CMPTM ;COUNT MOV 1,2 CMPLP: LDA 0,0,2 LDA 1,0,3 SUB# 0,1,SZR JMP NOTEQ ;NOT THE SAME INC 2,2 INC 3,3 ISZ CMPTM ;DONE ? JMP CMPLP RTRN NOTEQ: .IFE MBSW LDA 3,CSP ISZ ORTN,3 .ENDC .IFN MBSW ISZ @CSP .END.C RTRN CMPTM: 0 .IFE MBSW ; ; DIVIDE R0,,R1 BY R2. ; QUOTIENT IN R1 AND REMAINDER IN R0. ; SET CARRY ON OVERFLOW. ; DIVI: SUB 0,0 ;INTEGER DIVIDE ENTRY POINT DIVD: STA 3,RLOC ;RETURN SUBZ# 2,0,SZC ;WILL IT FIT? JMP DOFLO ;AHA, CAUGHTCHA! LDA 3,MuC20 MOVZL 1,1 D0: MOVL 0,0 SUB# 2,0,SZC SUB 2,0 MOVL 1,1 INC 3,3,SZR JMP D0 MOVZ 3,3,SKP ;MADE IT, CLEAR CARRY DOFLO: MOVO 3,3 ;FOR SHAME LDA 3,CSP JMP @RLOC MC20: -20 ; ; SET/RESET BITS ; AC0: WORD ; AC1: MASK ; RSTFL: MOVZ 0,0,SKP SETFL: MOVO 0,0 STA 3,RLOC ;RETURN COM 1,3 AND 3,0,SZC ADC 3,0 LDA 3,CSP JMP @RLOC .ENDC .IFN MBSW DIVI: SUB 0,0 ;INTEGER DIV DIVD: PSH 3,3 ;RTN DIV LDA 3,CSP POPJ ;BYE .ENDC ; AC0= ADDR TO MAP ; AC1= 0 IF BG, 1 IF FG ; AC2= MAPPED ADDR ON RTN ; 5IF NO BLK ASSIGNED, BAD RTN .IFE MBSW MBLK: STA @3,CSP .ENDC .IFN MBSW MBLK: PSH 3,3 .ENDC LDA 2,.PT1 ;PTBL 1 MOV# 1,1,SNR ;SKIP IF FG LDA 2,.PT2 LDA 3,CM1777 ;ADJUST ADDR TO BLOCK ANDS 0,3 MOVZR 3,3 ;FORM BLK # MOVZR 3,3 ADD 3,2 LDA 2,PMAzP,2 ;CURRENT CONTENTS LDA 3,CMTST ;377 ; SEE IF BLK THERE AND 3,2 SUB# 3,2,SNR JMP MBBEX ;NO-BAD RTN .IFE MBSW LDA 3,C177 ;DROP COMMAND BITS AND 2,3 LDA 2,CLSTB ;COMMAND BITDS FOR LAST BLK ADD 3,2 .ENDC .IFN MBSW STA 2,CLBLK ;SET NEW LAST , .ENDC SMLB 2 LDA 3,C1777 ;GET BLK OFFSET AND 0,3 ;GET BLK OFFSET LDA 2,C31K ;MOD 76000 ADD 3,2 .IFE MBSW ISZ @CSP ;GOOD RTN MBBEX: LDA 3,CSP JMP @0,3 .ENDC .IFN MBSW ISZ @SP ;GOOD RTN MBBEX: LDA 3,CSP POPJ .ENDC .PT1: PT1 .PT2: PT2 C177: 177 CM1777: 176000 C1777: 1777 CMTST: MPAPH ; ROUTINE TO TEST ERROR CODE IN CTMP2 OF CURRENT CELL ; FOR EQUALLITY/NON-EQUALLITY OF ERROR CODE AT CALL+1 ; ; RETURNS: CALL+1 - TEST FAILED ; CALL+2 - TEST TRUE TSTNE: MOVO 0,0,SKP ; TEST FOR NON-EQUALLITY TSTEQ: MOVZ 0,0 ; TEST FOR EQUALLITY RSAVE 0 LDA 2,ORTN,3 ISZ ORTN,3 LDA 1,0,2 ;TEST WORD LDA 2,CC ; CURRENT CELL LDA 2,CTMP2,2 ; CURRENT ERROR CODE SUB# 1,2,SNR ; EQUAL MOVC 1,1 ; YES, COMPLEMENT THE CARRY MOV# 1,1,SZC ; NOW TEST CARRY 6ISZ ORTN,3 RTRN ; MULTIPLY R1 BY R2 ; PRODUCT IN R0 R1 ; MPYAD ENTRY POINT RESULT IS R0+R1*R2 ; MPY: SUBC 0,0 ; CLEAR AC0, SAVE CARRY MPYAD: .IFE MBSW STA 3,RLOC ; SAVE RETURN LDA 3,MC20 ; STEP COUNT .MP: MOVR 1,1,SNC ; CHECK NEXT MULTIPLIER BIT 8MOVR 0,0,SKP ; 0-SHIFT ADDZR 2,0 ; 1-ADD MULTIPLICAND AND SHIFT INC 3,3,SZR ; DONE ? JMP .MP ; TRY AGAIN MOVCR 1,1 ; GET THE LAST BUGGER LDA 3,CSP JMP @RLOC .ENDC .IFN MBSW PSH 3,3 ;RTN MUL LDA 3,CSP POPJ .ENDC ; GMBK (ACTUALLY GMBLK) ; GMBK2 ; GET MEMORY BLOCK ROUTINES ; CPROG MUST BE SET UP IN CURRENT CELL FOR GMBK (GMBLK) ; CTMP4 MUST HAVE A 0/1 FOR FG, OR A 2 FOR BG FOR GMBK2 ; JSR GMBLK ; (ERROR RETURN) ; NO BLOCKS LEFT ; (NORMAL RETURN) ; AC1 = BLOCK NUMBER ; GET A MEM BLOC_AK GMBK: RSAVE 1 ; SAVE THE WORLD LDA 2,CC ; GET PROGRAM FLAG LDA 2,CPROG,2 GMB1: LDA 0,BBLK1 ; BACKGROUND COUNT AVAILABLE MOVZR# 2,2,SNR ; FG OR BG REQUEST ? LDA 0,FBLK1 ; FOREGROUND COUNT AVAILABLE LDA 1,MFREE ; START OF FREE CHAIN MOV 0,0,SZpR ; ANY LEFT FOR THIS GROUND ? COM# 1,1,SNR ; ANY LEFT ON FREE CHAIN ? RTRN ; WHEN YOUR OUT OF SHLITZ !! ISZ ORTN,3 ; OK- SET NORMAL RETURN .IFN MBSW LDA 0,CLBLK ; GET LAST BLOCK STA 0,TMP,3 ; SAVE IT STA 1,CLBLK ; SET TO NEW LAST BLOCK .EN-DC SMLB 1 LDA @0,C31K ;GET BLOCK ADDR STA 0,MFREE ;NEW START LDA 0,CMTST AND 0,1 STA 1,OAC1,3 ;SAVE BLK ASSIGNED ADC 0,0 ; SET TO TAKE ONE AWAY GMBEX: LDA 1,BBLK1 ; BACKGROUND COUNT AVAILABLE MOVZR# 2,2,SNR ; FG ?? LDA 1,FBLK1 ; YEP FORGROUNlD COUNT ADD 0,1 ; ADD OR TAKE MOVZR# 2,2,SNR ; WHICH ONE STA 1,FBLK1 ; FG MOVZR# 2,2,SZR STA 1,BBLK1 ; BG GMBER: .IFN MBSW LDA 2,TMP,3 ; RESTORE LAST BLOCK STA 2,CLBLK DOB 2,BMAP ; AND HARDWARE .ENDC .IFE MBSW LDA 2,CC LDA 2,CPTAD,2 ;PTB4L FOR RESTORE OF MAP JSR MFSTB .ENDC RTRN GMBK2: RSAVE 1 LDA 2,CC LDA 2,CTMP4,2 JMP GMB1 ; JOIN COMMON CODE MFREE: -1 ; POINTER TO FREE BLOCK LIST ; RMBK (ACTUALLY RMBLK) ; RMBK2 ; RELEASE A MEMORY BLOCK ; ON INPUT RMBK REQUIRES CPROG OF CC TO06 BE SET UP ; RMBK2 REQUIRES CTMP4 OF CC TO BE SET UP WITH 0 OR 1 FOR FG ; AND 2 FOR BG. ; ON INPUT AC1 CONTAINS THE BLOCK NUMBER ; JSR RMBLK ; (RETURN) ; ALL AC'S SAVED RMBK: RSAVE 1 LDA 2,CC ; GET FG BG FLAG LDA 2,CPROG,2 RMB1: .IFE MBSW LDA 0,C%177 ;GET REAL BLK AND 0,1 LDA 0,CLSTB ;MERGE WITH LAST LOG BLK ADD 0,1 .ENDC .IFN MBSW LDA 0,CLBLK ; SAVE LAST BLOCK STA 0,TMP,3 STA 1,CLBLK ; SET NEW LAST BLOCK .ENDC SMLB 1 LDA 0,MFREE ;CURRENT START STA @0,C31K ;LINK STA 1,MFREE  ;NEWlc FIRST SUBZL 0,0 ; ADD ONE BLOCK JMP GMBEX RMBK2: RSAVE 1 LDA 2,CC LDA 2,CTMP4,2 JMP RMB1 .IFN MNSW!MN3SW ; SEE IF A USER MAP IS LOADED BEFORE FALLING THRU TO MAPU ; AC 1,2,3 DESTROYED ; CARRY MUST BE PRESERVED ;AC2= PTBL MAPD: SUBC 1,1 ;INIT TOO INT ON SKPBN CPU ;SKIP IF INT ON INC 1,1 INTDS STA 1,ISW ;FOR EXIT STA 3,MURTN LDA 3,CMAP MOV# 3,3,SNR JMP MP01 ;FORCED REMAP-DO ALL SUB# 2,3,SNR ;SKIP IF MAP NEEDED JMP MAPX ;RETURN LDA 1,PMSZ,3 ;-OLD SIZE LDA 3,PMSZ,2 ;- NEW SIZE SUBZ7# 3,1,SNC ;USE LARGEST - INDEX MOV 1,3 MP02: STA 2,CMAP MP03: LDA 1,PMAP,2 ;NEXT BLOCK TO MAP SMBK 1 ; SEND BLOCK TO MAP INC 2,2 INC 3,3,SZR JMP MP03 .IFN MNSW LDA 3,CM8 LDA 2,CMAP ;PTBL ADDR LDA 1,PDEV,2 ;DEV ILLEG DOA DOA 1,MAP INC 2,2 ;BUMP POINTER INC 3,3,SZR JMP .-4 .ENDC MAPX: DSZ ISW ;INT ON WHEN ENTERED ? INTEN ;RESTORE JMP @MURTN ; MAP FIRST BLK TO MAP FOR PTBL IN AC2 AS LAST BLOCK ; AC1 DESTROYED MFSB: STA 3,MFRTN LDA 1,PMAP,2 ;FIRST BLOCK LDA 3,C177 AND 3,1 ;SAVE PHYSI=CAL ADDR LDA 3,CLSTB ;LAST BLK LOGICAL ADDR ADD 3,1 SMLB 1 ; SEND TO LAST BLOCK REGISTER LDA 3,CSP JMP @MFRTN ; MAP PTBL CONTAINED IN CC MAPC: LDA 2,CC LDA 2,CPTAD,2 ;PTBL JMP MAPD ;SEE IF MAPPING NEEDED MP01: LDA 3,ALLB ;MAP ALL JMP MP02 ~ISW: 0 MFRTN: 0 MURTN: 0 .IFN MNSW ALLB: -31. CM8: -8. .ENDC .IFN MN3SW ALLB: -32. DEVE: -4-1 .ENDC .ENDC .ENDC .END PLT1D.SRB 4 ; PLT1D.SR ; SECOND PLOTTER DCT RTITLE PLT1D .ENT PLT1D  .ENT PLT1Q .EXTN STOUT .EXTN COSER .EXTN PLOX .EXTN PLTDT .NREL ; PLOTTER DEVICE CONTROL TABLE PLT1D: 0 MKPLT ; MASK COSER ;INTERRUPT SERVICE ROUTINE DCSPO ; SPOOLABLE+SPOLLING ENABLED PLT1 ;DEV CODE PLOX PLTDT ;DISPATCH STOUT ;START OUTPUTTING PLTSZ*2 ;BUFFER SIZE PLTBF*2 ;BUFFER BYTE POINTER .BLK 5 ;PC,PP,RQLK,DP,DC BSUPC+BSDON+BSLPA ; BEAD STATUS .-4 ;BEAD ADDRESS -1 ;REQUEST POINTER .BLK 2 ;DEVICEۿ3 TMPS -1 ;NEGATIVE TIME IN .BLK 2 ;VARIABLE INFO .BLK 3 ;SPOOLER INFO PLTSZ= 100 ; BUFFER SIZE PLTBF: .BLK PLTSZ ; DEFINE THE BUFFER SPACE PLT1Q: .BLK 2 100000 ;FREE STACK USER PLT1D .BLK SQLN-4 .END PLTDR.SRB Z ; PLTDR.SR ; PLOTTER DRIVER RTITLE PLTDR .ENT PLTDCT .ENT PLTQ .ENT PLTDT .ENT PLOX .EXTN OPNO .EXTN CLSO .EXTN WRS .EXTN STOUT .EXTN COSER .NREL ; PLOTTER DEVICE CONTROL TABLE PLTDC: 0 MKPLT ; MASK COSER ;INTERRUPT SERVICE ROUTINE DCSPO ; SPOOLABLE+SPOLLING ENABLED PLT ;DEV CODE PLOX PLTDT ;DISPATCH STOUT ;START OUTPUTTING PLTSZ*2 ;BUFFER SIZE PLTBF*2 ;BUFFER BYTE POINTER .BLK 5 ;PC,PP,RQLK,DP,DC BSUPC+BSDON+BSLPA ; BEAD STATUS .-4 ;BEAD ADDRESS -1 ;REQUEST POINTER .BLK 2 ;DEVICE TMPS -1 ;NEGATIVE TIME IN .BLK 2 ;VARIABLE INFO .BLK 3 ;SPOOLER INFO PLTSZ= 100 ; BUFFER SIZE PLTBF: .BLK PLTSZ ; DEFINE THE BUFFER SPACE PLTQ: .BLK 2 100000 ;FREE STACK USER PLTDC .BLK SQLN-4 PLOX: 0 JMP 0,s{3 JMP 1,3 ; DISPATCH TABLE FOR PLOTTER FUNCTIONS PLTDT: OPNO ; OPEN CLSO ; CLOSE -1 ; READ SEQUENTIAL -1 ; READ LINE -1 ; READ RANDOM WRS ; WRITE SEQUENTIAL -1 ; WRITE LINE -1 ; WRITE RANDOM -1 ; OPEN FOR APPENDING OPNO ; RG=EAD ONLY OPEN OPNO ; EXCLUSIVE OPEN -1 ; TRANSPARENT OPEN .END CDR1D.SRB F RTITLE CDR1D .NREL .ENT CDR1D,CDR1Q .EXTN STCDR,CDRDT,CDRS ; CARD READER DEVICE CONTROL TABLE CDR1D: 0 MKCDR ; MASK CDRS ; INT SERVICE DCIDI+DCFWD+DCC80+DCSTB ; CHARACTERISTICS CDR1 ; DEVICE CODE CDREX CDRDT ; DISPATCH TABLE ADDRES!IS STCDR ; START ROUTINE CDRBS*2 ; BUFFER SIZE CDR1BF*2 ; BUFFER POINTER 81.*2 ; RESTART CONSTANT IN BYTES .BLK 4 ;PP,RQLK,DP,DC BSUPC+BSDON+BSLPA+BSQIT ;INITIAL STATUS .-4 ; BEAD ADDRESS -1 ;QUEUE POINTER .BLK 2 ; DEVICE TEMPS -1 ;K4 TIME OUT CONSTANT 0 1B0 ; 1B0 IF NEXT COL IS COL 1 CDR1Q: .BLK 2 100000 ; FREE STACK USER CDR1D .BLK SQLN-4 CDRBS= 81.*2 ; TWO CARDS CDR1BF: .BLK CDRBS ; BUFFER SPACE FOR 2ND CDR .IFE BSW!MBSW CDREX: 0 JMP 0,3 JMP 1,3 .ENDC J CDREX= 0 [ J] .END CDRDR.SRB /t RTITLE CDRDR CDRD .NREL .ENT STCDR .ENT CDRDC,CDRQ .ENT CDRDT,CDRS .EXTN OPNI,CLSI,RDS,CDRRL .EXTN FINQ,DISMIS,XNIOS .EXTN XDIAP,XSKPB .EXTN DEQRQ ; CARD READER DEVICE CONTROL TABLE CDRDCT: 0 MKCDR ; MASK CDRS ;INT SERVICE DCIDI+DCFWD0+DCC80+DCSTB ; CHARACTERISTICS CDR ;DEVICE CODE CDREX ;EXECUTE IO CDRDT ; DISPATCH TABLE ADDRESS STCDR ;START ROUTINE CDRBS*2 ;BUFFER SIZE CDRBF*2 ;BUFFER POINTER 81.*2 ; RESTART CONSTANT ONE CARD .BLK 4 ;PP,RQLK,DP,DC BSUPC+BSDON+BSLPA+BSQIT ;INITIAL STATUS .-4 ;BEAD ADDRESS -1 ;REQUEST POINTER .BLK 2 ;DEVICE TEMPS -1 ;TIME OUT CONSTANT 0 ;NOT USED 1B0 ;1B0 IF NEXT INT IS COL 1,ELSE 0 COL1= 26 ;COL.1 FLAG IN $CDR DCT CDRBS= 81.*2 ; TWO CARDS CDRBF: .BLK CDRBS :m; RESERVE THE BUFFER SPACE CDRQ: .BLK 2 100000 ;FREE STACK USER CDRDC .BLK SQLN-4 .IFE BSW!MBSW CDREX: 0 JMP 0,3 JMP 1,3 .ENDC J CDREX= 0 [J] ; CARD READER INTERRUPT SERVICE ROUTINE CDRS: JSR @.XSKPB ; END OF CARD ?? JMP NOEND ; NO, CONTIN2UE JSR @.XDIAP ; CLEAR DONE SUBZR 0,0,SKP ; YES SET SPECIAL CODE NOEND: JSR @.XDIAP ; READ THE WORD LDA 3,DCTQP,2 COM# 3,3,SNR ; ANYONE ACTIVE ? JMP @CDRD ; NO JUST DISMISS LDA 1,COL1,2 ;CHECK FOR COL. 1 STA 0,COL1,2 ; SAVE CHARACTER (1B0 = COL 1 NEXT FLAG) MOVZL# 1,1,SNC ;IS IT? JMP NCOL1 ;NO LDA 1,C7777 ;CHECK FOR POSSIBLE EOF CARD SUB# 1,0,SZR ;ALL HOLES PUNCHED IN COL.1? JMP NCOL1 ;NO, NOT EOF LDA 1,DCTQS,2 ;YES--SET EOF FLAG LDA 3,MKEOF ;WORD W/ONLY EOF BIT ON AND# 3,1,SNR ;EOF FLAG ALREADY SET? ADD 3,1 ;NO, SO SET IT. STA 1,DCTQS,2 ;PUT BACK NCOL1: LDA 3,DCTQP,2 ; QUEUE POINTER LDA 1,RQPTR,3 ; REQUEST POINTER ISZ RQPTR,3 ; UP POINTER ONE BYTE DSZ RQCNT,3 ; DOWN ONE BYTE ON ROOM LEFT ; NOTE FINQ WILL ADJUST FOR SECOND BYTE MOVZR 1,3 ; MAKE WORD POINTER STA 0,0,3 ; STORE WORD LDA 3,CDRD MOVZL# 0,0,SNC  ; EOC ? JMP @.FINQ ; NO FINISH INPUTING AND DON'T COME BACK JSR @.FINQ ; YES FINISH AND COME BACK ; FIND OUT IF TIME TO RESTART DEVICE LDA 3,CDRD ; ADDREESS TO GO TO = DISMISS LDA 0,DCTPP,2 ; PROGRAM POINTER LDA 1,DCTDP,2 ; DEVICE POINTER SUBZ 1,0,SZC ; COMPUTE EMPTY SPACE JMP EOC1 ; POSITIVE - BUFFER LAPPED LDA 1,DCTBC,2 ; NEGATIVE COMPUTE ROOM ADD 1,0 ; AC0 = # BYTES FREE IN BUFFER EOC1: LDA 1,D'CTPC,2 ; RESTART CONSTANT SUBZ# 1,0,SZC ; TIME TO RESTART ? JMP @DCTST,2 ; YES DO IT LDA 0,DCTQS,2 ; GET STATUS MOVZR# 0,0,SZC ; RDOS THINK IT'S RUNNING ? JMP 0,3 ; NO - MUST HAVE BEEN STOPED ALREADY JMP @.DEQRQ ; YES - HAVE TO STOP IT .DEQRQ: DEQRQ .XDIAP: XDIAP .XSKPB: XSKPB MKEOF: BSEOF .FINQ: FINQ CDRD: DISMIS C7777: 7777 ;$CDR EOF (ALL HOLES PUNCHED) ;DEFINE THE CARD READER DISPATCH TABLE CDRDT: OPNI ; CDR OPEN CLSI ; CDR CLOSE RDS ; CDR READ BINARY CDRRL ; CDR READ ASCIIPv LINE -1 ; CDR READ RANDOM -1 ; CDR WRITE SEQ -1 ; CDR WRITE LINE -1 ; CDR WRITE RANDOM -1 ; CDR OPEN FOR APPENDING OPNI ; CDR READ ONLY OPEN OPNI ; CDR EXCLUSIVE OPEN -1 ; CDR TRANSPARENT OPEN ; I/O START ROUTINE FOR $CDR. ; START LREADER UNLESS EOF CONDITION EXISTS IN .RDL MODE. STCDR: LDA 1,DCTQS,2 ;EOF & RDL FLAGS ARE IN BEAD STATUS LDA 0,MASK ;EOF-RDL MASK COM 1,1 ;INHIBIT START IF BOTH BITS WERE SET AND# 0,1,SZR ;WAS LAST CARD FROM $CDR AN EOF ; AND ARE WE IN ASCII ('.RDL) MODE? JMP @.XNIOS ;NO--DO START DEVICE! JMP 0,3 ;YES--INHIBIT DEVICE RESTART .XNIOS: XNIOS ;I/O START ROUTINE MASK: BSEOF+BSRDL .END PTP1D.SRB   ; PTP1D ; SECOND PAPER TAPE PUNCH DCT RTITLE PTP1D .NREL .ENT PTP1D,PTP1Q .EXTN PTPDT,PTPEX .EXTN STOUT,COSER ; PAPER TAPE PUNCH DEVICE CONTROL TABLE PTP1D: 0 MKPTP ; MASK COSER ;COMMON OUTPUT INTERRUPT SERVICE DCRAT+DCCPO+DCPCK+DCLAC+DCNAF+DCSPO+DCSPC; CHARACTERISTICS PTP1 ;DEVICE CODE PTPEX ;EXECUTE PTPDT ; DISPATCH TABLE ADDRESS STOUT ; PUNCH START ROUTINE PTPSZ*2 ; BUFFER SIZE PTPBF*2 ; BUFFER FIRST BYTE ADDRESS .BLK 1 ;PROGRAM BYTE COUNT .BLK 1 ;PROGRAM BYTE COsUNT .BLK 1 ;BEAD CHAIN LINK .BLK 1 ;DEBYTE DATA BYTE POINTER .BLK 1 ;DEVICE DATA COUNT BSUPC+BSDON+BSLPA ; BEAD STATUS .-4 ;BEAD ADDRESS -1 ;DEVICE REQUEST CHAIN .BLK 2 ;DEVICE TEMPS -1 ;NEGATIVE TIME IN .BLK 2 ; COLUMN/LINE COUNTER .BLK 3 ; SPOOL DCB POINTERS PTPSZ= 24 ; BUFFER SIZE PTPBF: .BLK PTPSZ ; RESERVE THE BUFFER SPACE PTP1Q: .BLK 2 100000 PTP1D .BLK SQLN-.+PTP1Q .END PTPDR.SRB  Q ; PTPDR ; PAPER TAPE PUNCH DRIVER RTITLE PTPDR .NREL .ENT PTPDC,PTPQ,PTPDT,PTPEX .EXTN OPNO,CLSO,WRS,WRL ;COMMAND ENABLE .EXTN STOUT,COSER ; PAPER TAPE PUNCH DEVICE CONTROL TABLE PTPDCT: 0 MKPTP ; MASK COSER ;COMMON OUTPUT INTERRUPT SERV4ICE DCRAT+DCCPO+DCPCK+DCLAC+DCNAF+DCSPO+DCSPC ; CHARACTERISTICS PTP ;DEVICE CODE PTPEX ;EXECUTE PTPDT ; DISPATCH TABLE ADDRESS STOUT ; PUNCH START ROUTINE PTPSZ*2 ; BUFFER SIZE PTPBF*2 ; BUFFER FIRST BYTE ADDRESS .BLK 1 ;PROGRAM BYTE CP`OUNT .BLK 1 ;PROGRAM BYTE COUNT .BLK 1 ;BEAD CHAIN LINK .BLK 1 ;DEBYTE DATA BYTE POINTER .BLK 1 ;DEVICE DATA COUNT BSUPC+BSDON+BSLPA ; BEAD STATUS .-4 ;BEAD ADDRESS -1 ;DEVICE REQUEST CHAIN .BLK 2 ;DEVICE TEMPS -1 ;NEGATIVE TIME IN .BLxyK 2 ; COLUMN/LINE COUNTER .BLK 3 ; SPOOL DCB POINTERS PTPSZ= 24 ; BUFFER SIZE PTPBF: .BLK PTPSZ ; RESERVE THE BUFFER SPACE PTPEX: 0 JMP 0,3 JMP 1,3 PTPQ: .BLK 2 100000 PTPDC .BLK SQLN-.+PTPQ ; DEFINE THE PAPER TAPE PUNCH DISPATCH TABLE P_TPDT: OPNO ; PTP OPEN CLSO ; PTP CLOSE -1 ; PTP READ SEQ -1 ; PTP READ LINE -1 ; PTP READ RANDOM WRS ; PTP WRITE SEQUENTIAL WRL ; PTP WRITE LINE -1 ; PTP WRITE RANDOM OPNO ; PTP OPEN FOR APPENDING OPNO ; PTP READ ONLY OPEN OPN=O ; PTP EXCLUSIVE OPEN -1 ; PTP TRANSPARENT OPEN .END PTR1D.SRB , ; PTR1D.SR ; SECOND PAPER TAPE READER DCT RTITLE PTR1D .NREL .ENT PTR1D,PTR1Q .EXTN PTRDT,PTREX .EXTN XNIOS ;EXECUTE I/O INSTRS .EXTN CISER ;INTERRUPT SERVICE ; PAPER TAPE READER DEVICE CONTROL TABLE PTR1D: 0 MKPTR ; MASK CISER ;INT S|ERVICE DCIDI+DCPCK ; CHARACTERISTICS PTR1 ;DEVICE CODE PTREX ;EXECUTE IO INSTRUCTION PTRDT ; DISPATCH TABLE ADDRESS XNIOS ; READER START ROUTINE ADDRESS PTRSZ*2 ; BUFFER SIZE PTRBF*2 ; BUFFER FIRST BYTE ADDRESS PTRSZ/2 ; RESTART CONSVTANT 1/4 BUFFER SIZE .BLK 1 ;PROGRAM BYTE POINTER .BLK 1 ;DEVICE BEAD LINK .BLK 1 ;DEVICE DATA BYTE POINTER .BLK 1 ;DEVICE DATA COUNT BSUPC+BSDON+BSLPA ; BEAD STATUS .-4 ;BEAD ADDRESS -1 ;REQUEST QUEUE POINTER .BLK 2 ;DEVICE TEMPS 2 ;TI8ME OUT IN SECONDS PTRSZ= 40 ; BUFER SIZE PTRBF: .BLK PTRSZ ; RESERVE THE BUFFER SPACE PTR1Q: .BLK 2 100000 PTR1D .BLK SQLN-.+PTR1Q .END PTRDR.SRB * ; PTRDR.SR ; PAPER TAPE READER DRIVER RTITLE PTRDR .NREL .ENT PTRDC,PTRQ,PTRDT,PTREX .EXTN RDS,OPNI,CLSI,RDL ;COMMAND ENABLE .EXTN XNIOS ;EXECUTE I/O INSTRS .EXTN CISER ;INTERRUPT SERVICE ; PAPER TAPE READER DEVICE CONTROL TABLE PTRDCT: 0 MKPTR ; MASK CISER ;INT SERVICE DCIDI+DCPCK ; CHARACTERISTICS PTR ;DEVICE CODE PTREX ;EXECUTE IO INSTRUCTION PTRDT ; DISPATCH TABLE ADDRESS XNIOS ; READER START ROUTINE ADDRESS PTRSZ*2 ; BUFFER SIZE PTRBF*2 ; BUFFER FIRST BYTE ADDR3ESS PTRSZ/2 ; RESTART CONSTANT 1/4 BUFFER SIZE .BLK 1 ;PROGRAM BYTE POINTER .BLK 1 ;DEVICE BEAD LINK .BLK 1 ;DEVICE DATA BYTE POINTER .BLK 1 ;DEVICE DATA COUNT BSUPC+BSDON+BSLPA ; BEAD STATUS .-4 ;BEAD ADDRESS -1 ;REQUEST QUEUE POINTER .BABLK 2 ;DEVICE TEMPS 2 ;TIME OUT IN SECONDS PTRSZ= 40 ; BUFER SIZE PTRBF: .BLK PTRSZ ; RESERVE THE BUFFER SPACE PTREX: 0 JMP 0,3 JMP 1,3 PTRQ: .BLK 2 100000 PTRDC .BLK SQLN-.+PTRQ ; DEFINE THE PAPER TAPE READER DISPATCH TABLE PTRDT: OP^?NI ; PTR OPEN CLSI ; PTR CLOSE RDS ; PTR READ SEQUENTIAL RDL ; PTR READ LINE -1 ; PTR READ RANDOM -1 ; PTR WRITE SEQ -1 ; PTR WRITE LINE -1 ; PTR WRITE RANDOM -1 ; PTR OPEN FOR APPENDING OPNI ; PTR READ ONLY OPEN OPNI ; PTR 4XEXCLUSIVE OPEN -1 ; PTR TRANSPARENT OPEN .END LP132.SRB l.h:2 RTITLE LP132 .ENT LP132 .ENT LPCHR LP132= 132. LPCHR= DCCGN+DCLAC+DCFFO+DCLTU+DCSPO+DCSPC .END LP180.SRB l.m RTITLE LP180 .ENT LP180 .ENT LPCHR LP180= 80. LPCHR= DCCGN+DCLAC+DCFFO+DCLTU+DCC80+DCSPO+DCSPC .END LP232.SRB l/h$ RTITLE LP232 .ENT LP232 .ENT LPCR1 LP232= 132. LPCR1= DCCGN+DCLAC+DCFFO+DCLTU+DCSPO+DCSPC .END LP280.SRB l.m RTITLE LP280 .ENT LP280 .ENT LPCR1 LP280= 80. LPCR1= DCCGN+DCLAC+DCFFO+DCLTU+DCC80+DCSPO+DCSPC .END LPD1D.SRB m7; LPD1D.SR ; SECOND DATA CHANEL LINE PRINTER DCT RTITLE LPD1D .NREL .ENT LPDC1 LPDC1= -1 ; JUST USED FOR LOADING .ENT LPT1D,LPT1Q .EXTN LPTDT,LPTEX .EXTN LPSRT .EXTN LPSER .EXTN LPCR1 ; SECOND PRINTER CHARACTERISTICS ; LINE PRINTER DEVIC=E CONTROL TABLE LPT1D: 3B1 ; FLAG AS DATACHANEL DEVICE MKLPT ; MASK LPSER ;INT SERVICE LPCR1 ; CHARACTERISTICS LPT1 ;DEVICE CODE LPTEX ;EXECUTE LPTDT ; DISPATCH TABLE ADDRESS LPSRT ; START ROUTINE ADDRESS LPTSZ*2 ; BUFFER SIZE INʸ BYTES LPTBF*2 ; BUFFER FIRST BYTE ADDRESS .BLK 1 ;BASE LEVEL BYTE COUNT .BLK 1 ;BASE LEVEL BYTE POINTER .BLK 1 ;Q LINK TO NEXT REQUEST .BLK 1 ;DEVICE BYTE POINTER .BLK 1 ;DEVICE BYTE COUNT (WORKING) BSUPC+BSDON+BSLPA ; BEAD STATUS .-4 ;BEAD ADDRESS -1 ;Q REQUEST STARTING ADDRESS .BLK 3 ;DEVICE TMPS .BLK 2 ;VARIABLE INFO .BLK 3 ;SPOLLER INFO 3 ; INITIAL STATUS 0 ; LAST TRAN AMOUNT 0 ;DATA CHANNEL MAP SLOT 2 ;NUMBER OF MAP SLOTS NEEDED .DO ?USW LPTSZ= 67. ; BUFFER SƁ LDA @0,.BUFNT ;WAITERS COUNT MOV# 0,0,SNR ;ANY ? JMP NUMPEN ;NO SUBZL 0,0 ;KEY FOR ASBUF WAITERS LDA 1,BQUSC,2 ;USER COUNT MOV# 1,1,SNR ;IS THIS A FREE BUFFER ? JSR @.UNPEN ;YES - WAKE WAITERS NUMPEN: LDA 3,DCTAD ;DCT ADDRESS LDA 0,BQQLK,2 ;NEXT REQUEST POINTER STA 0,DCCRQ,3 ;SET IN DCT RETRY: LDA 2,DCTAD COM# 0,0,SZR ;IS IT REALLY A REQUEST JSR DSKST ;START DISK AT CURRENT REQUEST LDA 2,DCTAD JMP @DSAD ;GO DISMISS DCTAD: 0 .UNPEN: UNPEND RMSK: -QTMOD-QTIOP-1 DSAD: DISMIS .BUFNT: BUFNT ; ; MULTIPLE BLOCK TRANSFER HANDLER ; BRANCHED TO BY INTERRUPT HANDLER--RETURNS THERE ; EXTND: DSZ BQNBK,2 ;DONE YET?? JMP CONTN ;NO .IFN MBSW ; REALLY IOCSW ISZ BQUST,2 ;YES--SET USER DONE FLAG LDA 1,BQUST,2 ;USER STATUS ADDL 1,1 ;SETS C ARRY BASED ON UNPEND BIT ; IN BQUST JMP DONE1 ;GO CLEAN UP AND EXIT .ENDC J JMP DONE2 ; SET FLAG TO UNPEND AND EXIT [J] CONTN: LDA 3,BQADR,2 ;CORE ADDR LDA 1,C400 ADD 1,3 ;INCREMENT BY 256. STA 3,BQADR,2 ;PUT BACK LDA 3,.QTCT ;CONTIG STATUSR BIT AND# 0,3,SZR ;IS FILE CONTIGUOUS JMP CONTIG ;YES- MAKES LIFE EASIER ISZ BQARD,2 ;INCREMENT ARRAY PTR LDA @3,BQARD,2 ;PICK UP NEXT DISC ADDR MOV# 3,3,SNR ; =0?? JMP EXTND ;YES-SKIP IT AND GET NEXT ONE STA 3,BQCA,2 ;NO- PUT IT IN BUFFER JMPA< RETRY CONTIG: ISZ BQCA,2 ;NEXT LOGICAL BLCK IS CURRENT+1 JMP RETRY ;GO DO IT .QTCT: QTCT C400: 400 ; ; ERROR RECOVERY PROCEDURE ; DKER: LDA 1,DSKER ; DON'T LET NUMBER OF DISK COM# 1,1,SNR ; ERRORS EXCEED 177777 JMP DKER2 ; IF DON'T THEN LDA 1,.DLAT ; IF HAD DATA LATE ERROR AND# 0,1,SZR ; THEN COUNT DATA ISZ DSKDL  ; DATA LATE AND ISZ DSKER ; AND DISK ERROR STA 0,DSKRG ; SAVE ERROR REGISTER DKER2: LDA 1,LGER ;RETRY MASK AND# 0,1,SNR JMP NOTRY ;NO RETRY IS POSSIBLE DSZ BQERC,2 ;C6OUNT DEPLETED ? JMP RETRY ;NO - TRY AGAIN AT SAME REQUEST NOTRY: LDA 1,DSKER ; DON'T WANT NUMBER TOO BIG COM# 1,1,SNR ISZ DSKNR ; RECORD NON RECOVERABLE ERROR LDA 0,BQST,2 ;STATUS WORD LDA 1,ERBIT ; ERROR DETECTED BIT .IFE BSW!MBSW JSR @.SETFL .ENDC .IFN BSW!MBSW IOR 1,0 .ENDC .IFN MBSW ; REALLY IOCSW LDA 1,INDMD ;INDIRECT BIT ANDZ 0,1,SNR ;IS MODE INDIRECT? JMP DONE1 ;NO - GO GET NEXT THING IN Q LDA 1,BQUST,2 ;YES - USER STATUS ADI 3,1 ;SETS ERROR AND DONE BITS STA 1,BQUST,2 ;STOYcRE IN USER STATUS ADDL 1,1 ;SETS CARRY FROM UNPEND BIT .ENDC J DONE2: MOVZ 0,0 ; SET TO UNPUND [J] JMP DONE1 .IFE BSW!MBSW .SETFL: SETFL .ENDC ERBIT: QTER LGER: 5 ;(DATA LATE + DATA ERROR)/2 .DLAT: 4 DSKER: 0 ; DISK ERROR COUNT DSKDL: 0 ; DISKgQ DATA LATE COUNT DSKNR: 0 ; COUNT OF NON RECOVERABLE ERRORS DSKRG: 0 ; DIA OF LAST DISK ERROR .END DP03DB.SRB . ; DP03DB.SR ; THIS MODULE CONTAINS THE DCBS AND DCTS ; FOR THE FIRST DISK PACK CONTROLLER. ; SYSGEN WILL PRODUCE A .LIMIT FOR THE ; SELECTED ONE IF ANY. RTITLE DP0DB .NREL .ENT DKPDC DKPEX .ENT DP3DC,DP2DC,DP1DC,DP0DC .ENT DP3DB,DP2DB,DP1DB,DP0DB ; THE FOLLOWING ENTRY POINTS ARE USED TO LIMIT ; THE LOADING OF THIS MODULE .ENT D04DL .ENT D03DL,D02DL,D01DL,D00DL .EXTN DKPIT .EXTN DSKDT .EXTN RDCBK .EXTN DKPST .EXTN DKPDST .EXTN RDLBK .EXTN RDNBK .EXTN DPINIT .EXTN DVRLS ; DEVICE COzNTROL TABLE FOR MOVING HEAD DISK DKPDC: 1B0 ; DCH INDICATOR MKDKP ; MASK DKPIT ; INT SERVICE .BLK 1 ; CHARACTERISTICS DKP ; DEVICE CODE DKPEX ; LOC TO XEQ I/O INSTRUCTIONS 1B0 ; TELL POWER FAIL ALL ABOUT IT DKPST ; DEVICE STARTUP ROUTINE DKPDST ; SETUP DST WORD IN QUEUE ENTRY -1 ; CURRENT REQUEST POINTER .BLK 1 ; DCH MAP SLOT 5 ; NUMBER OF PAGES TO MAP DKPDC ; LINK TO PARENT DCT .IFE BSW!MBSW DKPEX: 0 LDA 2,@CSP ; GET BUF ADDR TO AC2 JMP @RLOC ; RETURN .ENDC J DK+PEX= 0 ; NOT USED ON BIRD [J] .DDCB DP0DB,DP0DC,0,DP1DB,DP0,D00DL .DDCU DP0DC,0*2,DKP,DKP ** .NOMAC 1 .DDCB DP1DB,DP1DC,1*2,DP2DB,DP1,D01DL .DDCU DP1DC,1*2,DKP,DKP .DDCB DP2DB,DP2DC,2*2,DP3DB,DP2,D02DL .DDCU DP2DC,2*2,DKP,DKP .DDCB DP3DB,DP3DC,3*2,-1,DP3,D03DL .DDCU DP3DC,3*2,DKP,DKP ** .NOMAC 0 D04DL: .BLK 2 ; DUMMY ENTRY USED FOR LIMIT IF ; ; ALL DISKS ARE LOADED DP47DB.SRB h ; DP47DB.SR ; THIS MODULE CONTAINS THE DCBS AND DCTS ; FOR THE SECOND DISK PACK CONTROLLER. ; SYSGEN WILL PRODUCE A .LIMIT FOR THE ; SELECTED ONE IF ANY. RTITLE DP4DB .NREL .ENT DKP1D DKP1EX .ENT DP7DC,DP6DC,DP5DC,DP4DC .ENT DP7DB,DP6DB,DP5DB,DP 4DB ; THE FOLLOWING ENTRY POINTS ARE USED TO LIMIT ; THE LOADING OF THIS MODULE .ENT D14DL .ENT D13DL,D12DL,D11DL,D10DL .EXTN DKPIT .EXTN DSKDT .EXTN RDCBK .EXTN DKPST .EXTN DKPDST .EXTN RDLBK .EXTN RDNBK .EXTN DPINIT .EXTN DVRLS ; DEVICE CONTROL TABLE FOR MOVING HEAD DISK DKP1D: 1B0 ; DCH INDICATOR MKDKP ; MASK DKPIT ; INT SERVICE .BLK 1 ; CHARACTERISTICS DKP1 ; DEVICE CODE DKP1EX ; LOC TO XEQ I/O INSTRUCTIONS 1B0 ; TELL POWERFAIL ALL ABOUT IT DKPST ; DEVICE STARTUP 'ROUTINE DKPDST ; SETUP DST WORD IN QUEUE ENTRY -1 ; CURRENT REQUEST POINTER .BLK 1 ; DCH MAP SLOT 5 ; NUMBER OF PAGES TO MAP DKP1D ; LINK TO PARENT DCT .IFE BSW!MBSW DKP1EX: 0 LDA 2,@CSP ; GET BUF ADDR TO AC2 JMP @RLOC ; RETURN .ENDC JUy DKP1EX= 0 ; NOT USED ON BIRD [J] .DDCB DP4DB,DP4DC,0,DP5DB,DP4,D10DL .DDCU DP4DC,0*2,DKP1,DKP ** .NOMAC 1 .DDCB DP5DB,DP5DC,1*2,DP6DB,DP5,D11DL .DDCU DP5DC,1*2,DKP1,DKP .DDCB DP6DB,DP6DC,2*2,DP7DB,DP6,D12DL .DDCU DP6DC,2*2,DKP1,DKP .DDC"|B DP7DB,DP7DC,3*2,-1,DP7,D13DL .DDCU DP7DC,3*2,DKP1,DKP ** .NOMAC 0 D14DL: .BLK 2 ; DUMMY ENTRY USED FOR LIMIT IF ; ; ALL DISKS ARE LOADED DP03FD.SRB $ ; DP03FD.SR ; THIS MODULE CONTAINS THE DCBS AND DCTS ; FOR THE FIRST DISK PACK CONTROLLER. ; SYSGEN WILL PRODUCE A .LIMIT FOR THE ; SELECTED ONE IF ANY. RTITLE DP0FD .NREL .ENT DP3FC,DP2FC,DP1FC,DP0FC .ENT DP3FD,DP2FD,DP1FD,DP0FD ; THE FOLLOWING ENTRY POINTS ARE USED TO LIMIT ; THE LOADING OF THIS MODULE .ENT D04FL .ENT D03FL,D02FL,D01FL,D00FL .EXTN DKPDC .EXTN DKPEX .EXTN DKPIT .EXTN DSKDT .EXTN RDCBK .EXTN DKPST .EXTN DKPDST .EXTN RDLBK .EXTN RDNBK .EXTN DPINIT .EXTN DVRLS .DDOCB DP0FD,DP0FC,0*2+1,DP1FD,DP0F,D00FL .DDCU DP0FC,0*2+1,DKP,DKP ** .NOMAC 1 .DDCB DP1FD,DP1FC,1*2+1,DP2FD,DP1F,D01FL .DDCU DP1FC,1*2+1,DKP,DKP .DDCB DP2FD,DP2FC,2*2+1,DP3FD,DP2F,D02FL .DDCU DP2FC,2*2+1,DKP,DKP .DDCB DP3FD,DP3FC,3*2+1,-1,DP3|ZGF,D03FL .DDCU DP3FC,3*2+1,DKP,DKP ** .NOMAC 0 D04FL: .BLK 2 ; DUMMY ENTRY USED FOR LIMIT IF ; ; ALL DISKS ARE LOADED DP47FD.SRB 3Y ; DP47FD.SR ; THIS MODULE CONTAINS THE DCBS AND DCTS ; FOR THE SECOND DISK PACK CONTROLLER. ; SYSGEN WILL PRODUCE A .LIMIT FOR THE ; SELECTED ONE IF ANY. RTITLE DP4FD .NREL .ENT DP7FC,DP6FC,DP5FC,DP4FC .ENT DP7FD,DP6FD,DP5FD,DP4FD ; THE FOLLOWINR G ENTRY POINTS ARE USED TO LIMIT ; THE LOADING OF THIS MODULE .ENT D14FL .ENT D13FL,D12FL,D11FL,D10FL .EXTN DKP1D .EXTN DKP1EX .EXTN DKPIT .EXTN DSKDT .EXTN RDCBK .EXTN DKPST .EXTN DKPDST .EXTN RDLBK .EXTN RDNBK .EXTN DPINIT .EXTN DVRLS  .DDCB DP4FD,DP4FC,0*2+1,DP5FD,DP4F,D10FL .DDCU DP4FC,0*2+1,DKP1,DKP ** .NOMAC 1 .DDCB DP5FD,DP5FC,1*2+1,DP6FD,DP5F,D11FL .DDCU DP5FC,1*2+1,DKP1,DKP .DDCB DP6FD,DP6FC,2*2+1,DP7FD,DP6F,D12FL .DDCU DP6FC,2*2+1,DKP1,DKP .DDCB DP7FD,DP7FC,3*2+1,-1Ox,DP7F,D13FL .DDCU DP7FC,3*2+1,DKP1,DKP ** .NOMAC 0 D14FL: .BLK 2 ; DUMMY ENTRY USED FOR LIMIT IF ; ; ALL DISKS ARE LOADED DKPDR.SRB  y ; ; MOVING HEAD DISC DRIVER - WITH MULTIPLE BLOCKS ; RTITLE DKPDR .NREL .ENT DKPIT .ENT DKPST .ENT DKPDST .ENT DKPER ; DISK ERROR AND DATA LATE COUNT .EXTN DISMIS ; INTERRUPT DISMIS  .EXTN DIVI,DIVD ; INTEGER DIVIDE .EXTN MPY .EXTN GBLKNNO ; BAD BLOCK MAPPER .EXTN UNPEND ; UNPEND A TASK .EXTN BUFNT ; BUFFER WAITERS COUNT .EXTN XDOA,XDOBS,XDOC,XDOCP .EXTN XDIA,XNOC,XNIOC .IFN MSW .EXTD C31K .EXTN SWAMP .ENDC .IFE BSW!MBSW .EXTN SETFL ; SET BITS .ENDC ; ; PARAMETERS. ; LDPSKC=2*400 ; SEEK COMMAND DPRCL=7*400 ; RECAL COMMAND - COVERS ALL DISKS ; DEVICE STATUS BITS RDDN=1B0 ; READ DONE SKDN=17B4 ; SEEKS DONE DRDY=1B9 ; DISK READY SKER=1B10 ; SEEK ERROR CYLN=1B11 ; END OF CYLINDER ADER=1B12 ; ADDRESS ERROR OR UNSAFE DISK CKER=1B13 ; CHECKWORD ERROR DLAT=1B14 ; DATA LATE DERR=1B15 ; DISK ERROR ; DKPDS - SETUP BUFFER HEADER FOR NEXT I/O ; DONE BEFORE INITIAL QUEUE INSERTION AND AT INTERRUPT ; TIME FOR INDIRECT MODE TRANSFERS ; INPUT - AC0: BUFFER OHEADER ADDRESS ; AC2: UNIT DCT ADDRESS ; ==== ; CALL - JSR @DCDST,2 ; AC2 = DCT ADDRESS ; OUTPUT - BQCYL & BQDST CONTAIN DOA & DOC COMMANDS ; BQNBK & BQSCT ARE SET UP FOR INDIRECT CONTIGUOUS I/O ; STACK USAGE HEAD= TMP ; HEAD (SURFACE) NUMBER SEC7T= HEAD+1 ; RELATIVE SECTOR ON HEAD CYL= SECT+1 ; CYLINDER NUMBER UNIT= CYL+1 ; PHYSICAL DRIVE (UNIT) NUMBER SCNT= UNIT+1 ; MAXIMUM SECTOR COUNT ; FOR CONTIGUOS MULTI-BLOCK I/O, THIS IS SET TO ; PREVENT CYLINDER OVERFLOW ; FOR ALL OTHERD I/O MODES, IT IS ONE (1) DTYPE= SCNT+1 ; DEVICE CHARACTERISTICS ; 1B0 => 4231A DISC PACK SUBSYSTEM ; 1B1 => PHOENIX CARTRIDGE & FLOPPY DISC SUBSYSTEM  ; 1B0 & 1B1 ARE MUTUALLY EXCLUSIVE FSIZE= DTYPE+1-TMP ; FRAME SIZE DCTAD= OAC2 ; DCT AD{hDRESS BUFAD= OAC0 ; BUFFER HEADER ADDRESS DKPDS: RSAVE FSIZE MOV 0,2 LDA 0,BQST,2 ; GET BUFFER STATUS XLDA 1,= QTDSU ; DSU BIT AND# 1,0,SZR ; HAVE WE BEEN THRU HERE? RTRN ; YES, THEN SKIP THIS CODE ADD 1,0 STA 0,BQST,2 ; SET TO SKIP THIS ON RESTRYS LDA 0,BQUN,2 ; GET LOGICAL UNIT NUMBER MOVZR 0,0 ; MAKE IT PHYSICAL UNIT # STA 0,UNIT,3 SUBCL 1,1 ; IF LOW ORDER BIT ON SET TO HEAD 2 MOVZL 1,1 STA 1,HEAD,3 XXJSR GBLKNO ; GET BLOCK NUMBER TO AC0 & AC1, ; AND MAX # BLOCKS TO BQCYL LDA 2 ,BQDCT,2 LDA 2,DCTNS,2 ; GET # OF SECTORS/HEAD STA 2,SCNT,3 ; SAVE IT FOR LATER XXJSR DIVD ; DOUBLE WORD DIVIDE STA 0,SECT,3 ; REMAINDER IS SECTOR # LDA 2,DCTAD,3 LDA 0,DCTCH,2 ; GET DISK TYPE WORD STA 0,DTYPE,3 ; SAVE TYPE FLAG LDA 2,DCTNH,2 ; NUMBER OF HEADS/CYLINDER XXJSR DIVI ; SINGLE WORD DIVIDE STA 1,CYL,3 ; QUOTIENT IS CYLINDER # LDA 1,DTYPE,3 ; BIG DISK FLAG MOVZL 1,1 ; TO CARRY LDA 1,HEAD,3 ; EXISTING HEAD NUMBER ADD 0,1,SZC ; ADD IN REAL HEAD MOVZL 1,1 ; SHIFT LEFT FOR BIG DIS>K STA 1,HEAD,3 ; HEAD READY FOR DOA SUB 0,2 ; COMPUTE # SECTORS LEFT ON CYLINDER LDA 1,SCNT,3 ; GET DCTNS XXJSR MPY LDA 0,SECT,3 SUB 0,1 STA 1,SCNT,3 ; THIS WILL PREVENT CYLINDER OVERFLOW LDA 2,BUFAD,3 ; CHECK IF THIS IS LDA 0,BQST,2 ; INDIRECT MaODE XLDA 1,= QTIND AND# 1,0,SNR JMP NOIND ; NO XLDA 1,= QTCT ; AND A CONTIGUOS TRANSFER AND# 1,0,SNR JMP NOIND ; NO LDA 0,SCNT,3 ; GET MIN (SCNT, 16., MAXCOUNT) XLDA 1,= 16. ; INTO AC0 SUBZ# 0,1,SNC ; TLE 0,1 MOV 1,0 LDA 1,BQCYL,2 ; GET MAX "COUNT RETURNED BY GBLKNO SUBZ# 0,1,SNC ; TLE 0,1 MOV 1,0 STA 0,BQSCT,2 ; SAVE SECTOR COUNT FOR DKPIT LDA 1,BQNBK,2 ; ACTUAL BLOCKS LEFT SUB 0,1 ; COMPUTE LEFTOVER BLOCKS STA 1,BQNBK,2 ; AND STORE - ZERO MEANS DONE JMP YEIND NOIND: SUBZL 0,0 ; ONE$ SECTOR FOR ALL OTHER CASES YEIND: NEG 0,0 ; DOC REQUIRES NEGATIVE COUNT XLDA 1,= 17 ; SECTOR COUNT MASK AND 1,0 LDA 1,SECT,3 ; ADD IN SECTOR * 16 ADDZL 1,1 ADDZL 1,1 ADDS 1,0 LDA 1,HEAD,3 ; ADD IN (HEAD)B7 ADD 1,0 LDA 1,UNIT,3 ; ADD IN (UNIT)B1G MOVS 1,1 MOVZR 1,1 MOVZR 1,1 ADDS 1,0 STA 0,BQDST,2 ; THIS IS THE REAL DOC COMMAND LDA 1,CYL,3 XLDA 1,= 3B7 ; COMMAND MASK FOR SMALL DISKS LDA 0,DTYPE,3 ; TYPE WORD MOVZL# 0,0,SZC ; BIG DISK ? MOVZL 1,1 ; YES MAKE BIG DISK MASK LDA 0,CYL,3 ; EXISTING CYL # COM 1,3 AND 0,1 ; EXTRACT ANY BIT IN THE WAY OF THE COMMAND AND 3,0 ; GET RID OF BITS IN THE WAY ADDZL 1,1 ; MOVE IT LEFT OF COMMAND ADD 1,0 ; STORE IT BACK IN STA 0,BQCYL,2 ; BQCYL= REAL DOA WORD RTRN ; RETURN TO CALLER ; ; DISK PACK STARTUP ROUTINE ; (CALLED ONLY IF CONTROLLER IS IDLE) ; INITIATES A SEEK (ALWAYS) AND THEN STARTS THE ; REQUEST IN DCCRQ ; NOTE: BQDST MUST BE SETUP BEFORE USEING THIS DISK DRIVER ; AC2= DCT ADDRESS DKPST: RSAVE 0 LDA 2,DCTPD,2 ; GET REAL DCT ADDRESS LDA 2,DCCRQ,2 ; CURRENT REQUEST LDA 3,BQDCT,2 ; GET UNIT DESCRIPTOR ADDRESS LDA 3,DCTCH,3 ; GET DCT CHARACTERISTICS MOVZL 3,3 ; PUT BIG DISK BIT IN CARRY XLDA 3,= DPSKC ; SEEK COMMAND MOV# 3,3,SZC ; IS IT A BIG ONE ? MOVZL 3,3 ; YES, MOVE} COMMAND TO THE LEFT LDA 0,BQST,2 ; STATUS WORD XLDA 1,= QTSIO ; SPECIAL MODE IO ? AND 1,0,SZR ; WELL XLDA 3,= DPRCL ; YES RECAL IT AND DON'T SEEK LDA 0,BQCYL,2 ; DOA LESS COMMAND ADD 3,0 ; FORM CORRENT COMMAND DKPS1: XXJSR XDOA ; LOAD COMMAND ArND CYLINDER LDA 0,BQDST,2 ; GET UNIT, HEAD, SECTOR, & COUNT XXJSR XDOCP,.XDCP ; START THE SEEK RTRN ; SEEK IS DONE, INITIATE THE REQUEST SEKDN: LDA 1,BQST,2 ; STATUS WORD XLDA 0,= QTMOD ; READ/WRITE MASK ANDS 1,0 ; TO BUILD COMMAND LDA 3,BQDCT,2 ; UNIT DESCRIPTOR ADDRESS LDA 3,DCTCH,3 ; CHARACTERISTICS MOVL# 3,3,SZC ; BIG DISK ? MOVZL 0,0 ; YES, FORM CORRECT COMMAND LDA 1,BQCYL,2 ; SOME DISK REQUIRE THIS ADD 1,0 ; PUT IT INTO COMMAND WORD XXJSR XDOA ; SEND IT OUT LDA 0,BQDST,2 ; COMMAND WORD XXJSR XDOC ; HEAD, UNIT, SECTOR COUNT .IFE MSW MOV 2,0 ; ASSUME BUFFER ADDRESS XLDA 3,= QTIND LDA 1,BQST,2 ; GET STATUS WORD AGAIN AND# 3,1,SZR ; INDIRECT MODE? LDA 0,BQADR,2 ; YES, USE REAL ADDRESS MOVL# 0,0,SZC ; MUST CLEAR HIGH ORDER BIT IF SET ADDOR 0,0 ; THIS DOES IT .ENDC .IFN MSW LDA 3,BQDCT,2 LDA 3,DCTPD,3 ; REAL DCT ADDRESS LDA 0,DCHMP,3 LDA 1,DCHNM,3 XXJSR SWAMP .ENDC XXJSR XDOBS,XDBS RTRN ULPOOL ; WE HAVE SEEK COMPLETE, CHECK TO SEE THAT IT WAS ON DRIVE WE WANTED TSEEK: LDA 1,BQDST,2 ; CALCULATE THE BIT THAT SUBZR 3,3 ; SAYS THAT SEEK IS DONE ON MOVZL 1,1,SNC ; DRIVE WE ARE WAITING FOR JMP TSK1 MOVZR 3,3 MOVZR 3,3 TSK1: MOVZL 1,1,SZC MOVZR 3,3 MOVZR 3,3 ; GOT BIT, CHECK IF SEEK DONE ON DRIVE WE WANT AND# n0,3,SNR ; IF NOT DONE THEN JMP ERGO ; GO RESTART OP ON DRIVE WE WANT ; WE HAVE SEEK DONE, PROCESS IT LDA 0,BQST,2 ; SEEK/RECAL WAS SUCESSFUL XLDA 1,= QTEMD AND# 0,1,SNR ; WHICH WERE WE DOING? JMP SEKDN ; A SEEK - GO INITIATE READ/WRITE .IFE BSW!MlBSW COM 1,1 AND 1,0 .ENDC .IFN BSW!MBSW  ANC 1,0 .ENDC STA 0,BQST,2 ; NO LONGER DOING A RECAL JMP RETRY ; NOW RESTART THE ORIGINAL I/O RECAL: LDA 0,BQST,2 ; COME HERE FOR ANY TYPE OF ERROR XLDA 1,= QTEMD ; SET THAT WE ARE DOING A RECAL .IFE BSW!MBSW XXJSR SETFL .ENDC .IFN BSW!MBSW IOR 1,0 .ENDC STA 0,BQST,2 XLDA 0,= DPRCL ; GET RECAL COMMAND JMP DKPS1 ; DO DOC, DOAP, AND EXIT ULPOOL ; ; DKP INTERRUPT SERVICE ROUTINE ; AC2: DCT ADDRESS ; ; DEFINE THE TEMPS DKPIT: INTDS XXLDA 3,= DISMIS ; GET DISMISS ADDRESS RSAVE 0 ; SAVE EVERYTHING LDA 2,DCCRQ,2 ; GET CURRENT REQUEST COM# 2,2,SNR ; IS THERE ONE? JMP DKPIE ; NO XXJSR XDIA ; COLLECT STATUS XXJSR XDOA ; RESET DONE BITS MOVR# 0,0,SZC ; ANY ERRORS? JMP ERGO ; YES, CHECK FKOR RETRIES MOVL# 0,0,SNC ; READ/WRITE DONE? JMP TSEEK ; NO, SEEK/RECAL DONE LDA 0,BQST,2 ; BUFFER STATUS WRDS XLDA 1,= QTIND ; INDIRECT MODE? ANDZ 0,1,SZR ; IF NO, SET CARRY=0 TO UNPEND JMP EXTND ; YES DONE1: XLDA 1,= -QTIOP-QTMOD-1 ; RESET MASK  AND 0,1 STA 1,BQST,2 ; PUT STATUS BACK ;NOTE: AT THIS POINT CARRY = 0 MEANS UNPEND **; GET RID OF THIS CRAP NEXT REV MOV 2,0,SNC ; UNPEND ON BUFFER ADDRESS XXJSR UNPEND ; UNPEND ALL WAITERS XXLDA 0,BUFNT ; COUNT OF BUFFER WAITERS MOV# 0,0,SNR ; AoNY ? JMP NOBWT ; NO SUBZL 0,0 ; BUFFER WAITERS KEY LDA 1,BQUSC,2 ; USER COUNT ON BUFFER MOV# 1,1,SNR ; BUSY ? XXJSR UNPEND ; NO - UNPEND BUFFER WAITERS NOBWT: LDA 3,CSP LDA 3,DCTAD,3 ; DCT ADDRESS AGAIN LDA 0,BQQLK,2 ; LINK TO NEXT REQUEST STA  00,DCCRQ,3 ; BECOMES NEXT REQUEST COM# 0,0,SNR ; A REAL REQUEST? RTRN RETRY: LDA 3,CSP LDA 2,DCTAD,3 ; GET DCT ADDR JSR @DCSTR,2 ; START IT UP AGAIN RTRN DKPIE: LDA 2,DCTAD,3 ; GET DCT ADDR XXJSR XNIOC ; CLEAR THE INTERRUPT RTRN ; AND DISMISS CLPOOL ; ; MULTIPLE BLOCK HANDLER ; CALLED FROM INTERRUPT AND RETURNS THERE ; EXTND: XLDA 1,= QTCT AND# 1,0,SZR ; CONTIGUOUS FILE? JMP CONTIG ; YES EXT1: DSZ BQNBK,2 ; RANDOM FILE- DONE? JMP CONTN ; NO FIN1: .IFN MBSW ; SHOULD BE IOCSW ISZ BQUSNT,2 ; YES- SET USER DONE LDA 1,BQUST,2 ADDL 1,1 ; UNPEND? JMP DONE1 .ENDC J JMP DONE2 ; SET TO UNPEND AND EXIT [J] CONTN: LDA 3,BQADR,2 ; CORE ADDR MOVS 3,3 INCS 3,3 ; INCREMENT BY 400 STA 3,BQADR,2 ; PUT BACK LDA 3,BQDCT,2 LDA 3,DCTCH,3 ; D|EVICE CHARACTERISTICS MOVL# 3,3,SZC ; 3330? ISZ BQARD,2 ; YES, INC INDEX PTR FOR HIGH ORDER MOVL# 3,3,SNC ; 3330? SUB 1,1,SKP ; NO - HIGH ORDER IS ZERO LDA 1,@BQARD,2 ; YES - PICK UP HIGH ORDER ISZ BQARD,2 ; INCREMENT INDEX PTR LDA 3,@BQARD,2 ;T_ GET NEXT DISK ADDR MOV# 1,1,SZR ; HIGH ORDER =0? JMP NONZ ; NO MOV# 3,3,SNR ; DISK ADDRESS =0? JMP EXT1 ; YES - GO DO NEXT ONE NONZ: STA 1,BQCA1,2 ; STASH HIGH ORDER STA 3,BQCA,2 ; PUT IN DISC ADDR HOLDER MCENT: LDA 1,BQST,2 ; BUFFER STATUS XLDw/A 0,= -QTDSU-1 ; SETUP MASK COMPLEMENT AND 0,1 ; SHOW AS NOT SETUP STA 1,BQST,2 ; IN THE BUFFER MOV 2,0 ; BUF ADDR TO AC0 LDA 2,BQDCT,2 JSR @DCDST,2 ; SET UP BQDST & BQCYL JMP RETRY ; GO READ GOOD STUFF CONTIG: LDA 1,BQNBK,2 ; # OF BLOCKS LEFT TO! MOVE MOV# 1,1,SNR ; IS BQBNK = 0 ? JMP FIN1 ; YES - DONE - GO FINISH UP LDA 0,BQCA,2 ; INCREMENT DEV ADDR BY LDA 1,BQSCT,2 ; # OF SECTORS TRANSFERED ADDZ 1,0,SZC ISZ BQCA1,2 STA 0,BQCA,2 LDA 0,BQADR,2 ; GET PREVIOUS ADDRESS MOVS 1,1 ; # OF SECTORS * 400 ADD 1,0 ; UP ADDRESS STA 0,BQADR,2 ; NEW CORE ADDRESS JMP MCENT CLPOOL ; ; RESOLVE ERRORS. ; ERGO: LDA 1,DKPER ; DON'T LET ERRORS COM# 1,1,SNR ; EXCEED 177777 JMP ERGO2 ; IF NOT THEN XLDA 1,= DLAT ; CHECK FOR DATA LATE AND# 0,1,SZyR ; IF HAD A DATA LATE ISZ DKPDL ; COUNT DATA LATE AND ISZ DKPER ; THE ERROR LDA 1,BQERC,2 ; IF HAVE UNRECOVERAVLE ERROR MOVZR# 1,1,SNR ; THEN COUNT AS SUCH ELSE ISZ DKPNR ; DON'T STA 0,DKPRG ; SAVE STATUS REGISTER OF ERROR ERGO2: XXJSR XNOC ;K STOP THE DISK DSZ BQERC,2 ; DSZ ERROR RETRY COUNT JMP ERNXT ; GO TRY AGAIN LDA 0,BQST,2 ; BUFFER STATUS .IFE BSW!MBSW XLDA 1,= QTER ; ERROR BIT XXJSR SETFL ; ON .ENDC .IFN BSW!MBSW IORI QTER,0 .ENDC .IFN MBSW ; ACTUALLY IOCSW ELEF 1,QTIND' ANDZ 0,1,SNR ; INDIRECT MODE ?? JMP DONE1 ; GO TRY NEXT REQUEST LDA 1,BQUST,2 ; YES ADI 3,1 ; SET USER ERROR AND DONE BITS STA 1,BQUST,2 ; PUT AWAY USER STATUS ADDL 1,1 JMP DONE1 .ENDC J DONE2: MOVZ 0,0 ; CARRY = 0 UNPEND JMP DONE1 ; CONTINUrkE [J] ERNXT: XLDA 1,= DLAT AND 1,0,SNR ; DCH LATE JMP RECAL ; NO RECAL BEFORE RETRY JMP RETRY ; YES JUST RETRY IO LPOOL DKPER: 0 ; COUNT OF DISK ERRORS DKPDL: 0 ; COUNT OF DATA LATE ERRORS DKPNR: 0 ; COUNT OF NON RECOVERABLE ERRORS DKPRG: 0 ;' STATUS REG OF LAST ERROR (DIA) .END DS03DB.SRC 0 ; DS03DB.SR ; THIS MODULE CONTAINS THE DCBS AND DCTS ; FOR THE FIRST DISK PACK CONTROLLER. ; SYSGEN WILL PRODUCE A .LIMIT FOR THE ; SELECTED ONE IF ANY. RTITLE DS0DB .NREL .ENT DSPDC DSPEX .ENT DS3DC,DS2DC,DS1DC,DS0DC .ENT DS3DB,DS2DB,DS1DB,DS0D/B ; THE FOLLOWING ENTRY POINTS ARE USED TO LIMIT ; THE LOADING OF THIS MODULE .ENT S04DL .ENT S03DL,S02DL,S01DL,S00DL .EXTN DSPIT ;PAGING DISK INTERRUPT HANDLER .EXTN DSKDT .EXTN RDCBK .EXTN DSPST ;CALL TO START FIXED HEAD DISK .EXTN DSPDST ;SET UP COMMANDS TO DISK AT 'REQUEST QUEUE' ; TIME. NOT USED FOR PAGING DISK. EFFECTS ; A NO OPERATION. .EXTN RDLBK .EXTN RDNBK .EXTN DKINIT .EXTN DVRLS ; DEVICE CONTROL TABLE FOR PAGING DISK DSPDC: 1B0 ; DCH INDICATOR MKDSP ; MASK DSPI+T ; INT SERVICE .BLK 1 ; CHARACTERISTICS DSP ; DEVICE CODE DSPEX ; LOC TO XEQ I/O INSTRUCTIONS 1B0 ; TELL POWER FAIL ALL ABOUT IT DSPST ; DEVICE STARTUP ROUTINE DSPDST ; SETUP DST WORD IN QUEUE ENTRY -1 ; CURRENT REQUEST POINTER .BLK 1 ; DCH MAP SLOT 2+(MAXPAGE+1) ; NUMBER OF PAGES TO MAP DSPDC ; LINK TO PARENT DCT ; COMMAND QUEUE ; LIMIT OF MXBLK COMMAND QUEUE ENTRIES .BLK 1 ; DSPAD=0, DISK ADDRESS .BLK 1 ; CMDWD=1, COMMAND .BLK 1 ; MEMAD=2, BUFFER ADDRESS FOR I/O .B*LK 1 ; STWD=3, STATUS WORD RETURNED .BLK 1 ; USRWD=4, USER WORD (UNUSED) .BLK (MXBLK-1)*5 ; MXBLK-1 MORE QUEUE ENTRIES ; IN THE SAME FORMAT. .IFE BSW!MBSW DSPEX: 0 LDA 2,@CSP ; GET BUF ADDR TO AC2 JMP @RLOC ; RETURN .ENDC J DSPEX= 0 ;  NOT USED ON BIRD [J] .DDCB DS0DB,DS0DC,0,DS1DB,DS0,S00DL .DDCU DS0DC,0*2,DSP,DSP ** .NOMAC 1 .DDCB DS1DB,DS1DC,1*2,DS2DB,DS1,S01DL .DDCU DS1DC,1*2,DSP,DSP .DDCB DS2DB,DS2DC,2*2,DS3DB,DS2,S02DL .DDCU DS2DC,2*2,DSP,DSP .DDCB DS3DB,DS3DC,3*2,T -1,DS3,S03DL .DDCU DS3DC,3*2,DSP,DSP ** .NOMAC 0 S04DL: .BLK 2 ; DUMMY ENTRY USED FOR LIMIT IF ; ; ALL DISKS ARE LOADED DS47DB.SRB 84 ; DS47DB.SR ; THIS MODULE CONTAINS THE DCBS AND DCTS ; FOR THE SECOND DISK PACK CONTROLLER. ; SYSGEN WILL PRODUCE A .LIMIT FOR THE ; SELECTED ONE IF ANY. RTITLE DS4DB .NREL .ENT DSP1D DSP1EX .ENT DS7DC,DS6DC,DS5DC,DS4DC .ENT DS7DB,DS6DB,DS5DB,DS4DB ; THE FOLLOWING ENTRY POINTS ARE USED TO LIMIT ; THE LOADING OF THIS MODULE .ENT S14DL .ENT S13DL,S12DL,S11DL,S10DL .EXTN DSPIT ; PAGING DISK INTERRUPT HANDLER .EXTN DSKDT .EXTN RDCBK .EXTN DSPST ;CALL TO START FIXED HEAD DISK .EXTN DSPDST i ;SET UP COMMANDS TO DISK AT 'REQUEST QUEUE' ; TIME. NOT USED FOR PAGING DISK. EFFECTS ; A NO OPERATION. .EXTN RDLBK .EXTN RDNBK .EXTN DKINIT .EXTN DVRLS ; DEVICE CONTROL TABLE FOR PAGING DISK DSP1D: 1B0 ; DCH INDICATOR MKDSP ; MASK D\SPIT ; INT SERVICE .BLK 1 ; CHARACTERISTICS DSP1 ; DEVICE CODE DSP1EX ; LOC TO XEQ I/O INSTRUCTIONS 1B0 ; TELL POWERFAIL ALL ABOUT IT DSPST ; DEVICE STARTUP ROUTINE DSPDST ; SETUP DST WORD IN QUEUE ENTRY -1 ; CURRENT REQUEST POINTER .BLK 1 ; DCH MAP SLOT 2+(MAXPAGE+1) ; NUMBER OF PAGES TO MAP DSP1D ; LINK TO PARENT DCT ; COMMAND QUEUE ; LIMIT OF MXBLK COMMAND QUEUE ENTRIES .BLK 1 ; DSPAD=0, DISK ADDRESS .BLK 1 ; CMDWD=1, COMMAND .BLK 1 ; MEMAD=2, BUFFER ADDRESS FOR I/O  .BLK 1 ; STWD=3, STATUS WORD RETURNED .BLK 1 ; USRWD=4, USER WORD(UNUSED) .BLK (MXBLK-1)*5 ; MXBLK-1 MORE QUEUE ENTRIES ; IN THE SAME FORMAT. .IFE BSW!MBSW DSP1EX: 0 LDA 2,@CSP ; GET BUF ADDR TO AC2 JMP @RLOC ; RETURN .ENDC J DSP1EX= 0  ; NOT USED ON BIRD [J] .DDCB DS4DB,DS4DC,0,DS5DB,DS4,S10DL .DDCU DS4DC,0*2,DSP1,DSP ** .NOMAC 1 .DDCB DS5DB,DS5DC,1*2,DS6DB,DS5,S11DL .DDCU DS5DC,1*2,DSP1,DSP .DDCB DS6DB,DS6DC,2*2,DS7DB,DS6,S12DL .DDCU DS6DC,2*2,DSP1,DSP .DDCB DS7DB,DS7*DC,3*2,-1,DS7,S13DL .DDCU DS7DC,3*2,DSP1,DSP ** .NOMAC 0 S14DL: .BLK 2 ; DUMMY ENTRY USED FOR LIMIT IF ; ; ALL DISKS ARE LOADED DSPDR.SRB t ; ; PAGING DISK DRIVER ; WITH MULTIPLE BLOCK CAPABILITIES ; RTITLE DSPDR .NREL .ENT DSPIT ;PAGING DISK INTERRUPT HANDLER .ENT DSPST ;CALL TO START DISK WHEN IDLE .ENT DSPDST ;SET UP COMMANDS TO DISK AT 'REQUEST QUEUE' ; TIME. NOT USEDr FOR PAGING DISK. EFFECTS ; A NO OPERATION. .ENT DSPER ; DISK ERROR COUNT .EXTN UNPEND ;UNPEND A TASK .EXTN DISMIS .EXTN BUFNT ;BUFFER WAITERS COUNT .EXTN GBLKNO ;BAD BLOCK MAPPER .EXTN ECCOR ; ERROR CORRECTING ROUTINE .EXTN XNOC ; CLEAR 2THE INTERRUPT .EXTN XDOC ; FOR SELECTING ALTERNATE INSTR TYPE .EXTN XDIB ; TO GET ECC CODE BITS 17-32 .EXTN XDIA ; TO GET ECC CODE BITS 01-16 .EXTN XOAS ; START THE TRANSFER .IFN MSW .EXTN SWAMP ;DCH MAP ROUTINE .EXTD C31K .ENDC .IFE BSW!MBGSW .EXTN SETFL ;SET FLAGS .ENDC ; ERROR STATUS WORD ER = 1B00 ; ERROR TT = 1B01 ; UNDEFINED TT = 1B02 ; UNDEFINED BE = 1B03 ; BUSS ENABLE D1 = 1B04 ; * DISK CAPACITY D0 = 1B05 ; * ID = 1B06 ; IDLE DONE PR = 1B07 ; WRITE PARITY ERROR DC = 1B08 ; DCH ERROR TU = 1B09 ; R/W TIME OUT RD = 1B10 ; DISK UNIT READY UN = 1B11 ; DISK UNSAFE DL = 1B12 ; DATA LATE ERROR EC = 1B13 ; ECC ERROR DV = 1B14 ; DATA VERIFY ERROR PD = 1B15 ; PAGE DONE ECCFLG=1 ; FLAG TO MAKE ECC OPTIONAL, ; SAV&ES 28 WORDS READ=0B7+1B10 ; READ, HALT ON ERROR WRITE=1B7+1B10 ; WRITE, HALT ON ERROR HLT=1B9 ; HALT QUEUEING ; ; CALL TO START DISK WHEN IDLE. ; STARTS AT FIRST REQUEST POINTED TO BY DCCRQ. ; ALL ACCUMULATORS ARE LOST. ; ; INPUT: AC2 - DCT ADDRESSS, EITHER UNIT DCT OR REAL DCT ; ; SAVE RETURN POINTER AND GET SYS BUF OF PARENT DCT ; THIS DRIVER IS NOT REENTRANT DSPST: RSAVE 0 LDA 2,DCTPD,2 ; CONTROLLER DCT LDA 2,DCCRQ,2 ;REQUEST POINTER (NOT = -1) SUBZL 0,0 ; USE QNM TO INDEX CURRENT XSTA @0,= QNM ; COMMAND QUEUE,START AT 1 ;GET THE DISK ADDRESS XXJSR GBLKNO ; GET PHYSICAL DISK ADDRESS LDA 0,BQUN,2 ; AND ADD IN UNIT NUMBER MOVS 0,0 ; (UNIT# FROM BQUN=UNIT# * 2) ADDZL 0,0 MOVZL 0,0 ADD 0,1 XS}TA @1,= DSKADR ;SAVE DISK ADDRESS FOR LATER ; CALCULATE THE CORE ADDRESS FOR THE TRANSFER LDA 3,BQDCT,2 ; DCT ADDRESS LDA 3,DCTPD,3 ; PARENT DCT .IFE MSW ; GET THE ADDRESS OF THE COMMAND QUEUE XLDA 0,= DCTFH ; ADDRESS OF COMMAND QUEUE ADD 3,0 ; COMMl)AND QUEUE ADDRESS XSTA @0,= QUEAD ; SAVE THE COMMAND QUEUE ADDRESS ; GET THE DATA BUFFER ADDRESS MOV 2,0 ;BUFFER ADDRESS IS DEFAULT CORE ADDRESS XLDA 3,= QTIND ;INDIRECT MODE ? LDA 1,BQST,2 ;BUFFER STATUS WORD AND# 1,3,SZR ;INDIRECT MODE ? LDA 0,BQNXT,2 ;YES - CORE ADDRESS IN LINK WORD MOVL 0,0 ;RESET 1B0 MOVZR 0,0 .ENDC .IFN MSW ; SET UP THE DATA-CHANNEL MAP TO THE COMMAND QUEUE SMLD 1,MPSDC ; SET TO LOGICAL LOAD MAP XLDA 0,= DCTFH ; ADDRESS ON COMMAND QUEUE ADD 3,0 ; ADDRESS OF COMMAND NQUEUE LDA 1,C31K ; * COMPUTE THE LOGICAL ANDS 0,1 ; * PAGE NUMBER MOVZR 1,1 ; * MOVZR 1,1 ; * LDA 3,DCHMP,3 ; PICK UP THE MAP COMMAND ADD 3,1 ; THE COMPLETE COMMAND SMBK 1 ; OUTPUT THE MAP COMMAND XLDA 0,= MPAIN!1 ; GET THE COMMAND FOR THE NE}lXT BLOCK ADD 0,1 ; NEXT COMMAND SMBK 1 ; OUTPUT THE MAP COMMAND ; CALCULATE MAPPED ADDRESS OF COMMAND QUEUE XLDA 0,= MPALG ; CALC ADDR AND 3,0 .DO MPALG==37B7 MOVZL 0,0 MOVZL 0,0 .ENDC LDA 3,BQDCT,2 ; DCT ADDRESS LDA 3,DCTPD,3 ; PARENT DCT X5LDA 1,= DCTFH ; OFFSET TO COMMAND QUEUE ADD 3,1 ; ADDRESS OF COMMAND QUEUE XLDA 3,= 1777 ; REMOVE DISPLACEMENT IN AND 3,1 ; 1K BLOCK AND ADD TO ADD 1,0 ; MAKE COMPLETE ADDRESS OF TRAN XSTA @0,= QUEAD ; SAVE THE COMMAND QUEUE ADDRESS ; SET UP THE DATA-CHANNEL MAP FOR THE DATA BUFFER LDA 3,BQDCT,2 LDA 3,DCTPD,3 ; REAL DCT ADDRESS LDA 0,DCHMP,3 ;DATA CHANNEL SLOTS LDA 1,DCHNM,3 ;NUMBER OF PAGES TO MAP XLDA 3,= MPAIN*2 ADD 3,0 ; INCREASE LOGICAL PAGE BY 2 XLDA 3,= 2 ; THE COMMAD QUEUE USED TWO PAGES SUB 3,1 ; TWO LESS PAGES TO MAP XXJSR SWAMP ;CORE ADDRESS TO AC0 .ENDC STA 0,CORADR ; DATA CHANNEL LOGICAL ADDRESS ; BUILD COMMAND WORD LDA 1,BQST,2 ; BUFFER STATUS WORD XLDA 0,= READ ; READ AND HALT ON ERROR MOVR# 1,1,SZC ; SKIP IF BUFFERF NOT MODIFIED XLDA 0,= WRITE ; WRITE AND HALT ON ERROR STA 0,COMWRD ; ; CALCULATE ADDRESS OF START OF COMMAND QUEUE LDA 3,BQDCT,2 ; DCT ADDRESS LDA 3,DCTPD,3 ; PARENT DCT XLDA 0,= DCTFH ; COMMAND QUEUE OFFSET ADD 0,3 ; AC3=SmTART OF COMMAND QUEUE JMP NBLKS LPOOL ; DETERMINE HOW MANY BLOCKS FOR THIS TRANSFER IF FILE IS ; CONTIGUOUS AND INDIRECT. NBLKS: XLDA 1,= QTCT+QTIND ; CONTIGUOUS AND INDIRECT BITS LDA 0,BQST,2 ; BUFFER STATUS WORD COM 0,0 AND# 0,1,SZR ; IS FILE BOTH INDIRECT AND CONTIG? JMP SETUPQ ; ---NO--- XLDA 0,= MXBLK ; ---YES---, NUMBER OF BLOCKS IN LDA 1,BQCYL,2 ; THIS TRANSFER=MIN(BQCYL,MXBLK) USLE 0,1 ; WHERE BQCYL= MAX # BLOCKS MOV 1,0 ; (BAD BLOCK MAPPING), MXBLK= STA 0,BQSCT,2 ; # QUEUE ENTRI ES ; CREATE CURRENT COMMAND QUEUE ENTRY SETUPQ: LDA 0,DSKADR ; STA 0,DSPAD,3 ; DISK ADDRESS LDA 0,COMWRD ; STA 0,CMDWD,3 ; COMMAND WORD LDA 0,CORADR ; DCH LOGICAL ADDRESS STA 0,MEMAD,3 ;  'MEMORY ADDRESS SUB 0,0 STA 0,STWD,3 ; STATUS WORD ; IF FILE IS INDIRECT AND CONTIG, UP VALUES FOR NEXT QUEUE ENTRY XLDA 1,= QTCT+QTIND ; CONTIGUOUS AND INDIRECT BITS LDA 0,BQST,2 COM 0,0 AND# 0,1,SZR ; IS FILE INDIRECT AND CONTIG? JMP STRTIO ; ---:NO---, START THE TRANSFER LDA 0,QNM ; ---YES---, CAN MORE BLOCKS LDA 1,BQSCT,2 ; BE SET UP FOR THIS TRANSFER? USLT 0,1 JMP STRTIO ; ---NO---, START THE TRANSFER ; SET UP VALUES TO LOOP FOR NEXT QUEUE ENTRY XLDA 0,= 400 ; UP CORE ADDRESS BY 256 LDA 1,CORADR ; TO POINT TO AREA WHERE ADD 0,1 ; NEXT BLOCK WILL BE READ IN. STA 1,CORADR ISZ DSKADR ; POINT TO NEXT BLOCK ON DISK ISZ QNM ; UP COUNT OF QUEUE ENTRIES XLDA 0,= 5 ; POINT AC3 TO NEXT QUEUE ENTRY ADD 0,3 JMP SETUPQ ; SET UP NEXT ENԶTRY ; GET THE COMMAND QUEUE ADDRESS AND START THE TRANSFER STRTIO: LDA 0,CMDWD,3 ;SET HALT BIT IN COMMAND XLDA 1,= HLT ; WORD OF LAST QUEUE ENTRY ADD 1,0 STA 0,CMDWD,3 LDA 0,QUEAD ; COMMAND QUEUE ADDR(DCH LOGICAL) XXJSR XOAS ; START THE TRANSFER RTRN QUEAD: .BLK 1 ; ADDR OF COMMAND QUEUE (DCH LOGICAL) DSKADR: .BLK 1 ; DISK ADDRESS, USED TO BUILD QUEUE COMWRD: .BLK 1 ; COMMAND WORD, USED TO BUILD QUEUE CORADR: .BLK 1 ; BUFFER CORE ADDRESS, USED TO BUILD QUEUE QNM: .BLK 1 ; INDEX OF QUEUE ENTRY LPOOL ; ; SET DST ROUTINE - DUMMY FOR FH DISK ; .IFE BSW!MBSW DSPDST: STA 3,RLOC LDA 3,CSP JMP @RLOC .ENDC .IFN BSW!MBSW DSPDST: PSH 3,3 LDA 3,CSP POPJ .ENDC ; ; FH DISK INTERRUPT HANDLER ; AC2: DCT ADDRESS ; DSPIT: INTDS LDA 3,DCTPD,2. ; PARENT DCT ADDRESS STA 3,DCTAD LDA 2,DCCRQ,3 ;CURRENT REQUEST XLDA 0,= DCTFH ; COMMAND QUEUE OFFSET ADD 0,3 STA 3,QBASE CKSTAT: LDA 0,STWD,3 ; STATUS WORD MOV 0,0,SZR MOVZL 0,0,SZC JMP DKER ;YES - GO RESOLVE ERROR DSPP: LDA 0,BQST,2 ;BUFFER STATUS XLDA 1,= QTIND ;INDIRECT MODE? ANDZ 0,1,SZR ;RESET CARRY TO UNPEND JMP EXTND ;YUP DONE1: MOV 2,0 ; UNPEND KEY XXJSR UNPEN ;UNPEND WAITERS IF ANY DNNE1: LDA 0,BQST,2 ; STATUS XLDA 1,= -QTMOD-QTIOP-1 AND 1,0 ;IOIP AND MODBIT OFF STA 0,BQST,2 ;PUT IT BACK XXLDA 0,BUFNT ;WAITERS COUNT MOV# 0,0,SNR ;ANY ? JMP NUMPEN ;NO SUBZL 0,0 ;KEY FOR ASBUF WAITERS LDA 1,BQUSC,2 ;USER COUNT MOV# 1,1,SNR ;IS THIS A FREE BUFFER ? XXJSR UNPEN ;YES - WAKE WAITERS NUMPEN: LDA 3,DCTAD ;DCT ADDRESS LTkDA 0,BQQLK,2 ;NEXT REQUEST POINTER STA 0,DCCRQ,3 ;SET IN DCT ; CLEAR THE INTERRUPT, RETURN IF NO MORE BUFFERS IN QUEUE RETRY: XXJSR XNOC ; CLEAR THE INTERRUPT LDA 2,DCTAD LDA 0,DCCRQ,2 ; REQUEST QUEUE COM# 0,0,SZR ;IS IT REALLY A REQUEST XJSR DSPST d ;START DISK AT CURRENT REQUEST XXJMP DISMISS ;GO DISMISS LPOOL DCTAD: 0 QBASE: .BLK 1 ;POINTER TO CURRENT COMMAND QUEUE ENTRY ; ; MULTIPLE BLOCK TRANSFER HANDLER ; BRANCHED TO BY INTERRUPT HANDLER--RETURNS THERE ; EXTND: DSZ BQNBK,2 ;DONE YET?? JMP CONTN ;NO .IFN IOSW ; REALLY IOCSW ISZ BQUST,2 ;YES--SET USER DONE FLAG LDA 1,BQUST,2 ;USER STATUS JMP IFSS ; GO CHECK IF TO UNPEND .ENDC J JMP DONE1 ; GO UNPEND AND EXIT [J] CONTN: LDA 3,BQADR,2 ;CORE ADDR XLDA 1,= 400 ADD 1,3 ;INCREMENT BY 256. STA 3,BQADR,2 ;PUT BACK XLDA 3,= QTCT ;CONTIG STATUS BIT AND# 0,3,SZR ;IS FILE CONTIGUOUS JMP CONTIG ;YES- MAKES LIFE EASIER ISZ BQARD,2 ;INCREMENT ARRAY PTR LDA @3,BQARD,2 ;PICK UP NEXT DISC ADDR MOV# 3,3,SNR ; =0?? JMP EXTND ;YES-SKIP IT AND GET NEXT ONE STA 3,BQCA,2 ;NO- PUT IT IN BUFFER JMP RESETR CONTIG: ISZ BQCA,2 ;NEXT LOGICAL BLCK IS CURRENT+1 ; HALT BIT OR ECC BIT SET IMPLY LAST QUEUE ENTRY LDA 3,QBASE ; GET POINTER TO QUEUE ENTRY LDA 0,CMDWD,3 ; GET CURRENT COMMAND WiORD XLDA 1,= HLT AND# 0,1,SZR ; HALT BIT SET? JMP RESETR ; ---YES---, NO MORE QUEUE ENTRIES .IFN ECCFLG ; SKIP IF ECC CODE DISABLED LDA 0,STWD,3 ; ---NO--- XLDA 1,= EC AND# 0,1,SZR ; ECC ERROR BIT SET? JMP RESETR ; ---YES---, NO MORE QUEUE ENTKRIES .ENDC XLDA 0,= 5 ; ---NO---, ADD 5 TO COMMAND QUEUE ADD 0,3 ; BASE TO POINT TO NEXT ENTRY STA 3,QBASE ; NEXT ENTRY JMP CKSTAT ; CHECK NEXT QUEUE ENTRY STATUS ; RESET RETRY COUNT RESETR: XLDA 0,= SCMER STA 0,BQERC,2 JMP RETRY ;GO DO IT  ALT2=2 ; ALTERNATE INTRUCTION TYPE TWO ; ; ERROR RECOVERY PROCEDURE ; DKER: LDA 1,DSPER ; DON'T LET NUMBER OF DISK COM# 1,1,SNR ; ERRORS EXCEED 177777 JMP DKER2 ; IF DON'T THEN XLDA 1,= DL*2 ; IF HAD DATA LATE ERROR AND# 0,1,SZR ; THEN COUNT ۗDATA ISZ DSPDL ; DATA LATE AND ISZ DSPER ; AND DISK ERROR STA 0,DSPRG ; SAVE ERROR REGISTER ; ALWAYS RETRY, NO MATTER WHAT THE ERROR DKER2: DSZ BQERC,2 ;COUNT DEPLETED ? JMP RETRY ;NO - TRY AGAIN AT SAME REQUEST .IFN ECCFLG ; SKIP IF ECC CODE DISABLED XLDA 1,= EC*2 ; ECC ERROR BIT AND# 0,1,SNR JMP NOTRY ; FATAL ERROR ; CORRECT THE ECC ERROR LDA 0,DSPER ; UP ECC ERROR COUNT COM# 0,0,SZR ; IF TOTAL # OF ERRORS ISZ DSPEC ; HAS NOT OVERFLOWED. XLDA 0,= ALT2 ; SELECT ALTERNATE INSTR TYPE 2 XXJSR XDOC XXJSR XDIB ; BITS 17-32 OF ECC STA 0,ECCSV ; SAVE HIGH ORDER ECC XXJSR XDIA ; BITS 01-16 OF ECC LDA 1,ECCSV ; RESTORE ECC BITS 01-16 XXJSR ECCOR ; DO ERROR CORECTION ; COUNT ECC ERROR AS CORRECTED OR UNCORRECTED JMP BADECC ; ECC FAILED LDA 0,DSPER ; ECC SUCCESSFUL COM# 0,0,SZR ; UP SUCCESSFUL ECC COUNT IF ISZ DSPCE ; TOTAL # ERRORS HASN'T OVERFLOWED JMP DSPP BADECC: LDA 0,DSPER ; UP UNSUCCESSFUL ECC COUNT IF COM# 0,0,SZR ; TOTAL # ERRORS HASN'T OVERFLOWED ISZ DSPUE .ENDC ; FATAL ERROR, COUNT IT AND RETURN ERROR NOTRY: LDA 1,DSPER ; DON'T WANT NUMBER TOO BIG COM# 1,1,SZR ISZ DSPNR ; RECORD NON RECOVERABLE ERROR LDA 0,BQST,2 ;STATUS WORD XLDA 1,= QTER ; ERROR DETECTED BIT .IFE BSW!MBSW XXJSR SETFL .ENDC .IFN BSWyU!MBSW IOR 1,0 .ENDC STA 0,BQST,2 ; STATUS WORD .IFN IOSW ; REALLY IOCSW XLDA 1,= QTIND ;INDIRECT BIT ANDZ 0,1,SNR ;IS MODE INDIRECT? JMP DONE1 ;NO - GO GET NEXT THING IN Q LDA 1,BQUST,2 ;YES - USER STATUS ADI 3,1 ;SETS ERROR AND DONE BITS STAA 1,BQUST,2 ;STORE IN USER STATUS IFSS: ADDL 1,1,SZC ;SETS CARRY FROM UNPEND BIT JMP DNNE1 ; NO UNPEND IF 1B1 IS SET .ENDC JMP DONE1 LPOOL ECCSV: .BLK 1 ; SAVE AREA FOR ECC BITS 01-16 ; DISK ERRORS DSPER: 0 ; DISK ERROR COUNT DSPDL: 0 ; DISK DA(TA LATE COUNT DSPNR: 0 ; COUNT OF NON RECOVERABLE ERRORS DSPRG: 0 ; DIA OF LAST DISK ERROR .IFN ECCFLG ; SKIP IF ECC CODE DISABLED DSPEC: 0 ;COUNT OF ECC ERRORS DSPCE: 0 ;COUNT OF CORRECTED ECC ERRORS DSPUE: 0 ;COUNT OF UNCORRECTED ECC ERRORS .END ̨C .END DZ03DB.SRB   ; DZ03DB.SR ; THIS MODULE CONTAINS THE DCBS AND DCTS ; FOR THE FIRST ZEBRA DISK PACK CONTROLLER. ; SYSGEN WILL PRODUCE A .LIMIT FOR THE ; SELECTED ONE IF ANY. RTITLE DZ0DB .NREL .ENT DZPDC DZPEX .ENT DZ3DC,DZ2DC,DZ1DC,DZ0DC .ENT DZ3DB,DZ2DB,DZ1D#B,DZ0DB ; THE FOLLOWING ENTRY POINTS ARE USED TO LIMIT ; THE LOADING OF THIS MODULE .ENT Z04DL .ENT Z03DL,Z02DL,Z01DL,Z00DL .EXTN DZPIT .EXTN DSKDT .EXTN RDCBK .EXTN DZPST .EXTN DZPDST .EXTN RDLBK .EXTN RDNBK .EXTN DPINIT .EXTN DVRLS ; DEVICE CONTROL TABLE FOR MOVING HEAD DISK DZPDC: 1B0 ; DCH INDICATOR MKDZP ; MASK DZPIT ; INT SERVICE .BLK 1 ; CHARACTERISTICS DZP ; DEVICE CODE DZPEX ; LOC TO XEQ I/O INSTRUCTIONS 1B0 ; TELL POWER FAIL ALL ABOUT IT DZPST ; DEVICE STARTUP ROUTINE DZPDST ; SETUP DST WORD IN QUEUE ENTRY -1 ; CURRENT REQUEST POINTER .BLK 1 ; DCH MAP SLOT 5 ; NUMBER OF PAGES TO MAP DZPDC ; LINK TO PARENT DCT .IFE BSW!MBSW DZPEX: 0 LDA 2,@CSP ; GET BUF ADDR TO AC2 JMP @RLOC ; RETURN .ENDHC J DZPEX= 0 ; NOT USED ON BIRD [J] .DDCB DZ0DB,DZ0DC,0,DZ1DB,DZ0,Z00DL .DDCU DZ0DC,0*2,DZP,DZP ** .NOMAC 1 .DDCB DZ1DB,DZ1DC,1*2,DZ2DB,DZ1,Z01DL .DDCU DZ1DC,1*2,DZP,DZP .DDCB DZ2DB,DZ2DC,2*2,DZ3DB,DZ2,Z02DL .DDCU DZ2DC,2*2,DZP,DZP .DDCB DZ3DB,DZ3DC,3*2,-1,DZ3,Z03DL .DDCU DZ3DC,3*2,DZP,DZP ** .NOMAC 0 Z04DL: .BLK 2 ; DUMMY ENTRY USED FOR LIMIT IF ; ; ALL DISKS ARE LOADED DZ47DB.SRB  r ; DZ47DB.SR ; THIS MODULE CONTAINS THE DCBS AND DCTS ; FOR THE SECOND ZEBRA DISK PACK CONTROLLER. ; SYSGEN WILL PRODUCE A .LIMIT FOR THE ; SELECTED ONE IF ANY. RTITLE DZ4DB .NREL .ENT DZP1D DZP1EX .ENT DZ7DC,DZ6DC,DZ5DC,DZ4DC .ENT DZ7DB,DZ6DB,DZs5DB,DZ4DB ; THE FOLLOWING ENTRY POINTS ARE USED TO LIMIT ; THE LOADING OF THIS MODULE .ENT Z14DL .ENT Z13DL,Z12DL,Z11DL,Z10DL .EXTN DZPIT .EXTN DSKDT .EXTN RDCBK .EXTN DZPST .EXTN DZPDST .EXTN RDLBK .EXTN RDNBK .EXTN DPINIT .EXTN DVRLS ; DUEVICE CONTROL TABLE FOR MOVING HEAD DISK DZP1D: 1B0 ; DCH INDICATOR MKDZP ; MASK DZPIT ; INT SERVICE .BLK 1 ; CHARACTERISTICS DZP1 ; DEVICE CODE DZP1EX ; LOC TO XEQ I/O INSTRUCTIONS 1B0 ; TELL POWERFAIL ALL ABOUT IT DZPST ; DEVICE STARTUP ROUTINE DZPDST ; SETUP DST WORD IN QUEUE ENTRY -1 ; CURRENT REQUEST POINTER .BLK 1 ; DCH MAP SLOT 5 ; NUMBER OF PAGES TO MAP DZP1D ; LINK TO PARENT DCT .IFE BSW!MBSW DZP1EX: 0 LDA 2,@CSP ; GET BUF ADDR TO AC2 JMP @RLOC ; RETURN .YENDC J DZP1EX= 0 ; NOT USED ON BIRD [J] .DDCB DZ4DB,DZ4DC,0,DZ5DB,DZ4,Z10DL .DDCU DZ4DC,0*2,DZP1,DZP ** .NOMAC 1 .DDCB DZ5DB,DZ5DC,1*2,DZ6DB,DZ5,Z11DL .DDCU DZ5DC,1*2,DZP1,DZP .DDCB DZ6DB,DZ6DC,2*2,DZ7DB,DZ6,Z12DL .DDCU DZ6DC,2*2,DZP1,DZP k .DDCB DZ7DB,DZ7DC,3*2,-1,DZ7,Z13DL .DDCU DZ7DC,3*2,DZP1,DZP ** .NOMAC 0 Z14DL: .BLK 2 ; DUMMY ENTRY USED FOR LIMIT IF ; ; ALL DISKS ARE LOADED DZPDR.SRB s) ; ; ZEBRA MOVING HEAD DISC DRIVER - WITH MULTIPLE BLOCKS ; RTITLE DZPDR .NREL .ENT DZPIT .ENT DZPST .ENT DZPDS .ENT DZPER ; DISK ERROR TABLE, FOR REPORTER .EXTN DISMI ; INTERRUPT DISMISS .EXTN DIVI,DIVD ; INTEGER DIVIDE .EXTN MPY .EXTN GBLKNO ; BAD BLOCK MAPPER .EXTN UNPEND ; UNPEND A TASK .EXTN BUFNT ; BUFFER WAITERS COUNT .EXTN ECCOR ; I/O EXECUTES, AC2=HEADER .EXTN XDOA,XDOBS,XDOC,XDOCP .EXTN XDIA,XDIB,XDIC,XDOAP ; I/O EXECUTES, AC2=DCT .EXTN XNIOC .IFN MSW .EXT'1N SWAMP .ENDC .EXTN EITHER,TRESP ;PULL IN TRESPASSER IF IPB BUGIT=1 ;CHECKS FOR SHARED-ADAPTER PROBLEMS ; ; PARAMETERS. ; CONTROLLER 'DOA' COMMAND FIELDS ; ; 3B10 *** NON-SYMBOLIC REFERENCE ; DRIVE SELECT DZSKC=2B8 ; SEEK COMMAND DZRCL=1B8 O; RECAL COMMAND DZWRT=16B8 ; WRITE COMMAND DZRLS=7B8 ; RELEASE DRIVE COMMAND DZAM2=12B8 ; ALTERNATE MODE 2 ; CONTROLLER 'DIA' STATUS BITS ; ; 1B0 *** NON-SYMBOLIC REFERENCE ; CONTROL FULL RDDN=1B1 ; READ DONE SKDN=17B5 ; SEEKS DONE SKD3= 1B5  ; DRIVE 3 ATTN BIT DLAT=1B14 ; DATA LATE DECC=1B8 ; ECC ERROR DERR=1B15 ; READ/WRITE ERROR ; DRIVE FAULT ("DIB" BIT 15) IS PLACED IN BIT 0 OF "DIA". ; IF DRIVE ISN'T READY, AN ERROR IS REPORTED WITHOUT RETRY. ; IF 'DATA LATE' IS THE ONLY ERR\OR, RE-SEEK & RETRY I/O. ; ALL OTHER ERRORS, RECAL, THEN RE-SEEK, THEN RETRY I/O. ; ECC ERROR CORRECTION ATTEMPTED ONLY AFTER RETRIES FAIL. ANYBUT= -1-RDDN-SKDN-DLAT-DERR ; ANY ERROR BUT DATA LATE. ; DRIVE STATUS 'DIB' (DRIVE SELECTED BY 'DOA') ; READY= 1B3 ;DRIVE HEADS LOADED,INDEPENDENT OF "INVALID" ; INVALID = 1B0 *** NON-SYMBOLIC ;FAULT BITS 5-15 N.G. ; RESERVED = 1B1 *** NON-SYMBOLIC ;OTHER CPU HAS IT ; TRESPASSED= 1B2 *** NON-SYMBOLIC ;OTHER CPU GRABBED IT! ; THIS DRIVER CAN GENERzATE PANIC 'PNDPE' = 100007 IF AT TIME OF ;DISK INTERRUPT, THE DRIVE WE ARE USING IS EITHER RESERVED OR ;TRESPASSED. THIS CAN HAPPEN ONLY IF ADAPTER IS BAD, OR IF THIS ;CPU IS 'DEAD' AS FAR AS THE OTHER IS CONCERNED. ; AT TIME OF PANIC, ; AC0 = DIA WORD ; AC1 = DIB WORD ; AC2 = BUFFER HEADER ADDRESS ; CONTROLLER 'DOC' FIELDS, FOR READ/WRITE ;*** ALL NON-SYMBOLIC ; HEAD = 37B5 ; SECT = 37B10 ; COUNT= 37B15 (2'S COMPLEMENT) ; DZPDS - SETUP BUFFER HEADER FOR NEXT I/O ; DONE BEFORE INITIAL QUEUE INSERTION ANIOD AT INTERRUPT ; TIME FOR INDIRECT MODE TRANSFERS ; INPUT - AC0: BUFFER HEADER ADDRESS ; AC2: UNIT DCT ADDRESS ; ==== ; CALL - JSR @DCDST,2 ; AC2 = DCT ADDRESS ; OUTPUT - BQCYL & BQDST CONTAIN DOC COMMANDS FOR ; SEEK & READ/WRITE, RESPECTIVELY. ; *FOR INDIRECT, CONTIGUOUS I/O (MULTI-BLOCK I/O), ; BQSCT WILL BE SET TO NUMBER OF SECTORS TO TRY, ; BQNBK WILL BE REDUCED BY THAT NUMBER, FOR NEXT. ; STACK USAGE HEAD= TMP ; HEAD (SURFACE) NUMBER SECT= HEAD+1 ; RELATIVE SECTOR ON HEAD CYL= SECT+1 v; CYLINDER NUMBER SCNT= CYL+1 ; MAXIMUM SECTOR COUNT ; FOR CONTIGUOUS MULTI-BLOCK I/O, THIS IS SET TO ; PREVENT CYLINDER OVERFLOW FSIZE= SCNT+1-TMP ; FRAME SIZE DCTAD= OAC2 ; DCT ADDRESS BUFAD= OAC0 ; BUFFER HEADER ADDRESS DZPDS: RSAVE FSIZE MO4V 0,2 LDA 0,BQST,2 ; GET BUFFER STATUS XLDA 1,= QTDSU ; DSU BIT AND# 1,0,SZR ; HAVE WE BEEN THRU HERE? RTRN ; YES, THEN SKIP THIS CODE ADD 1,0 STA 0,BQST,2 ; SET TO SKIP THIS ON RETRIES XXJSR GBLKNO ; GET BLOCK NUMBER TO AC0 & AC1, ; AND MAX # BLOCKS TO BQCYL LDA 2,BQDCT,2 LDA 2,DCTNS,2 ; GET # OF SECTORS/HEAD STA 2,SCNT,3 ; SAVE IT FOR LATER XXJSR DIVD ; DOUBLE WORD DIVIDE STA 0,SECT,3 ; REMAINDER IS SECTOR # LDA 2,DCTAD,3 LDA 2,DCTNH,2 ; NUMBER OF HEADS/CYLINDER XXJSR DIVI ; SINGLE WORD DIVIDE STA 1,CYL,3 ; QUOTIENT IS CYLINDER # STA 0,HEAD,3 ; REMAINDER IS HEAD # SUB 0,2 ; COMPUTE # SECTORS LEFT LDA 1,SCNT,3 ; ON CYLINDER XXJSR MPY LDA 0,SECT,3 ;...ADD SECTORS IN THIS TRACK. SUB 0,1 STA 1,SCNT,3 ; PREVENT CYLINDER OVERFLOW LDA 2,BUFAD,3 ; CHECK IF THIS IS LDA 0,BQST,2 ; INDIRECT, CONTIGUOUS MODE COM 0,0 XLDA 1,= QTIND+QTCT AND# 1,0,SZR JMP NOIND ; NO LDA 0,SCNT,3 ; GET MIN (SCNT, 16., MAXCOUNT) XLDA 1,= 16. ; INTO AC0 SUBZ# 0,1,SNC ; TLE 0,1 MOV 1,0 LDA 1,BQCYL,2 ; GET MAXCOUNT RETURNED BY GBLKNO SUBZ# 0,1,SNC ; TLE 0,1 MOV 1,0 STA 0,BQSCT,2 ; SAVE SECTOR COUNT FOR DZPIT LDA 1,BQNBK,2 ; ACTUAL BLOCKS LEFT SUB 0,1 ; COMPUTE LEFTOVER BLOCKS STA 1,BQNBK,2 ; AND STORE - ZERO MEANS DONE NEG 0,0,SKP ; CONqVERT SECTOR COUNT TO NEG. NOIND: ADC 0,0 ; SINGLE SECTOR, USE -1. .IFN BSW!MBSW ANDI 37,0 ; SECTOR COUNT MASK .ENDC J XLDA 1,= 37 ; SECTOR COUNT MASK AND 1,0 [J] LDA 1,SECT,3 ; ADD IN (SECTOR)B10 ADDZL 1,1 ADDZL 1,1 MOVZL 1,1 ADD 1,0 LDA 1,b,HEAD,3 ; ADD IN (HEAD)B5 MOVS 1,1 ADDZL 1,1 ADD 1,0 STA 0,BQDST,2 ; THIS IS DOC WORD FOR READ/WRITE LDA 1,CYL,3 STA 1,BQCYL,2 ; THIS IS DOC WORD FOR SEEK RTRN ; RETURN TO CALLER ; ; DISK PACK STARTUP ROUTINE ; CALLED FROM BASE LEVEL WHEN CONTROL IDLE, INTERRUPTS OFF. ; CALLED FROM INTERRUPT TO RESTART CONTROLLER, DISK MASKED. ; NORMAL FUNCTION, BQST[QTSIO=0] : START SEEK ; BQDST MUST HAVE BEEN SET UP BEFOREHAND. ; SPECIAL FUNCTION, QTSIO=1 : RECALIBRATE ; BQDST IS NOT USED...WE DON'T KNOW DISK SIZE. ; ERROR MODE, QTEMD=1 : RECALIBRATE BEFORE RESTARTING. ; AC2= DCT ADDRESS...THE PARENT DCT ; ALL REGISTERS DESTROYED BY THIS CALL !! DZPST: STA 3 EXIT LDA 2,DCCRQ,2 ; CURRENT REQUEST DZRS: ;ENTER HERE FOR RESTART OR CHAINS (AC2 = BUFFER) ; WAIT UNTIL "CONTROL FULL" ISN'T XXJSR XDIA ;STATUS MOVL# 0,0,SZC ; 'ONE' MEANS FULL JMP .-2 ; MAX 50 MICROSEC SPIN XLDA 0,= DZSKC ; SEEK COMMAND LDA 3,BQST,2 ; STATUS WORD XLDA 1,= QTSIO+QTEMD ; SPECIAL MODE IO ? AND 1,3,SZR ; WELL ?? XLDA 0,= DZRCL ; YES, RECAL INSTEAD OF SEEK JSR FIXEC ; SEND COMMAND & DRIVE # ; NOW CHECK THAT DRIVE IS READY...IF NOT, BAG THIS REQUEST XXJSR XDIB ;DRIVE STATUS XLDA 1 = READY AND# 0,1,SNR ;READY? JMP @ ERG4 ; NO. ERROR W/O RELEASE LDA 0,BQCYL,2 ; YES. GET CYLINDER # XXJSR XDOCP,.XDCP ;START THE COMMAND & RESERVE JMP @EXIT ERG4: ERGO4 ; SEEK IS DONE, INITIATE THE REQUEST SEKDN: ; AC0 = BUFFER STATUS LDA 1,WRITE AND 1,0,SZR ;IF WE ARE DOING A WRITE LDA 0,WRCMD ; THEN LOAD WRITE COMMAND ; ELSEy READ COMMAND (=0) JSR FIXEC ;SEND COMMAND & DRIVE # LDA 0,BQDST,2 ; FETCH & SEND THE... JSR @.XDOC ; HEAD/SECTOR/COUNT. .IFE MSW MOV 2,0 ; ASSUME BUFFER ADDRESS XLDA 3,= QTIND LDA 1,BQST,2 ; GET STATUS WORD AGAIN AND# 3,1,SZR ; INDIRECT MODEk? LDA 0,BQADR,2 ; YES, USE REAL ADDRESS MOVL# 0,0,SZC ; MUST CLEAR HIGH ORDER BIT ADDOR 0,0 ; THIS DOES IT .ENDC .IFN MSW LDA 3,BQDCT,2 LDA 3,DCTPD,3 ; REAL DCT ADDRESS LDA 0,DCHMP,3 LDA 1,DCHNM,3 JSR @STMAP ;SET UP DCH MAP .ENDC JSR @ʌ.XDBS ; SEND MEM ADDRESS, START I/O. JMP @EXIT WRITE: QTMOD WRCMD: DZWRT .XDOC: XDOC ;EXECUTE "DOC 0 -" .IFN MSW STMAP: SWAMP .ENDC .XDBS: XDOBS ;EXECUTE "DOBS 0 -" ULPOOL ; DRIVE ATTENTION... SEE THAT IT WAS ON DRIVE WE WANTED. TSEEK: LDA 1,tVBQUN,2 ; MOVZR 1,1 ; OUR DRIVE # IN BITS 14-15. LDA 3,ATTN3 ; START WITH BIT FOR DRIVE 3. MOVZR 1,1,SNC ; DRIVE WE ARE WAITING FOR MOVZL 3,3 MOVZR 1,1,SNC ADDZL 3,3 ; GOT BIT, CHECK IF DRIVE WE WANT AND# 0,3,SNR ; IF NOT DONE THEN JMP @EXIT ;IGNORE --- IT'S BEEN CLEARED ;SINCE 'READY' & NO ERRORS, ASSUME WE HAVE SEEK DONE. .IFN BUGIT LDA 1 SDIB ;RECOVER DRIVE STATUS MOV 1,3 ADDL 3,3,SNC ;MUST NOT BE RESERVED MOVL 3,3,SZC ;MUST NOT BE TRESPASSED JSR PNIC .ENDC LDA 0,BQST,2 ; SEEK/RECAL WAS SUCCESSFUL LDA 1,RECAL AND# 0,1,SNR ;WHICH WERE WE DOING? JMP SEKDN ; NORMAL POSITION--START I/O. SUB 1,0 ; A RECAL AFTER ERROR... STA 0,BQST,2 ; NO LONGER DOING A RECAL JSR RLSE ;RELEASE DRIVE XJMP DZRS ; NOW RESTART THE POSITIONING. RʻECAL: QTEMD ATTN3: SKD3 PNIC: JSR @.PNIC PNDPE ;AC0= DIA, AC1= DIB ;EITHER RESERVED OR TRESPASSED DRIVE ;LAST 'DOA' SENT IS AT (AC2)+BQERC ; ; THIS IS A ROUTINE TO ASSEMBLE, ISSUE, AND SAVE ;A "DOA" COMMAND/UNIT WORD. THE WORD IS SAVED IN 'BQEgRC' ;OF CURRENT BUFFER HEADER, IN CASE AN ATTENTION INTERRUPT FROM ;A DRIVE OTHER THAN THE CURRENT ONE OCCURS WHILE "CONTROL FULL" ;IS SET. UNDER THOSE CIRCUMSTANCES, THE ATTENTION MUST BE CLEARED ;BY "DOA", BUT THE COMMAND/UNIT STORED IN CONTROLLER MUST N1OT ;BE OVERWRITTEN. ; IN: AC2=BUFFER ADDRESS, AC0=COMMAND & ATTENTION CLEAR BITS. ; OUT: AC0=COMMAND & ATTENTION CLEAR, PLUS UNIT (DRIVE). ; AC1,AC3 DESTROYED. "DOA" SENT TO CONTROLLER. FIXEC: .IFE BSW!MBSW STA 3,RLOC .ENDC LDA 1 BQUN,2 ;GEUT UNIT # FROM BUFFER ADDZL 1,1 ;SHIFT IT TO BITS 9-10 ADDZL 1,1 ADD 1,0 ;ADD TO CALLER'S COMMAND LDA 1 BQERC,2 ;MERGE RETRY COUNT .IFE BSW!MBSW XLDA 3 = 37 AND 3,1 .ENDC J ANDI 37,1 [J] ADD 0,1 ;AND COMMAND/UNIT STA 1 BQERC,2 .IFE BSW!MBS43W LDA 3,RLOC .ENDC XXJMP XDOA ;CHAIN OFF TO ISSUE 'DOA' ULPOOL EXIT: 0 .DISM: DISMI ; ; DKP INTERRUPT SERVICE ROUTINE ; AC2: PARENT DCT ADDRESS ; DZPIT: INTDS ;KEEP POWERFAIL FINGERS AWAY LDA 3, .DISM ;GET INTERRUPT DISMISS ADDRESS STA 3,EXIT ,N LDA 0,DCCRQ,2 ; GET CURRENT REQUEST COM# 0,0,SNR ; IS THERE ONE? JMP @.NIOC ; NO...JUST CLEAR INTERRUPT MOV 0,2 ; YES...BUFFER HEADER TO AC2 XXJSR XDIA ; COLLECT STATUS STA 0 STATS ;REMEMBER IT LDA 1,ATTNS ; POSSIBLE ATTENTION BITS ANDL 1,0 ;SHIFT TO POSITION FOR CLEAR LDA 1 BQERC,2 ;LAST COMMAND ISSUED. SEE "FIXEC" ADD 1,0 ;ATTN CLEAR/COMMAND/UNIT/RETRY XXJSR XDOA ;CLEAR ATTENTION (INTERRUPT) ; NOW CHECK UNIT STATUS (SEEK ERRORS, ETC) XXJSR XDIB ;GET STATUS OF "OUR" DRIVE, NOT ;NEHCESSARILY THE INTERRUPTER(S). ; WE USE THE TRICK BELOW, RATHER THAN CALLING 'XDIB', SO AS TO ;GET A FASTER SAMPLING OF DRIVE STATUS. THE TRICK DEPENDS ON THE ;WAY 'XDIB' (IN FILIO) RETURNS THE ASSEMBLED INSTRUCTION IN AC1. .IFE BSW!MBSW STA 1,.+1 ;WE DEPEND ON AC1= INSTRUCTION 'DIB 0 -' DBLUP: DIB 0,0 .ENDC J DBLUP: XCT 1 [J] MOVL# 0,0,SZC JMP DBLUP ;IF INVALID, WAIT (50 USEC MAX). STA 0 SDIB XLDA 1 = READY ;MAKE SURE OUR DRIVE IS READY AND # 0,1,SNR ; SKIP IF YES JMP NRDY ; NOT READY...NO uRETRY. LDA 1 STATS ;RECOVER CONTROLLER STATUS MOVL 1,1 ;MOVE DRIVE FAULT BIT TO MOVR 0,0 ;BIT 0 OF CONTROLLER STATUS. MOVR 1,0 ;PUT IT ALL IN AC0. MOVL# 0,0,SNC ;IF EITHER DRIVE FAULT, MOVR# 0,0,SZC ; OR READ/WRITE FAULT, JMP ERGO ;THEN DO ERMROR RECOVERY. ADDZL# 0,0,SNC ;NO ERRORS. READ/WRITE DONE? JMP TSEEK ; NO...DRIVE ATTENTION. .IFN BUGIT LDA 1 SDIB ;RECOVER DRIVE STATUS MOV 1,3 ADDL 3,3,SNC ;MUST NOT BE RESERVED MOVL 3,3,SZC ;MUST NOT BE TRESPASSED JSR PNIC .ENDC JSR RLSE ;RELaEASE DRIVE. READ/WRITE DONE. ; IF TRANSFER TO SYSTEM BUFFER, WE'LL GO TO 'DONE1' ; IF INDIRECT, WE NEED TO CHECK FOR MULTI-BLOCK EXTEND. DONE0: LDA 0,BQST,2 ; BUFFER STATUS WORD XLDA 1,= QTIND ; INDIRECT MODE? ANDZ 0,1,SZR ; IF NO, SET CARRY=0 TO UNOPEND JMP EXTND ; YES ; ALL I/O WHICH IS TRULY COMPLETE GOES TO NEXT PAGE... DONE1: ; REQUEST IS DONE. CLEAR TRANSIENT STATUS .IFE BSW!MBSW LDA 1, BQOFF AND 1,0 .ENDC J ANDI -QTIOP-QTEMD-QTMOD-1,0 [J] STA 0,BQST,2 ; PUT STATUS BACK ;NOTE: AT K^THIS POINT CARRY = 0 MEANS UNPEND **; GET RID OF THIS CRAP NEXT REV MOV 2,0,SNC ; UNPEND ON BUFFER ADDRESS JSR @.UNPE ;UNPEND ALL WAITERS LDA 0 @BUFWT ;COUNT OF BUFFER WAITERS MOV# 0,0,SNR ; ANY ? JMP NOBWT ; NO SUBZL 0,0 ; BUFFER WAITERS KEY LCDA 1,BQUSC,2 ; USER COUNT ON BUFFER MOV# 1,1,SNR ; BUSY ? JSR @.UNPE ; NO--LET THEM TRY FOR BUFFER NOBWT: LDA 3 BQDCT,2 ;DEQUEUE REQUEST FROM THE LDA 3 DCTPD,3 ; PARENT DCT. LDA 2,BQQLK,2 ;LINK TO NEXT REQUEST STA 2,DCCRQ,3 ; BECOMES NEXT REQUEST. #$ COM# 2,2,SNR ;IS NEW ONE REAL? JMP @EXIT ; NO-- THAT'S ALL. XJMP DZRS ;GO TO "DZRS" TO START DISK STATS: 0 ;TEMP HOLDER FOR "DIA" STATUS SDIB: 0 ;TEMP FOR "DIB" STATUS .UNPE: UNPEND .NIOC: XNIOC ;EXECUTE "NIOC -" ATTNS: RDDN!SKDN BUFWT: BUFNT .IFE BSW!MBSW BQOFF: -1-QTMOD-QTEMD-QTIOP .ENDC ; THIS ROUTINE RELEASES DRIVE. ;ASSUMPTION IS MADE THAT IT IS NOT RESERVED, BUT BELONGS ;TO US. ; IN: AC2= BUFFER HEADER ; OUT: ALL BUT AC2 DESTROYED. RELEASE COMMAND ISSUED, BUT ; NOT NECESSARILY COMPLETE.gE ; RLSE: LDA 1 BQUN,2 ADDZL 1,1 ADDZL 1,1 ;GET DRIVE # TO BITS 9,10 LDA 0,RLSCM ADD 1,0 ;ADD IN RELEASE COMMAND JMP @OAP ;CHAIN TO "XDOAP" OAP: XDOAP ;EXECUTE "DOAP 0 -" RLSCM: DZRLS CLPOOL ; ; MULTIPLE BLOCK HANDLER ; CALLED FROM INTERRUPT AUND RETURNS THERE ; EXTND: XLDA 1,= QTCT AND# 1,0,SZR ; CONTIGUOUS FILE? JMP CONTIG ; YES EXT1: DSZ BQNBK,2 ; RANDOM FILE- DONE? JMP RANDM ; NO FIN1: .IFN MBSW ; SHOULD BE IOCSW ISZ BQUST,2 ; YES- SET USER DONE LDA 1,BQUST,2 ADDL 1,1 ; UNPEN D? .ENDC J MOVZ 0,0 [J] JMP DONE1 ;CARRY=1 MEANS DON'T UNPEND RANDM: LDA 3,BQADR,2 MOVS 3,3 ;BUMP MEM ADDRESS BY 400 INCS 3,3 STA 3 BQADR,2 ISZ BQARD,2 ; INC INDEX PTR FOR HIGH ORDER LDA 1,@BQARD,2 ; PICK UP HIGH ORDER ISZ BQARD,2 ; INCREME.1NT INDEX PTR LDA 3,@BQARD,2 ; GET NEXT DISK ADDR MOV# 1,1,SZR ; HIGH ORDER =0? JMP NONZ ; NO MOV# 3,3,SNR ; DISK ADDRESS =0? JMP EXT1 ; YES - GO DO NEXT ONE NONZ: STA 1,BQCA1,2 ;STASH HIGH ORDER ; THIS CODE SHARED BY BOTH CONTIG AND RANDOM I/O. MCENT: STA 3,BQCA,2 ;STASH LOW ORDER DISK ADDRESS LDA 1,BQST,2 ; BUFFER STATUS .IFE BSW!MBSW XLDA 0,= -QTDSU-1 ; SETUP MASK COMPLEMENT AND 0,1 ; SHOW AS NOT SETUP .ENDC J ANDI -QTDSU-1,1 ; FORCE NEW SETUP [J] STA 1,BQST,2 ;RESTORE STATUS MOV 2,0 ;BUFFER ADDR IN AC0 LDA 2,BQDCT,2 JSR @DCDST,2 ; SET UP BQDST & BQCYL MOV 0,2 ; RESTORE BUFFER ADDRESS XJMP DZRS ;...START I/O, THEN EXIT. CONTIG: LDA 1,BQNBK,2 ; # OF BLOCKS LEFT TO MOVE MOV# 1,1,SNR ; IS BQBNK = 0 ? JMP FIN1 ; YES - DONE -o GO FINISH UP LDA 1,BQSCT,2 ; INCREMENT DISK ADDR BY CONT2: LDA 3,BQCA,2 ; # OF SECTORS TRANSFERRED ADDZ 1,3,SZC ISZ BQCA1,2 LDA 0,BQADR,2 ; GET PREVIOUS MEM ADDRESS MOVS 1,1 ; # OF SECTORS * 400 ADD 1,0 ; UP ADDRESS STA 0,BQADR,2 ; NEW MEM ADDRES:S JMP MCENT ;JOIN RANDOM PATH ULPOOL ; ; RESOLVE ERRORS. ; NRDY: ADDL# 0,0,SNC ; READY DROPPED ON US. AC0="DIB" JSR RLSE ; RELEASE UNLESS 'RESERVED'. JMP ERGO4 ; FATAL ERROR TO USER. ERGO: STA 0 DZPRG ;SAVE LAST DISK STATUS JSR RLSE ;ALWAYSJ RELEASE DRIVE LDA 0 DZPRG LDA 1 SDIB STA 1 LASTB ;SHOW 'DIB' ON LAST ERROR LDA 1,DZPER ; DON'T LET ERRORS COM# 1,1,SNR ; EXCEED 177777 JMP ERGO2 ; IF NOT THEN XLDA 1,= DLAT ; CHECK FOR DATA LATE AND# 0,1,SZR ; IF HAD A DATA LATE ISZ DZPDL  ; COUNT DATA LATE AND ISZ DZPER ; THE ERROR XLDA 1,= DECC ; CHECK TO SEE, IF HAD AND# 0,1,SZR ; ECC ERROR THEN ISZ DZPEC ; COUNT IT ERGO2: DSZ BQERC,2 ; DSZ ERROR RETRY COUNT JMP .+1 LDA 1 BQERC,2 ;EXTRACT THE REMAINING RETRIES XLDA 3 = 37 ; W{ITH MASK. ** SEE "FIXEC" ** AND# 1,3,SZR ;SKIP IF WE'VE TRIED ENOUGH. JMP ERNXT ; GO TRY AGAIN ; ; AT THIS POINT, WE'VE HAD REPEATED ERRORS XLDA 1,= DECC ADDL# 0,0,SZC ;IF NOT READ/WRITE INTERRUPT AND# 0,1,SNR ; OR IF ANY BUT ECC ERROR, JMP ERGO4Ha ; GIVE USER ERROR ; HERE IF REPEATED ECC ERROR... LDA 1 BQDST,2 ; IF THIS WAS A MULTI-SECTOR I/O, AND 3,1 ; THEN WE RESTART THE BAD PART. SUB 3,1,SNR ; BUT IF 1 SECTOR, WE TRY TO  JMP ERGO3 ;CORRECT THE ERROR. JSR @.XDIC ; GET END SECTOR COUNT NEG 0,0 ; AS POSITIVE NUMBER XLDA 3,= 37 AND 3,0 INC 0,0 ; INC BY ONE IN CASE LDA 1,BQSCT,2 ; GET NUMBER OF SECTORS TRIED USLE 0,1 MOV 1,0 LDA 1,BQNBK,2 ; GET # OF BLOCKS LEFT ADD 0,1 STA 1,BQNBK,2 ; AND CORRECT FOR RESTART. LDA 1,BQSCT,2 ; GETI SECTORS TRIED AGAIN SUB 0,1,SZR ; GET # XFER'D SUCCESSFULLY JMP CONT2 ;RESTART AT BAD SECTOR, UNLESS ; NOTHING WAS TRANSFERRED--FIRST SECTOR GAVE ECC. SUBZL 1,1 ;MAKE IT LOOK AS IF WE DID JUST STA 1,BQSCT,2 ;ONE SECTOR DSZ BQNBK,2 ; ONE BLOCK ;WEC0 CAN TRY TO CORRECT. IF OK, THEN RESTART AFTER BAD SECTOR. ERGO3: XXJSR XDIA ;WAIT FOR 'CONTROL FULL' TO DROP MOVL# 0,0,SZC JMP ERGO3 ;SHOULD BE VESTIGE OF RELEASE. LDA 0,ALT2 XXJSR XDOA ; SET ALT MODE 2 XXJSR XDIA ; GET IN FIRST WORD OF ECC STA 0,ECCWD ; STUFF IT XXJSR XDIB ; GET SECOND WORD MOV 0,1 LDA 0,ECCWD JSR @.ECCO ; CALL FOR CORRECTION JMP ERG35 ; WILL NOT CORRECT LDA 1,DZPER ; CORRECTED! RECORD FACT COM# 1,1,SZR ISZ DZPCE ; CORRECTED, OK NOW MAKE LIKE WE DID THIS SECTOR OK  XJMP DONE0 ; UNCORRECTED ECC ERROR ERG35: LDA 1,DZPER COM# 1,1,SZR ISZ DZPUE ; ALL ERRORS FOR WHICH WE HAVE GIVEN UP COME HERE... ERGO4: LDA 1,DZPER ; IF HAVE NOT GOT TOO MANY COM# 1,1,SZR ; ERRORS THEN COUNT A FATAL ISZ DZPNR ; ERROR LDA 0,BQST,2 ; BUFFER STATUS .IFE BSW!MBSW XLDA 1,= QTER ; ERROR BIT ADD 1,0 ;SET IT (IT'S ALWAYS OFF) .ENDC J ADI QTER,0 [J] .IFN MBSW ; ACTUALLY IOCSW XLDA 1 = QTIND ANDZ 0,1,SNR ; INDIRECT MODE ?? XJMP DONE1 ; NO, TRY NEXT REQUEST, CRY=0 LDA 1,BQ9=UST,2 ; YES ADI 3,1 ; SET USER ERROR AND DONE BITS STA 1,BQUST,2 ; PUT AWAY USER STATUS ADDL 1,1 XJMP DONE1 .ENDC J MOVZ 0,0 ; CARRY = 0 UNPEND XJMP DONE1 ; CONTINUE [J] ERNXT: LDA 1,NOTDL ;TEST ERROR TYPE... AND# 1,0,SNR ; SKIP IF ANY BUT DcATA LATE. XJMP DZRS ; DATA LATE ONLY...SEEK LDA 0,BQST,2 .IFE BSW!MBSW XLDA 1,= QTEMD ; SET THAT WE ARE DOING A RECAL AND# 1,0,SNR ;SKIP IF ALREADY SET ADD 1,0 ;ELSE SET IT .ENDC J IORI QTEMD,0 [J] STA 0,BQST,2 ; REPLACE STATUS XJMP DZRS ; START RECAL AND EXIT .ECCO: ECCOR ECCWD: 0 NOTDL: ANYBUT ; ALL POSSIBLE ERRORS EXCEPT DATA LATE ALT2: DZAM2 .XDIC: XDIC ;EXECUTE "DIC 0 -" LPOOL DZPER: 0 ; COUNT OF DISK ERRORS DZPDL: 0 ; COUNT OF DATA LATE ERRORS DZPNR: 0 ; COUNT OF NON-RECOVERABLE ERRORS DZPRG: 0 ; DIA FROM LAST DISK ERROR, BIT 0= DRIVE FAULT DZPEC: 0 ; COUNT OF ECC ERRORS DZPCE: 0 ; COUNT OF CORRECTED ECC ERRORS DZPUE: 0 ; UNCORRECTED ECC ERRORS LASTB: 0 ;'DIB' ON LAST ERROR (SAME TIME AS DZPRG) .END ECC.SRB " 12 RTITLE ECC .NREL .ENT ECCOR .EXTN MPYAD .EXTN DIVD .IFN MSW .EXTD C31K .IFN ANSW .EXTD CLSTB .ENDC .IFN ABSW .EXTD CLBLK .ENDC .ENDC ; ; THIS IMPLEMENTS THE ERROR CORRECTING CODE ALGORITHM DOCUMENTED ; IN THE ZEBRA ENGINEERING DATA SHEE .MACRO .EXOR .DO ?ANSW MOV ^2,^3 ANDZL ^1,^3 ADD ^1,^2 SUB ^3,^2 .ENDC J XOR ^1,^2 [J] % ECCOR: RSAVE 5 ; SPLIT THE 32 ECC BITS INTO P0 (21 BITS) AND P1 (11 BITS) MOV 1,2 ; 2ND ECC WORD XLDA 3,= 1B(15.-11.)-1 ;MASK FOR LOW-ORDER 11 BITS AND 3,2 ;ISOLATE P1, RIGHT ADJUSTED COM 3,3 AND 3,1 ;ISOLATE LOW ORDER 5 BITx_S OF P0 LDA 3,CSP STA 2,P1,3 ;SAVE P1 ; FIND N, THE # OF BIT ROTATES IT TAKES TO FIND P0(0-9) = 0 XLDA 2,= 21. ;UP TO 21 ROTATES STA 2,ECT,3 EZP0: XLDA 2,= -1B9 ;BITS 0-9 SET, 10-15 CLEAR AND# 2,0,SNR ;ARE THEY ZERO? JMP ZP0 ;YES XLDA 2,= 1B(20.-16.) ;LOW ORDER BIT OF 21 BIT FIELD MOVZL 1,1 ;ROTATE 21 BITS MOVL 0,0,SZC ;BIT SHIFTING OUT OF HIGH ORDER? ADD 2,1 ;YES, MOVE TO LOW ORDER DSZ ECT,3 ;21 PASSES ? JMP EZP0 JMP NOC ;YES, NOT CORRECTABLE ZP0: LDA 3,ECT,3 ;THE NUMBER W1E DID XLDA 2,= 21. ; IS THE INITIAL COUNT SUB 3,2 ; LESS THE NUMBER WE DIDN'T LDA 3,CSP STA 2,N,3 ;SAVE N ; LEFT-ADJUST P1 AND THE ERROR PATTERN FOR EASIER HANDLING XLDA 2,= 10.-16. SHP0: MOVZR 0,0 ;SHIFT ERROR PATTERN MOVR 1,1 ; FROM AC0(10c-15) & AC1(0-5) INC 2,2,SZR ; TO AC1(0-10) JMP SHP0 LDA 0,P1,3 ;PICK UP P1, STILL RIGHT-ADJUSTED STA 1,P1,3 ;SAVE ERROR PATTERN, LEFT-ADJUSTED XLDA 1,= 10.-15. SHP1: MOVZL 0,0 ;SHIFT P1 FROM AC0(5-15) INC 1,1,SZR ; TO AC0(0-10) JMP SHP1 v; WITH P1 IN AC0, FIND M, THE # OF SHIFT-XOR OPERATIONS ; IT TAKES TO MATCH THE ERROR PATTERN XLDA 2,= 2047. STA 2,ECT,3 ;UP TO 2047 PASSES ALLOWED TO MATCH EMP1: LDA 1,P1,3 ;PICK UP ERROR PATTERN SNE 1,0 ;WORDS MATCH? JMP MP1 ;YES MOVZL 0,0,"SNC ;NO: SHIFT P1, ZERO SHIFT OUT? JMP EMP1Z ;YES XLDA 1,= (4+1)B10 ;NO, XOR IT IN & MOVE TO LOW ORDER .EXOR 1,0,2 ;USE AC2 AS SCRATCH EMP1Z: DSZ ECT,3 ;2047 PASSES? JMP EMP1 ;NO JMP NOC ;YES, NON-CORRECTABLE MP1: LDA 2,ECT,3 XLDA 0,= 204/7. ;# PASSES = INITIAL LESS REMAINING SUB 2,0 STA 0,M,3 ;SAVE M LDA 1,N,3 USGT 1,0 ;N > M ? JMP NLEM ;NO, N <= M ; M < N: X := [(N-M)*19 MOD 21]*2047+M SUB 0,1 ;N-M XLDA 2,= 19. ;TIMES 19 SUB 0,0 XXJSR MPYAD ;AC0,1 = AC1*AC2+AC0 X$LDA 2,= 21. ;MODULO 21 XXJSR DIVD ;Q AC1 R AC0 = AC0,1/AC2 XLDA 2,= 2047. ;TIMES 2047 MOV 0,1 LDA 0,M,3 ;PLUS M JMP LMPA ;GO DO THE LAST MULTIPLY-ADD ;M >= N: X := [(M-N)*195 MOD 2047]*21+N NLEM: SUB 1,0 ;M-N MOV 0,1 SUB 0,0 XLDA 2,= 195. ;TIMES 195 XXJSR MPYAD ;AC0,1 = AC1*AC2+AC0 XLDA 2,= 2047. ;MODULO 2047 XXJSR DIVD ;Q AC1 R AC0 = AC0,1/AC2 MOV 0,1 XLDA 2,= 21. ;TIMES 21 LDA 0,N,3 ;PLUS N LMPA: XXJSR MPYAD ;MULTIPLY & ADD. NOTE: LARGEST POSSIBLE ; RESULT IS 22* 2047, ABOUT 44K, FITS IN ONE WORD ; NORMALIZE THE ERROR PATTERN TO ELIMINATE THE POSSIBILITY OF ; A NEGATIVE BIT DISPLACEMENT BEING VALID. LDA 2,P1,3 SNEZ 2 ;IF ZERO, ALL 32 BITS WERE ZERO - JMP NOC ; CONTROLLER SCREWED UP SOMEHOW NORMZ: MOVL# b2,2,SZC ;NORMALIZED? JMP NORDN ;YES MOVZL 2,2 ;NO, SHIFT INC 1,1 ;COMPENSATE BY ADDING TO DISPLACEMENT JMP NORMZ NORDN: STA 2,P1,3 ;SAVE XLDA 2,= 36812. ;MAGIC NUMBER SUBZ 2,1,SNC ;SUBTRACT TO GET BIT DISP IN SECTOR JMP NOC ;NEGATIVE - NOktT CORRECTABLE ; CONVERT BIT DISP & BIT STRING TO WORD DISP & DOUBLE-WORD MASK XLDA 2,= 16. ;SPLIT TO WORD & BIT DISPLACEMENTS XXJSR DIVD ;Q(AC1)=WD DISPL, R(AC0)= BIT DISPL STA 1,WDDSP,3 ;SAVE WORD DISPLACEMENT IN SECTOR MOV 0,2 ;BIT DISPLACEMENT?H FROM WORD BOUNDARY LDA 0,P1,3 ;PICK UP NORMALIZED PATTERN SUB 1,1 ;DOUBLE WORD NEG 2,2,SNR JMP SHPDN SHFP: MOVZR 0,0 ;SHIFT IT INTO PLACE MOVR 1,1 INC 2,2,SZR JMP SHFP SHPDN: STA 0,EWD0,3 ;SAVE ALIGNED PATTERN STA 1,EWD1,3 ; MAKE SUREH IT'S WITHIN SECTOR BOUNDARY LDA 0,WDDSP,3 ;DISPLACEMENT TO FIRST WORD IN ERROR SNEZ 1 ;ONLY ONE WORD IN ERROR? MOV 0,1,SKP ;YES, SAME DISP FOR LAST WORD IN ERROR INC 0,1 ;DOUBLE - LAST IS FIRST+1 XLDA 2,= 255. ;LAST WORD OF SECTOR USGT 1,2 ;ERROR CONTAINED IN SECTOR? JMP PACHUP ;YES, GO FIX IT UP USLE 0,2 ;ERROR STRADDLES SECTOR/ECC BOUNDARY? JMP CHKEC SUB 1,1 ;YES - DONT TRY TO PATCH ECC WORD STA 1,EWD1,3 JMP PACHUP ;GO CORRECT WORD IN SECTOR CHKEC: XLDA 2,= 257. USGT 1,2 4b;ERROR IN ECC WORD (256 OR 257)? JMP DONE ;YES, DATA WAS OK ALL ALONG ; NON-CORRECTABLE EXIT NOC: RTRN LPOOL ; CORRECT THE ERROR BY CHANGING SOME BITS PACHUP: LDA 2,OAC2,3 ;ADDRESS OF START OF SECTOR LDA 0,BQST,2 ; GET BUFFER STATUS XLDA 1,= QTIND ; CHECK, IF NOT INDERECT AND# 0,1,SZR ; THEN WE GOT IT EASY ELSE .IFN MSW JMP MAPFX ; GOT A PROBLEM .ENDC J LDA 2,BQADR,2 ; GET ADDRESS OF BUFF TO CORRECT [J] LDA 0,WDDSP,3 ADD 0,2 ;PLUS DISP YIELDS ADDRESS OF ERROR LDA 1,EWD0,3 LDA 0,0,2 ;CHANGE FIRST WORD .EXOR 1,0,3 STA 0,0,2 ;PUT IT BACK LDA 3,CSP LDA 1,EWD1,3 SNEZ 1 ;ANY CHANGE IN 2ND WORD? JMP DONE ;NO, DON'T REFER ; (IT COULD BE OUTSIDE OUR ADDRESS SPACE) LDA 0,1,2 .EXOR 1,0,3 ;CHANGE ANOTHER WORD STA 0,1,2 .IFN MSW JMP DONE MAPFX: .IFN MNSW LDA 1,CLSTB ADDOR 1,1 DOA 1,MAP DIC 1,MAP ; GET CURRENT LAST BLOCK MAPPING XLDA 0,= 377 AND 0,1 .ENDC .IFN MN3SW LDA 1,CLSTB DOA 1,MAP1 DIA 1,MAP1 XLDA 0,= 377 .ENDC .IFN MBSW LDA 1,CLBLK .ENDC .STA 1,SVLBK,3 ; AND SAVE FOR LATER RESTORE LDA 2,BQADR,2 ; GET LOGICAL BUF ADDR LDA 0,WDDSP,3 ADD 0,2 ;PLUS DISP YIELDS ADDRESS OF ERROR STA 2,VRADR,3 ; STORE ADDR TO CHANGE JSR MAPIT LDA 3,CSP ;RESTORE STACK POINTER LDA 1,EWD0,3 LDA 0,0,2 ;CHANGE FIRST WORD .EXOR 1,0,3 STA 0,0,2 ;PUT IT BACK LDA 3,CSP LDA 1,EWD1,3 SNEZ 1 ;ANY CHANGE IN 2ND WORD? JMP CDONE ;NO, DON'T REFER LDA 2,VRADR,3 ; GET ADDRESS TO CHANGE INC 2,2 ; INC TO ACTUAL VIRTUAL ADDRESS JSR MAPIT ; MAP IT IT LDA 3,CSP ; RESORE STACK POINTER LDA 1,EWD1,3 LDA 0,0,2 .EXOR 1,0,3 ;CHANGE ANOTHER WORD STA 0,0,2 CDONE: LDA 3,CSP LDA 0,SVLBK,3 ; RESTORE LAST BLOCK MAPPING .IFN MNSW LDA 0,CLSTB ADD 0,1 .ENDC .IFN MBSW  STA 1,CLBLK .ENDC SMLB 1 .ENDC DOܩNE: LDA 3,CSP ISZ ORTN,3 ;CORRECTED RTRN RTRN .IFN MSW ; MAPS ADDRESS HELD IN AC2 INTO LAST BLOCK AND ; RETURNS AC2 POINTING TO WHERE IS IN LAST BLOCK MAPIT: MOV 2,0 ; SAVE ADDR LDA 2,CSP ; GET ADDRESS OF MAP LDA 2,OAC2,2 LDA 2,BQDCB,2 XLDA 1,=- 37B5 ; GET THE PAGE NUMBER ANDS 0,1 MOVZR 1,1 MOVZR 1,1 ; GOT PAGE NUMBER ADD 1,2 ; NOW HAVE MAP SLOT LDA 2,0,2 ; GET MAP CONTENTS .IFN ANSW XLDA 1,= MPAPH ; GET JUST PHYSICAL AND 1,2 ; ADDRESS  LDA 3,CLSTB ; MAKE INTO LAST BLOCK MAPPING ADD~ 3,2 .ENDC .IFN MBSW STA 2,CLBLK ; STORE AS NEW LAST BLOCK .ENDC SMLB 2 ; SET IT IN THE MAP XLDA 1,= 1777 ; COMPUT ADDRESS TO REFER AND 1,0 ; TO MAPED IN WORD LDA 2,C31K ; IN LAST BLOCK ADD 0,2 JMP 0,3 ; RETURN TO CALLER .ENDC LPOOL .ENDD MCA1D.SRB   RTITLE MCA1D .NREL .TXTM 1 .ENT MCT1D,MCR1D,MCR1B,MCT1B,MCR1Q,MCT1Q .EXTN MCTIS,MCRIS,MCTDT,MCRDT .IFN ANSW ; TRANSMITTER I/O INSTRUCTION EXECUTE AREA MCAET: 0 LDA 2,@CSP ; RESTORE AC2 JMP @RLOC ; RETURN ; RECIEVER I/O INSTRUCTION EXECUTEN AREA MCAER: 0 LDA 2,@CSP ; RESTORE AC2 JMP @RLOC ; RETURN .ENDC J MCAET= 0 ; NOT USED ON ECLIPSE MCAER= 0 [J] ; MCA SECONDARY DEVICE DCT'S ; MCAT1 DEVICE CONTROL TABLE MCT1D: 1B0 ; 1B0 SET FOR MAPPING INIT MKMCA ; IO MASK MCTIS ; INTERRUPT SERVICE ENTRY DCDIO+DCSTO ; CHARACTERISTICS MCAT1 ; DEVICE CODE MCAET ; EXECUTE IO INSTRUCTION MCTDT ; DISPATCH TABLE 0 MBQST: 0 ; BQST OF BUFFER FOR PROTOCOL -1 ; CURRENT REQUEST POINTER .BLK 1 ; FIRST DATA CHANNEL SLOT 5 ; N UMBER OF SLOTS MCT1D ; POINTER TO PARENT DCT MBFAD: .+1 ; BUFFER ADDRESS MBUFF: 0 ; QQCNT 0 0 ; TFLAG 0 ; UNFLG 0 0 ; QPTR - CURENT UFT ; NOTE PROTOCOL BUFFER IS BUILT INTO ; DCT AND IS SET UP AS BUFFER HEADER **; ERROR TRAPS ** .NOCON 1 ** .DO MBUFF-MBQST<>BQBF-BQST LDA:; BUFFER DISP ERROR ******************* ** .ENDC ** .NOCON 0 ; MCAR1 DEVICE CONTROL TABLE MCR1D: 1B0 ; 1B0 SET FOR MAPPING INIT MKMCA ; IO MASK MCRIS ; INTERRUPT SERVICE ENTRY 0 ; CHARACTERISTICS MCAR1 ;` DEVICE CODE MCAER ; EXECUTE IO INSTRUCTION MCRDT ; DISPATCH TABLE 0 0 ; BQST OF BUFFER FOR PROTOLOC -1 ; CURRENT REQUEST POINTER .BLK 1 ; FIRST DATA CHANNEL SLOT 5 ; NUMBER OF SLOTS TO MAP MCR1D ; POINTER TO PARENT DCT .+1 ; BUFFER ADDRESS 0 ; QQCNT 0 0 ; RFLAG 0 ; UNFLG 0 0 ; QPTR .SPDCB MCR1B,MCR1D,MCT1B,MCAR1,MCR MCR1Q: .BLK 2 100000 ; USER OF A FREE STACK MCR1D ; DCT .BLK QLN-4 ; GET SOME MEMORY .SPDCB MCT1B,MCT1D,-1,MCAT1,MTR MCT1Q: .BLK 2 10000PI0 ; USER OF A FREE STACK MCT1D ; DCT .BLK QLN-4 ; GET SOME MEMORY .END MCADC.SRB  %B RTITLE MCADC .NREL .TXTM 1 .ENT MCTDC,MCRDC,MCRDB,MCTDB,MCRQ,MCTQ .EXTN MCTIS,MCRIS,MCTDT,MCRDT .IFN ANSW ; TRANSMITTER I/O INSTRUCTION EXECUTE AREA MCAET: 0 LDA 2,@CSP ; RESTORE AC2 JMP @RLOC ; RETURN ; RECIEVER I/O INSTRUCTION EXECUTE AnREA MCAER: 0 LDA 2,@CSP ; RESTORE AC2 JMP @RLOC ; RETURN .ENDC J MCAET= 0 ; NOT USED ON ECLIPSE MCAER= 0 [J] ; MCA PRIMARY DEVICE DCT'S ; MCAT DEVICE CONTROL TABLE MCTDC: 1B0 ; 1B0 SET FOR MAPPING INIT MKMCA ; IO MASK MCTIS ; INTERRUP6OT SERVICE ENTRY DCDIO+DCSTO ; CHARACTERISTICS MCAT ; DEVICE CODE MCAET ; EXECUTE IO INSTRUCTION MCTDT ; DISPATCH TABLE 0 MBQST: 0 ; BQST OF BUFFER FOR PROTOCOL -1 ; CURRENT REQUEST POINTER .BLK 1 ; FIRST DATA CHANNEL SLOT 5 ; NUMBER XOF SLOTS MCTDC ; POINTER TO PARENT DCT MBFAD: .+1 ; BUFFER ADDRESS MBUFF: 0 ; QQCNT 0 0 ; TFLAG 0 ; UNFLG 0 0 ; QPTR - CURENT UFT ; NOTE PROTOCOL BUFFER IS BUILT INTO ; DCT AND IS SET UP AS BUFFER HEADER **; ERROR TRAPS ** .NOCON 1 ** .DO MBUFF-MBQST<>BQBF-BQST LDA:; BUFFER DISP ERROR ******************* ** .ENDC ** .NOCON 0 ; MCAR DEVICE CONTROL TABLE MCRDC: 1B0 ; 1B0 SET FOR MAPPING INIT MKMCA ; IO MASK MCRIS ; INTERRUPT SERVICE ENTRY 0 ; CHARACTERISTICS MCAR ; DEVICE JCODE MCAER ; EXECUTE IO INSTRUCTION MCRDT ; DISPATCH TABLE 0 0 ; ; BQST OF RECEIVE BUFFER -1 ; CURRENT REQUEST POINTER .BLK 1 ; FIRST DATA CHANNEL SLOT 5 ; NUMBER OF SLOTS TO MAP MCRDC ; POINTER TO PARENT DCT .+1 ; BUFFER ADDRESS y0 ; QQCNT 0 0 ; RFLAG 0 ; UNFLG 0 0 ; QPTR .SPDCB MCRDB,MCRDC,MCTDB,MCAR,MCR MCRQ: .BLK 2 100000 ; USER OF A FREE STACK MCRDC ; DCT .BLK QLN-4 ; GET SOME MEMORY .SPDCB MCTDB,MCTDC,-1,MCAT,MCT MCTQ: .BLK 2 100000 ; USER OF AAf FREE STACK MCTDC ; DCT .BLK QLN-4 ; GET SOME MEMORY .END MCADR.SRB +^'; TYPE 4038 MULTIPROCESSOR COMMUNICATIONS ADAPTER RTITLE MCADR .IFN MSW .EXTN SWAMP .IFN MNSW!MN3SW .EXTD CLSTB .ENDC .IFN MBSW .EXTD CLBLK .ENDC .ENDC .ENT MCTIS,MCRIS,MCTDT,MCRDT,MCTBL,MCRBL .IFE BSW!MBSW .ENDC .NREL .TXTM 1 .EXTN MCOPN,MCCLS,MCWRS,MCROP,MCRCL,MCRDS .EXTN XDICC,XDOA,XNOS,XDOBS,XDIBC .EXTN XDIB,XDIC,XDOC .EXTN UPQUE,DISMIS ; ONCE AGAIN WE ARE ABOUT TO BUILD A ; FAKE BUFFER HEADER IN THE UFT SO BE CAREFUL ; IF ANY BUFFER HEADER, UFT, OR DCT PARAMETERS CHANGED ; THIS VCODE IS ******! ; OFSETS INTO THE UFT MCTOT= UFTEX-1 ; TIME OUT TRIES MCDEV= UFTEX ; DEVICE REQUESTED SHIFTED FOR ; STATUS WORD MCMSA= UFTLK ; (BQDCB) FOR MAP PTAD+PMAP MCLK= UFTBK ; UFT LINK MCDBN= UFTBC ; BINARY # OF DEVICE REQUESTED MCT|CB= UFTAD ; USER TCB ADDRESS MCBQST= UFTAC ; (BQST) STATUS WORD OF FAKE BUFFER HEADER MCTAD= UFTYD ; PROGRAM TABLE ADDRESS MCINU= UFTHM ; DEVICE IN USE FLAG MCCNT= UFTP1 ; REQUEST WORD COUNT MCADR= UFTUC ; (BQARD) USER STARTING ADDRESS MCDBA= UGFTDL ; (BQBF) FAKE BUFFER START CONTAINS . ; IT SHOULD BE NOTED THAT A BUFFER IS BUILT ; INTO THE DCT AND IF ANY DCT DISPLACEMENTS CHANGE THE ; WHOLE WORLD IS IN TROUBLE QBAD= DCTRL ; BUFFFER AREA FOR TRANSMITS QQCNT= DCTRD ; NUMBER OF WORDS IN REQʰUEST RFLAG= DCTIN ; STATE FLAG FOR RECEIVER TFLAG= DCTIN ; STATE FLAG FOR TRANSMITTER UNFLG= DCTRS ; PROTOCOL FLAG FOR REC QPTR= DCNBK ; ACTIVE ELEMENT ON QUEUE **; ERROR TRAPS IN CASE DISPLACEMENTS CHANGE ** .NOCON 1 ; DON'T SHOW UNLESS NEEDED *>* .DO MCDBA-MCBQS<>BQBF-BQST ** LDA:; DISPLACEMENT ERROR MCDBA,MCBSQ ** .ENDC ** .DO MCDBA-MCADR<>BQUST-BQADR ** LDA:; DISPLACEMENT ERROR MCDBA,MCADR ** .ENDC ** .DO QQCNT-QBAD<>1 ** LDA:;DISPCACEMENT ERROR QQCNT,QBAD ** .ENDC ** .DO MCDBA-MCMSA<>BQBF-BQD#CB ** LDA:; DISPLACEMENT ERROR MCDBA,MCMSA ** .ENDC ** .NOCON 0 MCANO= 32. ; NUMBER OF PROCESSORS MCTBL: .BLK MCANO ; MULTIPROCESSOR TABLE TO ; ASSOCIATED UFT'S MCRBL: .BLK MCANO .DCT= TMP+0 DBUF= .DCT+1 TYPE= DBUF+1 DBAD= TYPE+1 SC= DBAD+1 NTEMP=SC-TMP+1 ;DISPATCH TABLE - TRANSMITTER MCTDT: MCOPN ; OPEN MCCLS ; CLOSE -1 ; READ SEQUENTIAL -1 ; READ LINE -1 ; READ RANDOM MCWRS ; WRITE SEQUENTIAL -1 ; WRITE LINE -1 ; WRITE RANDOM MCOPN ; OPEN FOR APPENDING -1 ; READ ONLY OPEN MCOPN ; EXCLUSIVE OPEN ;DISPATCH TABLE - RECEIVER MCRDT: MCROP ; OPEN MCRCL ; CLOSE MCRDS ; READ SEQUENTIAL -1 ; READ LINE -1 ; READ RANDOM -1 ; WRITE SEQUENTIAL -1 ; WRITE LINE -1 ; WRITE RANDOM -1 ; OPE=N FOR APPENDING MCROP ; READ ONLY OPEN MCROP ; EXCLUSIVE OPEN MCROP ; TRANSPARENT OPEN ; MCAT INTERRUPT SERVICE ROUTINE MCTIS: LDA 3,.DSMS ; SAVE DISMIS RETURN RSAVE NTEMP STA 2,.DCT,3 ; SAVE DCT ADDRESS .IFN MSW JSR @.SMAP ; REESTABLISH MSpAP TO ACCESS TCB .ENDC LDA 2,OFSET ; MAKE PHONY BUFFER ON STACK ADD 3,2 STA 2,DBUF,3 ; SAVE IT FOR OTHER IO CALLS JSR @.XDC ; GET STATUS LDA 3,CSP ; GET STACK POINTER BACK LDA 1,TOMSK ; TIME OUT MASK LDA 2,THREE ; FOR INTEERRUPT DISPATCH TABLEv AND# 0,1,SNR ; IS IT A TIME OUT SUBZ 2,2 ; NO TRANSMISSION COMPLETE LDA 0,TADR ; GET TRANSMISSION TABLE ADDRESS ADD 2,0 ; OFSET INTO TABLE LDA 2,.DCT,3 ; GET DCT ADDRESS BACK LDA 3,TFLAG,2 ; GET STATE FLAG OF TRANSMITTER ADD 0,3 ; GOT ADDRESS fNOW JMP @0,3 ; ENTRY POINT FOR INTERRUPT OFSET: .DCT-BQDCT TOMSK: 1B12 TADR: .+1 TYPE0 TYPE1 TYPE2 TO0 TO1 TO2 THREE: 3 .XDC: XDICC TO0: LDA 3,QPTR,2 ; GET UFT SERVICING DSZ MCTOT,3 ; TRIED 10 TIMES ? JMP CONT ; NO, TRY NEXT ELEMENT ON QUEUE rc SUBZ 0,0 ; RETURN 0 BYTES SENT LDA 2,MCTCB,3 ; GET TCB STA 0,TAC1,2 MER: LDA 0,ERTO ; YES, RETURN TIME OUT ERROR MER1: LDA 3,MCTCB,3 ; GET TCB ADDRESS MER11: STA 0,TAC2,3 ; RETURN ERROR CODE DSZ TPC,3 ; ERROR RETURN DSZ TPC,3 MER2: LDA 0,TPRST,3 ; 2CLEAR TCB STATUS ADCZR 1,1 ; GENERATE 077777 AND 1,0 ; CLEAR 1B0 STA 0,TPRST,3 ; RESTORE STATUS WORD LDA 3,CSP ; GET UFT BACK LDA 2,.DCT,3 ; VIA DCT LDA 2,QPTR,2 ; VIA QPTR LDA 3,MCTAD,2 ; GET TABLE ADDRESS LDA 0,PSTAT,3 ; GET PROGRAM STATUS AN D 1,0 ; CLEAR 1B0 STA 0,PSTAT,3 ; RESTORE STATUS WORD SUBZL 0,0 ; KICK SCHEDULER STA 0,@.UPQUE STA 0,PINTU,3 ; AVOID THOSE RACES SUBZ 0,0 ; CLEAR USE FLAG STA 0,MCINU,2 LDA 0,MCLK,2 ; NOW DEQUE LDA 3,CSP LDA 3,.DCT,3 ; TO GET QUEUE POINTER LDAX 3,DCCRQ,3 ; START OF QUEUE SUBZ# 3,2,SNR ; MATCH ? JMP FST ; YES QLOOP: LDA 1,MCLK,3 ; GET ADDRESS OF NEXT ELEMENT SUBZ# 1,2,SNR ; THIS THE LINK ? JMP .+3 ; YES, DEQUE MOV 1,3 ; TRY NEXT ELEMENT JMP QLOOP STA 0,MCLK,3 ; NOW CAN DEQUE JMP .+4 FST: LDA 3,CSP LDA 2,.DCT,3 STA 0,DCCRQ,2 ; FIRST ONE USE DCT OFSET LDA 3,CSP LDA 2,.DCT,3 ; GET DCT BACK SUBZ 0,0 ; WANT TO CLEAR TFLAG STA 0,TFLAG,2 STA 0,QPTR,2 LDA 3,DCCRQ,2 ; DEVICE STILL ACTIVE ? COM# 3,3,SNR JMP @.MRTN ; DONE,NO ELEMENTSl ON QUEUE IO: STA 3,QPTR,2 ; PUT REQUEST NOW ACTIVE IN QPTR LDA 0,DCTCD,2 ; PICK UP DEVICE CODE MOVR# 0,0,SZC ; SEE IF IS TRANSMITTER OR RECIEVER JMP SME ; RECEIVER LDA 0,MCDEV,3 ; DEVICE INTERESTED IN LDA 3,CSP LDA 2,DBUF,3 JSR @.XDOC ; SETT STAHTUS REGISTER LDA 3,CSP ; SEE IF DIRECT LDA 2,.DCT,3 ; GET DCT LDA 3,QPTR,2 ; GET UFT LDA 0,UFTCH,3 ; CHARACTERISTIC MOVL# 0,0,SNC JMP TYPED ; DIRECT SME: ADC 1,1 ; TRANSMIT ONE WORD LDA 3,CSP ; SET UP SYSTM AREA LDA 2,.DCT,3 ; GET DCT LDA 0,QBAD,2 ; ADDRESS POINTER JMP MCTIO ; RESTART DEVICE CONT: LDA 3,QPTR,2 ; TRY NEXT ELEMENT ON QUEUE LDA 3,MCLK,3 ; GET NEXT ELEMENT COM# 3,3,SZR ; END OF QUEUE JMP IO ; RESTART WITH NEXT ELEMENT ON ; QUEUE LDA 3,DCCRQ,2 ; START FROM BEGINING OF Q/3UEUE JMP IO ERTO: ERDTO ; TIME OUT .UPQUE: UPQUE .DSMS: DISMIS .XDOC: XDOC .IFN MSW .SMAP: SMAP .ENDC TO2: TO1: LDA 3,QPTR,2 ; TRY TO START IT AGAIN DSZ MCTOT,3 ; ANY TRIES LEFT ? JMP RETRY ; RTY AGAIN, USE NIOS JMP MER ; GIVE UP RETRY: LDA 3n,CSP ; SET UP DUMMY BUFFER ADDRESS LDA 2,DBUF,3 JSR @.XNOS ; JUST START LDA 3,CSP LDA 2,.DCT,3 ; NEED DCT ADDRESS IN AC2 TO ; LEAVE JMP @.MRTN .XNOS: XNOS ; NOW SEND SECOND PROTOCOL MESSAGE WITH NUMBER OF WORDS TO TRANSMIT IN ; FOLLOWING MESSA+GE TYPE0: LDA 3,QPTR,2 ; ACTIVE ELEMENT LDA 0,MCCNT,3 ; GET # OF WORDS IN TRANSMIT MOV# 0,0,SNR ; ZERO LENGTH REQUEST ? ISZ TFLAG,2 ; BAG REQUEST AFTER THIS ; TRANSMISSION STA 0,QQCNT,2 ; PUT IN BUFFER TOSEND TO REC ISZ TFLAG,2 ; SHOW SECOND M0ESSAGE IN ; PROGRESS ADCZL 1,1 ; GENERATE -2 FOR WORD COUNT LDA 0,QBAD,2 MCTIO: LDA 3,CSP ; TO SET A AND B REGISTERS STA 1,SC,3 ; SAVE COUNT .IFN MSW LDA 2,.DCT,3 ; MAP TO SYSTEM AREA OR USER ; AREA LDA 0,DCHMP,2 ; GET DATA CHANNEL MAP LDA 1,DCHNM,2 ; GET # OF SLOTS LDA 3,QQCNT,2 ; COUNT = 0? MOV 3,3,SNR ; WELL ? JMP SYSCL ; YES SYSTEM BUFFER LDA 3,TFLAG,2 ; GET STATE FLAG MOVZR# 3,3,SNR ; WELL? JMP SYSCL ; MAP TO SYSYTEM AREA LDA 2,QPTR,2 ; MAP TO USER AREA  LDA 2,MCDBA,2 ; DU#MMY BUFFER IN UFT JMP CMN SYSCL: LDA 2,QBAD,2 ; GET DUMMY BUFFER IN DCT CMN: JSR @.SWAMP LDA 3,CSP ; GET CSP BACK .ENDC LDA 2,DBUF,3 ; GET DUMMY BUFFER ADDRESS JSR @.XDOA ; SET A LDA 3,CSP LDA 2,DBUF,3 ; TO SET B REGISTER LDA 0,SC,3 ; LOAD # OF pWORDS TO TRANS JSR @.XDBS LDA 3,CSP LDA 2,.DCT,3 ; FOR DISMIS JMP @.MRTN .XDOA: XDOA .IFN MSW .SWAMP: SWAMP .ENDC .MRTN: MRTN TYPE1: LDA 3,CSP ; GET STATUS LDA 2,DBUF,3 JSR @.XB LDA 3,CSP LDA 2,.DCT,3 ; GET DCT LDA 3,QPTR,2 ; GET ACTIVE ELEME NT MOV# 0,0,SNR ; SEND MESSAGE ? JMP TYPC ; YES SUBZ 1,1 STA 1,TFLAG,2 ; RESET TRANSMITTER STATE FLAG LDA 3,MCTCB,3 ; GET TCB LDA 0,ERT3 ; NO MCA REQUEST OUTSTANDING JMP M9T TYPED: ISZ TFLAG,2 ; SHOW USER MESSAGE IN PROGRESS TYPC: ISZ TFLAG,2 I; SHOW USER MESSAGE IN PROGRESS LDA 0,MCADR,3 ; GET USER ADDRESS LDA 1,MCCNT,3 ; GET COUNT NEG 1,1 ; 2'S COMP JMP MCTIO ; RESTART DEVICE TYPE2: LDA 3,CSP ; USER MESSAGE COMPLETE LDA 2,DBUF,3 ; GET # OF WORDS TRANSMITTED JSR @.XB LDA 3,CSP ; SE`T REGISTERS LDA 2,.DCT,3 ; GET DCT LDA 2,QPTR,2 ; GET ACTIVE ELEMENT LDA 3,MCTCB,2 ; GET TCB MOV# 0,0,SNR JMP @.MER2 ; GOOD RETURN LDA 1,MCCNT,2 ; GET # IN REQUEST ADD 0,1 ; GET # TRANSMITTED LDA 0,ERT2 ; SHORTER RECEIVE REQUEST M9T: STA 1,TAC1,sY3 ; RETURN THIS COUNT JMP @.MER ERT2: ERSRR ; SHORTER RECEIVE REQUEST .MER: MER11 .XB: XDIB .MER2: MER2 .MER1: MER1 .MMER: MER ERT3: ERNMC ; INTERRUPT SERVICE FOR MCAR MCRIS: LDA 3,.DSMS ; DISMIS RETURN RSAVE NTEMP STA 2,.DCT,3 ; SAVE DCT ADDRESS  .IFN MSW JSR @.SMAP .ENDC LDA 2,OFST ; SET UP DUMMY BUFFER ON STACK ADD 3,2 STA 2,DBUF,3 ; SAVE FOR OTHER IO CALLS JSR @.XC ; GET STATUS LDA 3,CSP LDA 2,.DCT,3 ; GET DCT BACK LDA 1,TMSK ; IS IT A TIME OUT AND# 0,1,SNR JMP @.TOER ; IT SURE IعS LDA 1,RADR ; RECEIVER DISPATCH TABLE LDA 3,RFLAG,2 ; GET RECEIVEER STATE ADD 1,3 ; OFSET IN TABLE JMP @0,3 ; TAKE OF THRU TABLE RADR: .+1 R0 R1 R2 OFST: .DCT-BQDCT TDONE: 1B14+1B15 .XC: XDIC TMSK: 1B14+1B15 DEMSK: 007400 .TOER: TOER R0: SUBZ 1^,1 STA 1,UNFLG,2 ; SET RECEIVER REC FLAG LDA 1,TDONE ; DID TRANSMITTER TIME OUT OR ; DIREC IO ? AND# 0,1,SNR JMP @.TOER ; TIME OUT LDA 1,DEMSK ; DEVICE MASK ANDZL 1,0 ;GET DEVICE # OF TRANSMITTER MOVZL 0,0 ; INTO BITS 0-3 MOVZL 0,0 MOVZL X0,0 LDA 2,DCCRQ,2 ;GET QUEUE POINTER SUBO 3,3,SKP ;CLEAR AC3 & CARRY MLOP: LDA 2,MCLK,2 ;NEXT QUEUE ELEMENT COM# 2,2,SNR ;END OF QUEUE? JMP NFND ;YES - NO RECEIVE FOR XMIT LDA 1,MCDEV,2 ;DEVICE # OF RECEIVE MOV 1,1,SZC ;HAS GENERAL RECEIVE BEEN FXOUND? JMP MGNOR ;YES - IGNORE ANY OTHERS MOV 1,1,SNR ;GENERAL RECEIVE? MOVO 2,3 ;YES - SAVE IT MGNOR: SUB# 0,1,SZR ;EXACT DEVICE MATCH? JMP MLOP ;NO - TRY ANOTHER MOV 2,3 ; EXACT MATCH NFND: LDA 2,CSP ; GET CSP LDA 2,.DCT,2 ; GET DCT ADDRESS k[MOV# 3,3,SNR ; WANT IT ? JMP INN ; BAG TRANSMITTEER STA 3,QPTR,2 ; SAVE ACTIVE REQUEST DONE: ADCZL 1,1 ; GENERATE A -2 ISZ UNFLG,2 ; SHOW TRANSMIT WANTED JMP INN2 INN: ADC 1,1 ; NOT WANTED INN2: ISZ RFLAG,2 ; NEW STATE OF RECEIVER LDA 0,QBAD,2 ;l BUFFER ADDRESS JMP @.MCTIO ; START IT .XDBS: XDOBS R1: DSZ UNFLG,2 ; IS THIS REQUEST WANTED ? JMP R1N0 ; DONT WANT IT ISZ RFLAG,2 ; UP STATE COUNT LDA 0,QQCNT,2 ; 0 LENGTH REQUEST ? MOV# 0,0,SNR ; WELL JMP PTH ; YEP, BAG REQUEST LDA 2,QPTR,28 ; GET READY FOR RECEIVE LDA 0,MCADR,2 ; USER ADDRESS LDA 1,MCCNT,2 ; CUSER COUNT NEG 1,1 ; 2'S COMP JMP @.MCTIO ; SET IT UP R1N0: SUB 0,0 ; SET RECEIVER STATE FLAG STA 0,RFLAG,2 STA 0,QPTR,2 LDA 3,CSP ; RESTORE THE BEUTIFUL STACK POINTER LDA Ӿ2,DBUF,3 ; DO IO TO CLEAR JSR @.XNC ; UNLOCK RECEIVER LDA 3,CSP LDA 2,.DCT,3 ; GET DCT RRSTR: LDA 0,QBAD,2 ; GET SYSTEM BUFFER AREA ADC 1,1 ; RECEIVE ONE WORD JMP @.MCTIO .XNC: XDICC R2: LDA 3,CSP LDA 2,DBUF,3 ; GET # OF WORDS RECEIVED JSR @.XDL_BC LDA 3,CSP LDA 2,.DCT,3 ; GET DCT SUBZ 1,1 ; RESET RECEIVER STATE STA 1,RFLAG,2 STA 1,UNFLG,2 STA 1,QQCNT,2 MOV# 0,0,SZR ; REQUEST COMPLETE ? JMP TOERR ; NO ENOUGH WORDS RECEIVED R2C: LDA 2,QPTR,2 LDA 3,MCTCB,2 ; GET TCB ADDRESS IN AC3 JMP @3.MER2 .XDBC: XDIBC .MCTIO: MCTIO .UP: UPQUE ;EOF ON TRANSMITTER ;RETURN 0 BYTES RECEIVED PTH: LDA 3,CSP LDA 2,DBUF,3 ; CLEAR DEVICE JSR @.XDBC LDA 3,CSP LDA 2,.DCT,3 LDA 3,QPTR,2 ; GET REQUEST LDA 3,MCTCB,3 ; TCB SUB 0,0 STA 0,TAC1,3 ; NO BYTES ?RECEIVED STA 0,RFLAG,2 STA 0,UNFLG,2 STA 0,QQCNT,2 JMP GT TOER: LDA 0,RFLAG,2 ; GET STATE OF RECEIVER MOVZR 0,0,SZR ; STATE 0 OR 1 ? JMP .+3 ; NO STA 0,RFLAG,2 ; RESET STATUS JMP RRSTR ; TRY AGAIN LDA 3,CSP LDA 2,DBUF,3 ; TRNASMITTER DOWN GETS7 # OF ; WORDS SENT JSR @.XDBC LDA 3,CSP LDA 2,.DCT,3 ; GET DCT SUBZ 1,1 ; RESET STATE STA 1,RFLAG,2 STA 1,UNFLG,2 TOERR: LDA 3,QPTR,2 ; GET ACTIVE ELEMENT LDA 1,MCCNT,3 ; GET REQUEST COUNT ADD 1,0 ; GET DIFFERENCE MOVZL 0,0 ; RETURN # OF BY?TES LDA 3,MCTCB,3 ; TO RETURN # BYTES RECEIVED STA 0,TAC1,3 GT: LDA 0,.ER ; EOF ERROR RETURN STA 0,TAC2,3 ; RETURN TO USER DSZ TPC,3 ; TAKE ERROR RETURN DSZ TPC,3 JMP R2C ; DO REST OF CLEAN UP .ER: EREOF .IFN MSW SMAP: STA 3,SMAPR ; SAVE RETURaN .IFN MNSW LDA 1,CLSTB ADDOR 1,1 INTDS DOA 1,MAP INTEN DIC 1,MAP LDA 0,C377 AND 0,1 .ENDC .IFN MN3SW LDA 1,CLSTB INTDS DOA 1,MAP1 INTEN DIA 1,MAP1 ; GET CURRENT LAST BLOCK MAPPING LDA 0,C377 .ENDC .IFN MBSW LDA 1,CLBLK .ENDC STA 1,SVLBK LDA 3,QPTR,2 ; GET ACTIVE UFT LDA 3,MCMSA,3 ; PROGRAM TABLE MAP + PMAP LDA 1,0,3 .IFE MBSW AND 0,1 LDA 3,CLSTB ADD 3,1 .ENDC .IFN MBSW STA 1,CLBLK .ENDC SMLB 1 LDA 3,CSP JMP @SMAPR C377: 377 SMAPR: 0 .ENDC MRTN: .IFN MSW LDA 1,SVLBK {.IFN MNSW LDA 0,CLSTB ADD 0,1 .ENDC .IFN MBSW STA 1,CLBLK .ENDC SMLB 1 .ENDC RTRN .IFN MSW SVLBK: 0 .ENDC .END ALMDB.SRB t RTITLE ALMDB .ENT QTDCB,ALMDC,ALINIT,MUXDC,CTADC .ENT KKMUX, RLMUX,LCMUX,MDMUX .ENT DLMUX,ALM?,O1MUX,O2MUX,O3MUX .ENT ALMD,QTYTB,QTB64,QTF64 .EXTN QTYIS,QTYDT,QTYST .EXTN ALMCK, MODINIT ;MODINIT BRINGS IN QTYMD.RB .NREL DLMUX= ALM ALM?= SKIP |;ITS AN ALM ;OUTPUT DATA AC0=DATA, AC3=LINE NUMBER O1MUX= DOB 0,ALM ;INDICATE TRANSMIT O2MUX= SUBZL 0,0 ;TURN ON TRANSMITTER O3MUX= DOC 0,ALM KKMUX= DOA 0,ALM ;KICK THE TRANSMITER RLMUX= DOC 0,ALM ;RELEASE THE TRANSMITER MDMUX= DOB 0,ALM ;MODEM OUTPUT LCMUX= DOC 0,ALM ;CHANGE LINE CHARACTERISTICS ALMD= . ; MULTIPLEXOR DEVICE CONTROL TABLE MUXDCT: CTADC: ;SHARES DEVICE CODES ALMDCT: 0 MKALM ;I/O MASK QTYIS ;INTERRUPT SERVICE ENTRY DCNI+DCCGN+DCLOC+DCTO+DCKEY+DCNAF+DCLAC+DCCRE+DCXON (S;A LITTLE BIT OF EVERYTHING DLMUX ;DEVICE CODE 0 ;EXECUTE IO INSTRUCTION QTYDT ;DISPATCH TABLE QTYST ;START ROUTINE (FOR PWRFL ONLY) .BLK 4 ;PAD SPACE .SPDCB QTDCB ALMDC -1 QTY QTY NLNS= 64. ;NUMBER OF LINES, ASSUMED 64. THROUGHOUT kUFTTB= 0 ;UFT TABLE ; 0 INDICATES UNOPENED ; 1B0 INDICATES FOREGROUND CHANNEL ; -1 INDICATES END OF TABLE ALMCH= NLNS+2+1 ;ALM LINE CHARACTERISTICS TABLE ; +2 FOR LINE 64 ; +1 FOR EOT QTYTB: .BLK NLNS ;UFT TABLE QTB64: .BLK( 1 ;FOR BACKGROUND LINE 64 QTF64: .BLK 1 ;FOR FOREGROUND LINE 64 -1 ;TERMINATES TABLE ; TABLE OF LINE CHARACTERISTICS. -1 IS REPLACED BY ; DEFAULT ENTRY (SPEED SET BY SYSGEN PLUS 1 STOP BIT, EVEN PARITY ; AND NO LOOPBACK) ** .NOLOC 1 ** .MACRO TAB3t ** K=I/10.+1 ** J=I-((K-1)*10.)+1 .EXTN ALM^K^J ALM^K^J % ** .NOLOC 0 ** I=0 .DO NLNS ;LINE CHAR. TABLE ** TAB 0 1 2 3 4 5 6 7 8 9 ** I= I+1 ** .ENDC .BLK 2 ;JUST IN CASE FOR LINE 64 ALINIT: STA 3,ALRTN ;SAVE THE RETURN (RSAVE IF INIT/RELEASE) lLDA 0,.SRMUX ;SET DEFAULT LINE CHARACTERISTICS LDA 1,.ALMCK ; BY ADDING IN DEFAULT LINE SPEED MOVS 1,1 MOVZR 1,1 ADD 1,0 STA 0,DALMCH ; SET UP TO LOOP TO SET LINE CHARACTERISTICS INTERRUPTS DISABLED SUB 2,2 ;AC2 <- LINE (FIRST IS ZERO) ALOOP: LDA 3,.QTYTB ;PICK UP LINE CHAR FOR THIS LINE ADD 2,3 LDA 1,ALMCH,3 COM# 1,1,SNR ;EVEN DEFAULT (A -1) LDA 1,DALMCH ; USE IT LDA 0,C.RDDSR ;CLEAR STATUS BITS AND 0,1 STA 1,ALMCH,3 LDA 0,MK.HWB ;GET ONLY HARDWARE BITS AND 1,0 ; JUST IN CASE ADDOR N0,0 ;FLIP BIT 0 TO SHOW LINE CHAR. MOVZL 2,3 ;SHOW RECEIVE DOAS 3,DLMUX SKPBZ DLMUX ;WAIT TILL RESET FINISHED JMP .-1 SUB 3,3 DOC 3,DLMUX ;TURN OFF RECEIVER DOC 0,DLMUX ;PUT OUT LINE CHARACTERISTICS SUBZL 3,3 DOC 3,DLMUX ;TURN ON RECEIVER MfOVOL 2,3 DOA 3,DLMUX ;PICK TRANSMIT LINE DOC 0,DLMUX ;PUT OUT LINE CHARACTERISTIC SUB 3,3 ;GET A ZERO DOC 3,DLMUX ;TURN OFF TRANSMIT LINE DOB 3,DLMUX ;CLEAR BREAK MODE STA 2,LINE ;SAVE LINE ACROSS CALL JSR @.MODINIT ;INIT MODEM LDA 2,LINE NIDOC DLMUX ;START THE DEVICE INC 2,2 ;BUMP THE LINE LDA 0,ALCNT ;CHECK FOR 64 LINES SEQ 0,2 JMP ALOOP ; ELSE LOOP ON JMP @ALRTN ALRTN: 0 .SRMUX: 100064+ALDTR+ALRTS ;CLOCK 0,1 STOP BITS, 7BITS/CHAR, ;EVEN PARITY, DTR AND RTS HIGH MK.HWB: 000777، ;HARDWARE BITS IN LINE CHARACTERISTICS .ALMCK: ALMCK DALMCH: 0 LINE: 0 C.RDDSR: -1-ALRD-ALDSR ALCNT: NLNS ;64 CHANNELS ALL TOLD .MODINIT: MODINIT .QTYTB: QTYTB .END ALM1D.SRB  RTITLE ALM1D .ENT QTDCB,ALM1DC,ALINIT,MUXDC .ENT KKMUX, RLMUX,LCMUX,MDMUX .ENT DLMUX,ALM?,O1MUX,O2MUX,O3MUX .ENT AL1D,QTYTB,QTB64,QTF64 .EXTN QTYIS,QTYDT,QTYST .EXTN ALMCK, MODINIT ;MODINIT BRINGS IN QTYMD.RB .NREL DLMUX= ALM1 ALM?= SKIP ;ITS{ AN ALM ;OUTPUT DATA AC0=DATA, AC3=LINE NUMBER O1MUX= DOB 0,ALM1 ;INDICATE TRANSMIT O2MUX= SUBZL 0,0 ;TURN ON TRANSMITTER O3MUX= DOC 0,ALM1 KKMUX= DOA 0,ALM1 ;KICK THE TRANSMITER RLMUX= DOC 0,ALM1 ;RELEASE THE TRANSMITER MDMUX= DOB 0,ALM1 ;MODEM OUTPUT LCMUX= DOC 0,ALM1 ;CHANGE LINE CHARACTERISTICS AL1D= . ; MULTIPLEXOR DEVICE CONTROL TABLE MUXDCT: ALM1DCT: 0 MKALM ;I/O MASK QTYIS ;INTERRUPT SERVICE ENTRY DCNI+DCCGN+DCLOC+DCTO+DCKEY+DCNAF+DCLAC+DCCRE+DCXON ;A LITTLE BIT OF EVERYTHING DLMUX ;DEVICE CODE 0 ;EXECUTE IO INSTRUCTION QTYDT ;DISPATCH TABLE QTYST ;START ROUTINE (FOR PWRFL ONLY) .BLK 4 ;PAD SPACE .SPDCB QTDCB ALM1DC -1 QTY QTY NLNS= 64. ;NUMBER OF LINES, ASSUMED 64. THROUGHOUT UFTTB= 0 ;UFT TABLE [; 0 INDICATES UNOPENED ; 1B0 INDICATES FOREGROUND CHANNEL ; -1 INDICATES END OF TABLE ALMCH= NLNS+2+1 ;ALM LINE CHARACTERISTICS TABLE ; +2 FOR LINE 64 ; +1 FOR EOT QTYTB: .BLK NLNS ;UFT TABLE QTB64: .BLK 1 ;FOR BACKGROUND LINE i64 QTF64: .BLK 1 ;FOR FOREGROUND LINE 64 -1 ;TERMINATES TABLE ; TABLE OF LINE CHARACTERISTICS. -1 IS REPLACED BY ; DEFAULT ENTRY (SPEED SET BY SYSGEN PLUS 1 STOP BIT, EVEN PARITY ; AND NO LOOPBACK) ** .NOLOC 1 ** .MACRO TAB ** K=I/10.+1 ** J=I-((K-X1)*10.)+1 .EXTN ALM^K^J ALM^K^J % ** .NOLOC 0 ** I=0 .DO NLNS ;LINE CHAR. TABLE ** TAB 0 1 2 3 4 5 6 7 8 9 ** I= I+1 ** .ENDC .BLK 2 ;JUST IN CASE FOR LINE 64 ALINIT: STA 3,ALRTN ;SAVE THE RETURN (RSAVE IF INIT/RELEASE) LDA 0,.SRMUX ;SET DEFAUL>T LINE CHARACTERISTICS LDA 1,.ALMCK ; BY ADDING IN DEFAULT LINE SPEED MOVS 1,1 MOVZR 1,1 ADD 1,0 STA 0,DALMCH ; SET UP TO LOOP TO SET LINE CHARACTERISTICS INTERRUPTS DISABLED SUB 2,2 ;AC2 <- LINE (FIRST IS ZERO) ALOOP: LDA 3,.QTYTB ;PICK UP LINE CHAR FOR THIS LINE ADD 2,3 LDA 1,ALMCH,3 COM# 1,1,SNR ;EVEN DEFAULT (A -1) LDA 1,DALMCH ; USE IT LDA 0,C.RDDSR ;CLEAR STATUS BITS AND 0,1 STA 1,ALMCH,3 LDA 0,MK.HWB ;GET ONLY HARDWARE BITS AND 1,0 ; JUST IN CASE ADDOR 0,0 ;FLIP BIT 0 TO SHOW LINE CHAR. MOVZL 2,3 ;SHOW RECEIVE DOAS 3,DLMUX SKPBZ DLMUX ;WAIT TILL RESET FINISHED JMP .-1 SUB 3,3 DOC 3,DLMUX ;TURN OFF RECEIVER DOC 0,DLMUX ;PUT OUT LINE CHARACTERISTICS SUBZL 3,3 DOC 3,DLMUX ;TURN ON RECEIVER MOVOL 2,3 DOA 3,DLMUX ;PICK TRANSMIT LINE DOC 0,DLMUX ;PUT OUT LINE CHARACTERISTIC SUB 3,3 ;GET A ZERO DOC 3,DLMUX ;TURN OFF TRANSMIT LINE DOB 3,DLMUX ;CLEAR BREAK MODE STA 2,LINE ;SAVE LINE ACROSS CALL JSR @.MODINIT ;INIT MODEM LDA 2,LINE NIOC DLMUX ;START THE DEV_ICE INC 2,2 ;BUMP THE LINE LDA 0,ALCNT ;CHECK FOR 64 LINES SEQ 0,2 JMP ALOOP ; ELSE LOOP ON JMP @ALRTN ALRTN: 0 .SRMUX: 100064+ALDTR+ALRTS ;CLOCK 0,1 STOP BITS, 7BITS/CHAR, ;EVEN PARITY, DTR AND RTS HIGH MK.HWB: 000777 ;HARDWARE BITS IN LINEu CHARACTERISTICS .ALMCK: ALMCK DALMCH: 0 LINE: 0 C.RDDSR: -1-ALRD-ALDSR ALCNT: NLNS ;64 CHANNELS ALL TOLD .MODINIT: MODINIT .QTYTB: QTYTB .END ALMSPD.SRB  g .TITLE ALMSPD .RB ALMSPD.RB ; ; THIS MODULE DEFINES THE LINE CHARACTERISTICS OF EACH ; LINE OF THE ALM. IF A LINE IS NOT DEFINED IN THIS MODULE ; OR ITS CHARACTERISTICS ARE SET AT DEFAULT THEN IT HAS ; THE FOLLOWING CHARACTERISTICS ; ; 1) CLOCK FREQUEN!UCY AS SET IN SYSGEN ; 2) 1 STOP BIT ; 3) 7 BITS PER CHARACTER ; 4) EVEN PARITY ; 5) NO LOOPBACK ; 6) DTR+RTS RAISED ON INITIALIZATION ; ; THESE CHARACTERISTICS CAN BE DEFINED FOR ANY LINE ; BY INCLUDING THE LINE ; ; LNDEF XX,DEFAULT ; ; INTO THIS MODULE WAHERE XX IS THE TWO DIGIT DECIMAL NUMBER ; FOR THE LINE TO BE SET. IF THE USER WHISHES TO DEFINE ; THE LINE CHARACTERISTICS THEN INCLUDE A LINE OF THE ; FORM ; ; LNDEF XX,SPD,STOP,BITS,PAR,LOOP ; OR ; LNDEF XX,SPD,STOP,BITS,PAR,LOOP,DTR,RTS ; ; WHERE XX IS THE 2 DIGIT DECIMAL LINE NUMBER, SPD IS THE ; CLOCK FREQUENCY (MAY BE 0,1,2, OR 3), STOP IS THE NUMBER ; OF STOP BITS PER CHARACTER (MAY BE 1 OR 2), BITS IS THE ; NUMBER OF BITS PER CHARACTER (THIS DOES NOT INCLUDE THE ; PARITY BIT, MAY BE 5,6,7, OR 8), ߻ PAR DEFINES WHETHER ; YOU WISH NO PARITY, EVEN PARITY, OR ODD PARITY (MAY BE ; NO,EVEN, OR ODD), AND LOOP TELLS WHETHER YOU WANT ; LOOP BACK ENABLED (MAY BE LOOPBACK OR NOLOOPBACK). ; DTR SPECIFIES THE STATE OF DATA TERMINAL READY ON ; INITIALIZATION, RTەS SPECIFIES THE STATE OF REQUEST TO ; SEND. DEFAULT STATE OF THESE SIGNALS IF ARGUMENT ; IS NOT SPECIFIED IS HIGH. (ARGUMENT IS EITHER ; DTRHIGH OR DTRLOW, RTSHIGH OR RTSLOW) ; ; FOR EXAMPLE TO SET LINE 3 TO HAVE CLOCK FREQUENCY 1, ; 2 STOP BITS, 7 BITS PER CHARACTER, EVEN PARITY, AND ; NO LOOPBACK THE FOLLOWING LINE IS NEEDED. BOTH DATA TERMINAL ; READY AND REQUEST TO SEND WILL BE INITIALIZED HIGH. ; ; LNDEF 03,1,2,7,EVEN,NOLOOPBACK ; ** .NOLOC 1 ** .MACRO LNDEF ** .NOLOC 1 ** .IFN (.ARGCT<2)!(^2.+0>63.) Ҩ**: ILLEGAL DEFAULT LINE DEFINITION CALL ** .ENDC ENDIT ** .ENT ALM^1 ** ALM^1 =DEFAULT ** .IFN (.ARGCT==2)&(^2==DEFAULT) ** .NOLOC 0 ; LINE ^1 IS SET TO RUN AT CLOCK FREQUENCY SET IN ; SYSGEN WITH 1 STOP BIT, 7 BITS PER CHARACTER, ; EVEN PARITY AND NO LO^OP BACK. BOTH DATA TERMINAL ; READY AND REQUEST TO SEND WILL BE INITIALIZED HIGH. ** .NOLOC 1 ** .ENDC ENDIT ** .IFN (.ARGCT<6)+(.ARGCT>10) **: ILLEGAL NUMBER OF ARGUMENTS FOR LINE DEFINITION ** .ENDC ENDIT ** .IFE ^2<4 **: ILLEGAL CLOCK FREQUENCY - LEGALd IS 0,1,2, OR 3 ** .ENDC ENDIT ** .IFE (^3<3)&(^3<>0) **: ILLEGAL NUMBER OF STOP BITS - LEGAL IS 1 OR 2 ** .ENDC ENDIT ** .IFE (^4.>4.)&(^4.<9.) **: ILLEGAL NUMBER OF BITS PER CHARACTER - LEGAL IS **: 5,6,7, OR 8 (DATA BITS ONLY, DOES NOT INCLUDE PARITY) ** .ENDC ENDIT ** .IFE ^5<4 **: ILLEGAL PARITY SPECIFICATION - LEGAL IS NO, EVEN, ODD ** .ENDC ENDIT ** .IFE ^6<2 **: ILLEGAL LOOPBACK SPECIFICATION - LEGAL IS LOOPBACK OR NOLOOPBACK ** .ENDC ENDIT ** DTR=1 ;DEFAULT ** RTS=1 ;DEFAULT ** .IFN .ARGCT>6 ** .IFE ^7<2 **:ILLEGAL DTR SPECIFICATION - LEGAL IS DTRHIGH OR DTRLOW ** .ENDC ENDIT ** DTR=^7 ** .ENDC ** .IFN .ARGCT>7 ** .IFE ^8<2 **:ILLEGAL RTS SPECIFICATION - LEGAL IS RTSHIGH OR RTSLOW ** .ENDC ENDIT ** RTS=^8 ** .ENDC ** ALM^1 =(RTS*2000)+(DTR*1000)+A(^2*200)+(^3-1*40)+(^4.-5.*10)+(^5*2)+^6 ** .NOLOC 0 ; LINE ^1 IS SET TO OPERATE WITH CLOCK FREQUENCY ^2, ; ^3 STOP BITS, ^4 BITS PER CHARACTER (NOT INCLUDING PARITY), ; ^5 PARITY, AND WITH ^6 ** .NOCON 1 ** .IFN DTR ; DATA TERMINAL READY WILL BE INITIALIZ ED HIGH AND ** .ENDC RTSM ; DATA TERMINAL READY WILL BE INITIALIZED LOW AND **[RTSM] .IFN RTS ; REQUEST TO SEND WILL BE INITIALIZED HIGH. ** .ENDC ENDM ; REQUEST TO SEND WILL BE INITIALIZED LOW. **[ENDM] .NOLOC 1 ** .NOCON 0 **[ENDIT] .NOLOC 0 % ** .NOLOC 0 ** DEFAULT =-1 ** NO =0 ** ODD =1 ** EVEN =2 ** LOOPBACK=1 ** NOLOOPBA=0 ** DTRHIGH=1 ** DTRLOW=0 ** RTSHIGH=1 ** RTSLOW=0 LNDEF 00,DEFAULT LNDEF 01,DEFAULT LNDEF 02,DEFAULT LNDEF 03,DEFAULT LNDEF 04,DEFAULT LNDEF 05,DEFAULT LNDEF 06,DEFAULT * LNDEF 07,DEFAULT LNDEF 08,DEFAULT LNDEF 09,DEFAULT LNDEF 10,DEFAULT LNDEF 11,DEFAULT LNDEF 12,DEFAULT LNDEF 13,DEFAULT LNDEF 14,DEFAULT LNDEF 15,DEFAULT LNDEF 16,DEFAULT LNDEF 17,DEFAULT LNDEF 18,DEFAULT LNDEF 19,DEFAULT LNDEF 20,DEFAULT LNDEF 21,DEFAULT LNDEF 22,DEFAULT LNDEF 23,DEFAULT LNDEF 24,DEFAULT LNDEF 25,DEFAULT LNDEF 26,DEFAULT LNDEF 27,DEFAULT LNDEF 28,DEFAULT LNDEF 29,DEFAULT LNDEF 30,DEFAULT LNDEF 31,DEFAULT LNDEF 32,DEFAULT LNDEF 33,DEFAULT LNDEF 34,DEFAULT LNDEF 3R5,DEFAULT LNDEF 36,DEFAULT LNDEF 37,DEFAULT LNDEF 38,DEFAULT LNDEF 39,DEFAULT LNDEF 40,DEFAULT LNDEF 41,DEFAULT LNDEF 42,DEFAULT LNDEF 43,DEFAULT LNDEF 44,DEFAULT LNDEF 45,DEFAULT LNDEF 46,DEFAULT LNDEF 47,DEFAULT LNDEF 48,DEFAULT LNDEF 49,DE\FAULT LNDEF 50,DEFAULT LNDEF 51,DEFAULT LNDEF 52,DEFAULT LNDEF 53,DEFAULT LNDEF 54,DEFAULT LNDEF 55,DEFAULT LNDEF 56,DEFAULT LNDEF 57,DEFAULT LNDEF 58,DEFAULT LNDEF 59,DEFAULT LNDEF 60,DEFAULT LNDEF 61,DEFAULT LNDEF 62,DEFAULT LNDEF 63,DEFAUL ݨT .END QTYDB.SRB 8 RTITLE QTYDB QTDB .ENT ALINIT .ENT QTDCB,QTYDC,MUXDC .ENT KKMUX,RLMUX,LCMUX,MDMUX .ENT DLMUX,ALM?,O1MUX,O2MUX,O3MUX .ENT QTYD, QTYTB, QTB64, QTF64 .EXTN QTYIS,QTYDT,QTYST .NREL DLMUX= QTY ALM?= NOP ;NOT AN ALM ;OUTPUT DATA AC0=DATA, AC1=LINE NUMBER O1MUX= MOVS 1,1 O2MUX= ADD 1,0 O3MUX= DOA 0,QTY KKMUX= NOP ;NO-OP MUX KICKER RLMUX= NOP ;NO-OP MUX REALEASE LCMUX= NOP ;NO-OP MUX LINE CARACATERISTICS MDMUX= NOP ;NO-OP MUX MODEM OUTPUT MODEM: MODINIT: ALINIT: JMP 0,3 ;DEFAULT ALM MO{DEM AND INITALIZER QTYD= . ; MULTIPLEXOR DEVICE CONTROL TABLE MUXDCT: QTYDCT: 0 MKQTY ;I/O MASK QTYIS ;INTERRUPT SERVICE ENTRY DCNI+DCCGN+DCLOC+DCTO+DCKEY+DCNAF+DCLAC+DCCRE+DCXON+DCPCK ;A LITTLE BIT OF EVERYTHING DLMUX ;DEVICE CODE 0 ;EXECUTE IO INSTRUCTION QTYDT ;DISPATCH TABLE QTYST ;START ROUTINE (FOR PWRFL ONLY) .BLK 4 ;PAD SPACE .SPDCB QTDCB QTYDC -1 QTY QTY NLNS= 64. ;NUMBER OF LINES, ASSUMED 64. THROUGHOUT UFTTB= 0 ;UFT TABLE ; 0 INDICATES UNOPENED ; 1B0 INDICATES FOREGROUND CHANNEL ; -1 INDICATES END OF TABLE ALMCH= NLNS+2+1 ;ALM LINE CHARACTERISTICS TABLE ; +2 FOR LINE 64 ; +1 FOR EOT QTYTB: .BLK NLNS ;UFT TABLE QTB64: .BLK 1 ;UFT FOR BACKGROUND LINE 64 QTF64: .BLK 1 ;UFT FOR FOHVREGROUND LINE 64 -1 ;TERMINATES TABLE ;NO ALM LINE TABLE .END QTY1D.SRB 9 RTITLE QTY1D .ENT ALINIT .ENT QTDCB,QTY1DC,MUXDC .ENT KKMUX,RLMUX,LCMUX,MDMUX .ENT DLMUX,ALM?,O1MUX,O2MUX,O3MUX .ENT QT1D, QTYTB, QTB64, QTF64 .EXTN QTYIS,QTYDT,QTYST .NREL DLMUX= QTY1 ALM?= NOP ;NOT AN ALM ;OUTPUT DATA AC0=DATA, AC1=LINNE NUMBER O1MUX= MOVS 1,1 O2MUX= ADD 1,0 O3MUX= DOA 0,QTY1 KKMUX= NOP ;NO-OP MUX KICKER RLMUX= NOP ;NO-OP MUX REALEASE LCMUX= NOP ;NO-OP MUX LINE CARACATERISTICS MDMUX= NOP ;NO-OP MUX MODEM OUTPUT MODEM: MODINIT: ALINIT: JMP 0,3 ;DEFAULT ALM MODE"M AND INITALIZER QT1D= . ; MULTIPLEXOR DEVICE CONTROL TABLE MUXDCT: QTY1DCT: 0 MKQTY ;I/O MASK QTYIS ;INTERRUPT SERVICE ENTRY DCNI+DCCGN+DCLOC+DCTO+DCKEY+DCNAF+DCLAC+DCCRE+DCXON+DCPCK ;A LITTLE BIT OF EVERYTHING DLMUX ;DEVICE CODE 0 ;EXEcCUTE IO INSTRUCTION QTYDT ;DISPATCH TABLE QTYST ;START ROUTINE (FOR PWRFL ONLY) .BLK 4 ;PAD SPACE .SPDCB QTDCB QTY1DC -1 QTY QTY NLNS= 64. ;NUMBER OF LINES, ASSUMED 64. THROUGHOUT UFTTB= 0 ;UFT TABLE ; 0 INDICATES UNOPENED ; 1B0 INDICATES FOREGROUND CHANNEL ; -1 INDICATES END OF TABLE ALMCH= NLNS+2+1 ;ALM LINE CHARACTERISTICS TABLE ; +2 FOR LINE 64 ; +1 FOR EOT QTYTB: .BLK NLNS ;UFT TABLE QTB64: .BLK 1 ;UFT FOR BACKGROUND LINE 64 QTF64: .BLK 1 ;UFT FOR FOHVREGROUND LINE 64 -1 ;TERMINATES TABLE ;NO ALM LINE TABLE .END QTYDR.SRB :I ; 4060 DATA COMMUNICATIONS MULTIPLEXOR RTITLE QTYDR ; WORDS OF UFT IN USE BY SYSTEM FOR QTY ; UFTUN, UFTCH,UFTDR, UFTDC,UFTST,UFTAT,UFTDL ; THE FOLLOWING ARE OFFSETS INTO THE UFT FOR ; STORAGE WORDS USED BY THIS PROGRAM ;**** NOTE: ANY CHANGE# SHOULD BE MADE IN ;**** QTYDR,QTYMD,SOV19,QTYOV,SOV5,ALMDB,ALM1D QTRXP=UFTFN ;RECEIVE BYTE POINTER ; 0 NO READ QTORG=UFTFN+1 ;INITIAL RECEIVE BYTE POINTER QTTXP=UFTFN+2 ;TRANSMIT BYTE POINTER ; 0 NO WRITE QTRXT=UFTFN+3 ;READ CALLER TCB 6 ; 1B0 + ERROR CODE QTXON=UFTFN+4 ;XON/XOFF FOR TELETYPE READER ; -1 DON'T PUT OUT ANYTHING QTTBL=UFTEX ;ADDR OF TABLE ENTRY QTTXT=UFCA1 ;TRANSMIT TCB QTRXS=UFTBN ;READ SEQUENTIAL LIMIT QTTXS=UFTBP ;WRITE SEQUENTIAL LIMIT ;READ BUFFGER QRSRT= UFTCA ;START OF BUFFER QREND= UFTCB ;END OF BUFFER QRGET= UFEA1 ;GET DATA POINTER QRSND= UFTEA ;SEND DATA POINTER ;WRITE BUFFER QWSRT= UFNA1 ;START OF BUFFER QWEND= UFTNA ;END OF BUFFER QWGET= UFLA1 ;GET DATA POINTER QWSND= UFT&LA ;SEND DATA POINTER ;HOLD WORDS QECHO= UFFA1 ;HOLD FOR ECHOING QXPND= UFTFA ;HOLD FOR EXPANDING ; -2 INDICATES WRITE IN PROGRESS QWCOL= UFTCN ;COLUMN COUNTER FOR TABBING ; 1B0 INDICATES WRITER BUSY NLNS= 64. ;NUMBER OF LINES, ASSUME.D 64. THROUGHOUT UFTTB= 0 ;UFT TABLE ; 0 INDICATES UNOPENED ; 1B0 INDICATES FOREGROUND CHANNEL ; -1 INDICATES END OF TABLE ALMCH= NLNS+2+1 ;ALM LINE CHARACTERISTICS TABLE ; +2 FOR LINE 64 ; +1 FOR TERMINATOR .ENT QTYIS,QTY;DT,QTYST .ENT QTYQ, QTRZAP,QTWZAP .ENT QKICK,SQT64,QTYNO .ENT RGET, WSEND .ENT TGET, TSEND .ENT ALMRI ;BREAK POINT HERE SHOWS ; ALM READ INTERRUPTS ; AC0= CHAR, AC1= LINE, AC3= STATUS ;ALMRI-6 SHOWS TRANSMIT INTERRUPTS ; AC1= LINE .E6ZNT PUT64 ;PUT WORD TO LINE 64 READS .ENT INTCH ;FIRST OF 2 INTERRUPT CHARS .EXTN QTYTB ;TABLES FOR DEV. CHAR., UFT, LINE.CHAR. .IFN MSW .EXTN MBLK .EXTN MPT1 ;FOREGROUND PT .IFG MSW-MBSW .EXTD CLSTB .ENDC .IFN MBSW .EXTD CLBLK .ENDC .EXTN MPT2 ;BACKGROUND PT .ENDC ;DEVICE SPECIFIC EXTERNALS .EXTN MUXDC, ALM?, QTB64,QTF64, MODEM .EXTN KKMUX, RLMUX, MODSET .EXTN UNPEND .EXTN DLMUX ;DEVICE LINK .EXTN O1MUX,O2MUX,O3MUX ;CHAR OUTPUT .EXTN DISMIS,INTLV .EXTN RESCH .EXTN QTOPN .EXSTN QTCLS .EXTN QTRDS .EXTN QTRDL .EXTN QTWRS .EXTN QTWRL .EXTN QTYI1, QTYI2 .EXTN ALINIT, QTDCB .NREL ; DISPATCH TABLE QTYDT: QTOPN ;OPEN QTCLS ;CLOSE QTRDS ;READ SEQUENTIAL QTRDL ;READ LINE -1 ;READ RANDOM QTWRS ;WRITE SEQUENTIAL QTWRL ;WRITE LINE -1 ;WRITE RANDOM QTOPN ;OPEN FOR APPENDING QTOPN ;READ ONLY OPEN QTOPN ;EXCLUSIVE OPEN -1 ;TRANSPARENT OPEN .DIA= DIA 0,0 DIA.C= DIAC 0,0 .DIB= DIB 0,0 .DICC3= DICC 3,0 .DOB= DOB 0,0 .NIOC= NIOC 0 .IFN MSW .MP'SV: MPSV .ENDC C77B7: 77B7 .IFN MNSW TP31: 1B0+37B7 .ENDC .MODEM: MODEM .QTYTB: QTYTB ; ENTER HERE ON INTERRUPT QTYIS: .IFN MSW ;SAVE MAP STATE .IFN MNSW LDA 1,TP31 INTDS ;IN CASE MAP GETS USED DOA 1,MAP ;LOAD MODE REG INTEN DIC 1,MAP ;RzEAD IT LDA 3,RBYTE ;MASK OFF ALL BUT PHYS PG NUM AND 3,1 .ENDC .IFN MN3SW LDA 1,CLSTB INTDS ;IN CASE MAP GETS USED DOA 1,MAP1 ; READ LAST BLOCK MAPPING INTEN DIA 1,MAP1 .ENDC .IFN MBSW LDA 1,CLBLK ;LAST .ENDC STA 1,@.MPSV ;SAVE CURRENT P G 31 MAP .ENDC RQTYIS: ALM? ;JMP .+1 (QTY) OR .+2 (ALM) JMP GQTY ; GET QTY INTERRUPT ;READ ALM LINE, STATUS AND DATA .GADD DLMUX,.DIA ;AC1 <- LINE MOVZR 0,1,SZC ; CARRY SET IF TRANS .GADD DLMUX,.NIOC ; CLEAR TRANSMIT MOV# 1,1,SZC JMP TRANS ; PROCESS TRANSMT .GADD DLMUX,.DIB ;AC0 <- CHARACTER IF THERE LDA 3,RBYTE ;MASK AN D STORE THE CHAR. AND 3,0 STA 0,RCHAR .GADD DLMUX,.DICC3 ;GET STATUS INTO AC3 ALMRI: MOV# 3,3,SNR JMP REC ; ALL OK-- IT WAS A READ MOV 3,0 ;AC0 <- STATUS WUORD (ERROR OR MODEM) MOVR# 0,0,SNC ;SKIP IF MODEM JMP HANER ; ELSE HANDLE ERROR ;MODEM INTERRUPT ;AC0= INTERRUPT, AC1= LINE, ; AC2 <- QTY TABLE ENTRY LDA 2,.QTYTB ADD 1,2 ;INDEXED BY LINE NUMBER JSR @.MODEM ;CALL THE MODEM PROCESSOR JMP @.QTRTN ;AND RETURN FROM INTERRUPT HANER: ;READ ERROR HANDLER, AC0= STATUS WORD ; , AC1= LINE JSR GETUFT JMP @.CHR64 ;LINE UNOPENED, REPORT CHARACTER MOVR 0,1 ;AC1 <- ERROR STATUS SHIFTED RIGHT LDA 0,.EROVR ;REPORT ALL OVER RUN ERRORS MOVRw 1,1,SZC ; 1B14 OVERRUN ERROR JMP RPERR MOVR 1,1,SZC ; 1B13 PARITY ERROR LDA 0,.ERPAR MOVR# 1,1,SZC ; 1B12 FRAMING ERROR LDA 0,.ERFRM RPERR: LDA 3,QTRXP,2 ;SEE IF READ IS WAITING MOV# 3,3,SNR JMP REMERR ; NO-- REMEMBER THE ERROR JSR @.@QTRZAP ;ERROR RETURN FOR TCB JMP @.QTRTN ; AND RETURN REMERR: LDA 1,QRSRT,2 ;RESET THE READ BUFFER STA 1,QRSND,2 LDA 1,QREND,2 STA 1,QRGET,2 ADDOR 0,0 ;FLAG ERROR STA 0,QTRXT,2 ;SAVEERROR JMP @.QTRTN ;READ QTY LINE AND CHARACTER GQTY: .GADD DLMUX, DIA.C LDA 1,C77B7 ;AC1 <- LINE ANDS 0,1 MOVL# 0,0,SNC ;CLEAR IF TRANSMIT INT. .GADD DLMUX,.DOB MOVL# 0,0,SNC ;TEST INT JMP TRANS ; TRANSMIT LDA 3,RBYTE ;AC0 <- CHARACTER AND 3,0 STA 0,RCHAR ;SAVE CHAR JMP REC ;RECEIVE CHAR RBYTE: 377 .EROVR: EROVR .ERPAR: ERPAR .ERFRM: ERFRM .NLNS: NLNS .QTRZAP: QTRZAP INTCH: ;ADDR OF INTERRUPT CHARS (-1 IS NULL) CTRLA: QTYI1 ; CTRLC: QTYI2 ; .DCKEY: DCKEY .DCNI: DCNI .TSEND: TSEND .RSEND: RSEND QTYNO: 0 ;HAND SHAKE FOR QTYOV RACING .CHR64: CHR64 C1.77: 177 TRANS: ;TRANSMIT RECEIVED, AC1= LINE JSR GETUFT JMP @.QTRTN ;UNOPENED LINE, DROP JSR QTXMT ;SEND OUT NEXT CHARACTER JMP @.QTRTN ; AND RETURN ;GET UFT FOR LINE IN AC1 ; IF LINE TOO LARGE RETURNS TO QTRTN GETUFT: LDA 2,C1.77 ;MASK LINE DOWN TO SIZE AND 2,1 LDA 2,.NLNS ;CHECK AGAINST MAX LINE USLT 1,2 JMP @.QTRTN ; OUT OF BOUNDS DROP LDA 2,.QTYTB ;GET UFT TABLE ADD 1,2 ;INDEX LDA 2,UFTTB,2 MOVZL# 2,2,SNR ;SKIP IF UFT DEFINED JMP 0,3 ; TAKE ERROR RETURN JMP 1,3 ;TAKE NORMAL RETURN ; SERVICE RECEIVER RCHAR, AC0= CHAR ; REC: JSR GETUFT ;AC2<- UFT JMP @.CHR64 ; NOT THERE, LET LINE 64 DO IT ;TRAP CONSOLE INTERRUPTS LDA 1,C177 ;CHECK FOR ^A OR ^C AND 0,1 LDA 3,CTRLA SUB# 1,3,SNR ; JMP IQT64 ; ^A-- CHECK IF ALLOWED LDA 3,CTRLC SUB# 1,3,SZR JMP QSCON ; NOT ^C IQT64: LDA 1,UFTCH,2 ;CHECK DCNI LDA 3,.DCNI ; AND# 1,3,SZR JMP QSCON ; IT'S SET MOVE ON LDA 0,.ERINT ;KILL ANY READS WITH AN ERROR JSR @.QTRZAP LDA 0,RCHAR ;RESsTORE CHAR TO AC0 ;00B1 FOR INTERRUPT CHARACTER LDA 1,UFTUN,2 ;AC1 <- LINE NUMBER JMP INT64 ;DO RECEIVE ON LINE 64 ;GIVE CHAR TO TASK, BUFFER, OR DROP QSCON: LDA 1,QECHO,2 ;CHECK FOR ECHO PENDING COM# 1,1,SZR ; (DROPS CHARS WHEN CLOSING) JMP @.QTRTN ; YES-- DROP THE CHARACTER LDA 1,QTRXP,2 ;GET INPUT BYTE POINTER LDA 3,QTYNO ;SHAKE HANDS SUB# 2,3,SZR ; MOV# 1,1,SNR ;CHECK FOR TASK WAITING JMP RHOLD ;TRY TO BUFFER THE BEAST JSR @.TSEND ;GIVE THE CHARACTER IN AC0 TO A TASK JMP ECHO ; TASK DONE, CONTINUE JMP ECHO ;ECHO THE CHARACTER RHOLD: JSR @.RSEND ;SEND TO READ BUFFER JMP @.QTRTN ; BUFFER FULL DROP THE CHARACTER ;ECHO CHARACTER ECHO: LDA 0,QTRXS,2 ;AC0 <- READ SEQUENTIAL INDICATOR LDA 1,UFTCH,2 ;GET CHARACTERISTICS LDA 3,.DCKEY ; MOV# 0,0,SNR ;SKIP IF READ SEQUENTION AND# 3,1,SNR ;SKIP IF ECHOING JMP @.QTRTN ; ELSE ALL DONE LDA 0,RCHAR ;AC0 <- CHARACTER ELOOP: JSR @.ESEND ;GIVE TO WRITE BUFFER WITH EXPANSION JMP EHOLD ; BUFFER FULL HOLD TILL LATER v COM# 0,0,SZR ;SKIP IF EXPANSION DONE JMP ELOOP ; LOOP ON MACDUFF EHOLD: STA 0,QECHO,2 ;B UPDATE THE ECHO JSR QKICK ; YES-- KICK HIM JMP @.QTRTN ; N0-- HE CAN TAKE CARE OF HIMSELF .QTRTN: QTRTN RCHAR: 0 ; SERVICE TRANSMITTER ; AC2=UFT, INTERRUPT CLEARED ; QKICK FOR WAKING UP IF NEEDED QKICK: LDA 0,QWCOL,2 ;IF HE NEEDS WAITING MOVL# 0,0,SZC JMP 0,3 ; BUT THEN HE DOESN'T ADDOR 0,0 ;INDICATE WRITER IS RUNNING STA 0,QWCOL,2 ;FOR STARTING AFTER POWER FAIL QTSRT: LDA 1,UFTUN,2 ;AC1S <- LINE NUMBER MOVOL 1,0 ;SELECT TRANSMIT LINE IF ALM KKMUX ;SEND OUT NEXT CHARACTER QTXMT: STA 3,QBRTN ;SAVE THE RETURN LDA 0,QTXON,2 ;CHECK FOR XON/XOFF ADC 1,1 ;CLEAR IT ANYWAY STA 1,QTXON,2 COM# 0,0,SZR JMP OUTCHAR ; YES-- SEND CHAR OUT GETCHAR: JSR @.WGET ;GET NEXT CHARACTER JMP NOCHAR ; BUFFER EMPTY OUTCHR: LDA 1,UFTUN,2 ;GET LINE ADDRESS O1MUX ;SET UP LINE O2MUX ; O3MUX ;OUTPUT CHAR ;GET NEXT CHAR FOR BUFFER LDA 0,QECHO,2 ;TEST FOR ECHOING ADDOR# 0,0,SZR ;SKIP IF CLOSING (1B0) COM# 0,0,SNR ;SKIP IF ECHOING JMP TWAIT ; NO--SEE IF DATA FROM TASK JSR @.ESEND ;SEND TO WRITE BUFFER WITH EXPANSION JMP .+1 ; BUFFER FULL (SHOULDN'T HAPPEN) STA 0,QECHO,2 ;UPDATE THE ECHO WORD JMP @QBRTN ;RETURN ;TURN OFF TRANSMITION NOCHAR: SUB 0,0 ;TURN OFF ALM LINE RLMUX ALM? JMP NOTALM LDA 3,QTTBL,2 ;AC1 <- LINE CHARACTERISTICS WORD LDA 1,ALMCH,3 JSR @.MODSET ;RESET THE MODEM STATE. THIS IS NEEDED ;BECAUSE CAN'T CHANGE MODEM BY .WRL LINE ;64 WHILE WRI,TING CHARACTERS NOTALM: LDA 1,QWCOL,2 ;FREE UP THE HANDLER MOVL# 1,1,SZC ; JUST IN CASE ADDOR 1,1 ; STA 1,QWCOL,2 ; LDA 1,QECHO,2 ;CHECK FOR CLOSING ADDOR# 1,1,SZR ; JMP @QBRTN ; NO--JUST RETURN MOV 2,0 ;UFT IS THE KEY JSR @.UNPEND ;UNPENDK THE POOR FELLOW WHO IS WAITING JMP @QBRTN ;AND RETURN ;GET CHAR FROM TASK TWAIT: LDA 0,QXPND,2 ;CHECK FOR EXPANSION IN PROGRESS COMZR# 0,0,SZR ; JMP WBUFF ; YES- SEND TO WRITE BUFFER WITH EXPANSION LDA 1,QTTXP,2 ;CHECK IF WAITING TASK COM# 40,0,SNR ;SHAKE HANDS MOV# 1,1,SNR ; JMP @QBRTN ;NOPE- RETURN JSR @.TGET ;GET THE DATA JMP .+1 ; TASK IS DONE, CONTINUE WBUFF: JSR WSEND ;SEND TO WRITE BUFFER JMP .+1 ; BUFFER FULL (SHOULDN'T HAPPEN) STA 0,QXPND,2 ;UPDATE THE EXPANDER WORD % JMP @QBRTN ;AND RETURN C177: 177 .ESEND: ESEND .UNPEND: UNPEND QBRTN: .BLK 1 .WGET: WGET .TGET: TGET .MODSET: MODSET .ERINT: ERINT .IFN MSW .MAPTCB: MAPTCB .ENDC .QTB64: QTB64 .QTF64: QTF64 .IFE BSW!MBSW .MACRO L.DB JSR @.LDB % .MACRO S.TB JSRnc @.STB % .ENDC .IFN BSW!MBSW .MACRO L.DB LDB ^1,^2 % .MACRO S.TB STB ^1,^2 % .ENDC ; RECEIVE FROM UNOPENED LINE ; RCHAR= DATA ; 00B1 CONSOLE INTERRUPT ; 10B1 READ CHAR ; 11B1 RING INTERUPT (SEE QTYMD.SR) ; AC1= LINE CHR64: ]LDA 0,RCHAR ;PICK UP CHARACTER ADDOR 0,0 ;FLAG CHARACTER LDA 2,@.QTB64 ;SEND TO BACKGROUND JSR PUT64 LDA 0,RCHAR ;SEND TO FOREGROUND LDA 2,@.QTF64 JSR XXX64 JMP @.QTRTN ;AND RETURN ;INTERRUPT CHAR FROM OPEN LINE INT64: MOVL 2,2,SNC ;SEND TO GROUND OF CHANNEL LDA 2,@.QTB64 MOV# 2,2,SZC LDA 2,@.QTF64 JSR PUT64 JMP @.QTRTN ;AND RETURN RTN64: 0 ;RETURN LOC ;ENTRY PUT64-- PUT CHAR TO LINE 64 READS ; AC0 <- WORD WITH FLAG BITS ; AC1 <- LINE NUMBER ; AC2 <- UFT (PRESERVED, ALL ELSE DESTROYED) ; (ZERO UFT MEANS NOP) PUT64: MOVS 1,1 ; MOVE LINE # TO OTHER BYTE ADD 1,0 ; RCHAR + LINE # STA 0,RCHAR XXX64: MOV# 2,2,SNR ; LINE OPEN ? JMP 0,3 ; NO- RETURN STA 3,RTN64 ; YES- SAVE RETURN LDA 3,QTRXP,2 ;RECEIVE OUTSTAN4DING? MOV# 3,3,SNR JMP QSEND ; NO - SAVE IT .IFN MSW JSR @.MAPTCB ;SET UP LAST BLOCK FOR TCBS .ENDC JSR SQT64 ;STORE THE WORD JMP @RTN64 ;RETURN ;GIVE TO TASK (ASSUMES TCB MAP BLOCK OK) SQT64: STA 3,SQRTN ; LDA 3,QTRXT,2 ;YES - GET RECEIVE /TCB STA 0,TAC2,3 ;STORE THE INT IN AC2 JSR @.RDEND ;GO UNPEND TASK JMP @SQRTN ;RETURN ;SEND CHARACTER TO QTY64 READ BUFFER ;AC0 = CHAR QSEND: LDA 3,QRSND,2 ;GET THE SEND POINTER LDA 1,QRGET,2 ; AND GET POINTER SUB# 1,3,SNR ;BUFFER FULL IF EQUAL JMP @RTN64 ; RETURN STA 0,0,3 ;STOR ETHE WORD LDA 1,QREND,2 ;PICK UP THE END SUBZ# 1,3,SNC ; AND WRAP AROUND IF NEEDED INC 3,3,SKP ; ELSE JUST GET NEXT ONE LDA 3,QRSRT,2 STA 3,QRSND,2 ;UPDATE THE SEND POINTER JMP @RTN64 ;RETURN .RDEND: RDEND SQRTN: 0 .DCCRE: DCCRE .DCLAC: DCLAC .DCNAF: DCNAF C34.: 34. .BRTN: BRTN BSLASH: "\ ;RING BUFFER MANAGEMENT PROCEDURES ; 4 POINTERS SRT START OF BUFFER ; END END OF BUFFER ; GET GET POINTER (1 BEFORE WORD TO GET) ; SND SEND POINTER (AT WO\gRD TO SEND) ;SEND CHARACTER TO WRITE BUFFER WITH EXPANSION ;AC0= CHAR WITH LEFT BYTE SEQUENCING CODE ; 1B0 IF WRS, LBYTE>0 IF SEQUENCING ;RETURNS AC0 NEXT CHAR TO INSERT OR -1 ;+1 RETURN FOR BUFFER FULL WSEND: STA 3,@.BRTN ;SAVE THE RET1URN MOVL# 0,0,SZC ;SKIP IF WRL JMP SEND ; WRS-- GIVE IT AWAY LDA 1,C177 ;CLEAN OFF PARITY BIT AND SEQUENCING AND 0,1 ; JMP TCTEST ;TEST FOR CR OR TAB ;SKIP A PAGE ; FORM FEED CRFF: ADDL# 0,0,SZC ;SKIP UNLESS SEQUENCE FF JMP COL0 ; IT h!IS IGNORE LDA 0,@.SFF ;ASSUME FORM FEED SEQUENCE LDA 3,UFTCH,2 ;CHECK FOR NULLS AFTER FF LDA 1,.DCNAF AND# 3,1,SZR LDA 0,@.SFFN ; YES-- ADD IN NULLS JMP COL0 ;UPDATE THE COLUMN ;CARRAIGE RETURN CRLF: LDA 3,UFTCH,2 ; CHECK FOR LINEFEED LDA 1%#,.DCLAC AND# 3,1,SZR LDA 0,SCR ; CR-- DO LINEFEED AFTER ;COLUMN 00 COL0: LDA 1,QWCOL,2 ;TRANSFER IN USE BIT TO A ZERO MOVL# 1,1,SZC SUBZR 1,1,SKP SUB 1,1 STA 1,QWCOL,2 ; UPDATE AT COLUMN 0 JMP SEND ;SEND CHAR TO WRTITE VFOR ECHOING ESENLD: STA 3,BRTN ;SAVE THE RETURN LDA 1,C177 ;CLEAN OFF PARITY BIT AND 0,1 ; LDA 3,BSLASH ; SUB# 3,1,SNR LDA 0,SBS ; BACK SLASH-- DO CR LF ;CARRAIGE RETURN ECHO LDA 3,FF ;CHECK FOR CR ADC# 3,1,SZR JMP ERUB ; NOPE-- CHECK FOR RUBOUT LDA 3,&UFTCH,2 ;AC3 <- DEVICE CHARACTERISTEICS LDA 1,.DCCRE ;IF NO CARRAIGE RETURN ECHO AND# 1,3,SNR JMP CNONE ; THEN ALL DONE JMP CRLF ;ELSE PROCESS CARRAIGE RETURN ;RUB OUT ERUB: LDA 3,RUB ;TEST FOR RUB OUT SUB# 3,1,SZR ; JMP TCTEST ; NO-- KEEP LOOKING LDA 1,UFTCH,2 ;CHECK FOR TELETYPE LDA 3,.DCTO LDA 0,BARR ; YES-- GIVE "_ AND# 3,1,SNR LDA 0,SRUB ; NO-- DO A BACK STEP JMP COLINC ;CHARACTER SWITCHING TCTEST: LDA 3,LF SUB# 1,3,SNR JMP SEND ; LF-- DON'T CHANGE COLUMN COUNT LDA 3,FF ADC# 3,1,SNR ; SKIP IF NOT CR JMP CRLF ; ELSE CHECK FOR EXPANSION SUB# 1,3,SNR ; SKIP IF NOT FF JMP CRFF ; FF-- MAKE CR,FF MAYBE NULLS LDA 3,TAB SUB# 3,1,SZR JMP COLINC ; NOT A TAB-- DO AS IS ;TAB EXPANSION LDA 1,UFTCH,2 ;CHE?CK FOR TAB EXPANSION LDA 3,.DCCGN AND# 3,1,SNR JMP SEND ; NO- RETURN AS IS LDA 1,QWCOL,2 ;PICK UP THE COLUMN COM 1,1 ;COMPUTE SPACES FOR TAB LDA 3,TBMSK ; BY NEGATING AND MASKING AND 3,1 ; LDA 3,.STAB ;GET PROPER TAB SEQUENCER ADC 1,3 ; #LDA 0,0,3 ; COLINC: LDA 1,QWSND,2 ;GET THE SEND POINTER LDA 3,QWGET,2 ; AND GET POINTER SUB# 1,3,SNR ;BUFFER FULL IF EQUAL JMP @BRTN ; SIMPLY RETURN ISZ QWCOL,2 ;BUMP THE COLUMN JMP STUFF ;WRITE BUFFER SEND: LDA 1,QWSND,2 ;GET THE SEND POINT ER LDA 3,QWGET,2 ; AND GET POINTER SUB# 1,3,SNR ;BUFFER IS FULL IF EQUAL JMP @BRTN ; SIMPLY RETURN STUFF: S.TB 1,0 ;STORE BYTE LDA 3,QWEND,2 ;PICK UP THE END SUBZ# 3,1,SNC ; AND WRAP AROUND IF NEEDED INC 1,1,SKP ; ELSE JUST GET NEXT ONE LDLA 1,QWSRT,2 ; STA 1,QWSND,2 ;UPDATE THE SEND POINTER ;SEQUENCE CHARACTER EG LF AFTER CR LDA 1,.C77B7 ;GET SEQUENCE MASK MOVL# 0,0,SNC ;SKIP IF WRS ANDS 0,1,SNR ;MASK AND SKIP IF SEQUENCING JMP CNONE ADDL# 0,0,SZC ;SKIP IF COUNTING JMP NSEQ ; ELSE TABLE SEQUENCE LDA 1,C1B7 ;DEC COUNT SUB 1,0,SNR JMP CNONE ; GONE TO ZERO--END JMP CSTA ;UPDATE RETURN NSEQ: LDA 3,STABLE ;GET NEXT CHARACTER ADD 1,3 ; LDA 0,0,3 ; JMP CSTA CNONE: ADC 0,0 ;NULL CONTINUATION CHAR CSTA: LDA 3,BRTN ;NORMAL RETURN JMP 1,3 .SFF: SFF .SFFN: SFFN BRTN: .BLK 1 TBMSK: 7 ;TAB MASK .C77B7: 77B7 C1B7: 1B7 .DCCGN: DCCGN .DCTO: DCTO TAB: 11 LF: 12 FF: 14 BARR: "_ RUB: 177 .MACRO CSEQ ** .IFN .ARGCT==1 ** 1B1+(.-STABLE)B7+^1 ** .ENDC ** .IFN .ARGCT==2 ** 1B1+^1 ** .ENDC ** .IFN .ARGCT==3 ** ^2B7+0 ** .ENDC % STABLE: .+1 ;SEQUENCE CONTROL TABLE ; IN EVEN PARITY SBS: CSEQ 134 ; BACK SLASH SCR: CSEQ 215 ; CR CSEQ 12 END ; LF SFF: CSEQ 215 ; CR FF SEQUENCE CSEQ 14 END SFFN: CSEQ 215 ; CR FF NULLS SEQUENCE CSEQ 14 ; FF CSEQ COUNT 20 NULLS SRUB: CSEQ 231 ; RUBOUT SEQUENCE ^Y CSEQ 232 ; ^Z CSEQ 27 ; ^W CSEQ 232 ; ^Z CSEQ 27 ; ^W CSEQ 240 ; SP CSEQ 231 ; ^Y CSEQ 232 ; ^Z CSEQ 27 ; ^W CSEQ 232 ; ^Z CSEQ 27 EN^qD ; ^W CSEQ 240 ;TAB EXPANSION SEQUENCE CSEQ 240 ; ALL SPACES CSEQ 240 CSEQ 240 CSEQ 240 CSEQ 240 CSEQ 240 CSEQ 240 END .STAB: . ;SEND CHARACTER TO READ BUFFER ;AC0= CHAR RSEND: STA 3,RSRTN ;SAVE THE RETURN LDA 1,QRSND,2 ;GET THE SEND POINTER LDA 3,QRGET,2 ; AND GET POINTER SUB# 1,3,SNR ;BUFFER IS FULL IF EQUAL JMP @RSRTN ; SIMPLY RETURN S.TB 1,0 ;STORE THE BYTE LDA 3,QREND,2 ;PICK UP THE END SUBZ# 3,1,SNC ; AND WRAP AROUND IF NEEDED INC 1,1,SKP ; ELSE JUST GET NEXbT ONE LDA 1,QRSRT,2 ; STA 1,QRSND,2 ;UPDATE THE SEND POINTER RRET: LDA 3,RSRTN ;RETURN JMP 1,3 RSRTN: 0 ;RETURN LOC ;NOTE: QSEND JUST LIKE RSEND .IFE BSW!MBSW .STB: STB. .ENDC ;GET CHARACTER FOR WRITE BUFFER ; ERROR RETURN-- BUFFER EMPTY ; NORMAL RETURN-- AC0<- CHAR ; 1B0 IF LINE TERMINATOR WGET: STA 3,BRTN ;SAVE THE RETURN LDA 1,QWGET,2 ;AC1 <- BUFFER GET POINTER LDA 0,QWEND,2 ;CHECK AGAINST THE END SUBZ# 0,1,SNC ; AND WRAP AROUND IF NEED BE INC 1,1,SKP ; ELSE SIM93PLY BUMP IT LDA 1,QWSRT,2 ; LDA 0,QWSND,2 ;CHECK FOR EMPTY BUFFER SUB# 0,1,SNR ; JMP 0,3 ; YES IT IS ERROR RETURN STA 1,QWGET,2 ;UPDATE BUFFER GET POINTER JMP WRET ;GET A BYTE AND RETURN ;GET CHAR FROM READ BUFFER ; ERROR RETURN-- BUFFER EMPTY ; NORMAL RETURN-- AC0<- CHAR RGET: STA 3,BRTN ;SAVE THE RETURN LDA 1,QRGET,2 ;AC1 <- BUFFER GET POINTER LDA 0,QREND,2 ;CHECK AGAINST THE END SUBZ# 0,1,SNC ; AND WRAP AROUND IF NEED BE INC 1,1,SKP ; ELSE SIMPLY BUMP IT LDA 1,QRSRT,2 ; $ LDA 0,QRSND,2 ;CHECK FOR EMPTY BUFFER SUB# 0,1,SNR ; JMP 0,3 ; YES -- RETURN EMPTY HANDED STA 1,QRGET,2 ;UPDATE BUFFER GET POINTER WRET: JMP UPLD ;GET A BYTE WRE2: LDA 3,BRTN ;+2 RETURN JMP 1,3 ;NOTE: QGET IN QTYOV.SR, JUST LIKE RGET ; WITH WORD POINTERS .IFE BSW!MBSW ;LOAD A BYTE 1,0 LDB.: STA 3,RETS ;SAVE REUTRN MOVZR 1,3 ;CORE ADDRESS LDA 0,0,3 ;BYTE WORD LDA 3,C377 ;MASK MOV# 0,0,SNC ; MOVS 0,0 ;SWAP WORD AND 3,0 ;MASK JMP @RETS ;RETURN RETS: .BLK 1 ;STORE A yBYTE 1,0 STB.: RSAVE 0 ;INTERFACE LDA 2,C377 ;HALF WORD MASK AND 2,0 MOVZR 1,3,SZC ;CORE ADDR MOVS 2,2 ;WORD MASK LDA 1,0,3 ;WORD TO UPDATE AND 2,1,SNC ;MASK MOVS 0,0 ADD 1,0 ;MERGE STA 0,0,3 ;STORE IT RTRN ;RETURN .ENDC ;SEND DATA TTO A TASK ; AC0= CHAR, AC2= UFT ; +1 RETURN-- REQUEST FINISHED, UNPENDS TASK ; +2 RETURN-- ; RETURNS 1B0 ON CHAR IF RDS TSEND: INC 3,3 ;GOOD RETURN STA 3,QRTN ;SAVE THE RETURN STA 2,LNUFT ;SAVE THE UFT STA 0,CHAR ;SAVE THE CHARACTER ;SET UP MAP LDA 1,QTRXP,2 ;BP .IFN MSW ;SET MAP FOR ACCESS TO USER MOVZR 1,0 ;BP TO REAL ADR SUB 1,1 MOVL# 2,2,SZC ;SKIP IF BG SUBZL 1,1 JSR@ .MBLK ;MAP IT- AC2= MAPPED ADDR JMP RMAPERR ;REC ADDR ERROR MOV 2,1 ;AC1 <- ADR LDA 2,LNUFT ;UFT LDA 3,QTRXP,2 ;BP LDA 0,CHAR ;RESTORE CHAR MOVR 3,3 ;B15 TO CARRY MOVL 1,1 ;TO BP .ENDC LDA 3,QTRXS,2 ;TEST FOR RDS MOV# 3,3,SZR ; JMP NOMSK ; YES-- DON'T MASK LDA 3,CMASK ;MASK THE CHARACTER AND 3,0 ; NOMSK: S.TB 1,0 .IFN MSW ~ ;RESTORE PG 31 MAP TO USER PG 0 JSR @MAP.TCB .ENDC LDA 3,QTRXT,2 ;GET RECEIVE TCB POINTER ISZ TAC1,3 ;INC BYTE COUNTER ISZ QTRXP,2 ;INC BYTE POINTER LDA 1,QTRXS,2 ;GET SEQUENTIAL LIMIT MOV# 1,1,SZR ;TEST FOR READ SEQUENTIAL JMP QTRS ;YES, READ SEQ ;PARITY ALM? ;CHECK LINE CHAR. IF ALM JMP ITSQTY JMP QTNPC ITSQTY: LDA 1,UFTCH,2 ;GET INHIBIT MASK LDA 3,PCK ;GET PARITY BIT ANDZ 1,3,SNR ;TEST INHIBIT, CLEAR CARRY JMP QTNPC ;NO PARITY NOW LDA 3,CHAR ;AC3 <- CHARACTER NEG 3,1 ;FORxM N-1 COM 1,1 ANDC 1,3,SZR ;ARE WE OUT OF ONES YET JMP .-3 ;NO MOV# 0,0,SNC ;IS PARITY EVEN JMP QTNPC ; QTPCK: LDA 0,E.PAR JMP @R.PER PCK: 1B7 R.PER: RPERR E.PAR: ERPAR ;AC0= CHAR AND 177R8 ;LINE EDITS QTNPC: LDA 3,UFTCH,2 ;IF NO ECHOING INHIBIT LINE EDITS LDA 1,DC.KEY AND# 1,3,SNR JMP NOEDIT LDA 3,QTRXT,2 ;AC3 <- TCB LDA 1,.LF ;LINE FEEDS NO EFFECT SUB# 1,0,SNR JMP QTLF LDA 1,EOF ;TEST FOR EOF SUB# 1,0,SZR ; ADC# 1,0,SNR ;TEST FOR ESCAPE JMP QTEOF ; YES TREAT EOF,ESCAPE |iAS EOF LDA 1,.RUB SUB# 1,0,SNR ;RUBOUT? JMP QTRBT ;YUP LDA 1,BSL SUB# 1,0,SNR ;BACK SLASH (SHIFT-L)? JMP QTSHL ;'FRAID SO ;TERMINATORS NOEDIT: LDA 3,QTRXT,2 ;AC3 <- TCB LDA 1,..FF ;TEST OF FORM FEED SUB# 1,0,SZR ADC# 1,0,SNR ; AND CR JMP READDONE ; TERM-- FINISH MOV# 0,0,SNR ;TEST FOR NULL JMP READDONE ; TERM-- FINISH LDA 1,TAC1,3 ;GET BYTE COUNT LDA 0,LGTH ;GET LINE LIMIT+1 SUB# 0,1,SNR ;TEST FOR END OF LINE JMP QTLLI ;LINE LIMIT ERROR JMP @QRTN ; OK--RETURN QTRS: ADDOR 0,0 ;SET 1B0 ON CHAR STA 0,CHAR ; LDA 0,TAC1,3 ;CHECK FOR DONE SUB# 0,1,SZR JMP @QRTN ; NO-- ALL DONE READDONE: JSR RDEND ; YES-- FINISH TASK LDA 3,QRTN ;SHOW TASK DONE JMP -1,3 UPLD: L.DB 1,0 JMP WRE2 C377: 377 .RQTYIS: RQTYIS .IFN ¬MSW MPSV: 0 ;USED TO SAVE P31 MAP ON ENTRY MSV2: 0 ;USED TO SAVE P0 MAP THRU BYTE PUSHING .ENDC QTDCT: MUXDCT ;DCT ADDRESS .DSMS: DISMIS BSL: "\ ;SHIFT-L (BACK SLASH) .IFN MSW RMAPERR: LDA 2,LNUFT ;UFT LDA 0,.ERMPR ;MEM ERROR JMP QTRERR MAP.TCB: MAPTCB .ENDC .RESC: RESCH QEOF: EREOF ;END OF FILE CMASK: 177 QRTN: .BLK 1 CHAR: .BLK 1 DC.KEY: DCKEY .LF: 12 EOF: 32 .RUB: 177 ..FF: 14 DNRTN: 0 .IFE BSW!MBSW .LDB: LDB. .ENDC ; HANDLE A RUBOUT QTRBT: DSZ TAC1,3 ;DECREMENT BYTE CNT TWICE DSZ TpAC1,3 ;ONLY ONCE IF ZERO JMP .+1 ;NOP LDA 1,TAC1,3 LDA 3,QTORG,2 ;INITIAL BYTE PTR ADD 3,1 STA 1,QTRXP,2 ;CORRECT B.P. FOR NEW CNT JMP @QRTN ; HANDLE BACK SLASH QTSHL: LDA 1,QTORG,2 ;INITIAL B.P. STA 1,QTRXP,2 ;RESET CURRENT TO IT SUB 1,1 ;I&NVENT ZERO STA 1,TAC1,3 ;AND REMEMBER IT IN THE COUNT JMP @QRTN LNUFT: .BLK 1 .IFN MSW .MBLK: MBLK .ENDC ; LINE FEED QTLF: DSZ QTRXP,2 ;BACK DOWN BYTE POINTER DSZ TAC1,3 ;AND BYTE COUNT JMP @QRTN ; RETURN JMP @QRTN ; (MAY SKIP) ; END OF FsILE QTEOF: DSZ TAC1,3 ; BACK UP BYTE COUNT SO THAT JMP .+1 ; ESC OR CTRL-Z CHAR NOT COUNTED. LDA 0,QEOF ;GET END FILE ERROR JMP QTRERR ; LINE LIMIT EXCEEDED QTLLI: LDA 0,.ERLLI ;GET LINE LIMIT ERROR QTRERR: JSR QTRZAP ;TAKE DOWN THE READ LDA 3b,QRTN ;TAKE ERROR RETURN JMP -1,3 ;ERROR IN AC0 TO RECEIVE TCB. AC1 DESTROYED QTRZAP: STA 3,DNRTN LDA 3,QTRXP,2 ;IF NO READ POSTED MOV# 3,3,SNR JMP @DNRTN ; THEN IGNORE .IFN MSW JSR MAPTCB ;SET UP TCB .ENDC LDA 3,QTRXT,2 ;RESTORE AC3 STAP 0,TAC2,3 ;GIVE ERROR CODE TO USER DSZ TPC,3 ;GIVE CALLER BAD RETURN DSZ TPC,3 JMP ENDRD ;TERMINATATE THE READ ;ERROR IN AC0 TO WRITE TCB. AC1 DESTROYED QTWZAP: STA 3,DNRTN LDA 3,QTTXP,2 ;IF NO WRITE POSTED SNEZ 3 JMP @DNRTN ; THEN IGNORE | .IFN MSW JSR MAPTCB ;SET UP TCB .ENDC LDA 3,QTTXT,2 ;RESTORE AC3 STA 0,TAC2,3 ;GIVE ERROR TO USER DSZ TPC,3 ;TAKE ERROR RETURN DSZ TPC,3 JMP ENDTR ;END THE TRANSMIT ; END OF TRANSMISSION - TCB ALL SET UP TREND: STA 3,DNRTN ;SAVE THE RETURN >dENDTR: STA 0,CHAR ;SAVE THE CHARACTER SUB 1,1 ;GET ZERO STA 1,QTTXP,2 ;RESET BYTE POINTER LDA 3,QTTXT,2 ;GET TCB POINTER JMP QTFIN ;GO UNPEND TASK RDEND: STA 3,DNRTN ;SAVE RETURN ENDRD: SUB 1,1 ;GET ZERO STA 1,QTRXP,2 ;RESET BYTE POINTER LDA 3,UFTCH,2 ;SEE IF XON/XOFF TELETYPE READING LDA 1,.DCXON AND# 1,3,SZR JMP Q1 ; NOPE--CONTINUE LDA 1,.XOFF ; YEP-- SEND OUT XOFF TO TURN READER OFF ; IF HE'S THERE. MAY BE DUPLICATES STA 1,QTXON,2 JSR @.QKICK ;PAUSE TO KICK THE WRITER Q1: LD@A 3,QTRXT,2 ;AC3 <- RECEIVE TCB QTFIN: INTDS ;DISABLE INTERRUPTS (ALREADY IF BASE LEVEL) STA 2,LNUFT ;SAV E THE LINE'S UFT ;KILL TASK LDA 0,TPRST,3 ;UNPEND TASK ADCZR 1,1 ;MASK AND 1,0 ;RESET 1B0 STA 0,TPRST,3 ;PUT IN TCB LDA 2,TSYS,3 ;PREV STORED PTBL ADDR MOVZR 1,1 ;MASK = 0B0 0B1 LDA 0,PSTAT,2 ;RESET NOT READY AND QTASK FLAGS AND 1,0 STA 0,PSTAT,2 SUBZL 0,0 ;OUT OF THIN AIR STA 0,PINTU,2 ;RACE CONDITION FLAG STA 0,@.RESC LDA 1,@.INTLV ;CHECK INTERRUPT WORLD .IFE BSW!MBSW MOV# 1,?1,SZR .ENDC .IFN BSW!MBSW COM# 1,1,SZR .ENDC INTEN ; YES-- RE-ENABLE LDA 2,LNUFT ;AND RETURN WITH AC2=UFT LDA 0,CHAR ;RESTORE THE CHAR JMP @DNRTN ; LGTH: SCLLG+1 ;MAX LINE LENGTH + 1 .DCXON: DCXON .QKICK: QKICK .XOFF: 23 ; RETURN FROM INoTERRUPT HANDLER QTRTN: .SKPDZ= SKPDZ 0 .GADD DLMUX,.SKPDZ ;SEE IF ANY LINES WAITING JMP @.RQTYIS ; YES--KEEP SERVICING .IFN MSW ;RESTORE MAP BEFORE RETURNING LDA 1,MPSV ;WHERE IT WAS SAVED EARLIER .IFN MNSW LDA 0,CLSTB ;ONLY PG 31 WAS USED ADD 0,1 ;FORMAT FOR MAP .ENDC .IFN MBSW STA 1,CLBLK ;LAST BLK .ENDC SMLB 1 .ENDC LDA 2,QTDCT ;RESTORE DCT POINTER JMP@ .DSMS ;BACK TO SYSTEM .IFN MSW MAPTCB: ;SETS MAP FOR TCB BY FG/BG BIT IN AC2 STA 3,MPRET LDA 1,@.MPT1 ;FOREGROUND PAGE 0 MAP MOVL# 2,2,SNC LDA 1,@.MPT2 ;USE BACKGROUND INSTEAD .IFE MBSW LDA 3,CLSTB ;LOGICAL PAGE WILL BE 31 ADD 3,1 .ENDC .IFN MN3SW LDA 3,C176777 ;MASK OUT WHICH MAP BIT AND 3,1 .ENDC .IFN MBSW STA 1,CLBLK ;SET MAP WORD .ENDC SMLB 1 ;SET MAP ߪJMP @MPRET .MPT1: MPT1 .MPT2: MPT2 .ERMPR: ERMPR MPRET: .BLK 1 C176777: 176777 .ENDC .ERLLI: ERLLI C.MASK: 177 LN.UFT: 0 ;SAVE FOR UFT ;GET THE NEXT CHARACTER FROM A TASK ; +1 RETURN-- OUT OF CHARS ; IF REQUEST DONE, UNPENDS TASK ; BOTHN RETURNS-- AC0 <- CHAR (1B0 IF WRS) TGET: INC 3,3 ;NORMAL RETURN STA 3,TRTN ;SAVE THE RETURN STA 2,LN.UFT ;SAVE THE UFT LDA 1,QTTXP,2 ;BP ;SET UP MAP .IFN MSW ;SET MAP FOR ACCESS TO USER MOVZR 1,0  ;BP TO REAL ADR SUB 1,1 MOVL# 2,2,SZC ;SKIP IF BG SUBZL 1,1 JSR@ .MBLK ;MAP IT- AC2= MAPPED ADDR JMP WMAPERR ;XMT ADDR ERROR MOV 2,1 ;AC1 <- ADDR LDA 2,LN.UFT ;UFT LDA 3,QTTXP,2 ;BP MOVR 3,3 ;B15 TO CARRY MOVL 1,1 ;TO BP .ENDC L.DB 1,0 .IFN MSW ;MUST RESTORE MAP JSR MAPTCB ;SET ϸMAP FOR TCB .ENDC ISZ QTTXP,2 ;INCREMENT BP LDA 3,QTTXT,2 ;GET TCB AGAIN ISZ TAC1,3 ;INCREMENT BYTE COUNT LDA 1,QTTXS,2 ;GET SEQUENTIAL LIMIT MOV# 1,1,SZR ;TEST FOR WRITE SEQUENTIAL JMP QTTWS ;YES ;CHECK PARITY ALM? JMP .+2 JMP QTNP LDA h^1,UFTCH,2 ;GET INHIBIT MASK LDA 3,P.CK ;GET PARITY BIT AND 3,1,SNR ;TEST FOR PARITY CHECK JMP QTNP ;NO LDA 1,C.MASK ;STRIP PARITY LEFT OVERS ANDZ 0,1 ; PUT IN AC1, CLEAR CARRY NEG 1,3 ;FORM N-1 COM 3,3 ANDC 3,1,SZR ;REMOVE A ONE JMP .-3 iQ ;KEEP GOING MOV 1,1,SZC ;EVEN PARITY? LDA 1,PBIT ;NO, MAKE IT EVEN AND# 1,0,SNR ;SKIP IF BIT SET ALREADY ADD 1,0,SKP ;SET THE HIGH ORDER BIT SUB 1,0 ;CLEAR HIGH ORDER BIT QTNP: LDA 1,C.MASK ;MASK JUST CHAR AND 0,1 ; ;LINE TERMINATORS LDA 3t,.FF ;TEST OF FORM FEED SUB# 3,1,SZR ADC# 3,1,SNR ; AND CR JMP ALLDONE ; TERM-- FINISH MOV# 1,1,SNR ;TEST FOR NULL JMP ALLDONE ; YES -- ALL DONE LDA 3,QTTXT,2 ;TCB LDA 1,TAC1,3 ; OUTPUT COUNT LDA 3,LGTH ;MAX LINE LENGTH+1 SUB# 3,1,SZR T;TEST LINE LIMIT JMP @TRTN ;OK LDA 0,.ERLLI ;TOO LONG JMP EWRT .IFN MSW WMAPERR: LDA 0,.ERMPR LDA 2,LN.UFT .ENDC ;RETURN TRANSMIT ERROR IN AC0 EWRT: JSR .QTWZ JMP EWRTN ; TEST FOR END OF WRITE SEQUENTIAL QTTWS: ADDOR 0,0 ;SET BIT ZERO LDA 3,TAC1,3 ;GET OUTPUT COUNT SUB 1,3,SNR ;COMPARE WITH LIMIT ALLDONE: JSR TREND EWRTN: LDA 3,TRTN ;TAKE TASK DONE RETURN JMP -1,3 .QTWZ: QTWZAP .INTLV: INTLV TRTN: 0 PBIT: 1B8 P.CK: 1B7 ; ; START ROUTINE ; ONLY CALLED ON A POWER FAIL WITH INTEeRRUPTS DISABLED ; QTYST: STA 3,PRET ;RETURN JSR @.ALINI ;INIT ALM OR DO NOTHING QTS0: LDA 3,Q.TYTB ;LINE TABLE ADDR QTS1: LDA 2,UFTTB,3 ;UFT ADDRESS COM# 2,2,SNR ;TEST FOR END OF TABLE JMP @PRET ; YES-- THEN RETURN MOV# 2,2,SNR ;DOES IT EXIST? 0JMP QTS2 ;NO LDA 0,QWCOL,2 ;ARE WE BUSY MOVL# 0,0,SZC ; JSR @.QTSRT ;YES-- LETS SHOW THE WORLD LDA 3,QTTBL,2 ;RESTORE TABLE ENTRY QTS2: INC 3,3 ;AND GET NEXT ONE JMP QTS1 ;NO - GET NEXT ONE PRET: 0 Q.TYTB: QTYTB .FF: 14 .ALINI: ALINIT .QTSRT:nQ QTSRT QTYQ: .BLK 2 1B0 ; USER OF A FREE STACK MUXDC ; DCT .BLK QLN-4 ; GOBBLE UP SOME MEMORY .END QTYMD.SRB ; MODEM PROTOCALL RTITLE QTYMD .ENT MODEM, MODINIT, MODSET .EXTN QTRZAP, QTWZAP, DLMUX .EXTN PUT64, QTB64, QTF64 .NREL ; THE FOLLOWING ARE OFFSETS INTO THE UFT FOR ; STORAGE WORDS USED BY THIS PROGRAM ;**** NOTE: ANY CHANGE SHOULD BE MADE zbIN ;**** QTYDR,QTYMD,SOV19,QTYOV,SOV5,ALMDB,ALM1D QTRXP=UFTFN ;RECEIVE BYTE POINTER ; 0 NO READ QTORG=UFTFN+1 ;INITIAL RECEIVE BYTE POINTER QTTXP=UFTFN+2 ;TRANSMIT BYTE POINTER ; 0 NO WRITE QTRXT=UFTFN+3 ;READ CALLER TCB ; 1B0 + ERR OR CODE QTXON=UFTFN+4 ;XON/XOFF FOR TELETYPE READER ; -1 DON'T PUT OUT ANYTHING QTTBL=UFTEX ;ADDR OF TABLE ENTRIES INTO QTYTB QTTXT=UFCA1 ;TRANSMIT TCB QTRXS=UFTBN ;READ SEQUENTIAL LIMIT ; 0 READ LINE QTTXS=UFTBP ;WRITE SEQUENTIAL LIMIT ; 0 WRITE LINE ;READ BUFFER QRSRT= UFTCA ;START OF BUFFER QREND= UFTCB ;END OF BUFFER QRGET= UFEA1 ;GET DATA POINTER QRSND= UFTEA ;SEND DATA POINTER ;WRITE BUFFER QWSRT= UFNA1 ;START OF BUFFER QWEND= UFTNA ;END OF BUFFER QWGEAT= UFLA1 ;GET DATA POINTER QWSND= UFTLA ;SEND DATA POINTER ;HOLD WORDS QECHO= UFFA1 ;HOLD FOR ECHOING ;-1 NO ECHO ;1B0 INHIBITS RECEIVES ; ON EMPTY BUFFER, WAKES UFT ; FLAGS CLOSING CHANNEL QXPND= UFTFA ;HOLD FOR EXPANDING 3 ; -1 NO EXPANSION ; -2 DON'T GET DATA (CLOSING) QWCOL= UFTCN ;COLUMN COUNTER FOR TABBING ; 1B0 INDICATES WRITER BUSY QRBUF= 7 ;READ BUFFER QRBEN= 16 QWBUF= 17 ;WRITE BUFFER QWBEN= 20 NLNS= 64. ;NUMBER OF LINES, ASSUMED 64. THROUGHOUT UFTTB= 0 ;UFT TABLE ; 0 INDICATES UNOPENED ; 1B0 INDICATES FOREGROUND CHANNEL ; -1 INDICATES END OF TABLE ALMCH= NLNS+2+1 ;ALM LINE CHARACTERISTICS TABLE ; +2 FOR LINE 64 ; +1 FOR EOT DOB0= DOB 0,0 MODINIT: ;CALL0ED AT SYSTEM INIT AND POWER RESTORE ; FROM ALINIT ;AC1 = ALMCH ENTRY ; INTERRUPTS OFF, LINE SELECTED ;AC3 = RETURN ADDR. SUBZR 0,0 ;LOWER RTS, DTR .GADD DLMUX,DOB0 ; SO INTERRUPT WILL SHOW IN ALDSR MODSET: ;CALLED FROM OVERLAY AND DRI NO USER JMP PF1 LDA 0,.FPAC ;FPU IN USE - MUST SAVE STATE SKPBZ FPU ;WAIT FOR IT TO BE AVAILABLE JMP .-1 DOBS 0,FPU2 ;STORE FPAC TO MEMORY LDA 0,.FTEMP SKPBZ FPU JMP .-1 NIOC FPU2 ;MOVE FTEMP TO FPAC SKPBZ FPU JMP .-1 DOBS 0,FPU2 ;STORE FPAC  (HAS CONTENTS OF ; FTEMP) SKPBZ FPU JMP .-1 DIAC 0,FPU ;READ STATUS TO AC0 SKPBZ FPU JMP .-1 STA 0,FSTAT ;SAVE IT .ENDC .IFN BSW!MBSW ;CMSK ALL READY SAVED LDA 0,@.FPUSV ;FPU IN USE FLAG MOV# 0,0,SZR ; = 0 => NO USER FPSH ;THERE IS3 A USER - SAVE THE ; STATE .ENDC PF1: LDA 0,NJMP STA 0,0 ;STORE JUMP COMMAND IN 0 LDA 0,RTL STA 0,RLOC ;ADDRESS OF RETURN ROUTINE HALT ;STOP! RTL: PWRBK ;ADDRESS OF RETURN ROUTINE NJMP: JMP@ RLOC ;INSTRUCTION JUMPED TO BY CPU PFMES: . .TXTV /<15><12>POWER RESTORED<15><12>/ IHAND: .BLK 1 .IFE MBSW MAPS: 0 .ENDC .FPUSV: FPUSV .IFN N3SW .ENVIR: ENVIR .ENUN3: ENUN3 .ENDC .IFN N3SW!MN3SW SVSP: .BLK 1 SVFP: .BLK 1 .ENDC .IFN ANSW .FPAC: FPACS .FTEMP: FTEMP FPACS: .BLK 4 FTEMP: .BLK 4 FSTAT:* 0 .ENDC .INTL: INTLV .DIRR: DIRR BOMB: LDA 0,JMP. ;SET UP FOR PHONY RESTART STA 0,0 HALT ; ALL DONE JMP.: JMP . ;JUST AS IT SAYS. ; USER BEWARE. APPEARANCES DO NOT MAKE THE WORLD .DUMI: DUMI ;POWER FAIL STARTS OVER AGAIN DUMI: SKPDZ CPUL ;RE-HALT ON POWERFAIL, DON'T SAVE STATE JMP PF1 JMP @IHAND ;CONTINUE INTERRUPT PROCESSING ;ASSUMES ONLY PWRFL CAN GET THROUGH ; A MASK OF -1 .IFN MNSW TP31: 1B0+37B7 .ENDC ; ;ROUTINE TO HANDLE POWER COMING BACK AGAIN ; PWRBK: LDA 0,TIMED 6;PICK UP TIMER COUNT XXLDA 1,IPBDC ;IF NO IPB MOV# 1,1,SZR ;THEN SKIP NIOC IPB ;ELSE CLEAR IT PLOOP: SUB 1,1 ;GIVE A TTY TIME TO SYNC ITSELF INC 1,1,SZR JMP .-1 INC 0,0,SZR JMP PLOOP IORST ;SET THE WORLD TO ZERO ADC 1,1 ;MASK OUT ALL INTERRFUPTS BUT PWRFL DOBS 1,CPU ;SET MASK AND ENABLE PWRFL XSTA @1,= TFIRST ;INITIALIZE TFIRST INDICATOR ; ;WRITE A MESSAGE ON THE CONSOLE TTY ; LDA 2,PFMES ;ADDRESS OF MESSAGE OMES: INCZ 2,2 ;INC POINTER - CARRY TO ZERO LDA 0,0,2 ;GET THE WORD OM1: DOAS 0,TTO ;PUT OUT FIRST BYTE SKPBZ TTO ;WAIT FOR IT TO GO OUT JMP .-1 MOVCS 0,0,SZC ;SWAP AND TEST JMP OM1 ;ONE MORE BYTE IN THIS WORD MOV# 0,0,SZR ;ALL DONE? JMP OMES ;NO - GET NEXT WORD JMP N3RST ;YES-- RESTORE FOR NOVA 3 LPOOL TIMED: -10. { ;TIMED SHOULD BE 1 TO 2 SECONDS .IFN MSW .IFN MNSW C377: 377 .ENDC .IFE MBSW .ZREL CLBLK: .BLK 1 .NREL .ENDC .ENDC .IFN BSW!MBSW RTC.I?: RTCI? .ENDC ; ;RESTORE NOVA 3 STACK VARIABLES ; N3RST: .IFN N3SW LDA 2,@.ENVIR ; CHECK FOR NOVA 3 LDA 0,&.ENUN3 AND# 0,2,SNR JMP NORST ; NOPE-- DON7T RESTORE .ENDC .IFN N3SW!MN3SW LDA 0,SVSP ;RESTORE STACK POINTER MTSP 0 LDA 0,SVFP ;RESTORE FRAME POINTER MTFP 0 NORST: .ENDC ; ;RESTORE FLOATING POINT UNIT STATE - IF IN USE ; LDA@ 0,.FPUSV ;PICKU UP FLAG .IFE BSW!MBSW MOV# 0,0,SNR ;IN USE? JMP CPCK ;NO - GO FISH LDA 0,.FTEMP ;ADDRESS OF TEMP STORAGE DOBP 0,FPU2 ;LOAD FPAC WITH VALUE FOR FTEMP SKPBZ FPU JMP .-1 NIOP FPU2 ;MOVE FPAC TO FTEMP LDA 0,.FPAC ;ADDRESS OF FPAC STORAGE SKPBZ OFPU JMP .-1 DOBP 0,FPU2 ;LOAD FPAC FROM MEMORY LDA 0,FSTAT ;STATUS SKPBZ FPU JMP .-1 DOA 0,FPU ;RESTORE IT TO UNIT .ENDC .IFN BSW!MBSW MOV# 0,0,SZR ;IN USE? FPOP ;YES - RESTORE IT .ENDC ; ;WAIT FOR ALL INITIALIZED PACKS TO COME UP ; CPC,K: LDA 2,@.DIRR ;START OF DCB CHAIN NLP: LDA 0,SFLK,2 ;GET INDICATOR WORD LDA 1,SFKEY,2 ;PICK UP KEY WORD MOV# 1,1,SZR ;DISK? COM# 0,0,SNR ;DISK? XJMP CPDN ;NO - ALL DONE LDA 1,DCBST,2 ;STATUS LDA 3,DCBDC,2 ;DCT ADDRESS MOVL# 1,1,SZC ;INITED JMP .NEXT ; NO-- GET NEXT ONE ; MATCH DEVICE CODE OF DISK WITH THOSE IN A TABLE LDA 1,DCTCD,3 ;DEVICE CODE XLDA 3,= SATAB ;START OF TABLE FINDA: LDA 0,0,3 ;GET A DEVICE CODE FROM THE TABLE COM# 0,0,SZR ;END OF TABLE? JMP INTAB HALT ;---YES---, MAÃJOR PROBLEMS=>DIE JMP .-1 ;DISALLOW CONTINUING INTAB: SUB# 0,1,SNR ;---NO---,DEVICE CODE FOUND? JMP GOTSA INC 3,3 ;---NO---,GET NEXT TABLE ENTRY INC 3,3 JMP FINDA GOTSA: MOV 3,1 LDA 3,DCBDC,2 ;---YES---, GET DCT FOR DEVICE CODE LDA 0,DCTCD,3 ;PASS DEVICE CODE AND MOV 1,3 LDA 1,DCBUN,2 ;UNIT # * 2 TO DISK WAIT CODE JMP @1,3 ;BRANCH TO WAIT CODE FOR DISK LPOOL ; TABLE OF DEVICE CODES AND ADDRESSES OF WAIT CODE SATAB: 20 ;OLD FIXED HEAD DISK FIXED 26 ;NEW FIXED HEAD DISK FIXED 27 ;ZEBRA DISK ZEBRA 33 ;MOVING HEAD DISK MHD 60 ;SECOND OLD FIXED HEAD DISK FIXED 66 ;SECOND NEW FIXED HEAD DISK FIXED 67 ;SECOND ZEBRA DISK ZEBRA 73 ;SECOND MOVING HEAD DISK MHD -1 ;END OF TABLE ; POSSIBLE ALTERNATE SOLUTION TO&S TEST READY FOR ; THE NEW FIXED HEAD DISK ; DISK ON-LINE AND READY SEQUENCE: ; 1. START AT QUEUE ADDRESS ; 2. WAIT UNTIL THIRD DCH CYCLE COMPLETE (ALT MODE 3,DIA) ; 3. WAIT UNTIL BUS ENABLE IS TRUE ; 4. WAIT FOR READY AND WHEN FINISHED OR IF BUS ENABLE GOES ; ZERO THEN GO START AGAIN ; COMMENTS: ; 1. DCH READS MUST BE STABLE FOR ALL MACHINE TYPES ; 2. BUS ENABLE MUST BE AN ACCURATE REFLECTION OF CONTROLLER ; STATE (DOUBTFUL) ; 3. THERE MAY BE HARDWARE PROBLEMS ; 4. THIS METHOD ]"MAY NOT BE SUPPORTED SINCE IT IS UNDOCUMENTED ; THIS IS A NORMAL MOVING-HEAD DISK MHD: MOVZR 1,1 ;PUT DRIVE # (UNIT) IN BITS 0-1 MOVZR 1,1 MOVR 1,1 MOVR 1,1 XLDA 3,= DOC 1,0 ADD 0,3 XCT 3 ;SELECT UNIT ; WAIT UNTIL DEVICE IS READY NRDY: XLDA 3,= D NIA 1,0 ADD 0,3 XCT 3 ;GET STATUS XLDA 3,= 1B9 AND# 1,3,SNR ;READY? JMP NRDY ;---NO---, READ STATUS AGAIN ; RECALIBRATE THE DISK XLDA 1,= 7B7 ;---YES--- XLDA 3,= DOAP 1,0 ADD 0,3 XCT 3 ;ISSUE RECAL COMMAND NRDY1: XLDA 3,= DIA 1,0 ;WAIT FOR COMMAND TO FINISH ADD 0,3 XCT 3 ;GET STATUS XLDA 3,= 17B4 AND# 1,3,SNR ;CHECK FOR SEEK DONE JMP NRDY1 XLDA 3,= DOAC 1,0 ;CLEAR STATUS BITS FOR NEXT DISK ADD 0,3 XCT 3 .NEXT: JMP NEXT ;GET THE NEXT DISK LPOOL ; WAIT FOR READY TO COME TRUE FOR THEM ZEBRA DISK ZEBRA: LDA 1,DCBUN,2 ; UNIT * 2 ADDZL 1,1 ADDZL 1,1 ; UNIT * 1B10 XLDA 3,= DOA 1,0 ADD 0,3 ; DEVICE CODE XCT 3 ; DOA 1,ZEBRA ZEBXX: XLDA 3,= DIB 3,0 ADD 0,3 ; DEVICE CODE XCT 3 ; EXECUTE DIB 3,ZEBRA XLDA 1,= 1B3 ; READY BIT AND# Ԣ1,3,SNR JMP ZEBXX ; WAIT FOR READY ; DO A CLEAR TO THE ZEBRA DISK XLDA 3,= NIOC 0 ADD 0,3 ; DEVICE CODE XCT 3 ; EXECUTE NIOC ZEBRA JMP NEXT ; GET NEXT DISK LPOOL .IFN MBSW C32.: 32. C8.: 8. .PDEV: PDEV .PMAP: PMAP .ENDC .IFN MNSW STP: 176000E ;CODE TO START MAP .ENDC ; WAIT 30 SEC (1US CPU INSTRUCTION TIME) FOR FIXED HEAD DISK TO POWER UP FIXED: ISZ TFIRST ;SKIP IF FIRST TIME JMP NEXT ; ELSE GET NEXT DISK XLDA 0,= -290. ;WAIT SO ALL TOLD 30 SECONDS DLOOP: SUB 1,1 ; INC 1,1,SZR J„MP .-1 INC 0,0,SZR JMP DLOOP JMP NEXT ;GET THE NEXT DISK TFIRST: .BLK 1 ;ONLY DELAY ONCE ON FIXED HEADS LPOOL ; PAGING DISK. TO DETERMINE STATUS ISSUE DISK WRITE BUFFER ;PAGIN: MOVS 1,1 ;SHIFT UNIT # FOR DISK COMMAND ; ADDZL 1,1 ; MOVL 1,1 ; STA 11q,QUEUE ;UNIT # FOR DISK ADDRESS OF COMMAND QUEUE ; XLDA 3,= 5B7+1B9 ; STA 3,QUEUE+1 ;WRITE BUFFER COMMAND + HALT ;RLOOP: XLDA 1,= DOAS 3,0 ; ADD 0,1 ;ADD DEVICE CODE TO DISK COMMAND ; XLDA 3,= QUEUE ;START OF COMMAND QUEUE ; XCT 1 ;ISSUE DISK WRITE BUFFER COMMAND ; WAIT FOR DISK COMMAND TO COMPLETE ; XLDA 3,= SKPBZ 0 ; ADD 0,3 ; XCT 3 ; JMP .-1 ; CHECK READY BIT IN STATUS REGISTER OF DISK ; XLDA 3,= DICC 1,0 ; ADD 0,3 ;ADD DEVICE CODE ; XCT 3 ;ISSUE COMMAND TO READ STATUS REGISTER ; XLDA 3,= 1B10 ;READГY BIT MASK ; AND# 1,3,SNR ;DISK READY? ; JMP RLOOP ;---NO---,REISSUE COMMANDS TO CHECK STATUS ; JMP NEXT ;---YES---, MOVE ON TO NEXT DISK ; DISK COMMAND QUEUE ;QUEUE: .BLK 1 ;DISK ADDRESS ; .BLK 1 ;COMMAND ; 0 ;MEMORY ADDRESS ; .BLK 1 ;UNUSED STATUS ; .BLK 1 ;UNUSED COMMAND WORD ; LPOOL NEXT: LDA 2,SFNX,2 ;ADVANCE DCB POINTER COM# 2,2,SZR ;ARE WE AT THE END? XJMP NLP ;NO - GET THE NEXT ONE CPDN: IORST ;YES - ONE MORE RESET ADC 2,2 ; TURN ON INTERRUPTS DOBS 2,CPU ; WITH ALL DEVS MASKEDE OUT ; ;RE-INITIALIZE THE MAP ; .IFN MBSW ;LOAD BG MAP .DO BB?MSW XLDA 2,= MPSA2 ; SET TO ACCESS PT2 MAP SMST 2 .ENDC LDA 3,.PMAP LDA 2,.PT2 ;PT2 ADD 3,2 ;LMP ADDR LDA 1,C32. ;ALL MAP SLOTS SUB 0,0 ;FOR MICROCODE ERROR LMP ;LOAD FG nMAP TOO .DO BB?MSW XLDA 2,= MPSA1 ; SET TO ACCESS PT1 MAP SMST 2 .ENDC LDA 2,.PT1 ADD 3,2 LDA 1,C32. LMP .DO B?MSW ;BG DEV PROTECTION LDA 3,.PDEV LDA 2,.PT2 ADD 3,2 LDA 1,C8. LMP ;FG DEV PROTECTION LDA 2,.PT1 ADD 3,2 LDA 1,C8. LM

DSZ PDTOT,3 ;DEC TOTAL JMP INTS8 ;IF QUEUE IS NOT EMPTY INTS9: SUBC 1,1 ;CLEAR FIRST TCB STA 1,PDFR,3 ;CLEAR CHAIN STA 1,PDEN,3 STA 1,PDCNT,3 ;IN CASE BAD TCB ENTRY... INTS8: LDA 3,PLNK,3 ;NEXT PTBL COM# 3,3,SZR ;SKIP IF END JMP IRTC2 ; BUMP TIM] E OF DAY INTS4: XXLDA 2,= TODI ;START OF TABLE MOVZ 0,0 ;INIT CARRY TOD1: LDA 1,0,2 ;COUNTER LDA 3,1,2 ;END TEST CONSTANT OR -1 INC 1,1 ;BUMP COUNTER COM# 3,3,SNR ;ARE WE AT DAY COUNTER (END OF ; TABLE) JMP TOD2A ;IF YES SUB# 1,3,SZR ;END OF COUNTER REACHED JMP TOD2A ;IF NO SUBZ 3,3 ;0-SET CARRY TO SHOW FLIP STA 3,0,2 ;0 COUNTER INC 2,2 INC 2,2 JMP TOD1 TOD2A: STA 1,0,2 ;TO COUNTER MOV# 1,1,SZC ;FLIP ? ISZ RESCH ;YES, RESCHEDULE TO CATCH ;TIME-OUTS JMP TOD2 ;CONTINUE .IFN ANSW ; RESTORE STATE AND EXIT TODX2: XLDA 0,TCRY MOVL 0,0 ;RESTORE CARRY PFRET: XLDA 0,TIA0 XLDA 1,TIA1 UKITR: XLDA 2,TIA2 .IFE MSW XLDA 3,TIA3 INTEN JMP @0 .ENDC .IFN MNSW XLDA 3,TIA3 XDSZ INUSR ;ARE WE IN THE USER NIOS MAP ;YES - MUST< START MAP INTEN JMP @.+1 @0 .ENDC .IFN MN3SW XLDA 3,INUSR ; GET OLD MAP STATE DOA 3,MAP ; TOO MAP XLDA 3,TIA3 ; RESTORE AC3 INTEN ; ENABLE JMP @0 ; TA TA .ENDC .ENDC .IFN ABSW INTLV: -1 ;INIT AT TOP .ENDC .IFN MSW TCBER: LDA 2,PLNK,3 ;PT1 OR PT2 OTHER PTBL ? COM# 2,2,SNR ;IT'S PT2- ADDR IF NOT -1 XXLDA 2,= PT1 ;PT1 OTHER LDA 1,PDCNT,2 ;ADJUST COUNT XSTA 1,DTOTL ;ONLY OTHER'S XLDA 1,= PSBRK ;SET ABORT STA 1,PSTAT,3 XLDA 1,= 1B1 STA 1,PFLAG,3 ;TRAP BIT ADC 1,1 ;PC OF TRAPr = -1 STA 1,PMPC,3 SUB 1,1 LDA 2,C31K ;76000 STA 1,1,2 ;RESET IN SCHED IF SET JMP INTS9 ;FINISH CLEANING UP SFSTB: 0 LPOOL .ENDC .IFN BSW!MBSW RTCI?: 0 ;1 IFF PROCESSING RTC INTERRUPTS .ENDC USCIS: XXLDA 1,INTSK ;IN SYST TASK ? MOV# 1,1,SZR ADCZL 0,0 ;YES-FLAG IS 177770 JMP USCEX TICKER: TSCNT ;CLICKS/PULSE TSECI: 0 LPOOL ; ON EQUAL FORE/BACK GROUND PRI. KEEP PROCESSES BALANCED BY MAKING ONE ; PROCESSES PRIVILEGED WHENEVER THE OTHER PROCESS IS HOGGING TOD2: XXLDA 1,PRISW ;EQUALɝ PRIORITY? MOV# 1,1,SZR DSZ TICKER ; AND TIME TO PULSE? JMP UCLOCK ; NOPE XXLDA 0,= TSCNT ;RESET TICKER STA 0,TICKER XXLDA 0,SYSIN,.SYIN ;IN SYSTEM SUB 1,1 MOV# 0,0,SZR JMP RESET ; YES, DECRIMENT PRIORITYS LDA 1,CQ ; GET PT ADDRESS XXLDA L2,PTSWP ; CHECK, IF NON PRIVELEGED GROUND SUB# 1,2,SZR ; THEN WE MUST GIVE OTHER PRIVELEGE JMP RESET ; ELSE GO DELETE SOME OF PRIVELEGE XXLDA 0,PTPRV ; SET IN OTHER GUY AS MOV 0,0,SZR MOVOL 0,0 MOVOL 0,0 ; THE PRIVELEGED ONE BUT NOT XXSTA 0,PTPRV ; OVER 1.6 SECONDS OF PRIORITY COM# 0,0,SZR ; UNBALANCED JMP UCLOCK ; NOT YET ISZ RESCH ;FORCE A RE-SCHEDULING MOVZL 0,0 MOVS 0,0 XXSTA 0,PTPRV ; SET TO GO .4 SECONDS BEFORE RESCHED JMP UCLOCK ; IF SAME GROUND STILL RUNS CLPOOL RESCH: 0 ; RESHEDULE FLAG RESET: XXLDA 0,PTPRV ; GET PRIVELEGE WORD MOVZR 0,0,SNR ; COUNT DOWN BY ONE MOV# 1,1,SNR MOV# 0,0,SKP XXSTA 1,PTSWP ; SET CURENT GROUND IN IF NOT PRIVELEGED XXSTA 0,PTPRV ; AND STORE BACK ; SEE IF THERE IS A USER CLOCK DEFINED UCLOCK: LDA 3,UTOTL ;SEE IF ANY UCLKS MOV# 3,3,SNR JMP TODX ;NO .IFN IOSW LDA 2,CMAP STA 2,IMPSV ; SAVE CURRENT MAP .ENDC XXLDA 2,= PT1 ;FIRST TABLE UCL1: LDA 0,PCLAC,2 ;SEE IF A CLOCK IS DEF MOV# 0,0,SZR ;SKIP IF NO DSZ PCLAC,2 ;DEC TIMERn JMP TOD3 ;NO LDA 1,PCLCN,2 ;RESET CLOCK STA 1,PCLAC,2 .IFE MSW STA 2,PADD ;SAVE SO DIRTY USER CAN'T GET US ; AC0 FLAGS WHERE INT OCCURED ; = -1 IF IN SYSTM, = 1B0 IF IN OTHER PROCESS, ELSE = PC ADC 0,0  ;= IN SYSTEM CODE XXLDA 1,SYSIN,.SYIN MOV#e 1,1,SZR JMP USCIS ;IN RDOS LDA 1,CQ ;USER WE WERE IN SUBZR 0,0 ;IN OTHER USER FLAG SUB# 1,2,SNR LDA 0,0 ;LOAD PC- WE WERE IN HIM USCEX: JSR@ PCLAD,2 ;GO TO USER CODE LDA 2,PADD ;PLACE .ENDC .IFN MSW LDA 1,CMAP ;CURRENT MAP .IFN MNSW!MN3SW MOV# 1,1,SNR ;IF CURRENT 0 SET UCMAP=1 INC 1,1 .ENDC LDA 0,UCMAP ;HAVE WE CHANGED ONCE? MOV# 0,0,SNR STA 1,UCMAP ;SAVE FOR RESTORE .IFN MNSW!MN3SW JSR MAPED ;MAP IT LDA 2,CMAP ;RESTORE ; AC0 FLAGS WHERE INT OCCURED ; = -1 IF IN SYSTM, = 1B0 cIF IN OTHER PROCESS, ELSE = PC ADC 0,0 ;= IN SYSTEM CODE XXLDA 1,SYSIN,.SYIN MOV# 1,1,SZR JMP USCIS ;IN RDOS SUBZR 0,0 ;IN OTHER USER LDA 1,UCMAP ;INTERRUPTED USER SUB# 1,2,SZR JMP USCEX .IFN MNSW ; ORIGIONAL NOVA ONLY NIOP MAP ; GET PC JMP .+1 LDA 0,0 USCEX: LDA 1,PCLAD,2 ;PROC ADDRESS NIOS MAP .ENDC .IFN MN3SW LDA 0,0 ; PC OF INTERUPT USCEX: LDA 1,USRMP ; USER MAP DOA 1,MAP ; TO MAP LDA 1,PCLAD,2 ; ADDRESS OF ROUTINE .ENDC .ENDC .IFN IOSW XXJSR MAPCK ;SEE IF MAP CHANGE NEED;pED .ENDC .IFN MBSW ; AC0 FLAGS WHERE INT OCCURED ; = -1 IF IN SYSTM, = 1B0 IF IN OTHER PROCESS, ELSE = PC ADC 0,0 ;= IN SYSTEM CODE XXLDA 1,SYSIN,.SYIN MOV# 1,1,SZR JMP USCIS ;IN RDOS LDA 1,CQ ;USER WE WERE IN SUBZR 0,0 ;IN OTHER USER FLAG SUBg# 1,2,SNR LDA 0,0 ;LOAD PC- WE WERE IN HIM USCEX: LDA 1,PMST,2 ;STATE WORD STA 2,CMAP ;SAVE CURRENT PROG SELECTED DOA 1,BMAP ;SELECT AND TURN ON LDA 1,PCLAD,2 .ENDC STA 1,IWRTN ;EXIT JMP @IWRTN .ENDC .IFN MSW UCRIN: LDA 2,CMAP ;RESTORE LDA ?3,UCMAP ;REALLY IN THIS PATH ? .IFE MBSW MOV# 3,3,SNR ;SKIP IF YES XXJMP TCBAD ;NO-USER TRAPPED IN ERROR .ENDC B2 MOV# 3,3,SZR ;SKIP IF NO JMP UCR1 ; CONTINUE DSZ RTCI? ;NO MORE IN CLOCKER JMP .+1 ;WILL SKIP XXJMP TCBAD ;DO ERROR UCR1: [B2{>] .ENDC MOV# 1,1,SZR ;NO RESCHED FLAG FROM USER JSR IWKUP ;WAKE UP PROG TOD3: LDA 2,PLNK,2 ;NEXT PTBL COM# 2,2,SZR ;SKIP IF END JMP UCL1 .IFN IOSW LDA 2,IMPSV ;OLD CONTEXT XXJSR MAPCK ;RESTORE IT IF NEEDED .ENDC .IFN MSW LDA 2,UCMAP ;RESTORE NEEDED MOV# 2,2,SNR ;CAN BE = 1 JMP TODX ;NO RESTORE NEEDED ;NO .IFE MBSW MOVZR# 2,2,SZR ;IF = 1 DON'T REMAP JSR MAPED ;RESTORE TO PRIMEVIL STATE .ENDC .IFN MBSW STA 2,CMAP .ENDC SUB 0,0 STA 0,UCMAP ;INIT TODX: LDA 1,SFSTB ;SEE IF MAP> CHANGED MOV# 1,1,SNR JMP TODX3 ;NO .IFN MBSW STA 1,CLBLK .ENDC SMLB 1 ; SET THE LAST BLOCK SUB 0,0 STA 0,SFSTB ;FOR NEXT INT TODX3: .ENDC .IFE MSW TODX: .ENDC XXLDA 3,= HISTIN ;GET HISTOOGRAM POINTER COM# 3,3,SZR ;SEE IF HISTO THERE JM P 0,3 ;GO TO IT IHDN: .IFN ANSW LDA 1,RESCH ;RESCHED NEEDED ? MOV# 1,1,SNR XJMP TODX2 ;NO XXLDA 1,SYSIN,.SYIN ;IN SYSTEM ? XXLDA 3,INTLV ;AT TOP ADD 3,1,SZR ;ACCUMULATE XJMP TODX2 ;IF EITHER IN SYSTEM OR NOT AT ; TOP .IFN MNSW XDSZ INU&SR ;WHERE WERE WE? NIOP MAP ;IN THE USER - MAP IT JMP .+1 .ENDC LDA 0,0 ;GET PC XLDA 1,TCRY ;AND CARRY MOVL 1,1 ;MOVE TO CARRY MOVL 0,0 ;ADD TO PC XSTA 0,TIPC ;SAVE IT XLDA 3,= TIPC-IPCC ;DUMMY STATE SAVE BASE JMP DUSER ;COMMON EXIT .ENDC .IFN ABSW DSZ RTCI? ;NO MORE IN CLOCKER JMP .+1 ;WILL SKIP JMP DISMIS ;EXIT INTERRUPT SERVICE .ENDC CLPOOL .IFN MSW UCMAP: 0 .ENDC PADD: 0 UTOTL: 0 ;AC2 = PTBL TO READY IWKUP: STA 3,IWRTN LDA 3,PSTAT,2 ;RESET NOT READY IF SET XLDA 0,= 377e%77 AND 0,3 STA 3,PSTAT,2 XLDA 3,= 1 ;PRESERVE CARRY STA 3,PINTU,2 STA 3,RESCH JMP@ IWRTN IWRTN: 0 .IFN MBSW ; THIS ROUTINE IS ENTERED ON ALL MBIRDOS INTERRUPTS PRIOR ; TO GOING TO THE REAL INTERRUPT SERVICE ROUTINE ; NOT POWERFAIL MAPST: INTؔDS DIA 1,BMAP ;GET MAP STATE AT POINT OF ; INTERRUPT PSH 1,1 ;TO STACK INTEN JMP@ DCTIS,2 ;GO TO REAL INTERRUPT SERVICE .ENDC .IFN IOSW IMPSV: 0 .ENDC ULPOOL ; COMMON INTERRUPT DISMISSAL ROUTINE ; AC2 = DCT ADDR DISMIS: INTDS ;DISABLE /INTERRUPTS DISI2: .IFE MBSW!BSW LDA 3,CSP ;GET STACK POINTER LDA 0,USSV ;ORIGINAL SAVED STACK POINTER XDSZ INTLV ;AT BOTTOM? LDA 0,OSP,3 ;NO - JUST POP SS DISI3: STA 0,CSP ;SAVE NEW STACK POINTER LDA 1,ICMSK,3 ;OLD MASK .ENDC .IFN MBSW POP 0,Ts0 ;POP MAP STATE STA 0,DMAPX ;SAVE IT .ENDC .IFN MBSW!BSW XDSZ INTLV ;TAKE IT DOWN (UP?) JMP .+1 POP 1,1 ;POP MASK .ENDC MSKO 1 ;TO DEVICES STA 1,CMSK ;RESTORE SAVED MASK .IFN MBSW!BSW XLDA 1,INTLV ;AT TOP ? COM# 1,1,SZR JMP DISB ;NO-JUST RTN .ENDC XXLDA 2,UPQUE ;SEE IF RESCHED NEEDED LDA 1,RESCH ADD# 2,1,SNR ;SKIP IF YES JMP DSYS .IFE MBSW!BSW XLDA 2,INTLV XXLDA 1,SYSIN,.SYIN ;ADD TO LEVEL ADD# 1,2,SZR ;IN SYSTEM FLAG .ENDC .IFN BSW!MBSW XXLDA 1,SYSIN,.SYIN MOV# 1,1,SZR ;SKIP IF NIOT IN SYSTEM .ENDC JMP DSYS ;RETURN TO SYSTEM ; SUSPEND CURRENT TCB UNTIL SYSTEM LOOPS THRU QUEUES DUSER: SUBC 1,1 XSTA 1,RESCH ;CLEAR RESCH .IFN MSW LDA 2,CQ LDA 1,PMAP,2 .IFE MBSW XLDA 0,= 177 AND 0,1 LDA 0,CLSTB ADD 0,1 ;LAST BLOCK FOR DATA SMLB 1 XLDA 1,76001 ;GET MON INT FLAG .ENDC .IFN MBSW LDA 2,C31K DOB 1,BMAP LDA 1,1,2 .ENDC MOV# 1,1,SZR JMP DMON1 ;MON WAS INTERRUPTED LDA 1,C31K XLDA 0,76000+USP ;RESTORE USP .ENDC .IFE MSW LDA 0,USP ;RESTORE USP LDA 1~,@USTP ; CHECK IF USER IN MOVZR# 1,1,SZR ; UMTI TYPE MONITOR JMP DMON1 ; IF YES, STORE STUFF IN PROGRAM TABLE ; PUT AC'S INTO USER'S TCB .ENDC LDA 2,USTP LDA 2,USTCT,2 .IFN MSW ADD 1,2 .ENDC STA 0,TUSP,2 .IFN ANSW DUS2: LDA 0,IPCC,3 ;GET PC AkND CARRY STA 0,TPC,2 LDA 0,IAC0,3 ;AC0 STA 0,TAC0,2 LDA 1,IAC1,3 ;AC1 STA 1,TAC1,2 LDA 0,IAC2,3 ;AC2 STA 0,TAC2,2 LDA 0,IAC3,3 ;AC3 STA 0,TAC3,2 MOVL# 2,2,SZC ; ETCB OR STORING INTO PROGRAM TABLE USED? XXJMP SMON ; YES, NO EXTENDED SAVE .IFN vN3SW XXLDA 1,ENVIR ;CHECK FOR NOVA 3 XLDA 0,= ENUN3 AND# 0,1,SNR ; JMP NOSV ; NOPE-- DON'T SAVE STACK MFSP 0 ;SAVE STACK POINTER STA 0,TSP,2 ; MFFP 0 ;SAVE FRAME POINTE STA 0,TFP,2 ; LDA 0,CSL ;STACK LINIT STA 0,TSL,2 LDA 0,TRPC ;INST>RUCTION TRAP PC STA 0,TSO,2 ; NOSV: .ENDC .IFN MN3SW LDA 3,C31K MFSP 0 ;SAVE STACK POINTER STA 0,TSP,2 ; MFFP 0 ;SAVE FRAME POINTE STA 0,TFP,2 ; LDA 0,CSL,3 ;STACK LINIT STA 0,TSL,2 LDA 0,TRPC,3 ;INSTRUCTION TRAP PC STA 0,TSO,2 ; .ENDC  .ENDC .IFN ABSW DUS2: POP 1,0 ;POP PC AND AC3 MOVZL 1,1,SZC ;MAKE INTO RDOS PC+CARRY INC 1,1 ;CARRY STA 1,TPC,2 ;TO TCB STA 0,TAC3,2 ;AC3 POP 1,3 ;POP AC2,AC1,AC0 STA 1,TAC2,2 STA 0,TAC1,2 STA 3,TAC0,2 ; ONLY SAVE IN PTBL IF UNMAPPED BIRD  .IFN BSW LDA 3,CQ ;PTBL POP 1,0 ;POP STK FAULT AND END STA 1,PSSV1+CSO-HRBEG,3 STA 0,PSSV1+CSL-HRBEG,3 MOVL# 2,2,SNC ; IF NOT TCB THEN SKIP STA 1,TSO,2 ;ALSO SAVE IN TCB FOR MULTITASK ; CASE MOVL# 2,2,SNC ; IF NOT TCB THEN SKIP STA 0,TSL,2hy POP 1,0 ;POP FP AND SP STA 1,PSSV1+CSP-HRBEG,3 STA 0,PSSV1+SP-HRBEG,3 MOVL# 2,2,SNC ; IF NOT TCB THEN SKIP STA 1,TFP,2 ;FOR MULTITASK CASE MOVL# 2,2,SNC ; IF NOT TCB THEN SKIP STA 0,TSP,2 LDA 0,XOPA ;XOP ORIGIN ADDRESS STA 0,PSSV1+XOPA-HRBEG,3 ;SAVE IT LDA 0,FPFA ;FLOATING POINT FAULT ADDRESS STA 0,PSSV1+FPFA-HRBEG,3 ;SAVE IT LDA 0,46 ; SAVE 46 AND 47 IN PROGRAM TABLE STA 0,PSSV7,3 LDA 0,47 STA 0,PSSV8,3 .ENDC MOVL# 2,2,SZC ; ETCB USED? XXJMP SMON ; YES - NO EXTENDED SAVE .IFN MBSW ; MOVE STACK INFO TO TCB LDA 3,C31K LDA 0,SP,3 STA 0,TSP,2 LDA 0,CSP,3 STA 0,TFP,2 LDA 0,CSL,3 STA 0,TSL,2 LDA 0,CSO,3 STA 0,TSO,2 .ENDC .ENDC LDA 3,USTP LDA 1,USTSV,3 ;EXTENDED SAVE ADDR ? MOVZL 1,1,SNR ;EXTENDED SAVE ? XXJMP SMON ;dNO MOVOR 1,1 ;SET FLAG STA 1,USTSV,3 ;SYSTE WILL FOLLOW UP XXJMP SMON CLPOOL .IFN ANSW DSYS: LDA 0,IRLOC,3 STA 0,RLOC ;LINKAGE TEMPORARY DCEX: LDA 0,IPCC,3 ;PC AND CARRY MOVZR 0,1 ;RESTORE CARRY STA 1,0 ;AND PUT PC BACK LDA 0,IAC0,3 LDA 1,IRZAC1,3 .IFN MNSW LDA 2,INTUS,3 STA 2,DMAPX .ENDC .IFN MN3SW LDA 2,INTUS,3 ; OLD MAP STATE DOA 2,MAP ; TO MAP .ENDC LDA 2,IAC2,3 LDA 3,IAC3,3 .IFN MNSW DSZ DMAPX ;IN USER NIOS MAP ;YES - HIT MAP .ENDC INTEN JMP @0 .ENDC .IFN ANSW USSV: 0 ;BASE LEVEL STACK POINTER .ENDC .IFN MSW DMAPX: 0 .ENDC .IFN MBSW!BSW DISB: .IFN MBSW LDA 1,DMAPX ;MAP STATE DOA 1,BMAP ;RESTORE .ENDC INTEN POPB ;TO LAST INTERRUPT STATE DSYS: .IFN MBSW LDA 1,DMAPX DOA 1,BMAP ;RESTORE MAP STATE .E2NDC INTEN RSTR ;RESTORE PRE-INTERRUPT STATE ; AND STK .ENDC ULPOOL .IFE MSW ; ONLY UNMAPPED ; RETURN FROM USER ROUTINE ; AC1= RESCHEDULE CODE, AC3= CALLING ADDRESS ; IF AC1= 0 ; NO RESCHEDULE UINTR: INTDS MOV# 1,1,SNR ;SKIP IF RESCHED JMP DISI2 XXLDA 1,SYSFG ;FG RUNNING ? MOV# 1,1,SNR JMP UIRT3 ;NO XXLDA 2,= PT1 ;FG XXLDA 1,SFGNP ;FG NREL SUBZ# 3,1,SZC ;SKIP IF CALLING LOC BELONGS TO FG UIRT3: XXLDA 2,= PT2 ;BG DEV XJSR IWKUP ;WAKE UP LITTLE SUSEY JMP DISI2 .ENDC .IFN? MBSW UINTR: .IFN IOSW POP 2,2 ;OLD MAP PSH 1,1 ;INFOS:2.00 - SAVE THE RESCHEDULING FLAG FROM USER JSR MAPCK POP 1,1 ;INFOS:2.00 - RESTORE THE RESCHEDULING FLAG .ENDC XLDA 2,INTLV ;SEE IF IN INT WORLD COM# 2,2,SNR XXJMP TCBAD ;NO-USER TRAPPεED AT RANDOM POP 3,3 ;POP OLD CMAP .IFE IOSW LDA 2,CMAP ;PTBL ADDR OF USER RETURNING STA 3,CMAP ;RESTORE CMAP LDA 3,0,3 ;STATE WORD SBI 1,3 ; DON'T TURN ON-JUST SELECT .ENDC .IFN IOSW POP 2,2 ; GET USER PT STA 3,CMAP ; RESTORE CMAP POP 3,3 ; RESTORE STATE WORD MOVZR 3,3 MOVZL 3,3 ; DON'T ENABLE MAP .ENDC DOA 3,BMAP MOV# 1,1,SZR ;RESCHEDULE ASKED FOR ? XJSR IWKUP ;YES JMP DISI2 ;EXIT .ENDC ; THIS HERE CODE IS ENTERED FOR ALL USER DEFINED DEVICES ; IT WILL SAVE THE MAP STATE AND SELECT THE USER MAP ; IF BIRDOS,IT JUST LOADS THE RETURN AND EXITS TO THE USER ROUTINE .IFN MBSW UDEX: INTDS DIA 1,BMAP ;GET MAP STATE PSH 1,1 ;TO STK .IFE IOSW LDA 1,CMAP ;PTBL .ENDC PSH 1,1 ;TO STK XXLDA 1,IVTTB SUBZL# 1,2,SNR ;IS IT THE  IVT? XXJSR IIVT ;YES - SHOW OTHER PROC DEAD INTEN LDA 1,UIDCD-UIDEX,2 ;BIT 0 = 1 IF FG .IFE IOSW XXLDA 3,= PT2 MOVL# 1,1,SZC XXLDA 3,= PT1 .ENDC .IFN IOSW MOV 2,3 XXLDA 2,= PT2 MOVL# 1,1,SZC ;SKIP IF GOING TO BG XXLDA 2,= PT1 PSH 2,2 ; SAVE USER PT LDA 1,CMAP ; GET OLD CMAP PSH 1,1 ; SAVE PSH 1,1 ; AND AGAIN PSH 3,3 ; SAVE DCT JSR MAPCK ;INSTALL CONTEXT MOV 2,3 ;PTBL POP 2,2 .ENDC STA 3,CMAP ;SELECTED LDA 3,0,3 ;TURN ON XLDA 1,= -MPSLF-1 ;DISABLE LFE AND 1,3 DOA 3,BMAP MOV 2,3 ; GIVE THE USER HIS DCT ADDRESS IN AC2 LDA 2,UIDCT-UIDEX,3 INTEN JMP @UIDIS-UIDEX,3 ;GO TO USER .ENDC .IFN BSW UDEX: XXLDA 1,IVTTB INTDS ;TURN OFF, IN CASE, FOR IVT ROUTINE SUBZL# 1,2,SNR ;IS IT THE IVT? XXJSR IIVT ;YES INTEN ;BACK AGAIN XXLDA 3,= UINTR ;RTN ADDR JMP@ DCTIS,2 .ENDC CLPOOL DMON1: LDA 2,CQ ; GET PROGRAM TABLE ADDRESS .IFN USW STA 0,PMUSP,2 .ENDC .IFN N3SW XXLDA 1,ENVIR ;CHECK FOR NOVA 3 XLDA 0,= ENUN3 AND# 0,1,SNR ; JMP NOSV1 ; NOPE-- DON'T SA"KVE STACK .ENDC .IFN MN3SW!N3SW MFSP 0 ;SAVE STACK POINTER STA 0,PN3SP,2 ; MFFP 0 ;SAVE FRAME POINTE STA 0,PN3FP,2 ; NOSV1: .ENDC XLDA 1,= @PMPC ;OFFSET FOR PTBL SAVE AREA ADD 1,2 ;FOR COMMON CODE JMP DUS2 ;MAPPED RETURN FROM USER ROUTINE ; USER SETS AC1 = 0 IF NO RESCHEDULE NEEDED .IFN MNSW!MN3SW UINTR: .IFN MN3SW SUB 3,3 LDA 0,.STOF STA 3,.STOF MOV 0,0,SZR ; WAS IT STACK OVERFLOW ? XJMP DISMIS ; YES JUST DISMISS .ENDC LDA 3,CSP XLDA 0,INTLV ;SEE IF IN INT WORLD MOV# 0,@0,SNR XXJMP TCBAD ;NO-USER TRAPPED AT RANDOM LDA 0,USSV ;BASE LEVEL STACK XDSZ INTLV ;BACK UP... LDA 0,OSP,3 ;NOT AT TOP - JUST POP STACK STA 0,CSP LDA 0,ICMSK,3 MSKO 0 ;SET OLD MASK STA 0,CMSK MOV# 1,1,SNR ;RESCHEDULE NEEDED? JMP UNOTU ;NpO MOV 3,1 ;SAVE POINTER LDA 2,CMAP ;PTBL FOR INT USER XJSR IWKUP ;RESCHEDULE MOV 1,3 ;RESTORE XXLDA 1,SYSIN,.SYIN ;SEE IF NOT IN SYSTEM XXLDA 2,INTLV ;OR IF NOT AT BOTTOM ADD# 2,1,SNR ;SKIP IF EITHER TRUE JMP DUSER UNOTU: LDA 2,IRLOC,3 ;OLD 9CMAP STA 3,DMAPX ;SAVE AC3 MOV# 2,2,SZR ;NOT IF CMAP WAS 0 JSR MAPED ;MAP IT LDA 3,DMAPX ;RESTORE STATE POINTER JMP DCEX .ENDC .IFN MSW .ENDC .IFN IOSW ; SEE IF MAP CONTENTS IS OK ; AC2= CONTEXT ; IF 0B0 AC2= PT1,PT2 ; IF 1B0 AC2= IOCS STATI.C SYSTEM BASE- CMAPI= DYNAMIC BASE ; ON RTN AC1,AC3 GONZO MAPCK: LDA 0,CMAPA SUB# 0,2,SNR ;SKIP IF NOT THERE JMP 0,3 ;NO LOAD NEEDED LDA 0,CMAPB SUB# 0,2,SNR JMP 0,3 ;NO LOAD NEEDED ; MUST LOAD UP MAP SUBC 1,1 ;INFOS:2.00 - CLEAR AC1 SKPBZ CPUb ;INFOS:2.00 - SEE IF INTERRUPTS ON AT ENTRY INC 1,1 ;INFOS:2.00 - IF ON THE SET FLAG PSH 1,3 ;SAVE AC2 AND RTN MOVL# 2,2,SZC ;SKIP IF USER JMP MAPC1 ;IOCS .IFN NEWMAP ;INFOS:2.00 - IF NEW MAP, MUST LDA 0,PMST,2 ;INFOS:2.00 - GET MAP SELECT WOj6RD DOC 0,BMAP ;INFOS:2.00 - SELECT THE MAP FOR THE LMP .ENDC ;INFOS:2.00 - END CONDITIONAL ADDI PMAP,2 ;MAP BASE LDA 1,C32 ;LOAD IT ALL UP SUB 0,0 MAPC2: INTDS LMP ;****** HOME: POP 3,1 ; RESTORE REGS STA 2,@ADMAP STA 2,CMAP MOV# 1,1,SZR ;- ENABLE IF DISABLED INTEN JMP 0,3 ; LOAD IOCS MAP MAPC1: ADDOR 2,2 LDA 0,IMPSL ;A OR B MAP SELECT LDA 1,.ISMSZ ;SYSTEM MAP SIZE INTDS ; DON'T LET NOTHIN HAPPEN WHILE MAP CHANGEING .IFN NEWMAP ;INFOS:2.00 - IF NEW MAP DOC 0,BMAP ;INFOS:2.00 - SELECT MAP AND SUBC 0,0 ;INFOS:2.00 - CLEAR AC0 FOR THE LMP .ENDC ;INFOS:2.00 - LMP LDA 2,CMAPI ;DYNAMIC MAP MOV# 2,2,SNR ;IF 0 NO CONTEXT JMP HOME LDA 1,.IDYSZ ;SIZE JMP MAPC2 C32: 32. .ISMSZ: SMSZ .IDYSZ: DMSZ .ENDC CLPOOL ; BIG BEN T[ODI: 0 ;CLOCK INCS/SEC COUNTER SCNT ;INCS/SEC TODS: 0 ;SEC/MIN COUNTER 3600. TODH: 0 ;HOUR COUNTER 24. TODD: 1 ;DAY COUNTER (JULIAN) - DOES ; NOT RECYCLE -1 ;END OF TABLE .IFN N3SW!MN3SW STKDC: 0 ; NOVA3 STACK HANDLER DCT 0 USTIS ; INTERUPT ADDRESS USTIS: INTDS ; DO IT QUIETLY MLDA 3,CSO ; OVERFLOW HANDLER DEFINED MOV 3,3,SNR ; WELL ? XJMP DISMIS ; NO FORGET IT MLDA 1,CSL ; STACK LIMIT MFSP 0 ; STACK POINTER .IFN N3SW ; UNMAPED USLT 0,1 ; OVERFLOW ? JSR @CSO ; YES LET USER KNOW XJMP DISMIS ; DISMIS THE INTERUPT .ENDC .IFN MN3SW ; MAPPED USGE 0,1 ; IF NOT OVERFLOW XJMP DISMIS ; THEN EXIT ELSE ISZ .STOF ; SHOW STACK INTERUPT MLDA 2,CSO ; GET OVERFLOW HANDLER STA 2,STKEX ; SAVE FOR EXIT LDA 3,CS P ; STACK POINTER LDA 3,INTUS,3 ; MAP OF USER WHO TRAPED DOA 3,MAP ; TO MAP JMP @STKEX ; TO USER STKEX: 0 .STOF: 0 .ENDC .ENDC LPOOL .IFN MSW UITBL: .BLK 12*UILTH -1 ;MARK END OF TABLE .ENDC .END DUMP.SRB . ; DUMP.SR ; CORE DUMP ROUTINE RTITLE DUMP .NREL .TXTM 1 .ENT DUMP,PDUMP .ENT DUMPT ; DUMP TYPE SWITCH, CONTENTS ; BEING NON-ZERO SAYS DUMP TO ; DATA CHANNEL LINE PRINTER .EXTN DUMPF ; FLAG SET BY SYSGEN ON TYPE OF ; LINE PRINTER WEwY ARE TO DUMP ; TO, STORED IN "DUMPT" .EXTN REG ;WHERE TO FIND SAVED REGISTERS INTR: NIOC TTI ;ZAP TTI DUMP: HALT ;HALT FOR ENTRY VIA SWITCHES PDUMP: SUB 0,0 ;ZERO STA 0,START ;STARTING DUMP ADDRESS LDA 2,LASTA ;77770 STA 2,END ;STOP THERE:X READS 0 ;READ SWS HALT ;WAIT FOR NEXT READING READS 1 ;SWS SUB# 0,1,SNR ;DUMP ALL IF THE SAME JMP DMPAL AND 2,0 ;0 MOD 8 STA 0,START AND 2,1 ;0 MOD 8 STA 1,END .IFN USW ; UNMMAPPED SYSTEM DUMP DMPAL: LDA 0,FF ;FORM FEED PRINTER JSR PUT ;PUTIT LDA 1,.T ;ADDRESS OF STATUS AREA JSR O.LINE ;OUTPUT THE LINE BREAK: LDA 1,START ;CURRENT ADDRESS JSR PUTADR ;PRINT ADDRESS LDA 0,CHAR LDA 2,SPACE STA 2,CHAR JSR PUT LDA 1,START ;ADDRESS AGAIN JSR OLINE ;PRINT A LINE OF DUMP SKP!DZ TTI ;KEYBOARD INPUT ? JMP INTR ;YES - ABORT DUMP NXLIN: LDA 2,START ;CURRENT ADDRESS LDA 3,TEN ;INCREMENT STA 3,RC2 ;SETUP CONSTANT ADD 2,3 ;ADDRESS OF NEXT LINE STA 3,START ;FOR NEXT LINE LDA 1,END ;LAST ADDRESS ADCZ# 2,1,SNC ;SLT 2,1 JMP INTR ;ALL DONE - BAG IT CKLP: LDA 0,0,2 ;WORD OF LAST LINE LDA 1,0,3 ;WORD OF NEXT LINE SUB# 0,1,SZR ;SAME ? JMP BREAK ;NO - PRINT THIS LINE INC 2,2 ;FOR NEXT INC 3,3 DSZ RC2 ;DONE ? JMP CKLP ;KEEP GOING LDA 0,STAR ;STAR NEXT PRINT LIN3E STA 0,CHAR JMP NXLIN ;DONT PRINT THIS LINE START: 0 ;STARTING ADDRESS TEN: 10 ;SURE ENUF RC2: 0 ;WORD COUNTER CHAR: " FF: 14 END: 0 LASTA: 77770 ; ; OUTPUT A LINE TO THE LINE PRINTER ; ; AC1: ADDRESS OF EIGHT LOCATIONS TO PRINT ; ALL AC'S DAESTROYED ; O.LINE: LDA 0,PR.CAD ;PANIC LOC INFO LDA 2,C5 ;FIVE LOCS TO PRINT JMP OSKIP ;CONTINUE OLINE: LDA 0,PRCAD ;NORMAL INFO LDA 2,TEN ;TEN LOCS TO PRINT OSKIP: STA 0,PROC ;INIT PROCEDURE TABLE STA 1,FIRST ;SAVE FIRST ADDRESS STA 3,OLRET ,;SAVE RETURN OLLP1: STA 2,RC1 ;SAVE COUNT LDA 1,FIRST ;WORD ADDRESS STA 1,CADD ;SAVE CURRENT ADDRESS OLLP: LDA @1,CADD ;WORD ISZ CADD ;BUMPIT JSR @PROC ;PROCESS THE WORD DSZ RC1 ;DONE ? JMP OLLP ;NEXT WORD ISZ PROC ;NEXT ENTRY LDA 2,TEN .;PICK UP TEN COUNT FOR NORMAL CASE JMP OLLP1 ;KEEP GOING QUIT: LDA 0,CR ;END OF LINE PROCESSOR JSR PUT LDA 0,LF JSR PUT JMP @OLRET PRCAD: @.+1 BINASC ;BINARY PUTBY ;BYTES QUIT ;ALL DONE PR.CAD: @.+1 BINASC QUIT OLRET: 0 ;RETURN ADDRMESS PROC: 0 ;PROCESSING ROUTINE RC1: 0 ;COUNTER FIRST: 0 ;WORD ADDRESS CADD: 0 CR: 15 LF: 12 .T: REG C5: 5 HI: "Z LO: " SPACE: " ; ; PRINT BYTES ; ; AC1: WORD ; PUTBY: STA 3,PBRET ;SAVE RETURN MOV 1,0 ;TO AC0 LDA 1,C377 ;MASK AND 0,1 SU|BOS 1,0 ;SEPERATE BYTES AGAIN: LDA 2,HI ;HI LIMIT LDA 3,LO ;LOW LIMIT SUBZ# 0,2,SZC ;SGT 0,2 ADCZ# 0,3,SZC ;SGE 0,3 LDA 0,STAR ;NON PRINTING JSR PUT ;PRINT CHARACTER MOVC 1,0,SZC ;DONE ? JMP AGAIN ;MO - DO OTHER JMP @PBRET ;RETURN PBRET: 0 ;SAVE RETURN C377: 377 STAR: "* ;STAR BINAS: STA 3,BINRT ;SAVE RETURN ADDRESS SUBZR 2,2,SKP ;100000 BNLP: SUB 2,1,SKP ;FIRST DIGIT BNLP1: LDA 0,C57 ;ZERO - 1 INC 0,0 SUBZL# 2,1,SNC JMP BNLP JSR PUT ALT: MOVZR 2,2 MOVZR 2,2 MOVZR 2,2,SZR v JMP BNLP1 JSR PUTSP JMP @BINRT ;RETURN PUTAD: STA 3,BINRT ;SAVE RETURN SUBZR 2,2 MOVL 1,1 ;SCRATCH 1B0 MOVZR 1,1 JMP ALT ;JUMP IN BINRT: 0 C57: 57 .ENDC .IFN MSW DMPAL: LDA 0,FF ;FORM FEED PRINTER JSR@ .PUT ;PUTIT LDA 1,.T ;ADDRESS OFG STATUS AREA JSR O.LINE ;OUTPUT THE LINE BREAK: LDA 1,START ;CURRENT ADDRESS JSR XBINA LDA 0,ZERO JSR@ .PUT ;FINAL ZERO LDA 0,CHAR LDA 2,SPACE STA 2,CHAR JSR@ .PUT LDA 1,START ;ADDRESS AGAIN JSR OLINE ;PRINT A LINE OF DUMP SKPDZ TTI ;KEYBOARD IN6|PUT ? JMP INTR ;YES - ABORT DUMP NXLIN: LDA 2,START ;CURRENT ADDRESS ISZ START ;BUMP FOR NEXT LINE LDA 3,TEN ;INCREMENT STA 3,RC2 ;SETUP CONSTANT LDA 1,END ;LAST ADDRESS ADCZ# 2,1,SNC ;SLT 2,1 JMP INTR ;ALL DONE - BAG IT STA 2,COMPD ;SAVE COMPARE ADDRESS CKLP: LDA 0,COMPD ;COMPARE ADDRESS LDA 1,RC2 ;WORD IN LINE JSR@ .ALOAD ;LOAD A WORD FROM MEMORY STA 1,SWORD ;SAVE IT LDA 0,COMPD ;ADDRESS AGAIN INC 0,0 ;NEXT LINE LDA 1,RC2 ;RESTORE LOW ORDER BITS JSR@ .ALOAD ;GET CORRESPONDING WORD LDA 0,SWORD ;SAVED WORD SUB# 0,1,SZR ;SAME ? JMP BREAK ;NO - PRINT THIS LINE DSZ RC2 ;DONE ? JMP CKLP ;KEEP GOING LDA 0,STAR ;STAR NEXT PRINT LINE STA 0,CHAR JMP NXLIN ;DONT PRINT THIS LINE .ALOAD: ALOAD .PUT: PUT START: 0 ;STARTING ADDRESS TEN: 10 ;SURE ENUF RC2: 0 ;WORD COUNTER CHAR: " FF: 14 END: 0 ZERO: "0 SWORD: 0 COMPD: 0 LASTA: ((MPAPH&377)+1)*(2000/10)-1 ; ; OUTPUT A LINE TO THE LINE PRINTER ; ; AC1: ADDRESS OF EIGHT LOCATIONS TO PRINT ; ALL AC'S DESTROYED ; OLINE: MOVO 1,1,SKP ;NORMAL ENOTRY O.LINE: MOVZ 1,1 ;PRINT PANIC INFO ENTRY STA 3,OLRET ;SAVE RETURN LDA 0,PRCAD ;PROCEDURE TABLE STA 0,PROC ;INIT IT STA 1,FIRST ;SAVE FIRST ADDRESS SUBC 0,0,SZC ;SKIP IF PANIC INFO ENTRY JMP OLLP1 ; ELSE CONTINUE NORMALLY (AC0= 0) LDA 0,C5 ;5 LOCATIONS TO PRINT STA 0,RC1 ALOOP: LDA 1,@FIRST ;PICK UP DATA JSR @PROC ;PRINT IT ISZ FIRST ;TO NEXT DATA DSZ RC1 ;SKIP IF DONE JMP ALOOP ; ELSE LOOP AWAY JMP QUIT ;ALL DONE OLLP1: LDA 1,TEN ;TEN OCTAL LOCATIONS STA 1,RC1 ;SAVE IT LDA 1,FIRST ;WORD ADDRESS LDA 3,CM3 ;-3 MOVZL 1,1 ;BIT TO CARRY MOVL 0,0 ;MOVE TO AC0 INC 3,3,SZR ;SHIFT LEFT THREE BITS JMP .-3 STA 0,HIAD ;HIGH PART OF ADDRESS STA 1,LOWAD ;LOW ADDRESS OLLP: LDA 0,HIAD ;HIGH ADDRESS LDA 1,LOWAD ;LOW ADDRESS JSR pWLOAD ;LOAD WORD FROM MEMORY ISZ LOWAD ;INCREMENT LOW PART JMP .+2 ISZ HIAD ;ZERO - CARRY TO HIGH ORDER JSR@ PROC ;PROCESS THE WORD DSZ RC1 ;DONE ? JMP OLLP ;NEXT WORD ISZ PROC ;NEXT ENTRY JMP OLLP1 ;KEEP GOING QUIT: LDA 0,CR ;END OF LINE PROCESSOR JSR PUT LDA 0,LF JSR PUT JMP@ OLRET PRCAD: @.+1 BINARY ;BINARY PUTBY ;BYTES QUIT ;ALL DONE C5: 5 CM3: -3 OLRET: 0 ;RETURN ADDRESS PROC: 0 ;PROCESSING ROUTINE RC1: 0 ;COUNTER FIRST: 0 ;WORD ADDRESS HIAD: 0 LOWAD: 0 CC31K: 1777 CR: 15 LF: 12 .T: REG HI: "Z LO: " SPACE: " ; ; PRINT BYTES ; ; AC1: WORD ; PUTBY: STA 3,PBRET ;SAVE RETURN MOV 1,0 ;TO AC0 LDA 1,C377 ;MASK AND 0,1 SUBOS 1,0 ;SEPERATE BYTES AGAIN: LDA 2,HI ;HI LIMIT LDA 3,LO ;LOW LIMIT SUBZ# 0,2,SZC ;SGT 0,2 ADCZ# 0,3N,SZC ;SGE 0,3 LDA 0,STAR ;NON PRINTING JSR PUT ;PRINT CHARACTER MOVC 1,0,SZC ;DONE ? JMP AGAIN ;NO - DO OTHER JMP@ PBRET ;RETURN PBRET: 0 ;SAVE RETURN C377: 377 STAR: "* ;STAR XBINA: LDA 2,XMASK ;MASK JMP .+2 BINAS: LDA 2,MASK STA 3,BINRT ;SAVEe RETURN BNLP: LDA 3,ZERO ;ASCII ZERO SUB 0,0 ;CLEAR AC0 MOVZL 1,1 ;SHIFT BINARY WORD MOVL 0,0 ;BIT TO AC0 MOVZL 2,2,SNC ;SHIFT MASK - DIGIT DONE ? JMP .-3 ;NO - KEEP GOING ADD 3,0 ;MAKE ASCII DIGIT JSR PUT ;PRINT IT MOV# 2,2,SZR ;DONE WHEN MASK EXHAUSTED JMP BNLP JMP@ BINRT MASK: 111111 XMASK: 11111 BINAR: STA 3,BYRET JSR BINASC JSR PUTSP JMP@ BYRET BYRET: 0 BINRT: 0 C57: 57 ; ; ROUTINE TO LOAD WORD FROM MEMORY ; ; AC0/AC1: ADDRESS (18 BITS) ; RETURN VALUE IN AC1  LOAD: STA 3,LOADR $r;SAVE ETURN ADDRESS MOVL 1,2 ;COPY AC1 LDA 3,MC6 ;6 COUNT MOVL 0,0 MOVL 2,2 INC 3,3,SZR ;SHIFT BLOCK BITS TO AC2 JMP .-3 .IFN MNSW!MN3SW LDA 3,CLSTB ;PROTECT BITS ADD 3,0 ;FORM MAP WORD .ENDC SMLB 0 ; SET MAP LAST BLOCK .IFN MN3SW ; SET PULSE TO WORK OFF WORD SUB 0,0 ; JUST PUT IN MAP DOA 0,MAP .ENDC LDA 2,CC31K ;WORD MASK (10 BITS) AND 2,1 ;RID OF BLOCK BITS COM 2,2 ADD 1,2 ;WORD OFFSET IN LAST BLOCK .IFN MN3SW NIOP MAP .ENDC LDA 1,0,2 ;LOAD WORD JMP@ LOADR ;RETURN LOADR: 0 MC13: -13. MC6: -6 .IFN MNSW CLSTB: 17400 .ENDC .IFN MN3SW CLSTB: 76000 .ENDC ; ; ALT LOAD A WORD ROUTINE ; ; AC0: HIGH 15 BITS OF ADDRESS ; AC1: LOW 3 BITS (RIGHT JUSTIFIED) ; AC1: RETURNED VALUE ALOAD: STA 3,LOADR ;SAVE RETURN ADDRESS MOVR 1,1 ;LEFT  JUSTIFY LOW 3 BITS MOVR 1,1 MOVR 1,1 MOVR 1,1 ;AGAIN LDA 3,MC13 ;SHIFT RIGHT DOUBLE 13 MOVZR 0,0 MOVR 1,1 INC 3,3,SZR JMP .-3 JMP LOAD+1 .ENDC PUTSP: LDA 0,SPACE ;A SPACE PUT: STA 3,PUTRT ; SAVE RETURN ADDRESS SKPBZ LPT ;WAIT FOR PRINTER JMP .-1 LDA 3,DUMPT ; IF GOING TO DATA CHAN SEQZ 3 ; THEN WE MUST JUMP JMP PUTDC ; ELSE WE JUST DOAS 0,LPT ; SEND THE CHAR JMP @PUTRT PUTDC: STA 0,PUTCH ; STORE CHAR TO SEND ADC 3,3 ; SAY WE IS OUTING ONE DOC 3,LPT ; CHARACTER LDA 3,.PUTCH ; SAY WHERE CHAR IS DOBS 3,LPT ; AND START IT OUT JMP @PUTRT DUMPT: DUMPF ; ZERO EQUAL DUMP TO NORMAL PRINTER ; NON-ZERO SAYS DATA CHANNEL PRINTER PUTRT: 0 .PUTCH: .+1*2+1 PUTCH: 0 .END MTDMP.SRB |; ; MTDMP MAGTAPE DUMP ROUTINE RTITLE MTDMP ; ENTRY POINTS IN THIS MODULE USED BY OTHER MODULES .ENT ALDMP ; DUMP THE CORE TO THE MAG-TAPE UNIT 3 .ENT MTDMP ; ENTRY POINT TO CAUSE THIS MODULE TO BE LOADED ; ENTRY POINTS IN OTHER MODULES CALLED HERE . .EXTN SIZE ; IS THIS PHYSICAL BLOCK IS PRESENT? .EXTN TYPE ; ROUTINE TO TYPE MESSAGES, ; TRAILING ARGUMENT IS WORD POINTER .EXTN RETRY ; THE DUMP WAS COMPLETED OR THERE WAS AN ERROR ; DEFINE DEVICE STATUS BITS ER= 1B0 ; ERROR DL= 1B1 ; DATA hLATE RW= 1B2 ; UNIT IS REWINDING IL= 1B3 ; ILLEGAL STATUS DN= 1B4 ; RECORDING DENSITY 1=HIGH,0=LOW PR= 1B5 ; PARITY ERROR ET= 1B6 ; END OF TAPE ENCOUNTERED EF= 1B7 ; END OF FILE LP= 1B8 ; LOAD POINT ( BOT ) UT= 1B9 ; UNIT TYPE 1= 9, 0= 7 : TRACK BT= 1B10 ; BAD TAPE TT= 1B11 TT= 1B12 WP= 1B13 ; UNIT IS WRITE PROTECTED OC= 1B14 ; ODD CHARACTER UR= 1B15 ; UNIT READY MTAUN=3 ; UNIT NUMBER, SET IN SYSGEN WRITE=5 ; COMMAND TO WRITE TO MTA WREOF=6 ; COMMAND TO WRITE-EOF TO MTA REWIND=1 ; COMMAND TO REWIND THE MAG-TAPE .NREL ; ALDUMP ; THIS ROUTINE OUTPUTS CORE TO MAGTAPE MEDIA UNTILL FINISHED ; OR THERE IS AN MAG-TAPE ERROR. FIRST IT REWINDS, THEN ; WRITES CORE, THEN WRITES TWO EOF'S, THEN REWINDS. ; FOR AN ERROR AC1 IS RyETURNED WITH THE ERROR CODE. MTDMP: ; ENTRY POINT TO CAUSE THIS MODULE TO BE LOADED ; SELECT THE UNIT, GET THE DEVICE STATUS, CHECK IF WRITE-PROTECTED ALDMP: SUB 1,1 ; SET INITIAL CORE ADDRESS TO ZERO SKPBZ MTA ; WAIT UNTIL NOT IN USE JMP .-1 XLDA 0,= MTAUN ; GET THE MAG-TAPE UNIT NUMBER DOA 0,MTA ; SELECT THE UNIT DIA 2,MTA ; GET THE STATUS OF THE UNIT XLDA 0,= WP ; WRITE-LOCK BIT AND# 2,0,SZR JMP ERR ; UNIT WRITE-PROTECTED MOVR# 2,2,SNC JMP ERR ; UNIT NOT READY, ERROR ; IF 7-TRACK THEN Sz IMPLY GIVE-UP XLDA 0,= UT ; UNIT TYPE, 9 TRACK IS SET AND# 2,0,SNR JMP ERR7T ; NO 7-TRACK MAG-TAPE ; REWIND THE MAG-TAPE FIRST XLDA 2,= REWIND*1B12+MTAUN ; REWIND COMMAND JSR MTACM ; GO REWIND DIA 2,MTA ; ERROR STATUS WORD MOVR# 2,2,SNC JMP .-2 ; WAIT UNTILL READY ; OUTPUT 1K WORD BLOCKS OF CORE UNTILL FINISHED SUB 0,0 MTASIZ: XXJSR SIZE ; RETURN + 1 IF NOTHING AT THIS PHYSICAL ; PAGE, RETURN AC1 = LOGICAL ADDRESS JMP FINIS ; FINISHED XLDA 2,= WRITE*1B12+MTAUN ; COMMAND TO WRITE THE BZLOCK JSR MTACM ; GO WRITE THE BLOCK TO TAPE INC 0,0 ; POINT TO NEXT 1K BLOCK JMP MTASIZ ; GO DO THE NEXT 1K BLOCK ; FINISHED, WRITE 2 EOF'S FINIS: XLDA 2,= WREOF*1B12+MTAUN ; WRITE EOF COMMAND JSR MTACM ; GO WRITE AN EOF XLDA 3,= EF ; EOF STATUSD BIT AND# 3,2,SNR JMP ERR ; NO EOF WRITTEN XLDA 2,= WREOF*1B12+MTAUN ; WRITE EOF COMMAND JSR MTACM ; GO WRITE AND EOF XLDA 3,= EF ; EOF STATUS BIT AND# 3,2,SNR JMP ERR ; NO EOF WRITTEN ; REWIND THE MAG-TAPE XLDA 2,= REWIND*1B12+MTAUN ; COMMAND `TO REWIND THE MAG-TAPE JSR MTACM ; GO REWIND THE MAG-TAPE ; TYPE THE 'DONE' MESSAGE XXJSR TYPE ; TYPE A MESSAGE DONE ; 'DONE' ; RETURN THE THE 'INIT DUMP MODULE' WITH ERROR RETURN XXJSR RETRY ; SUCESSFUL COMPLETION ; OUTPUT THE MTA COMMAND IN AC2e, ADDRESS IN AC1 MTACM: DOA 2,MTA ; SELECT THE UNIT AND COMMAND DOB 1,MTA ; SELECT THE ADDRESS XLDA 2,= -4000 ; 1K WORDS DOCS 2,MTA ; WORD COUNT OF ZERO SKPBZ MTA ; WAIT UNTIL TRANSFER FINISHED JMP .-1 ; CHECK FOR ANY ERROR DIA 2,MTA ; GET THE ERROR STATUS FOR MTA XLDA 1,= DL+IL+PR+BT+ET ; ALL THE ERROR BITS AND# 2,1,SZR JMP ERR ; THERE WAS AN ERROR ; GO RETURN TO THE CALLER JMP 0,3 ; RETURN TO THE CALL + 1 ; ERROR CONDITION, JUST TYPE 'ERROR' AND RETURN TO DUMP INIT ERR: MOV 2,1 ; MTA ST\ATUS WORD XXJSR TYPE ; TYPE THE FOLOWING MESSAGE MERROR ; 'ERROR' XXJSR RETRY ; ERROR COMPLETION ; 7-TRACK MAG-TAPE, IMPOSSIBLE TO DO CORE DUMP ERR7T: MOV 2,1 ; MTA STATUS WORD XXJSR TYPE ; TYPE THE FOLLOWING MESSAGE ER7TR ; 'NO 7-TRACK' XXJlSR RETRY ; ERROR COMPLETION LPOOL .TXTM 0 MERROR: .TXT !ERROR<15><12>! 0 DONE: .TXT !DONE<15><12>! 0 ER7TR: .TXT !7-TRACK, NO<15><12>! 0 .END FLDMP.SRB$4K ; 6030 CONTROLLER FOR CORE DUMP ; AND DETERMINES WETHER THE DUMP WILL BE TO A PRIMARY OR SECONDARY ; CONTROLLER. RTITLE FLDMP .EXTN DUMP,SIZE,RETRY,TYPE .EXTN FLPY ; THE VALUE FLPY IS SET EXTERNALLY TO EITHER 33 OR 73 (OCTAL), ; AND DETERMINES T:HE DEVICE CODE OF THE DUMP DISKETTE DRIVE ; CONTROLLER. ; TO MAKE IT WORK, SYSGEN WILL HAVE TO LOAD EITHER ; DMP33, OR DMP73 (WITH ENTRY POINTS OF THE SAME NAME). .ENT ALDMP,FLDMP .NREL ; FOR THIS MODULE, WE HAVE TO CREATE I/O INSTRUCTIONS ; IN LINE.  HERE ARE THE PSUEDO INSTRUCTIONS WHICH ALLOW ; US TO DO THAT : .DOC1= DOC 1,0 .DOAP1= DOAP 1,0 .DIA1= DIA 1,0 .DOB1= DOB 1,0 .DOAS1= DOAS 1,0 .SKPDN= SKPDN 0 FLDMP: ALDMP: SUB 0,0 ; PAGE COUNTER STA 0,TRKNT ; SET TRACK COUNT TO ZERO ; HERE{'S THE LOOP..... ; PHASE I: SELECT THELP: LDA 1,DAASC ; SELECT UNIT 3, SECT'S 0 -> 3. LDA 2,K100 MOVR# 0,0,SZC ADD 2,1 ; CHANGE TO SECT'S 4 -> 7, .GADD FLPY,.DOC1 ; SELECT DRIVE, SURFACE, SECTOR, ; (DOC 1,FLPY) ; AND NUMBER OF SECTORS (4). .GADD FLPY,.DIA1 ; GET THE STATUS. ; (DIA 1,FLPY) LDA 3,READY ; READY FLAG. AND# 1,3,SNR JMP EREXT ; NOT READY. LDA 3,DISKT ; DISKET FLAG. AND# 1,3,SNR JMP EREXT ; NOT A DISKETTE. ; PHASE II: POSITION LDA 2,TRKNT ; TRACK COUNTER. LDA 1,TKMAX ; MAX NUMBER OF TRACKS ON FLOPPY. USGT 1,2 ; IS THE TRACK COUNTER > 77. ? JMP MFEXT ; YEP. LDA 1,SEEK ; BASIC SEEK. ADD 2,1 ; ADD IN TRACK NUMBER. .GADD FLPY,.DOAP1 ; (DOAP 1,FLPY) ; ISSUE SEEK. LDA 2,READY ; READY STATUS BIT. .GADD FLPY,.DIA1 ; (DIA 1 FLPY) ; GET STATUS. AND# 1,2,SNR ; READY SET ? JMP .-2 ; NO. MOVR# 1,1,SZC ; ERROR FLAG SET ? JMP EREXT ; YES ; PHASE III: WRITE ; LOAD MEMORY ADR. REG. XXJSR SIZE ; GET A PAGE. JMP NMEXT ; MEMORY EXHAUSTED. .GADD FLPY,.DOB1 ; (DOB 1,FLPY) ; SPECIFY COMMAND AND CYLINDER. LDA 1,WRITE ; BASIC WRITE. LDA 2,TRKNT ; CYLINDER (TRACK) NUMBER. ADD 2,1 .GADD FLPY,.DOAS1 ; (DOAS 1,FLPY) ; START WRITE. .GADD FLPY,.SKPDN ; (SKPDN FLPY) JMP .-1 ; WAIT FOR WRITE TO COMPLETE. 7 .GADD FLPY,.DIA1 ; (DIA 1,FLPY) ; GET STATUS. MOVR# 1,1,SZC ; ERROR ? JMP EREXT ; YES. ; PHASE IV: GET READY FOR NEXT PASS. INC 0,0 ; NEXT PAGE MOVR# 0,0,SNC ISZ TRKNT ; EVERY OTHER TIME. JMP THELP ; EXIT ROUTINES ; FLOPPY FULL MFEXT:= XXJSR TYPE MEDFL HALT ; WHILE MEDIA IS BEING REPLACED. SUB 2,2 STA 2,TRKNT ; RESET TRACK COUNTER. JMP THELP ; ERROR EREXT: XXJSR TYPE OOPS MOV 2,1 ; ERROR STATUS XXJMP RETRY ; SUCCESSFUL DUMP NMEXT: XXJSR TYPE DONE XXJMP RETRY ; CONSePTANTS AND TEXT STRINGS READY: 1B9 TKMAX: 77. ; MAX CYLINDERS ON DISKETTE. K100: 100 ; TO GET SECTORS 4 -> 7. TRKNT: 0 ; CYLINDER (TRACK) COUNTER. DISKT: 1B5 ; "IT'S A FLOPPY" STATUS BIT. DAASC: 3B1+0+14 ; SPECIFY UNIT 3, 4 SECTOR XFER. WRITE: 37B4+1hB7 ; BASIC WRITE SEEK: 37B4+2B7 ; BASIC SEEK MEDFL: .TXT /REPLACE<12><15>/ 0 OOPS: .TXT /ERROR!<12><15>/ 0 DONE: .TXT /DONE<12><15>/ 0 ; FOR THE EXTENDED INSTRUCTIONS..... LPOOL SIZE.SRB 9 RTITLE SIZE .ENT SIZE .NREL ; ALL MY CODE IS NORMAL ; THIS ROUTINE IS CALLED THUSLY: XXJSR SIZE ; EXCEPTION RETURN ; NORMAL RETURN ; ; WHEN CALLED AC0 SHOULD HAVE THE PHYSICAL PAGE NUMBER ; WHICH IS TO BE MAPPED. ; ; A NORMAL RETURN INDICATES THAT THE TWO PHYSICAL PAGE ; (AC0) HAS BEEN MAPPED TO THE PAGE POINTED TO BY AC1. ; (AC1 HAS THE LOGICAL CORE ADDRESS OF THE FIRST ; WORD OF THE PAGE) .IFN USW .DUSR MPAPH= 32. .ENDC ; SET MAP BLOCK TO STATE DEFINED IN REGISTER GIVEN AS ; ASG} TO MACRO CALL. ON THE BIG BIRD MAP, THE MACRO ; EXPECTS THAT THE MAP HAS ALREADY BEEN SET UP TO LOAD ; INTO THE PROPER MAP (IE A, B, OR DCH) .MACRO SETBK ** .PUSH .NOMAC ** .NOMAC ?L?NI % .IFN B?MSW .MACRO SETBK DOA ^1,BMAP % .ENDC .IFN \N?MSW .MACRO SETBK DOA ^1,MAP % .ENDC .IFN N3?MSW .MACRO SETBK DOB ^1,MAP % .ENDC .IFN BB?MSW .MACRO SETBK STA ^1,TEMP ; MAP INST. IN AC^1. SUB 0,0 ; ADDEND SUBZL 1,1 ; 1 WORD MOVE. XLDA 2,= TEMP ; ADR. OF MAP INST. LMP LDA 0,SIZE0 ; RESTORE AC0. % .ENDC .MACRO SETBK ** .NOMAC .POP % ; SAVE THE AC'S AND CHECK FOR MAXIMUM PAGE SIZE SIZE: STA 0,SIZE0 ; SAVE THE AC'S STA 1,SIZE1 STA 2,SIZE2 STA 3,SIZE3 ; CHECK MAXIMUM PAGE SIZE XLDA 3,= MPAPH ; MAXIMUM PAGE SIZE (IN PARS). USLT 0 3 JMP XSIZE ; THIS PAGE IS OUT OF RANGE .IFN MSW SUB 2,2 ; GENERATE A PAGE ZERO DISPLACEMENT. LDA 1,DCEBL SMST 1 ; ENABLE AND PROTECT THE DATA CHANNEL SMLD 1,MPSUA ; INDICATES BIG BIRD USER MAP A. LDA 1,PGTST ADD 0,1 .1ENDC .IFN USW ; UNMAPPED MOVS 0,2 ADDZL 2,2 ; GENERATE A CORE ADDRESS. .ENDC ; SEE IF THE PAGE EXISTS. MLDA 3,0,2 ; SAVE FIRST WORD MSTA 0,0,2 MLDA 1,0,2 SUB# 1,0,SZR ; DOES MEMORY REALLY EXIST ? JMP XSIZE ; NO. MSTA 3,0,2 ; RESTORE FIRST WOmRD. ISZ SIZE3 ; SET NORMAL RETURN. STA 2,SIZE1 ; LOCATION OF DATA ; HERE IS THE MAPPED ROUTINE. .IFN MSW SMLD 1,MPSDC ; BIG BIRD DCH MAP A LDA 1,DCPG0 ADD 0,1 SETBK 1 ; MAP INDICATED PAGE TO DATA CHANNEL SPACE .ENDC ; EXIT ROUTINE. XSIZE: LةDA 0,SIZE0 LDA 1,SIZE1 LDA 2,SIZE2 LDA 3,SIZE3 JMP 0,3 ; BYE ! LPOOL ; MAP PARM'S ; PGTST - MAP TO LOGICAL PAGE ZERO. ; DCPG0 - MAP DATA CHANNEL TO LOGICAL PAGE ZERO. ; DCEBL - ENABLE THE DATA CHANNEL MAP. .IFN N?MSW ; 840/830 MAP PGTST: 0 DCPG0: 1B2 DCEBL: 3B1+1B5 .ENDC .IFN N3?MSW ; NOVA 3 MAP PGTST: 0 DCPG0: 1B0 DCEBL: 3B1 .ENDC .IFN B?MSW!BB?MSW ; BIG OR SMALL BIRD MAP PGTST: 1B6 DCPG0: 1B7 DCEBL: 3B14 .ENDC .IFN BB?MSW TEMP: 0 .ENDC ; AC SAVE AREA. SIZE0: 0 SIZE1: 0 SIZE2: 0 SIZE3: 0 DMMP.SRB wy .TITL DMMP .RB DMMP.RB .ENT DUMP,PDUMP,TYPE,RETRY .EXTN ALDMP .NREL ; THIS IS THE INITIAL CODE FOR THE COREDUMP ROUTINE. ; IT CAN BE ENTERED MANUALY AT LOCATION DUMP, OR ; AUTOMATICALY FROF THE PANIC ROUTINE. ; (PDUMP) ; ; THE AC'S ARE SAVED IN LOC'!S DUMP0 -> DUMP3, THEN THE ; PROPER DUMP DEVICE DRIVER IS ENTERED. ; ; A QUICK AND DIRTY ROUTINE (TYPE) IS ALSO INCLUDED TO ; ALLOW MESSAGES TO BE SENT TO THE OPERATOR. ; THE CALL TO IT IS ; XXJSR TYPE ; WORD POINTER TO MESSAGE. ; NORMAL RETURN ; ; THERE IS NO ERROR RETURN. ; THE LAST WORD OF THE MESSAGE SHOULD = 0. ; THE ENTRY POINT "RETRY" IS SUPPLIED TO ALLOW FOR ; ADDITIONAL DUMPS (OR RETRIES AFTER ERRORS) WITHOUT ; DESTROYING THE AC VALUES STORED IN DUMP0 -> DUMP3. ; THE SUGGESTED RETRY PROSE+#DURE IS: ; ; XXJSR TYPE ; "A MEANINGFUL MESSAGE" ; XXJMP RETRY ; ; THE READY MESSAGE WILL BE SENT AND THE CPU WILL HALT. PDUMP: DUMP: IORST ; RESET THE WORLD STA 0,DUMP0 ; SAVE THE AC'S... STA 1,DUMP1 STA 2 DUMP2 STA 3 DUMP3 RETRY: IORST JSR TXYPE READY HALT XXJMP ALDMP ; PROPER ROUTINE CHOSEN AT LOAD TIME. ; HERE'S WHERE WE SAVE THE AC'S... DUMP0: 0 DUMP1: 0 DUMP2: 0 DUMP3: 0 ; THE TYPE ROUTINE .TXTM 0 ; BYTES ARE WRITTEN RIGHT TO LEFT TYPE: STA 0,EDB0 ; SAVE THE AC'S STA 2,EDB2 INCϑ 3,3 ; GET PAST WORD POINTER LDA 2,-1,3 ; GET WORD POOINTER. TYPLP: LDA 0,0,2 ; GET A WORD MOV# 0,0,SNR ; IS IT ZERO ? JMP TYPEX ; YEP, WE'RE DONE SKPBZ TTO ; $TTO BUSY JMP .-1 ; YES WAIT DOAS 0,TTO ; SEND RIGHT BYTE MOVS 0,0 SKPBZ TTO JMP .-1 DOAS 0,TTO ; SEND LEFT BYTE INC 2,2 ; POINT TO NEXT WORD JMP TYPLP ; RESTORE AC'S AND LEAVE. TYPEX: SKPBZ TTO ; WAIT FOR FINAL CHAR. JMP .-1 LDA 0,EDB0 LDA 2,EDB2 JMP 0,3 ; TEMP. STOREAGE AREA EDB0: 0 EDB2: 0 ; READY MESSAGE READY: .TXT /READY70 ?<12><15>/ 0 ; AND FOR THE EXTENDED JUMP.... LPOOL PANIC.SRB # ; PANIC.SR ; SYSTEM PANIC ROUTINE RTITLE PANIC .ENT PNIC .ENT REG .EXTN PDUMP .NREL PNIC: INTDS ;DISABLE INTERRUPTS STA 0,REG ;SAVE AC0 SUB 0,0 ;LINGER LONGER INC 0,0,SZR ;... JMP .-1 ;... IORST ;RESET STA 1,REG+1 ;SAVE AC1 STA 4@2,REG+2 ;SAVE AC2 STA 3,REG+3 ;SAVE AC3 LDA 0,0,3 ;PANIC CODE STA 0,REG+4 ;SAVE IT JSR CRLF ;CRLF TO TTO LDA @1,.REG ;WROD ISZ .REG ;BUMP ADDRESS JSR BINAS ;TYPE IT ISZ COUNT ;DONE ? JMP .-4 ;DO MORE  JSR CRLF ;ANOTHER CRLF HALT ;STOaP THE WORLD LDA 0,.DUMP ;DUMP ADDRESS INC# 0,0,SNR ;IS IT THERE ? JMP .-3 ;NO - KEEP HALTING JMP @.+1 ;JUMP TO DUMP .DUMP: PDUMP COUNT: -5 ;OUTPUT 5 WORDS .CRLF: 12*400+15 ;CRLF CRLF: STA 3,CRRET ;SAVE RETURN LDA 0,.CRLF ;CRLF WORD JSR PUT ;TYPE CR MOVS 0,0 JSR PUT ;TYPE LF JMP @CRRET CRRET: 0 PUT: SKPBZ TTO ;TYPE A CHARACTER JMP .-1 DOAS 0,TTO JMP 0,3 ;RETURN BOCT: BINAS: STA 3,BINRT ;SAVE RETURN SUBZR 2,2,SKP ;100000 BLP1: SUB 2,1,SKP ;SUBTRACT POWER OF EIGHT BLP2: LDA 0,C57 ;"0 - 1 INC 0,0 ;COUNT TO THE CORRECT DIGIT SUBZL# 2,1,SNC ;IS IT ? JMP BLP1 ;NO JSR PUT ;TYPE A CHAR MOVZR 2,2 MOVZR 2,2 MOVZR 2,2,SZR ;DONE ? JMP BLP2 ;NO. LDA 0,SPACE ;TYPE A JSR PUT ;SPACE JMP @BINRT BINRT: 0 ;SAVE RETURN ALDDRESS C57: 57 SPACE: " .REG: REG ;ADDRESS OF SPACE REG: .BLK 10 .END DDPMOD.SRB & 1 RTITLE DDPMOD ; DUMMY DUAL PROCESSOR MODULE TO HANDLE CALLS TO ; DPMOD WHEN IT IS NOT LOADED .ENT DLOCK DUNLOCK .ENT DGRAB .ENT DVLOCK DVUNLOCK .ENT DMPLOCK DMPUNLOCK .NREL DLOCK: DUNLOCK: DGRAB: DVLOCK: DVUNLOCK: DMPLOCK: DMPUNLOCK: .IFN ANS$W STA 3,@CSP ; SAVE RETURN LDA 3,CSP ; RESTORE STACK POINTER JMP @0,3 ; RETURN TO CALL+1 .ENDC .IFN ABSW PSH 3,3 ; SAVE RETURN LDA 3,CSP ; RESTORE STACK POINTER POPJ ; RETRUN TO CALL+1 .ENDC .END TABLE.SRC%  ; ; TABLES SECTION. ; RTITLE TABLE .TXTM 1 .NREL .IFN MN3SW!N3SW .EXTN STKDC ; NOVA 3 STACK DCT .ENDC .IFN BSW!MBSW .ENT SSL .ENT BTBL,NBTBL .EXTN ERCCH ; ERCC HANDLER .ENDC .ENT PS1 .ENT FSYSF .ENT SYSTM ;SYSTEM TIME LOCATION .ENT kSYSTR ;START OF SYSTEM .ENT SYSFL ;SYSTEM PROCESS FLAGS WORD .ENT SYSIN ;BASE LEVEL "IN SYSTEM" FLAG .ENT ENVIR ;ENVIRONMENT WORD .IFN IOSW .ENT ISMAP ;INFOS STATIC MAP .ENDC .ENT SPOOL ;SPOOL COUNT .ENT SPOLF ; SPOOL CONTINUE FLAG .ENT STD4hCC ;START OF SPOOLABLE DCT'S .ENT SS ;SYSTEM STACK .ENT MDCB ;MASTER DCB ADDRESS  .ENT PPDCB ;PRIMARY PARTITION DCB ADDRESS .ENT ITBL .ENT BQ ;BUFFER QUEUE .ENT DPTBL .ENT IVTTB .ENT LNKDR .ENT ADTDB ;ADDITIONAL DCB'S .ENT SPOLQ,SPPTH ; SPOOL Q PLUS PATH CONTROL WORD .ENT FIMSG,FTMSG .ENT BIN,FIN .ENT DSQ1,DSQ2 .ENT SYSQ .ENT DIRR ;RING OF DIRECTORY CONTROL BLOCKS .ENT OVTAB ;SYSTEM OVERLAY TABLE .ENT PT1,PT2 ;FG/BG PROGRAM TABLES .ENT NTI1Q,NTO1Q .ENT SYSTB ;LIST OF RESOURCES h ;POINTED AT BY C((1)-1) .IFN MSW .ENT TMSG .ENT CMOVE .ENT CPFLG,CPUSH,CPFPS,CPDDR .ENT CPAMS .ENT CPEM,CPEXM .ENT CPDSV .ENT MDCH1,MDCH2 .ENT BUEND,FUEND .ENT MPT1,MPT2 .ENDC .ENT .IPINIT .ENT .IPBQ ;FOR INIT2 .ENT ALMIN .EXTN ALINIT V.EXTN IPINIT .ENT SYSFG,SFGNP,SFGZP .ENT OSNAM ;NAME OF OPERATING SYSTEM .ENT SYSNM .ENT MAPNM .ENT BRSV,FBRSV .ENT BUFNT .ENT BQ2,BQ3,BQ4,BQ5,BQ6 .ENT BQ7,BQ8,BQ9,BQ10,BQ11,BQ12,BQ13,BQ14,BQ15 .ENT BQ16,BQ17,BQ18,BQ19,BQ20 .ENT BQ21,BQ22,BQ23,BQ24,BQ25,BQ26,BQ27,BQ28,BQ29,BQ30 .ENT SQ .ENT NSEG .ENT IVFWA,IVLWA .ENT TTRTB,TTITB .ENT PFLTB .ENT PTRTB .ENT TUNE ;TUNING ENTRY, REGULAR .ENT ITUNE ;TUNING ENTRY, INTERRUPTIBLE .ENT TUSW ;TUNE SWITCH .IFN MSW .EXTN SACHN,CLIBT,SSINI,}SENQ ;FOR CMOVE .EXTN BCEC,NFUFT,NBUFT .EXTD SYSEN .EXTN MTMVW .EXTN SMON1 .ENDC .EXTN SMON ;START OF NREL CODE (SCHED) .EXTN PENTR,TWINK,TACT .EXTN CLIBU .EXTN FCELL .EXTN SPLST .EXTN ERCCT,DZPER,DKPER,DSKER,DSPER .EXTN STK00,STK01,STK02,ST7K03,STK04 .EXTN STK05,STK06,STK07,STK08,STK09 .EXTN TTIQ,TTI1Q .EXTN TTRQ,TTR1Q .EXTN TTOQ,TTO1Q .EXTN PTRQ,PTR1Q .EXTN PTPQ,PTP1Q .EXTN MTAQ,MTA1Q .EXTN CTAQ,CTA1Q .EXTN CDRQ,CDR1Q .EXTN LPTQ,LPT1Q .EXTN PLTQ,PLT1Q .EXTN MCRQ,MCR1Q .EXTN MCT Q,MCT1Q .EXTN DPIQ,DPOQ .EXTN IPBQ,QTYQ .EXTN DSKDC,DSK1D ;DEVICE CONTROL TABLES .EXTN DKPDC,DKP1D .EXTN DZPDC,DZP1D .EXTN DSPDC,DSP1D .EXTN TTIDC,TTI1D .EXTN TTRDC,TTR1D .EXTN TTODC,TTO1D .EXTN PTRDC,PTR1D .EXTN PTPDC,PTP1D .EXTN MTADC,MTA1D } .EXTN CTADC,CTA1D .EXTN CDRDC,CDR1D  .EXTN LPTDC,LPT1D .EXTN PLTDC,PLT1D .EXTN MCRDC,MCR1D .EXTN MCTDC,MCT1D .EXTN IPBDC .EXTN DPIDC,DPODC .EXTN QTY1D,ALMDC,ALM1D .EXTN QTYDC .EXTN PFLDC,RTCDC .EXTN DK0DB,DK1DB .EXTN DS0DB,DS4DB .EXTN NDS0D,N#<12>FG INT<15><12>/ ** .NOLOC 0 MAPNM: "M*400+"A "P*400+0 0 0 0 "D*400+"R .IFN MSW ** .NOLOC 1 CPEM: .+1*2 .TXT /<15><12><7>CP ENT<15><12>/ CPAMS: .+1*2 .TXT /<15><12>CP INT<15><12>/ TMSG: 89.+1*2 .TXT /<15><12>TRAP= <15><12>/ CPEXM: .+1*2 .TXT /<15><12>CP RTN<15><12>/ ** .NOLOC 0 .ENDC ** .NOLOC 1 FTMSG: .+1*2 .TXT /<15><12>FG TERM<15><12>/ ** .NOLOC 0 ; NOTE- IN AND OUT DEV FOR EACH PROG MUST BE CONTIG BIN: BCI*2 BOUT: BCO*2 FIN: FCI*2 FOUT: FCO*2 .NOLOC 1 BCI: .TXT /$TTI/ BCO: .TXT /$TTO/ FCI: .TXT /$TTI1/ FCO: .TXT /$TTO1/ .TXT /COPYRIGHT(C)DGC,1972,1973,1974,1975,1977 ALL RIGHTS RESERVED/ .NOLOC 0 ; ENVIRONMENT FLAGS .IFN NSW ENVIR: ENUNV+ENZRDOS .ENDC .IFN BSW ENVIR: ENUEC+ENRDOS .ENDC .IFN MNSW ENVIR: ENMNV+ENMAP+ENRDOS .ENDC .IFN ?MSW&?ABSW&?RDOS ENVIR: ENMEC+ENMAP+ENRDOS .ENDC .IFN MN3SW ENVIR: ENMN3+ENMAP+ENRDOS .ENDC .IFN ?INFOS ENVIR: ENMEC+ENMAP+ENINFO .ENDC .IFN MSW CPFPCS: .IFE MBSW .BLK 9. ;SAVE AREA FOR CHECKPOINTED ; PROG FPU STAT .ENDC .IFN MBSW .BLK 18. .ENDC CPDSV: .BLK 8. ;SAVE FOR CHECKPOINTED PROG DEV ; STAT CPFLG: 0 CPUSH: 0 CPDDR: 0 .ENDC ; TUNING NORMAL ENTRY POINT. TUNE: STA 3,TURET LDA U3,TUSW ;PICK A SWITCH COM# 3,3,SNR ;TUNING TODAY? JMP TUSKP ;NOPE STA 0,TU0 ;YES, SAVE ACCS STA 1,TU1 ;(WE MAY NOT HAVE A STACK) STA 2,TU2 LDA 2,@TURET ;GIVE TOONER THE TUNE KEY JSR @TUSW ;GO TO TOONER & COME BACK LDA 0,TU0 ;BACK AGAIN, REST3ORE STATE LDA 1,TU1 LDA 2,TU2 TUSKP: LDA 3,CSP ISZ TURET ;SKIP TUNE KEY JMP @TURET TU0:0 TU1:0 TU2:0 TURET:0 ; INTERRUPTIBLE TUNING ENTRY POINT. ; ALL ACCUMULATORS LIABLE TO BE LOST. ITUNE: LDA 2,TUSW ;PICK A SWITCH COM# 2,2,SNR ;TUNING TODAY? [ JMP 1,3 ;NO, GET OUT LDA 2,0,3 ;YES, GIVE TOONER THE KEY INC 3,3 ; & SKIP OVER IT JMP @TUSW ;PRETEND CALLER JSR'D DIRECTLY TUSW: -1 ;DEFAULT IS NO TUNING ; INTERRUPT VECTOR ; ; DEVICE CODE IVFWA: BTBL: @PFLDC ; 0 NOTE: NOT CHANGED BY INIT1 ITBL: -1 ; 1 NOTE: WE DON'T PROTECT NOVA MUL/DIV .IFN MBSW @ERCCH ; 2 = ECLIPSE ERCC ("INIT" CLEARS BIT 0) 1B0 ; 3 = ECLIPSE MAP .ENDC J .IFN BSW @ERCCH ; 2 = ECLIPSE ERCC ("INIT" CLEARS BIT 0) -1 ; 3 .ENDC J .IFN MN3SW 1B0 ; 2 = NOVA 3 MMU 1B0 ; 83 = NOVA 3 PROTECTION .ENDC J .IFN MNSW 1B0 ; 2 = 830/840 MMPU -1 ; 3 .ENDC J -1 ; 2 IF NOT ONE ABOVE -1 ; 3 IF NOT ONE ABOVE [J] -1 ; 4 NOTE: WE DON'T PROTECT NOVA 3 PARITY -1 ; 5 MCTDCT ; 6 MCRDCT ; 7 TTITB: TTIDCT ; 10 TTODCT ; 11 PTRTB: PTURDCT ; 12 PTPDCT ; 13 -1 ; 14 - CLOCK PLTDCT ; 15 CDRDC ; 16 LPTDCT ; 17 DSKDCT ; 20 -1 ; 21 MTADCT ; 22 -1 ; 23 -1 ; 24 -1 ; 25 DSPDC ; 26 DZPDCT ; 27 QTYDC ; 30 -1 ; 31 -1 ; 32 DPTBL: DKPDCT ; 33 CTADC ; 34 SHARED WITH ALMDC -1 ; 35 LYNKDR: IPBDC ; 36 IVTTB: -1 ; 37 DPIDC ; 40 DPODC ; 41 -1 ; 42 -1 ; 43 ALM1D ; 44 -1 ; 45 MCT1D ; 46 MCR1D ; 47 TTI1D ; 50 TTO1D ; 51 PTR1D ; 52 PTP1D ; 53 -1 ; 54 PLT1D ; 55 CDR1D ; 56 LPT1D ; 57 DSK1D ; 60 -1 ; 61 MTA1D ; 62 -1 ; 63 -1 ; 64 -1 ; 65 DSP1D ; 66 DZP1D ; 67 QTY1D ; 70 -1 ; 71 -1 ; 72 DKP1D ; 73 CTA1D ; 74 -1 ; 75 -1 ; 76 PFLTB: -1 ; 77 -1 ; 100 ; TTIDCT FILLED IN BY INIT1. NOTE INIT1 ; REFERENCES THIS BY A DISPLACEMENT OF 100 FROM ; IVFWA. THIS LOCATION WILL BE FILED IN WITH THE ; CONTENTS OF IVFWA+TTI AFTER INITIALIZATION IN ; INIT1 TTRTB: TTRDCT ; 101 -1 ; 102 ; TTI1D SAME WARNING AS TTIDCT ABOVE. . . . TTR1D ; 103 .IFN N3SW!MN3SW STKDC ; 104 ; NOVA 3 STACK DCT .ENDC IVLWA= .-1 NBTBL=BTBL+1B0 .IFN MSW MDCH1: 0 MDCH2: -1 ;BIT=1 FOR FREE SLOT BUEND: 0 FUEND: 0 .ENDC PPDCB: .BLK 1 ;PRIMARY PARTITION DCB ADDRESS MDCB: .BLK 1 ;MASTER DCB ADDRESS SYSTM: .BLK 1 ;SYSTEM TIME SYSTR: .GADD SMON,-1 ;START OF SYSTEM SYSFL: .BLK 1 ;FLAGS FSYSF: 0 SYSFG: 0 SFGZP: 0 DIRR: 0 ; START OF DCB CHAIN BUFNT: .BLK 1 ;NUMBER OF USERS WAITING FOR ; BUFFERS SYSIN: 1 ;INHIBIT FLAG SPOOL: .BLK 1 ;SPOOL COUNT STDCC: .BLK 1 ;START OF SPOOLABLE DCT'S .IPINIT: IPINIT .IPBQ: IPBQ ALMIN: ALINIT .IFE]] BSW!MBSW SS=.-SP .BLK NFRAM*SLGT+1 ;SYSTEM STACK .ENDC .IFN BSW!MBSW SS=. .BLK ISLGT ;SYSTEMM INTERRUPT STACK SSL=.-1 ;INTERRUPT STACK LIMIT .ENDC ADTDB: DK0DB 1 DK1DB 1 DP0DB NDP0D DS0DB NDS0D DS4DB NDS4D DP0FD NDP0F DP4DB NDP4D DP4FD NDP4F DZ0DB NDZ0D DZ4DB NDZ4D P00DB NP00D M00DB NM00D M10DB NM10D C00DB NC00D C10DB NC10D QTDCB 1 MCRDB 2 ; RECEIVER AND TRANSMITTER MCR1B 2 ; RECEIVER AND TRANSMITTER 0 ; END OF ADDITIONAL DCB'S SQ: SYSQ ; SYSTEM QUEUE NTI1 Q: TTI1Q NTO1Q: TTO1Q BSTRT: PTRQ ; PTR QUEUE CDRQ LPTQ TTIQ MCRQ MCTQ PTPQ PLTQ QTYQ TTOQ MTAQ MTA1Q DPOQ DPIQ IPBQ DSQ1 ; MUST PRECEED DSQ2 DSQ2 ; I TOLD YOU SO CTAQ CTA1Q TTRQ TTR1Q PTR1Q LPT1Q PTP1Q CDR1Q PLT1Q SPOLQ MCR1Q M/CT1Q 0 BQ=BSTRT+BQHDL BQ2= BQ+BQEL BQ3= BQ2+BQEL BQ4= BQ3+BQEL BQ5= BQ4+BQEL BQ6= BQ5+BQEL BQ7= BQ6+BQEL BQ8= BQ7+BQEL BQ9= BQ8+BQEL BQ10= BQ9+BQEL BQ11= BQ10+BQEL BQ12= BQ11+BQEL BQ13= BQ12+BQEL BQ14= BQ13+BQEL BQ15= BQ14+BQEL BQ16= BQ15+BQEL BQ17= BQ16.+BQEL BQ18= BQ17+BQEL BQ19= BQ18+BQEL BQ20= BQ19+BQEL BQ21= BQ20+BQEL BQ22= BQ21+BQEL BQ23= BQ22+BQEL BQ24= BQ23+BQEL BQ25= BQ24+BQEL BQ26= BQ25+BQEL BQ27= BQ26+BQEL BQ28= BQ27+BQEL BQ29= BQ28+BQEL BQ30= BQ29+BQEL .IFN MSW ; RESERVE SPACE FOR 6 BUFFERS -.BLK BQ2-. ;REST OF BQ .BLK BQEL*4 ;4 MORE ; NOTE- CMOVE= BQ6 (HEADER IS ALREADY RESERVED) ; MOVE THE MINI-CLI PAGE 0 AND NREL TO USER BLKS CMOVE: .DO BB?MSW ELEF 1,MPSA2 ; ACCESS PT2 SMST 1 ; MAP .ENDC LDA 1,.CLIBT ;CLI START LDA 2,.SSIN ;IF NO SYMBOLS USE SSINI AS END MOV 1,0 ;CLI STARTING ADDR SUB 0,2 ;COUNT= CLIBT+TMIN INC 2,2 JSR@ .MTMVW ;MOVE CODE LDA 0,C16 MOV 0,1 ;MOVE IN PAGE 0 LDA 2,.SYSC ;BYTE COUNT JSR@ .MTMVW ;MOVE IT LDA 1,.BCEC ;# BUFS LDA 0,C6 ;SUB MIN NUM SUB 0,1 LDA 3,SYSEN ;CURRENT END INCLUDES MIN BUF + ; UFT LDA 2,C177L AND 3,2 ;GET NEXT 1K ADDR LDA 0,CNXTB ;BUMP ADD 0,2 LDA 0,BQELG ;SIZE OF A BUFFER ADD 0,3 ;ONE FIT IN ? .IFE IOSW ;INFOS:2.00 - CJM - NO EXTRA BUFFERS IF INFOS SUBZ# 2,3,SZC .ENDC ;INFOS:2.00 - CJM - 10/25/76 END CONDITIONAL JMP .+3 ;NO INC 1,1 ;ONE MORE BUFFER JMP .-4 ;TRY FOR ANOTHER LDA 3,.CLIBT ;START MOV# 1,1,SNR ;ANY EXTRAS ? JMP BUFT ;NO-BUILD UFTS STA 1,NBUFS ;SAVE LDA 2,.BQ6 ;LINK TO PRESENT END STA 3,BQNXT,2 SUB 1,1 BUFPL: MOV 3,2 STA 1,BQTLA,2 ;INIT HEADER STA 1,BQUSC,2 STA 1,BQST,2 STA 1,BQDCB,2 STA 1,BQDCT,2 ADD 0,3 ;NEXT BUF STA 3,BQNXT,2 ;LINK IN DSZ NBUFS ;DONE ? JMP BUFPL ADC 1,1 ;LINK TO -1 STA 1,BQNXT,2 ;BUILD UFTS- AC3=START BUFT: LDA 2,.PT2 STA 3,PUFPT,2 ;START=POINTER BASE LDA 1,.NBUFT ;NUMBER BG CHANS NEG 1,2 ADDOR 1,1 LDA 0,.UFTEL ;UFT SIZE STA 1,0,3 ;POINTER TO AREA ADD 0,1 INC 3,3 ;INC POINTER INC 2,2,SZR ;DONE ? JMP .-4 LDA 1,.NBUFT ;NUMBER UFTS N4EG 1,1 ADD 0,3 ;FIND END INC 1,1,SZR JMP .-2 LDA 2,.PT1 STA@ 3,.BUEND ;SYSTEM CONSTANT FOR END STA 3,PUFPT,2 ;FG START LDA 1,.NFUFT ;NUM FG UFTS NEG 1,2,SNR ;ANY ? JMP BUFT1 ;NONE ADDOR 1,1 ;CLOSED STA 1,0,3 ;POINTER ADD 0,1 ;ADD SIZE INC 3,3 INC 2,2,SZR ;DONE ? JMP .-4 LDA 1,.NFUFT ;NUM FG UFTS NEG 1,1 ADD 0,3 INC 1,1,SZR JMP .-2 STA@ 3,.FUEND ;SAVE FG END BUFT1: SUB 0,0 MSTA 0,1 ;CLEAR IN USER LDA 1,C400 ;SET USTP IN CLIBT MSTA 1,USTP INTDS LDA 2,.SPOLQ ;SET UP REAL CHAIN NOW STA@ 2,.SACHN LDA 2,CQ ;SYSQ STA 0,QSTAT,2 ;INIT STA 0,POLNK,2 LDA 2,ZIPBQ ;PUT IBP PROCESS BACK ON ACTIVE ; CHAIN COM# 2,2,SNR ; (IF IT EXISTS) JMP JSMON1 SUB 0,0 ;DON'T LET SENQ THINK STA 0,POLNK,2 ; IT'S ON THE QUEUE JSR @.SENQ J`SMON1: INTEN SUB 0,0 STA 0,CMOVE+BQUSC ;BQ6 CAN BE USED NOW JMP@ .SMON1 .SMON1: SMON1 C400: 400 .BUEND: BUEND .FUEND: FUEND .BQ6: BQ6 .NBUFT: NBUFT .NFUFT: NFUFT .PT1: PT1 .PT2: PT2 .BCEC: BCEC .SSINI: SSINI NBUFS: 0 C6: 6 .SYSC: UST+USTEN+TLN-15 ;COUN|T FOR PAGE 0 MOVE C177L: 176000 CNXTB: 1B5 .UFTEL: UFTEL .SPOLQ: SPOLQ .SACHN: SACHN ZIPBQ: IPBQ .SENQ: SENQ BQELG: BQEL .CLIBT: CLIBT C16: 16 .MTMVW: MTMVW .BLK BQ7-. ;REST OF BUFFER .ENDC .END RESOLVE.SRB:L RTITLE RESOLVE .NREL ; THIS MODULE RESOLVES ALL UNLOADED MODULS FOR RDOS. ; IN MOST CASES THIS IS DONE SIMPLY BY RESOLVING THEM ; TO -1, THEREFORE REMOVEING THEM FROM THE UNDEFINED LIST. .MACRO RES ; RESOLVE UNDEFINEDS ** I=1 ; START THE ARG COmcUNTER ** .DO .ARGCT ** .ENT ^I ** ^I= -1 ** I=I+1 ** .ENDC % RES MTAQ M00DB MTADC NM00D ; MT0 RES MTA1Q M10DB MTA1D NM10D ; MT1 RES CTAQ C00DB CTADC NC00D ; CT0 RES CTA1Q C10DB CTA1D NC10D ; CT1 RES PTPQ PTPDC ; $PTP RES PTP1Q PTP1D ; $PTP1 RESx PTRQ PTRDC ; $PTR RES PTR1Q PTR1D ; $PTR1 RES CDRQ CDRDC ; $CDR RES CDR1Q CDR1D ; $CDR1 RES LPTQ LPTDC ; $LPT RES LPT1Q LPT1D ; $LPT1 RES PLTQ PLTDC ; $PLT RES PLT1Q PLT1D ; $PLT1 RES MCRQ MCRDC MCRDB MCRBL ; MCAR RES MCR1Q MCR1D MCR1B ; 1MCAR1 RES MCTQ MCTDC MCTBL ; MCAT RES MCT1Q MCT1D ; MCAT1 RES DPOQ DPODC ; $DPO RES DPIQ DPIDC ; $DPI RES IPBQ IPBDC ; IPB RES IVTIN OTHER IPINI ; IPB RES TTI1Q TTI1D ; $TTI1 RES TTO1Q TTO1D ; $TTO1 RES TTR1Q TTR1D ; $TTR1 RES RTCNS RTCDV RTCST ; RTC RES RTCDC RES DKPDC NDP0D NDP0F ; DKP RES DP0DB DP0FD ; DKP RES DKP1D NDP4D NDP4F ; DKP1 RES DP4DB DP4FD ; DKP1 RES DZPDC NDZ0D ; DZP RES DZ0DB ; DZP RES DZP1D NDZ4D ; DZP1 RES DZ4DB ; DZP1 RES TRESP RES DK0DB DSKDC ; DK0z RES DK1DB DSK1D ; DK1 RES DSPDC,NDS0D,DS0DB ; DS0 RES DSP1D,NDS4D,DS4DB ; DS1 RES P00DB ; EXTRA DCB'S RES PWRFL PFLDC IUD USSV ; POWER FAIL RES DISI3 PFRET ; POWER FAIL RES OPPRO ; OPCOM RES STK02 STK03 STK04 STK05 ; STACKS RES STK06 STK07 +STK08 STK09 ; STACKS RES TUNIN TUVSW TRPRT OVUSG ; TUNING RES PDUMP ; DUMP RES HISTI ; HISTOGRAM RES TRPRT CLSTB ; MIS MAP STUFF RES GSTAT REWND WTEOF SBRCD ; MAG TAPE STUFF RES RDRCD SBFIL SFFIL SFRCD ; MORE MAG TAPE STUFF RES WTRCD ; AND MORE MAG TAPE STUFF RES QTYQ QTDCB QTYDC QTY1D ; QTY RES ALMDC ALM1D ALINI DLALM ; ALM RES ALM? QTYTB SQT64 QKICK ; QTY-ALM STUFF RES QTRZAP QTYWZAP ; QTY-ALM STUFF RES RGET TSEND TGET WSEND ; QTY-ALM STUFF RES MODEM MODINIT MODSET ; ALM MODEM STUFF )+RES ALM00 ALM01 ALM02 ALM03 ; ALM SPEED STUFF RES ALM04 ALM05 ALM06 ALM07 ; ALM SPEED STUFF RES ALM08 ALM09 ALM10 ALM11 ; ALM SPEED STUFF RES ALM12 ALM13 ALM14 ALM15 ; ALM SPEED STUFF RES ALM16 ALM17 ALM18 ALM19 ; ALM SPEED STUFF RES ALM20 ALM21 ALM22} ALM23 ; ALM SPEED STUFF RES ALM24 ALM25 ALM26 ALM27 ; ALM SPEED STUFF RES ALM28 ALM29 ALM30 ALM31 ; ALM SPEED STUFF RES ALM32 ALM33 ALM34 ALM35 ; ALM SPEED STUFF RES ALM36 ALM37 ALM38 ALM39 ; ALM SPEED STUFF RES ALM40 ALM41 ALM42 ALM43 ; ALM SPEED STEUFF RES ALM44 ALM45 ALM46 ALM47 ; ALM SPEED STUFF RES ALM48 ALM49 ALM50 ALM51 ; ALM SPEED STUFF RES ALM52 ALM53 ALM54 ALM55 ; ALM SPEED STUFF RES ALM56 ALM57 ALM58 ALM59 ; ALM SPEED STUFF RES ALM60 ALM61 ALM62 ALM63 ; ALM SPEED STUFF  RES QTYNO MSV2 DLMUX QTWZAP RES ERCCT,DZPER,DKPER,DSKER ; ERROR COUNTS RES DSPER ; THIS RESOLVES THE PATCH SPACE ENTRIES WITHOUT MUCH TYPING. .IFN ?USW ; ONLY FOR UNMAPPED SYSTEMS ** K=0 ** .DO 25 ** L=K+1 ** M=K+2 ** N=K+3 RES PL\K PL\L PL\M PL\N ** K=K+4 ** .ENDqKC .ENDC .ENT URDOS,MRDOS,NRDOS,BRDOS,ARDOS,ZRDOS,INFOS,JNFOS URDOS = -1 ;INIT ALL FLAVOR SWITCHES FIRST MRDOS = -1 NRDOS = -1 BRDOS = -1 ARDOS = -1 ZRDOS = -1 INFOS = -1 JNFOS = -1 .IFN ?USW&?ANSW URDOS = 1 .ENDC .IFN ?MSW&?NSW&N?MSW MRWDOS = 1 .ENDC .IFN ?MSW&?N3SW&N3?MSW NRDOS = 1 .ENDC .IFN ?USW&?ABSW BRDOS = 1 .ENDC .IFN ?MSW&?ABSW&B?MSW&?RDOS ARDOS = 1 .ENDC .IFN ?MSW&?ABSW&BB?MSW&?RDOS ZRDOS = 1 .ENDC .IFN ?MSW&?ABSW&B?MSW&?INFOS INFOS = 1 .ENDC .IFN ?MSW&?ABSW#&BB?MSW&?INFOS JNFOS = 1 .ENDC TRES.SRCCa; ; DUAL-PROCESSOR ZEBRA TRESPASSER ; CALLED WHEN 'OTHER' CPU GOES AWAY ; CALLER IS ASSUMED AN RDOS QUEUE (IPBQ) RTITLE TRES .NREL .ENT SPOIL .ENT TRESP ;MAY BE SPOILED IF NOT DUAL-PROC ZEBRA .EXTN XDOA, XDIB, XDIA, XDOAP,XNOC .EXTN DIRR SPOIL: CPTRESP: TRESP ;A WAY FOR CALLER TO FIND US. RSAVE .EXTN OTHER LDA 0 @.OTHER ;SEE IF OTHER CPU THERE LDA 1 FLIP STA 0 FLIP ;FLIP FOLLOWS OTHER SUBL# 1,0,SNC ;NEG RESULT MEANS OTHER JUST DROPPED RTRN ;ELSE RETURN JMP ZAPEM ;HERE WE GO! FLIP: 1 .OTHER: OTHER ZAPEM: LDA 2 @.DIRR ;BEGINNING OF DCBS WZAP: ; AT THIS POINT, AC2 = A SYSTEM DCB (DIRECTORY) LDA 3,OFFSET ;NOW CONVERT DCB TO WHAT WILL SUB 3,2 ;LOOK LIKE A BUFFER HEADER. LDA 3,SFKEY+(BQDCT-DCBDC),2 ; DEVICE KEY LDA 0,DZ ; IS IT "oDZ" SOMETHING? SUB 3,0,SZR ;SKIP IF YES. JMP NEXT ; ELSE TRY NEXT DCB. STA 0,RESTART ;INIT DEVICE RESTART TO 'NO' W0: INTEN LDA 3,BQDCT,2 LDA 3,DCTPD,3 ;CONTROLLER DCT INTDS LDA 3,DCCRQ,3 COM# 3,3,SNR ;DOES IT HAVE A REQUEST? JMP W1 ; NO...OHK TO PLAY WITH IT. LDA 0,BQERC,3 ; YES...SELECT DRIVE IT'S USING JSR @.DOA0 ;WITHOUT CHANGING ANYTHING. JSR @.DIB0 ; GET DRIVE STATUS ADDL# 0,0,SNC ;IS DRIVE RESERVED BY 'OTHER'? JMP W1 ; NO...OK TO PLAY. DISK IS GOING. STA 2,RESTART ; YES... GOTTA BOMB CONTROLLER!! JSR @.NIOC ;CLEAR THE POOR BASTARD W1: JSR @.DIA0 ;WAIT FOR 'CONTROL FULL' TO DROP MOVL 0,0,SZC JMP W0 ;MIGHT TAKE A WHILE. W2: LDA 0,BQUN,2 ;DRIVE WE WANT TO CHECK ADDZL 0,0 ADDZL 0,0 ;SHIFT TO BITS 9,10 STA 0,TDRV ;SuLAVE FOR LATER JSR @.DOA0 ;SELECT DRIVE JSR @.DIB0 ; THEN GET ITS STATUS. ADDL# 0,0,SNC ;IS IT RESERVED? JMP WOK ; NO...NEXT DRIVE, PLEASE. LDA 1,BZRDY ; YES...SEE IF BUSY (AND READY) AND 1,0 SUB 1,0,SNR ;IF BOTH TRUE, WE DON'T WANT TO JMP W0 pW ;OVERRUN SEEKS, SO WAIT. ; ; WE ARE FINALLY GOING TO BLAST A TRESPASS! LDA 0,TDRV ;RECALL DRIVE # LDA 1,TPASS ;FORM TRESPASS ADD 1,0 JSR @.DOAP ; START THE COMMAND. JSR @.DIA0 ;WAIT FOR 'CONTROL FULL' DROP MOVL 0,0,SZC JMP .-2 ;SHOULD BE QUIŐCK LDA 0,TDRV ;NOW WE GOTTA RELEASE, LDA 1,RLSE ; SINCE TRESPASS GRABBED ADD 1,0 ; THE DRIVE. JSR @.DOAP ;DONE! LDA 3,RESTART ;DID WE DESTROY CONTROLLER ? MOV 3,3,SNR ; SKIP IF YES. JMP WOK ; WE DIDN'T (WHEW!) LDA 2,BQDCT,2 ;GOTTA PASS AC2= ~DCT LDA 2,DCTPD,2 ;CONTROLLER DCT JSR @ DCSTR,2 ; RESTART ITS REQUEST LDA 2,RESTART ;RESTORE "HEADER" OF DRIVE WE ;TRESPASSED. WOK: INTEN NEXT: LDA 2,SFNX+(BQDCT-DCBDC),2 ;NEXT SYSTEM DCB. COM# 2,2,SZR ; ANY MORE? JMP WZAP ; YES...DO 'EM RTRNj ; NO...ALL DONE. RESTART: -1 TDRV: -1 .DIRR: DIRR ; RDOS LIST OF SYSTEM DIRECTORIES OFFSET: BQDCT-DCBDC ; FUDGE FACTOR DZ: "D*400+"Z ; KEY TO ZEBRA'S STRIPES BZRDY: 14000 ; READY & BUSY DRIVE STATUS BITS TPASS: 10B8 ; TRESPASS COMMAND RLSE: 7B8 A; RELEASE COMMAND .DIA0: XDIA ; EXECUTE 'DIA 0 -' GET CONTROL STATUS .DOA0: XDOA ; 'DOA 0 -' SELECT DRIVE .DIB0: XDIB ; 'DIB 0 -' GET DRIVE STATUS .DOAP: XDOAP ; 'DOAP 0 -' SELECT & DO COMMAND .NIOC: XNOC ; 'NIOC -' CLEAR CONTROLLER .END DTSP.SRB .6; SPOILER MODULE. GETS LOADED IF EITHER ; DUAL-PROCESSOR WITHOUT ZEBRA ; OR ZEBRA WITHOUT DUAL-PROCESSOR. ; ; THIS MODULE MUST FOLLOW 'EITHER' ; THIS MODULE MUST PRECEDE TRESP. RTITLE DTSP .ENT IPSTK,DZPIT .LMIT SPOIL ;PREVENT 'TRESP' LOAD IPSTK j= -1 DZPIT = -1 .END EITH.SRB ON + 1B0 JMP MAKE1 CONNS: LDA 2,CONAS ; ATCON+1B0 JMP MAKE ; NO MAPING TCCON: INC 0,0 ; TRANSPARENT FLAG CCONT: LDA 2,@CC ; TCB ADDRESS LDA 1,TAC1,2 ; BLOCK COUNT LDA 2,CONAT ; CONTIGUOUS ATTRIBUTE JMP MAKE1 ; GO ON WITH CREATE CCONS: LDA 2,CONA]T ; CONTIGUOUS ATTRIBUTE JMP MAKE ; NOW MAKE ONE TCRND: INC 0,0 CRAND: LDA 2,RANAT ; RANDOM ATTRIBUTE JMP MAKE1 TCRET: INC 0,0 CREAT: SUB 2,2 ; NO ATTRIBUTE MAKE1: MOVO 0,0,SKP ;MAP THE FILENAME BYTE POINTER MAKE: MOVZ 0,0 ;NO MAP STA 2,ATRBS,3 ; SAVE THE ATTRIBUTES STA 1,BLKCT,3 ;SAVE BLOCK COUNT SUBCL 1,1 STA 1,MAPN,3 ;SAVE MAP SWITCH LDA 1,OAC0,3 ; INPUTTED AC0 SUB# 0,1,SNR ; SAME AS ONE I HAVE ? JMP GETIM ; YES, GET CURRENT TIME INFO LDA 2,@CC ; NO, GET TCB ADDRESS LDA 0,TAC2,2 ; TRA6NSPARENT CREATE, GET ; 'FROM' POINTER LDA 1,.FTAC ; STACK OFFSET ADD 3,1 ; FORM 'TO' POINTER LDA 2,C3 ; WORD COUNT JSR @.MFMVW ; MOVE TIME INFO TO STACK COMON: JSR @.PREOV SRUFE ; START FILSY ON WAY IN LDA 2,CQ ; CURRENT QUEUE LDA 2,QSUFPx,2 ; QUEUE UFT POINTER STA 2,TPSUF,3 ; SAVE ON STACK LDA 0,ENTLG ; UFT LENGTH JSR @.CLEAR ; CLEAR IT LDA 0,OAC0,3 ; NAME POINTER MOV 2,1 ; UFT TO AC1 LDA 2,MAPN,3 ;MAP SWITCH JSR @.OVLAY ; CHECK & UNPACK FILENAME CSFNAM MOV 1,0 ; UFT TO AC0 STA 2,TPDCB,3 ; SAVE RETURNED DCB LDA 1,SFLK,2 ; GET DCB MAP LINK WORD COM# 1,1,SZR ; IF -1 THEN NOT A DISK DEVICE JMP NOMTA ; NOT A MAG TAPE DEVICE MOV 0,3 ; UFT TO AC3 LDA 1,UFTEX,3 ; GET EXTENTSION LDA 3,CSP ; RECOVER STACK POINTER MOV# 1,1,S^NR ; IS THERE AN EXTENSION ? JMP ICRET ; NO, IGNORE THE CREATE LDA 2,CC ; YES, GET CURRENT CELL LDA 2,CPTAD,2 ; GET PROGRAM TABLE ADDRESS LDA 2,PDDCB,2 ; DEFAULT DCB STA 2,TPDCB,3 ; SAVE IT NOMTA: LDA 2,DCBDC,2 ; DCT ADDRESS LDA 1,DCTCD,2 ; LINK W_ ORD MOV 0,2 ; UFT STA 1,UFTDL,2 SUB 0,0 STA 0,UFTBK,2 ; LAST BLOCK NUMBER STA 0,UFTBC,2 ; BYTE COUNT STA 0,UFTAD,2 ; FIRST BLOCK ADDRESS LDA 0,ATRBS,3 ; GET ATTRIBUTE STA 0,UFTAT,2 ; SET ATTRIBUTE LDA 0,FTAC,3 STA 0,UFTAC,2 ; YEAR/DAY LAST ACCESSED LDA 0,FTYD,3 STA 0,UFTYD,2 ; YEAR/DAY CREATED LDA 0,FTHM,3 STA 0,UFTHM,2 ; HOUR/MIN CREATED JMP CRET1 ; FINISH PROCESSING ; ROUTINE TO GATHER CURRENT TIME INFORMATION GETIM: LDA 0,@.TODD ; TIME OF DAY - DAY STA 0,FTAC,3 STA 0,FTYD,3 ; SAVE  KON STACK LDA 1,@.TODS ; TIME OF DAY - SECONDS LDA 2,CD60 ; SECONDS PER MINUTE JSR @.IDIV ; FORM MINUTE COUNT LDA 0,@.TODH ; TIME OF DAY - HOURS MOVS 0,0 ; TO LEFT BYTE ADD 1,0 ; HOURS (LEFT), MINUTES (RIGHT) STA 0,FTHM,3 ; TO THE STACK JMP COMON ; COMMON CODE CRET1: LDA 2,TPDCB,3 ; GET SYS.DR DCB ADDRESS LDA 0,TPSUF,3 ; & UFT ADDRESS JSR @.OVLAY ; SEARCH FOR ENTRY & EXTEND SRUFE ; DIRECTORY IF NECESSARY JMP CFNF ; FILE NOT FOUND STA 2,SBAD,3 ; FILE FOUND - SAVE BUFFER ADDRESS MOV 1#,2 ; ENTRY TO AC2 LDA 0,UFTAT,2 ; GET ATTRIBUTES LDA 1,LNKMK ; & LINK MASK AND# 0,1,SZR ; IS THIS A LINK ENTRY ? JMP LINK ; YES- RESOLVE JMP .+2 ; NOT A LINK ENTRY TPRIF: STA 0,TPDCB,3 ; SAVE RESOLVED LINK ENTRY LDA 0,UFTDL,2 ; DCT LINK LDA 2,SBAD,3 ; BUFFER ADDRESS JSR @.RELB ; RELEASE THE BUFFER LDA @2,TPDCB,3 ; GET DCT ADR FROM DCB LDA 1,DCTDT,2 ; ADR COMMAND DISPATCH TABLE MOVL 1,1 ; 1B0 = DISK. MOVE IT TO CARRY. LDA 1,DCTCD,2 ; DEVICE CODE LDA 2,C37 ; MASK TO CLR HIGHEST DEV CODE B/IT AND 2,1 ; DON'T CARE IF DEV. CODES ; DIFFER BY 40 (OCTAL). AND 2,0,SZC ; MASK OFF HIGH ORDER BIT OF DEV ; CODE IN DCT LINK, TOO. ; THIS DEVICE A DISK ? SUB# 0,1,SZR ; DEVICE IS A DISK. DEV CODES ; SAME OR DIFFER BY 40 ? JMP ICRET8 ; NO- ALLOW CREATE JSR @.RETER ; YES- RETURN FILE ALREADY EXISTS ERCRE ; ERROR LINK: LDA 1,SBAD,3 ;PICK UP ENTRY BUFFER ADDR LDA 0,TPDCB,3 ; & DCB JSR @.OVLAY ;(AC2 ALREADY POINTS TO ENTRY) LNKRS ;RESOLVE THE LINK JMP LTSTE ;ERROR, SEE IF A[FILE NOT FOUND STA 1,SBAD,3 ;FILE FOUND - SAVE BUFFER ADDR JMP TPRIF ;SEE IF PERIPHERAL ENTRY LTSTE: JSR @.TSTEQ ;FILE NOT FOUND? ERDLE RTRN ;NO, SOMETHING ELSE STA 0,TPDCB,3 ;YES, SAVE NEW DCB MOV 0,2 LDA 2,DCBDC,2 ;PICK UP THE LDA 0,DCTCD,2 '; POSSIBLY NEW DEVICE CODE LDA 2,TPSUF,3 STA 0,UFTDL,2 ;STORE IN UFT JMP CRET1 ;CONTINUE (LNKRS PUT NEW NAME ; IN THE QUEUE UFT) ICRET: ISZ ORTN,3 RTRN .PREOV: PREOV RANAT: ATRAN CONAT: ATCON .IDIV: DIVI .TODD: TODD .TODH: TODH .TODS: TODS CD6*0: 60. .OVLAY: OVLAY .CLEAR: CLEAR ENTLG: UFDEL .FTAC: FTAC C3: 3 .MFMVW: MFMVW C37: 37 CFNF: STA 2,DULKY,3 ; SAVE UNLOCK KEY JSR @.TSTEQ ; TEST FOR EXPECTED ERROR ERDLE ; FILE DOES NOT EXIST RTRN ; WRONG ERROR - BAG IT STA 0,BLKA1,3 ; SAVE BLOCK ADDRESS (HIGH ORDER) STA 1,BLKAD,3 ; SAVE BLOCK ADDRESS LDA 2,TPDCB,3 ; DCB ADDRESS OF SYS.DR LDA 2,DCBDC,2 ; SYS.DR'S DCT ADDRESS LDA 0,DCTCD,2 ; DEVICE CODE = LINK LDA 2,TPSUF,3 ; UFD ADDRESS LDA 1,UFTDL,2 ; THIS FILE'S LINK SUB# 0,1,SZR ; SAME DEVICE ? JMP NOADR ; NO, DON'T ALLOCATE A BLOCK LDA 0,UFTAT,2 ; GET ATTRIBUTES LDA 1,CONAT ; & CONTIGUOUS ATTRIBUTE AND# 0,1,SZR ; CONTIGUOUS CREATE ? JMP CONTI ; YES, GO TO IT LDA 1,TPDCB,3 ; NO, GET SYS.DR'S DCB ADDRESS LDA 2,@CQ  ; QUEUE DCB ADDRESS SUB 0,0 ; +0 STA 0,DBFA1,2 ; SET FIRST ADDRESS TO ZERO STA 0,DCBFA,2 ; LOW ORDER JSR @.FIDCB ; MAKE COPY OF SYS.DR'S DCB JSR @.RDNBK ; READ FIRST BLOCK OF NEW FILE JMP CERTN ; ERROR LDA 3,NXLK ; LINK WORD OFFSET ADD 1,3 ; LINK WORD ADDRESS STA 0,0,3 ; CLEAR THE LINK WORD STA 0,1,3 ; BOTH PARTS MOV 2,3 ; SAVE DCB ADDRESS MOV 1,2 ; BUFFER ADDRESS TO AC2 LDA 0,DBFA1,3 ; SAVE FIRST ADDRESS FOR UFT LDA 1,DCBFA,3 ; LOW ORDER JSR @.RELMB ; RELEASE IT MODIFIED LDA 2,TPSUF,3 ; REChOVER UFT ADDRESS STA 1,UFTAD,2 ; FIRST ADDRESS LOW ORDER LDA 1,UFTDL,2 ; GET DEVICE LINK WORD MOVS 0,0 ; HIGH ORDER ADDRESS TO LEFT BYTE ADD 0,1 ; MERGE STA 1,UFTDL,2 ; SET IN UFT JMP NOADR CERTN: LDA 0,DULKY,3 ;PICK UP UNLOCK KEY COM# 0,0,SZR ;ANYTHINGG LOCKED? JSR @.DUNLOCK ;YES, UNLOCK RTRN .DUNLOCK:DUNLOCK LNKMK: ATLNK .FIDCB: FIDCB .RELB: RELB .RETER: RETER .TSTEQ: TSTEQ CONTI: LDA 0,CONAT ; REAL CONTIGUOUS ATRIBUTE STA 0,UFTAT,2 ; IN CASE 1B0 SET LDA 2,TPDCB,3 ; GET DCB ADDRESS LDA 1,BLKCT,3 ; GET BLOCK COUNT JSR @.OVLAY WDCBK JMP CERTN ; ERROR LDA 2,@CQ ; Q DCB ADDRESS STA 0,DBFA1,2 ; SAVE BLOCK ADDRESS STA 1,DCBFA,2 ; LOW ORDER CMTX: LDA 2,TPSUF,3 ; TEMP UFT STA 1,UFTAD,2 ; FIRST BLOCK ADDRESS LDA 1,UFTDL,2 ; GET DEVICE LINK MOVS 0,0 ; HIGH ORDER TO LEFT BYTE ADD 0,1 ; MERGE STA 1,UFTDL,2 ; SAVE IT LDA 1,BLKCT,3 ; # OF BLOCKS NEG 1,1 COM 1,1 STA 1,UFTBK,2 ; LAST BLOCK NUMBER LDA 1,C1000 STA 1,UFTBC,2 ; LAST BLOCK BYTE COUNT LDA 1,ATRBS,3 ; ATRIBUTES AND NO IޛNIT FLAG MOVZL# 1,1,SZC ; NO INIT ?? JMP NOADR ; YES SKIP ALL THIS STUFF LDA 1,TPDCB,3 ; DCB ADDRESS LDA 2,@CQ ; Q DCB ADDRESS JSR @.FNDCB ; FULL INIT QUEUE DCB CLLP: JSR @.ASBUF ; ASSIGN A BUFFER MOV 1,2 ; INDEX ON THE BUFFER LDA 0,C400 ; CLEAR COUNT JSR @.CLEAR ; CLEAR THE BLOCK SUB 0,0 STA 0,BQST,2 ; CLEAR I/O IN PROGRESS STA 0,BQTLA,2 ; USE ME FIRST JSR @.RELMB ; RELEASE MODIFIED LDA 2,@CQ ; DCB ADDRESS ISZ DCBCA,2 ; BUMP BLOCK ADDRESS JMP .+2 ; NO ADDRESS OVERFLOW ISZ DBCA1,2 ; OVERFLOW UP HIGH ORDER ADDRESS DSZ BLKCT,3 ; FINISHED ? JMP CLLP ; NO NOADR: JSR @.OVCHN ; FINISH THE CREATE FCRET JMP CERTN NXLK: BQNXL C400: 400 C1000: 1000 .OVCHN: OVCHN .RELMB: RELMB .ASBUF: ASBUF .FNDCB: FNDCB .RDNBK: RDNBK ENDOV .E[TND DELETE.SRB R5k ; THIS SET OF ROUTINES DELETES FILE ENTRIES AND FILE SPACE ; ENTRY IS MADE BY AN OVERLAY CALL DIRECTLY TO THE ROUTINE DESIRED ; RTITLE DELETE .NREL  .ENT DELFIL .ENT UNLNK .ENT TRDEL .ENT EQUIV .EXTN FIDCB .EXTN FLUSH .EXTN RDNBK .EXTN RELZT,RBELMB .EXTN MVWD ; STACK PARAMETERS BFAD=TMP ;BUFFER ADDRESS TPDCB=BFAD+1 ;TEMP DCB ADDRESS FOR SYS.DR BFD1=TPDCB+1 ;COPY OF BFAD TPAT=BFD1+1 ;COPY OF ATTRIBUTES TUFT=TPAT+1 ;COPY OF UFT ADDRESS DFSSW=TUFT+1 ;DELETE FILE SPACE SWITCH QUFT=DFSSW+1 ;QUEUE UFT ADDRESS COUNT=QUFT+1 ;***************************************** ; NUMBER OF STACK TEMPORARIES USED ; MUST BE THE FIRST WORD IN THE OVERLAY .IFN ABSW 10 .ENDC ; ; DELETE FILE DIRECTORY ENTRY. ; ; AC0: BYTE POINTER TO FILE NAME STRINGr ; JSR DELFIL ; -ERROR (CODE IN AC2) ; -NORMAL RETURN ; UNLNK: SUBZL 1,1,SKP ; SET DELETE FILE SPACE FALSE DELFIL: SUB 1,1 ; SET DELETE FILE SPACE TRUE STA 1,DFSSW,3 ; IN THE STACK LDA 2,CQ ; CURRENT QUEUE LDA 1,QSUFP,2 ; QUEUE UFT POINTER STA 1,QU[FT,3 ; SAVE IT CALLO CFNAM ; CHECK & UNPACK NAME MOV 1,0 ; UFT TO AC0 CKDIR: LDA 1,SFLK,2 ; MAP.DR LINK COM# 1,1,SZR ; IS THERE A MAP ASSOCIATED ? JMP HASMP ; YES MOV 0,3 ; NO, INDEX ON UFT LDA 1,UFTEX,3 ; GET ENTRY'S EXTENSION LDA 3,CSP MOV# c1,1,SNR ; IS THERE AN EXTENSION ? JMP ILDEV ; NO, ILLEGAL COMMAND FOR DEVICE LDA 2,CC ; YES, GET CURRENT CELL LDA 2,CPTAD,2 ; PROGRAM TABLE ADDRESS LDA 2,PDDCB,2 ; DEFAULT DCB HASMP: STA 2,TPDCB,3 ; IS THE ONE TO USE CALLO SRUFD ; SEARCH FOR THE ENTRY RTRN ; ERROR FROM SRUFD STA 2,BFAD,3 ; FOUND, SAVE BUFFER ADDRESS STA 1,TUFT,3 ; & UFT ADDRESS MOV 1,2 ; INDEX ON UFT LDA 0,UFTAT,2 ; GET ATTRIBUTES XLDA 1,= ATLNK ; LINK MASK AND# 0,1,SNR ; IS THIS A LINK ? JMP TSTFL ; NO, TEST FOR UNLINK CALL ISZ DFSSW,3 ; YES, BUMP SWITCH DSZ DFSSW,3 ; UNLINK CALLED ? JMP DELOK ; YES LDA 2,BFAD,3 ; NO, GET BUFFER ADDRESS XXJSR RELZT ; & RELEASE IT LDA 0,QUFT,3 ; GET QUEUE UFT ADDRESS LDA 2,TPDCB,3 ; & DCB ADDRESS CALLO STATUS ; FIND RESOLU&UTION ENTRY RTRN ; ERROR FROM STATUS MOV 0,3 ; INDEX ON UFT LDA 3,UFTAT,3 ; GET ATTRIBUTES XLDA 1,= ATPER ; & PERMENANT MASK AND# 1,3,SZR ; IS RESOLUTION PERMENANT ? JMP PRESE ; YES LDA 3,CSP ; NO, GET STACK POINTER JMP CKDIR ; RESOLVED - LO1FOK IT UP TSTFL: ISZ DFSSW,3 ; BUMP THE FILE SPACE SWITCH DSZ DFSSW,3 ; UNLINK CALLED ? JMP NLEER ; YES, ERROR STA 0,TPAT,3 ; & SAVE FOR LATER XLDA 1,= ATPER ; PERMENENT MASK AND# 0,1,SZR ; IS THIS A PERMENENT FILE ? JMP PRER ; YES, THAT'S A NO-NO LDA 1,UFTUC,2 ; NO, GET USER COUNT MOV# 1,1,SZR ; IS FILE IN USE ? JMP FIUER ; YES, CAN'T DELETE IT XLDA 1,= ATPAR+ATDIR ; MASK FOR DCB SEARCH AND# 0,1,SNR ; IS SEARCH REQUIRED ? JMP DELOK ; NO, DELETE OK LDA 1,TUFT,3 ; YES, GET ADDRESS OF U1 NPACKED ; NAME LDA 2,TPDCB,3 ; & DCB ADDRESS CALLO DELPP JMP ERDEL ; ERROR RETURN LDA 2,TUFT,3 ; GOOD RETURN - GET UFT ADDRESS DELOK: SUB 0,0 ; +0 STA 0,UFTFN,2 ; CLEAR NAME TO VACATE ENTRY XLDA 1,= 377*400 ; ADDRESS MASK LDA 0,UFTDL,2 ; HIDD EN HERE ANDS 1,0 ; ALL SET LDA 1,UFTAD,2 ; GET LOW ORDER LDA 2,BFAD,3 ; BUFFER ADDRESS DSZ 0,2 ; DECREMENT ENTRY COUNT JMP .+1 XXJSR RELMB ;RELEASE MODIFIED XXJSR FLUSH ; GET RID OF ALL BLOCKS LDA 2,@CQ ; QUEUE DCB ADDRESS STA 0,DBFA1,2 STA Q1,DCBFA,2 ; SET AS FIRST LDA 1,TPDCB,3 ; SYS.DR DCB ADDRESS XJSR FIDCB ; INIT THE DCB STA 2,TPDCB,3 ; SAVE NEW DCB ADDRESS JMP DLP PRESE: XLDA 0,= ERDE1 ; PERMENANT FILE ERROR CODE JMP ERET FIUER: XLDA 0,= ERFIU ; GET ERROR CODE JMP PRER2 ; ERRcOR RETURN NLEER: XLDA 0,= ERNLE JMP PRER2 ILDEV: XLDA 0,= ERICD JMP ERET ERDEL: LDA 2,CC LDA 0,CERR,2 JMP PRER2 ; ANOTHER ENTRY POINT: TRDEL: STA 0,TUFT,3 ; ENTRY ADDRESS STA 1,TPAT,3 ; SAVE ATTRIBUTES STA 2,TPDCB,3 ; & DCB ADDRESS JMP DLP0 ; & JUMP IN ;MORE ERROR STUFF: PRER: XLDA 0,= ERDE1 PRER2: LDA 2,BFAD,3 XXJSR RELZT ERET: MOV 0,2 ;ERROR CODE TO AC2 ERROR ; RETURN THE ERROR CODE EQUIV: JMP EQUI ; BRIDGE OVER THE RIVER 7BITS LPOOL ; ; DELETE FILE SPACE SETCION. ; DLP: DSZ D'FSSW,3 ; TEST DELETE FILE SPACE SWITCH JMP DLP0 ; REAL FILE, DELETE IT JMP CRET2 ; NO FILE SPACE TO DELETE DLP0: LDA 0,TPAT,3 ; ATTRIBUTES XLDA 1,= ATCON ; CONTIGUOUS MASK AND# 0,1,SZR ; IS IT CONTIGUOUS ? JMP DELCT ; YES, USE DIFFERENT DELETE Ť ; PROCESS DESEQ: LDA 0,DCBNA,2 ; NEXT ADDRESS MOV# 0,0,SZR ; IS THERE A NEXT ? JMP GTIT ; YES LDA 0,DBNA1,2 ; TRY HIGH ORDER MOV# 0,0,SNR ; WELL ? JMP CRET ; NO, ALL DONE GTIT: XXJSR RDNBK ; YES, READ THE NEXT BLOCK RTRN ; ERROR STA 1,BFAD,3 ; SAVE BUFFER ADDRESS STA 1,BFD1,3 ; TWICE LDA 0,DBCA1,2 ; DEVICE ADDRESS (HIGH ORDER) LDA 1,DCBCA,2 ; DEVICE ADDRESS OF THIS BLOCK LDA 3,DCBDC,2 ; DCT ADDRESS LDA 3,DCTCH,3 ; DEVICE CHARACTERISTIC MOVL 2,2 ; SET CHARACTERISTIC IN BIT 0 MOVL 3,3ڂ ; SET CARRY FOR DEVICE CHARACTERISTIC MOVR 2,2 ; GOT IT CALLO DEBLK ; RETURN FREE BLOCK TO MAP JMP ERGO ; ERROR LDA 0,TPAT,3 ; ATTRIBUTES XLDA 1,= ATRAN ; RANDOM MASK AND# 0,1,SNR ; IS THIS A RANDOM FILE ? JMP RBK ; NO XLDA 1,= SCWPB ; YES, nGET MAX SLOT COUNT MOVL# 2,2,SZC ; BIG DISK ? XLDA 1,= SCWPB/2 ; YES, ONLY 1/2 AS MANY ENTRIES PER INDEX SLOT STA 1,COUNT,3 ; INDEX COUNTER SUB 0,0 ; REALLY NEED THIS FOR SMALL DISKS DLP1: MOVL# 2,2,SNC ; DISK SIZE TEST JMP .+3 ; SMALL DISK LEAVE HyIGH ORDER ADDRESS 0 LDA 0,@BFAD,3 ; BIG DISK, GET HIGH ORDER ADDRESS ISZ BFAD,3 ; KEEP THEM HONEST LDA 1,@BFAD,3 ; LOW ORDER ISZ BFAD,3 ADDZR# 0,1,SNR ; GEORGE'S TEST FOR ZERO JMP NOBLK ; VACANT CALLO DEBLK ; YES, RETURN IT TO THE MAP JMP ERGO ; ERROR NOBLK: DSZ COUNT,3 ; TRIED ALL SLOTS ? JMP DLP1 ; NO RBK: LDA 2,BFD1,3 ; GET BUFFER ADDRESS XXJSR RELZT ; RELEASE IT LDA 2,TPDCB,3 ; RECOVER DCB ADDRESS JMP DESEQ ; CONTINUE DELCT: LDA 2,TUFT,3 ; UFT ADDRESS LDA 1,UFTBK,2 ; NUMBER OF LAST% BLOCK COM 1,1 ; NEGATIVE BLOCK COUNT STA 1,COUNT,3 LDA 0,UFTDL,2 ; HIGH ORDER XLDA 1,= 377*400 ANDS 1,0 ; SET UP NOW LDA 1,UFTAD,2 ; FIRST DEVICE ADDRESS LDA 2,TPDCB,3 ; GET DCB BACK DELCL: CALLO DEBLK RTRN ; ERROR INC 1,1,SNR INC 0,0 ; OVERFLOW ISZ COUNT,3 ; DONE ? JMP DELCL ; NO JMP CRET CRET: XXJSR FLUSH CRET2: ISZ ORTN,3 RTRN ERGO: LDA 2,BFD1,3 ; BUFFER ADDRESS XXJSR RELZT ; RELEASE IT RTRN ; RETURN TO CALL+1 ; ROUTINE TO CHANGE A GLOBAL LOGICAL DIRECTORY/DEVICE SPECIuFIER ; ; INPUTS: AC0 - BYTE POINTER TO CURRENT NAME ; AC1 - BYTE POINTER TO NEW NAME ; ; OUTPUTS: NONE ; ; RETURNS: CALL+1 - ERROR.......ERROR CODE IN AC2 ; CALL+2 - GOOD RETURN QUFT=TMP TDCB=TMP+1 EQUI: LDA 2,CQ ; CURRENT QUEUE LDA 1,QSUFP,2 ; QUEUE UFT POINTER STA 1,QUFT,3 ; SAVE FOR LATER CALLO CFNAM ; CHECK & UNPACK CURRENT NAME CALLO SDIRR ; SEARCH FOR CURRENT SPECIFIER JMP SNKER ; SPECIFIER NOT KNOWN ERRROR LDA 0,DCBST,2 ; FOUND, GET STATUS MOVL# 0,0,SNC ; IS DIRECTORY INIT'D ? JMP  ILLCM ; YES, THAT'S ILLEGAL STA 2,TDCB,3 ; NO, SAVE DCB ADDRESS LDA 2,@CC ; TCB ADDRESS LDA 0,TAC1,2 ; USER'S AC1 LDA 1,QUFT,3 ; UNPACK AREA CALLO CFNAM ; CHECK & UNPACK NEW SPECIFIER CALLO SDIRR ; LOOK FOR NEW SPECIFIER JMP EQVOK ; NOT THERE, CONTINUE ; FOUND, CAN'T HAVE 2 WITH SAME ILLCM: ERROR ERDIU ; NAME, GIVE DIRECTORY IN USE ERROR EQVOK: LDA 2,TDCB,3 ; GET DCB ADDRESS XLDA 1,= SFLNA ; LOGICAL NAME OFFSET ADD 2,1 ; ADDRESS OF LOGICAL NAME LDA 0,QUFT,3 ; 'FROM' ADDRESS XLDA 2,= S CFNL-1 ; SPECIFIER LENGTH XJSR MVWD ; MOVE NEW SPECIFIER TO DCB ISZ ORTN,3 ; GOOD RETURN RTRN SNKER: ERROR ERDSN ; DIRECTORY SPECIFIER NOT KNOWN LPOOL ENDOV .END FILSY.SRB R5- ; THIS OVERLAY CONTAINS MODULES WHICH ARE USED TO SEARCH FOR ; AN ENTRY IN A DIRECTORY AND MAINTAIN THE DIRECTORY ; RTITLE FILSY FLSY .NREL .ENT SRUFE .ENT SRUFD .EXTN CMPWD .EXTN OVLAY .EXTN SYSNM .EXTN FIDCB .EXTN RELPB,RELMB .EXTN FLUSH aF .EXTN DIVI .EXTN BLKIN .EXTN WDBLK .EXTN OICAL .EXTN RDBNO .EXTN ASBUF .EXTN CLEAR .EXTN RETER .EXTN DLOCK,DUNLOCK ;DUAL PROCESSOR STUFF ;***************************************** ; NUMBER OF STACK TEMPORARIES USED ; MUST BE THE FIRST WORD IN THE OVERLAY .IFN BSW!MBSW 7 .ENDC ; ; ROUTINE TO SEARCH SYS.DR FOR A MATCH ON FILE NAME. ; ; IN OUT OUT ; (FOUND) (NOT FOUND AND NO ERROR) ; ; AC0 - PTR TO UFD X DEVICE ADDRESS OF ; AVAILABLE BLOCK (SRUFE) ; ; AC1 - X PTR TO ENTRY AVAILABLE BLOCK ADDRESS ; LOW ORDER (SRUFE) ; ; AC2 - PTR TO DCB PTR TO LOCK KEY OR ; ENT'S BUFFER PTR TO DCB ON ERROR CONDITION ; (SRUFE ONLY) ; ; ; ENTRY POINTS: ; SRUFD - SEARCH FOR ENTRY NAME ; ; SRUFE - SEARCH FOR ENTRY NAME; IF NOT FOUND, ; >FIND & LOCK A BLOCK (ALLOCATE ONE IF ; NECESSARY) WITH A VACANCY (RETURN IN ; AC2 THE LOCK KEY, OR INPUT AC2 IF AN ; ERROR OTHER THAN FILE DOES NOT ; EXIST WAS ENCOUNTERED. ; ; RETURNS: ; ; CALL+1 - NOT FOUND , OR OTHER ERROR ; CALL+2 - ENTRY FO_UND MNVB1=OAC0 MNVBK=OAC1 DCBAD=OAC2 FRMSZ=TMP BFAD=FRMSZ+1 CHSHP=BFAD+1 ECNT=CHSHP+1 WDCNT=ECNT UFDPT=ECNT+1 ULKY=UFDPT+1 ;UNLOCK KEY FOR OURSELVES DULKY=OAC2 ;UNLOCK KEY RETURNED TO CALLER SRUFE: ADC 1,1,SKP ; SHOW SRUFE AND NOTHING LOCKED SRUFD: SUB 1,1 STA 1,ULKY,3 ; SAVE SRUFE/SRUFD SWITCH AND/LOCK FLAG ADC 1,1 STA 1,MNVB1,3 ; INIT HIGH VACANT ADDRESS STA 1,MNVBK,3 ; INIT LOW VACANT ADDRESS LDA 2,DCBDR,2 ;MAKE SURE WE TAKE FROM A ; DIRECTORY DCB LDA 1,SFMSZ,2 ; GET MAGIC NUMBER STA 1,FRMSZ,3 ; & SAVE LDA 2,DCBAD,3 ;GET ORIGINAL DCB BACK LDA 2,DCBDC,2 ; DCT ADDRESS LDA 1,DCTCH,2 ; GET CHARACTERISTIC MOVZL 0,0 ; SET IN UFD ADDRESS MOVL 1,1 ; CARRY SET IF BIG DISK MOVR 0,0 ; STORE IN UFD POINTER STA 0,UFDPT,3 ; SAVE NSAME POINTER SUB 1,1 ; CLEAR AC1 LDA 2,UFDPT,3 ; UNPACKED NAME POINTER LDA 0,NAMLG ; NEGATIVE NAME LENGTH STA 0,WDCNT,3 ; SAVE IN STACK HSHLP: LDA 0,0,2 ; GET 2 BYTES OF FILE NAME ADD 0,1 ; ADD 'EM IN INC 2,2 ; BUMP THE ADDRESS POINTER ISZ WDCNT0,3 ; BUMP & TEST WORD COUNT JMP HSHLP ; NOT DONE LDA 2,FRMSZ,3 ; GET FRAME SIZE AS DIVISOR SUBO 2,1,SNC ; COMPUTE HASH/FRMSZ-FRMSZ JMP .-1 STA 1,CHSHP,3 ; SAVE AS CURRENT POINTER SRLP0: LDA 3,DCBAD,3 ; CALLER'S DCB LDA 2,@CQ ; QUEUE DCB LDA 0,DCBFA,3 STA 0,DCBFA,2 ; MAKE A COPY WE CAN MUCK WITH LDA 0,DBFA1,3 STA 0,DBFA1,2 MOV 3,1 ; CALLER'S IS PATTERN TO COPY FROM JSR @.FIDCB ; INIT THE QUEUE DCB LDA 1,CHSHP,3 ; CURRENT HASH POINTER LDA 0,FRMSZ,3 ; & FRAME SIZE ADD 0,1 ; NEW CURRENT (STA 1,CHSHP,3 ; SAVE IT LDA 2,@CQ ; QUEUE DCB ADDRESS JSR @.OICAL GMTFB ; DEMAND PAGING JMP URET ; UNLOCK IN CASE BLOCK FROM PRE FRAME STA 0,BFAD,3 ; SAVE BUFFER ADDRESS ADD 0,2 ; FORM SLOT ADDRESS LDA 1,0,2 ; GET SLOT CONTENTS (LOW ORDER) LD[A 0,-1,2 ; GET SLOT CONTENTS (HIGH ORDER) LDA 2,UFDPT,3 ; CHECK CHARACTERISTIC MOVL# 2,2,SNC ; REALLY DOUBLE ADDRESSING ? SUB 0,0 ; NO, ZERO HIGH ORDER WORD LDA 2,BFAD,3 ; BUFFER ADDRESS MOV# 0,0,SZR ; IS SLOT VACANT ? JMP SRCH ; NO, GO SEARCH T HIS BLOCK MOV# 1,1,SZR ; IS THERE ONE ? JMP SRCH ; NO, GO SEARCH THIS ONE LDA 0,ULKY,3 ; LOCK KEY/SRUFE FLAG LDA 1,MNVB1,3 ; VACANT ADDRESS HIGH ORDER MOV# 0,0,SZR ; SRUFE ? COM# 1,1,SZR ; AND WE DON'T HAVE FREE BLOCK ? JMP ERR ; NO OR NO THAVTS AN ERROR JSR @.DLOCK ;MUST LOCK INDEX BLOCK UNTIL STA 0,ULKY,3 ; WE'VE DECIDED HOW TO SET IT JSR @.RELPB ;MUST RELEASE BUFFER LDA 2,@CQ ; YES, GET QUEUE DCB ADDRESS JSR @.OVLAY WDBLK ; WITHDRAW A FREE BLOCK JMP URET ; ERROR, MUST UNLOCK INDtEX BLOCK STA 0,MNVB1,3 ; RETURN DEVICE ADDRESS STA 1,MNVBK,3 ; RETURN DEVICE ADDRESS LDA 1,CHSHP,3 ; GET CURRENT HASH POINTER JSR @.OICAL GMTFB ; GET SLOT BLOCK JMP URET ; ERROR...... ADD 0,2 ; SLOT ADDRESS LDA 1,MNVBK,3 ; DEVICE ADDRESS STA 1,0,2 ; SET INTO SLOT LDA 1,MNVB1,3 ; GET HIGH ORDER ADDRESS LDA 3,UFDPT,3 ; TEST CHARACTERISTIC MOVL# 3,3,SZC ; REALLY NEED THIS ? STA 1,-1,2 ; YEP MOV 0,2 ;BUFFER ADDRESS TO AC2 JSR @.RELMB ;RELEASE MODIFIED LDA 2,@CQ ; QUEUE DCB STA 1,DBCA1,2 ; SET CURRENT ADDRESS (HIGH ORDER) LDA 1,MNVBK,3 ;RECOVER CURRENT LOW ORDER STA 1,DCBCA,2 ;SET CURRENT ADDRESS (LOW ORDER) JSR @.ASBUF ; ASSIGN A BUFFER MOV 1,2 SUB 0,0 STA 0,BQST,2 ; CLEAR I/O IN PROGRESS LDA 0,DBKSZ ; DATA BLOCK SIZE JSR @.CkLEAR LDA 0,ULKY,3 ;INDEX BLOCK'S UNLOCK KEY JSR @.DUNLOCK ;NOW GIVE UP INDEX BLOCK JSR @.DLOCK ; AND HOLD ONTO DIRECTORY BLOCK STA 0,ULKY,3 JSR @.RELMB ;RELEASE MODIFIED LDA 0,CHSHP,3 ; GET CURRENT POINTER LDA 2,DCBAD,3 ; SYS.DR DCB LDA 1,SFBK,2 Sv; LAST BLOCK # OF SYS.DR ADCZ# 1,0,SNC ; EXTENDING SYS.DR ? JMP NO1 ; NO, RETURN 'DOES NOT EXIST' STA 0,SFBK,2 ; YES, UPDATE SYS.DR'S SIZE LDA 0,.SYSNM ; UNPACKED SYS.DR NAME POINTER JSR @.OICAL ; RECURSIVE CALL SRUFD JMP DIRER ; NO SYS.DR IN NOT GOOD ! LDA 0,CHSHP,3 ; NEW LAST BLOCK # MOV 1,3 ; ENTRY ADDRESS TO AC3 STA 0,UFTBK,3 ; SET INTO SYS.DR'S ENTRY ALSO JSR @.RELMB ;RELEASE MODIFIED JSR @.FLUSH ; START ALL MODED BUFFS GOING JMP NO1 ; NOW RETURN 'DOES NOT EXIST' ; ERROR ERR: KJSR @.RELPB JMP NO1 ; FILE NOT FOUND ERROR URET: JMP URET1 ; UNLOCK AND RETURN GMTFB: LDA 2,IBKSZ ; INDEX BLOCK SIZE LDA 3,OSP,3 ; GET LAST FRAME LDA 3,UFDPT,3 ; GET DISK CHAR BIT MOVL# 3,3,SZC ; REALLY ONLY 1/2 DENSE ? MOVZR 2,2 ; YEP JSR ]@.IDIV LDA 2,OAC2,3 ; RECOVER DCB ADDRESS LDA 3,OSP,3 ; GET LAST FRAME LDA 3,UFDPT,3 ; GET DISK CHAR BIT MOVL# 3,3,SZC ; BIG ONE ? MOVOL 0,0 ; OFFSET*2+1 LDA 3,CSP STA 0,OAC2,3 ; RETURN OFFSET IN AC2 MOV 1,0 ; BLOCK # TO AC0 JSR @.RDBNO ; REAnfD NTH BLOCK RTRN ; ERROR........ STA 0,OAC0,3 ; RETURN BUFFER ADDRESS IN AC0 ISZ ORTN,3 ; GOOD RETURN RTRN JMPSL: JMP SRLP0 NAMLG: -SCFNL .OICAL: OICAL .FIDCB: FIDCB .OVLAY: OVLAY .RDBN0: RDBNO .ASBUF: ASBUF .CLEAR: CLEAR ENTLG: UFDEL .IDIV: DIVI .RELPB: RELPB .RELMB: RELMB .FLUSH: FLUSH .SYSNM: SYSNM IBKSZ: SCWPB DBKSZ: SCDBS .DLOCK: DLOCK .DUNLOCK:DUNLOCK SRCH: JSR @.RELPB LDA 2,@CQ ; QUEUE DCB STA 0,DBCA1,2 ; SET CURRENT ADDRESS STA 1,DCBCA,2 ; SET CURRENT ADDRESS JSR @.BLKIN ; GET THE BLOCK JMP URET ; UNLOCK IF NECESSARY STA 0,BFAD,3 ; SAVE ADDRESS INC 0,1 ; POINT TO FIRST ENTRY LDA 2,@BFAD,3 ; GET ENTRY COUNT LDA 0,MXCNT ; MAX LEGAL COUNT ADCZ# 2,0,SZC ; ANY VACANCIES ? JMP SRCH1 ; YES SUB# 2,0,SNR ; LEGAL ENTRY COUNT ? pJMP EMTST ; YES, SEARCH THIS BLOCK JMP DIRER ; DIRECTORY ERROR SRCH1: LDA 2,MNVB1,3 ; MIN VACANT ADDRESS COM# 2,2,SZR ; IS THERE ONE ? JMP EMTST ; YES, JUST SEARCH THIS BLOCK LDA 2,BFAD,3 ; NO, GET THE BUFFER ADDRESS LDA 0,ULKY,3 COM# 0,0,SNR ; SURFE AND NOTHING LOCKED ? JSR @.DLOCK ; YES - WE HAVE TO LOCK STA 0,ULKY,3 ;REMEMBER KEY LDA 0,BQCA1,2 ; HIGH ORDER DEVICE ADDRESS LDA 2,BQCA,2 ; NOW DEVICE ADDRESS STA 2,MNVBK,3 ; AND RETURN IT STA 0,MNVB1,3 ; RETURN HIGH ORDER EMTST: LDA 2,@BFAD,3 ; ENTRY COUNT MOV# 2,2,SNR ; ANY ENTRIES ? JMP NOENT ; NO STA 2,ECNT,3 ; YES, SAVE COUNT IN STACK SRLP: MOV 1,2 ; INDEX ON ENTRY LDA 2,0,2 ; GET FIRST ENTRY WORD MOV# 2,2,SZR ; IS IT VACANT ? JMP CMPAR ; NO, COMPARE THE STRINGS NEXEN: LDA 2,ENTLG ; GET ENTRY LENGTH ADD 2,1 ; ADDRESS OF NEXT ENTRY JMP SRLP ; KEEP LOOKING CMPAR: LDA 0,UFDPT,3 ; GET UFD POINTER LDA 2,FNLGT ; FILENAME LENGTH JSR @.CMPW ; COMPARE WORDS JMP ENTFD ; ENTRY FOUND DSZ ECNT,3 ; NOT FOUND, DEC THE COUNT JmMP NEXEN ; MORE ENTRIES, KEEP LOOKING NOENT: LDA 2,BFAD,3 ; GET BLOCK'S BUFFER ADDRESS LDA 3,HECOS ; HIGHEST ENTRY COUNT OFFSET ADD 2,3 ; HIGHEST ENTRY COUNT ADDRESS LDA 1,0,3 ; HIGHEST ENTRY COUNT NOLK: JSR @.RELPB ; RELEASE THE BUFFER LDA 2,MXCNT ; MAX ENTRY COUNT ADCZ# 1,2,SNC ; WAS THIS BLOCK EVER FULL ? JMP JMPSL ; YES, TRY NEXT FRAME NO1: LDA 0,ULKY,3 ; LETS SEE WHICH WAY TO GO MOV 0,0,SZR ; ANY LOCK ? COM# 0,0,SNR ; WELL ? JMP NO2 ; NO DON'T BLOW UP CALLERS AC2 STA 0,DULKY,3 ;$ YES - RETURN LOCK KEY TO CALLER NO2: JSR @.RETER ; FILE DOES NOT EXIT ERROR ERDLE ENTFD: STA 1,OAC1,3 ; RETURN ENTRY ADDRESS LDA 1,BFAD,3 ; ENTRY'S BUFFER ADDRESS STA 1,OAC2,3 ; RETURN ALSO ISZ ORTN,3 ; RETURN TO CALL+2 URET1: LDA 0,ULKY,3 ; LETS  SEE WHICH WAY TO GO COM# 0,0,SZR ; IS THERE A LOCK KEY ? MOV# 0,0,SNR ; WELL ? RTRN ; NO DON'T UNLOCK WHAT ISN'T LOCKED JSR @.DUNLOCK ; YES - DON'T LEAVE LOCKS LYING AROUND RTRN FNLGT: SCFNL HECOS: SCWPB-1 MXCNT: SCWPB-1/UFDEL .BLKIN: BLKIN .gCMPW: CMPWD .RETER: RETER .ERSDE: ERSDE ; DIRECTORY DATA ERROR DIRER: LDA 0,.ERSDE ; ERSDE LDA 2,CC ; CURRENT CELL STA 0,CERR,2 ; RETURN ERROR CODE IN CELL JMP URET1 ; COMMON ERROR RETURN ENDOV .END SOV1.SRB q 5 RTITLE SOV1 .NREL .ENT MEM .ENT CHAT .ENT CHLAT .ENT GTAT .ENT OEBL,ODIS .ENT FGND .ENT UCLI,UCLR,RTCF .ENT GTIME,STIME .ENT GCIN,GCOUT .ENT RDSW .ENT SECI .EXTN RETER .EXTN FOPE,DTER .EXTN TODS,TODH .EXTN RTCI .EXTN DIVI .EXTN SCNT .EXTN SYSFG .EXTN TSECI .EXTN UTOTL .EXTN BIN,FIN .EXTN MTMVB .IFN MSW .EXTD BBLK1,FBLK1 .EXTD CMAP .ENDC ;***************************************** ; NUMBER OF STACK TEMPORARIES USED ; MUST BE THE FIRST WORD IN THE OVERLAY .IFN BSW!MBSW 0 .0ENDC ; USER WANT'S TO KNOW CONSOLE IN/OUT DEV ; AC0= AREA (3 WDS) TO PUT INFO INTO  GCIN: MOVO 0,0,SKP ;CARRY TELLS WHO GCOUT: MOVZ 0,0 ;OUT LDA 2,CC LDA 1,CPROG,2 ;SEE IF FG LDA 2,.BIN ;ASSUME BG MOVZR# 1,1,SNR LDA 2,.FIN MOV# 1,1,SNC ;SKIP IFf INPUT DEV INC 2,2 ;ADDR OUTPUT FOLLOWS MOV 0,1 ;TO ADDR LDA 0,0,2 ;FROM ADDR LDA 2,C6 ;BYTE COUNT JSR @.MTMVB JMP EX2 .BIN: BIN .FIN: FIN .MTMVB: MTMVB C6: 6 ; REQ FROM TQTASK TO INTERRUPT FOR A RESCHED EVERY SEC SECI: LDA @1,.TSECI LDA 2,CCj LDA 2,CPROG,2 ;SEE IF FG OR BG ADCZL 0,0 ;MASK FOR BG MOVZR# 2,2,SNR ;SKIP IF BG ADCZR 0,0 ;FG MASK AND 0,1 ADC 0,1 ;OR BIT STA @1,.TSECI JMP EX2 .TSECI: TSECI ; CHANGE FILE ATTRIBUTES ; INPUT: AC2 - UFT ADDRESS ; AC0 - NEW ATTRIBUTE WORm,D CHLAT: LDA 0,UFTAT,2 ; GET CURRENT ATTRIBUTES LDA 1,RESAT ; RESOLUTION MASK AND# 0,1,SZR ; OPENED VIA A LINK ? JMP CHAE0 ; YES, THAT'S A GOTCHA ! SUBZL 1,1,SKP ; +1 FOR LINK ACCESS ;ATTRIBUTES CHAT: SUB 1,1 ; 0 FOR REGULAR ATTRIBUTES JSR CHECK ; VALIDATE OPEN CHANNEL LDA 3,.STUTP ;CHECK STATUS AND# 3,0,SZR JMP CHAE0 ;PROTECTED BIT-- GOTCHA ON QTY, MCA ADD 1,2 ; POSSIBLE FUDGE OF UFT ;ADDRESS LDA 0,UFTAT,2 ; CURRENT ATTRIBUTES LDA 1,CHG ; ATTRIBUTE PROTECT MASK AND# 0,1,SZR ;' ATTRIBUTE PROTECTED ? JMP CHAE0 ; YES, THAT'S A GOTCHA LDA 3,CSP ; NO, GET STACK POINTER ISZ ORTN,3 ; GOOD RETURN NOW LDA 1,NOCHG ; NOT CHANGEABLE ATTRIBTUES AND 1,0 ; SAVE ALL THAT CAN'T BE ;ALTERED LDA 3,OAC0,3 ; USER'S REQUESTED ATTRIBUTEES LDA 1,CHABL ; CHANGEABLE ATTRIBUTE MASK AND 3,1 ; ALL LEGALLY CHANGEABLE ONES COM 1,3 ; INVERT AGAIN AND 3,0 ; INCLUSIVE OR ADD 0,1 ; THAT'S IT STA 1,UFTAT,2 ; RETURN TO UFT RTRN ; SO LONG, IT'S BEEN GOOD TO ;KNOW YA CHAE0: JSR @.RETEwR ERCHA ; UNABLE TO ALTER ATTRIBUTES .STUTP: STUTP ; GET ATTRIBUTES ; INPUT: AC2 = UFT ; OUTPUT: USTA0 - FILE ATTRIBUTES ; USTA1 - DEVICE ATTRIBUTES GTAT: JSR CHECK ;MAKE SURE CHAN IS OPEN LDA 3,CSP ISZ ORTN,3 ;OK RETURN LDA 3,@CC ;TCB LDA 1,.uSTUTP ;CHECK STATUS AND# 1,0,SNC JMP .+3 ; OK-- CONTINUE LDA 0,CHG ; UFT PROTECTED-- RETURN ATCHA JMP FASTA LDA 0,UFTAT,2 ; FILE ATTRIBUTES FASTA: STA 0,TAC0,3 LDA 2,UFTDC,2 ; DCT ADDRESS LDA 0,DCTDT,2 ; IF DISK RETURN 0 DEVICE CHAR. MOVL# 0,0,SZC SUB 0,0,SKP LDA 0,DCTCH,2 ; DEVICE CHARACTERISTICS STA 0,TAC1,3 RTRN CHG: ATCHA RESAT: ATRES XCHEK: .BLK 1 ; RETURNS AC0= STATUS, AC2= UFT CHECK: MOVL# 2,2,SZC ;SEE IF CHAN OPEN JMP @.FOPE ;IF NO STA 3,XCHEK ; YES- SAVE RETURN LDA 3,UFTYDR,2 ; SYS.DR DCB ADDRESS LDA 0,UFTST-UFTDC,3 ; GET STATUS JMP @XCHEK ; AND RETURN .FOPE: FOPE NOCHG: ATRAN+ATCON+ATDIR+ATPAR+ATRES ;+ATLNK NEVER IN CORE CHABL: ATWP+ATRP+ATSAV+ATPER+ATCHA+ATNRS+ATUS1+ATUS2 .RETER: RETER ; CALL TO SEE IF FG RUNNINGA ; AC0 = 0 IF NO, =1 IF YES ; AC1= CURRENT PUSH LEVEL FOR CALLER FGND: LDA @2,CC LDA @0,.SYSFG STA 0,TAC0,2 LDA 3,CC LDA 3,CPTAD,3 LDA 1,PTSPN,3 ;PUSH LVL STA 1,TAC1,2 ;RTN IT JMP EXIT ; READ SWITCHES INTO AC0 RDSW: LDA @2,CC DIA 0,CPU JMP RCTXBT ; ENTRY POINTS FOR ROUTINES IN THE SECOND HALF OF THE OVERLAY UCLI: JMP .UCLI UCLR: JMP .UCLR RTCF: JMP .RTCF MEM: JMP .FMEM STIME: JMP .STIME ; CALL TO DISABLE CONL A,CONTL C,CONTL F ; CALL TO ENABLE AFTER A ODIS ODIS: SUBZR 0,0,SKP ;FLAG CALL OEGBL: SUB 0,0 LDA 2,CC LDA 2,CPTAD,2 ;PTBL LDA 1,PFLAG,2 ADCZR 3,3 ;MASK OUT CURRENT STATE AND 3,1 ADD 0,1 ;NEW FLAG STA 1,PFLAG,2 JMP EXIT .SYSFG: SYSFG ; GET SYSTEM TIME ; ON RETURN AC0=SEC,AC1=MIN,AC2=HOURS GTIME: LDA @1,.TODS ;SEC LDA 2,C6͓0. ;DIVIDE SEC/MIN TO GET BOTH SUB 0,0 JSR @.DIVI ;0 = SEC,1= MIN LDA @3,CC STA 0,TAC0,3 ;PASS IN TCB STA 1,TAC1,3 LDA @0,.TODH ;HOURS STA 0,TAC2,3 EXIT: EX2: LDA 3,CSP ISZ ORTN,3 RTRN ; SET SYSTEM TIME ;ON ENTRY USER TCB AC'S CONTAIN NEW VALUES>6 ; SET TOD- USER AC'S ARE AS FOLLOWS: ;AC0= SEC ;AC1= MIN ;AC2= HOURS .STIME: LDA @3,CC ;TCB LDA 0,TAC0,3 LDA 1,TAC1,3 LDA 2,TAC2,3 LDA 3,C24. ADCZ# 2,3,SNC ;VALIDATE HOURS IN AC2 JMP TIMER ;TOO HIGH LDA 3,C60. ;VALIDATE ADCZ# 1,3,SNC JMP TIMER ADCZ# 0,3,SNC ;CHECK SEC JMP TIMER MOVZL 1,1 ;MULT MINX60 TO GET SEC ! MOVZL 1,3 ;NEED 4 LATER MOVZL 3,1 MOVZL 1,1 MOVZL 1,1 MOVZL 1,1 SUB 3,1 ADD 0,1 ;ADD SEC INTDS STA @1,.TODS ;RESULT MIN/SECS STA @2,.TODH ;HOURS INTEN JMP EX2 TIKMER: JSR @.RETER ERTIM .TODS: TODS C60.: 60. .TODH: TODH .DIVI: DIVI C24.: 24. ; DEFINE A USER CLOCK ROUTINE ; AC0= # TICKS TO WAIT BEFORE INTERRUPTING USER ;AC1 = ADDR USER ROUTINE .UCLI: LDA 2,CC LDA 2,CPTAD,2 ;PTBL ADDR LDA 3,PCLAC,2 ;IS A CLK bDEFINED ? MOV# 3,3,SZR JMP IDER1 .IFN MSW LDA 1,PDEV+7,2 ;ENABLE CPU MOVR 1,1 MOVZL 1,1 STA 1,PDEV+7,2 .IFE MBSW SUB 3,3 STA 3,CMAP .ENDC .IFN B?MSW SMST 1 ;TO MAP .ENDC .ENDC STA 0,PCLCN,2 ;CONSTANT LDA @3,CC LDA 1,TAC1,3 ;ADDR STA 1,P,CLAD,2 ;USER ROUTINE STA 0,PCLAC,2 ;STORE AS ACT COUNT ISZ @.UTOTL ;INC CLOCK COUNT JMP EX2 ; REMOVE A USER CLOCK .UCLR: LDA 2,CC LDA 2,CPTAD,2 ;PTBL LDA 0,PCLAC,2 ;ADDR DEF NOW ? MOV# 0,0,SNR JMP IDER1 ;NO-ERROR SUB 0,0 ;REMAOVE IT STA 0,PCLAC,2 ;KILL TIMER DSZ @.UTOTL ;DEC CLOCK COUNT JMP .+1 JEX2: JMP EX2 ; PASS USER THE RTC FREQ SET BY SYSGEN ; CODES: 0= NO CLK,1=10HZ,2=100 HZ,3= 1000 HZ,4= LINE FREQ .RTCF: LDA @2,CC ;TCB LDA 0,.RTCI ;ADDR FREQ CONTROL MOV# 0,0,SZR ;SKIP IF LINE FړREQUENCY JMP NOTLF ;NOT LINE FREQ LDA 0,C4 ;FOR LITTLE DICKY ;FARWELL...... LDA 1,.SCNT ;GET SECOND COUNT LDA 3,C60 ;& DECIMAL 60 SUB# 1,3,SZR ;IS IT 60 HZ ? INC 0,0 ;NO, BUMP THE CONSTANT NOTLF: COM# 0,0,SNR ;IF NO CLOCK CHANGE -1 TO 0 SUB 0,0 RCTXT: STA 0,TAC0,2 ;TO USER JMP JEX2 .RTCI: RTCI .UTOTL: UTOTL .SCNT: SCNT C60: 60. IDER1: JSR @.RETER ERIBS C4: 4 ; MEMORY ; OUTPUT: TA0 - HIGHEST MEMORY AVAILABLE ; TA1 - HIGHSET MEMORY CURRENTLY IN USE PLUS 1 .FMEM: LDA @2,CC ;TCB LDA 3,USTP LDA 0,USTNM,3 ;NMAX STA 0,TAC1,2 ;RETURN TO USER LDA 1,USTES,3 ; END OF SYSBOL TABLE USGT 1,0 ; SEE HOW IT COMPARES JMP MEM1 ;SEE IF A MULTI-TASKED GUY MEM2: LDA 2,@CC ;TCB STA 1,TAC0,2 ; PUT THE HIGHER IN USTA0 LDA 3,CSP ISZ ORTN,3 RTRN .IFE MSW MEM1: LDA 3,CC LDA 3,CPTAD,3 ;PTBL LDA 1,PUFPT,3 ;END IS UFPT-1 NEG 1,1 ;DEC COM 1,1 JMP MEM2 .ENDC .IFN MSW MEM1: LDA 2,CC LDA 2,CPROG,2 ;FG CALLER ? LDA 1,BBLK1 ;ASSUME NO MOVZR# 2,2,SNR LDA 1,FBLK1 ;FG COUNT LDA 2,CC ; GET UAMOUNT IN USE BY CORE IMAGE LDA 2,CPTAD,2 LDA 2,PMSZ,2 ; (AC2) = -(NUMBER OF BLOCKS USED BY CORE IMMAGE) SUB 2,1 ; ADD THEM IN LDA 2,CMXBK ;ONLY GIVE 31K SUBZ# 1,2,SNC MOV 2,1 MOVS 1,1 ;FORM HI ADDR NEGZL 1,1 ; # BLOCKS *2000 -1 COMOL 1,1 JMPw MEM2 CMXBK: .IFN MNSW 31. ; 830/840 MAX 31KW .ENDC X 32. ; NOVA 3/ECLIPSE MAX 32KW [X] .ENDC ENDOV .END SOV2.SRB S  RTITLE SOV2 .ENT CFNAM ; CHECK & UNPACK FILENAME .ENT CSFNAM ; CFNAM WITH MAP/NO MAP SWITCH .ENT DNCK ; DEVICE NAME CHECK .ENT NAMCK ; NAME CHECKER .ENT OPNCK ; OPEN CHANNEL CHECK .ENT SDIRR ; SEARCH DIRECTORY RING .ENT TFTX ; TEST FOR TER!MINATOR .EXTN SYSER .EXTN CLEAR .IFE BSW .EXTN MLDBT .ENDC .EXTN SYSE2 .EXTN DIRR .EXTN CMPWD .IFE BSW!MBSW .EXTN LDBT,STBT .ENDC .NREL ;***************************************** ; NUMBER OF STACK TEMPORARIES USED ; MUST BE THE FIRST/ WORD IN THE OVERLAY .IFN BSW!MBSW 4 .ENDC ; ROUTINE TO CHECK A FILENAME FOR LEGALITY ; AND UNPACK IT INTO SYS.DR FORMAT ; PREFIXED DIRECTORY SPECIFIERS ARE ACCEPTED AND ; THE CORRESPONDING DCB ADDRESS IS RETURNED ; INPUTS: AC0 - BYTE POINTER TO PACKED FILENAME FOLLOWED ; BY A TERMINATOR ; AC1 - WORD ADDRESS FOR RETURN OF UNPACKED NAME ; (MUST BE AT LEAST 'SCFNL' WORDS IN LENGTH) ; OUTPUTS: AC2 - SYS.DR DCB ADDRESS CKTYP=TMP PNBPT=CKTYP+1 CURBP=PNBPT+1 ; REQUEST TO OPEN A CHANNEmL - SEE IF OPEN ALREADY ; AND VALIDATE NAME PASSED BY USER ; AC1 - UFT POINTER OPNCK: STA 1,TMP,3 ; SAVE UFT POINTER MOV 1,2 ; UFT POINTER LDA 1,0,2 ; UFT ADDRESS ; NOTE - DON'T USE UFT IN CELL, MAY BE DIFFERENT NOW MOVL# 1,1,SNC ; IS CHANNEL ALREADY OPEN ? JMP OPNER ; SURE IS LDA 1,OAC2,3 ;MAPPED UFT IF NEEDED LDA 3,@CC ; TCB ADDRESS LDA 0,TAC0,3 ; FILENAME BYTE POINTER JSR CFNMI ; CHECK FILENAME (INTERNAL) LDA 3,TMP,3 ; GET UFT POINTER LDA 1,0,3 ; GET UFT POINTER ADDL 1,1 ; SHIFT LEFT TWO BITS MOVOR 1,1 ; SHOW OPEN IN PROGRESS MOVZR 1,1 ; & CHANNEL ASSIGNED STA 1,0,3 ; TO UFT POINTER TABLE MOV 3,0 ; POINTER ADDRESS TO AC0 LDA 3,CC ; CELL ADDRESS STA 0,CTMP2,3 ; SAVE POINTER ADDRESS FOR SOV4 LDA 3,CSP ; RELOAD FROM INPUT FOR MAPPED LDA 0,OAC2,3 MOVL 0,0 ; RESET 1B0 FOR SOV4 MOVZR 0,0 JMP OPNRT ; COMPLETE THE PROCESSING DNCK: LDA 2,@CC ; TCB ADDRESS LDA 0,TAC0,2 ; FILENAME BYTE POINTER JSR CKDRN ; CHECK DIRECTORY NAME OPNRT: LDA 3,@CC ; TCB ADDRESS LDA 1,TAC1,3 ; USER'S AC1 LDA 3,CC ; CELL ADDRESS STA 0,CAC0,3 ; SET CELL'S AC0 STA 1,CAC1,3 ; & AC1 STA 2,CAC2,3 ; & AC2 LDA 3,CSP ; STACK POINTER LDA 2,DCBDC,2 ; DCT ADDRESS STA 2,OAC0,3 ; RETURN TO CALLER RTRN CKDRN: RSAVE 3 LDA 2,CQ ; CURRENT QUEUE LDA+ 1,QSUFP,2 ; UNPACK ADDRESS ADC 2,2 ; -1 IS CHECK DIRECTORY NAME FLAG JMP CSFNAM CFNMI: RSAVE 3 CFNAM: SUBZL 2,2 ; +1 IS CHECK FILENAME, WITH MAP CSFNAM: ;ENTRY FOR MAP SWITCH PASSED IN AC2: ; 0 - NO MAP, 1 - MAP STA 2,CKTYP,3 ; SAVE IN THE STACKu LDA 2,CC ; CURRENT CELL LDA 2,CPTAD,2 ; CURRENT PROGRAM TABLE ADDRESS LDA 2,PDDCB,2 ; DEFAULT DCB LDA 0,CKTYP,3 ; GET ENTRY TYPE COM# 0,0,SNR ; DIRECTORY NAME CHECK ? JMP .+4 ; YES, DON'T TEST STATUS LDA 0,DCBST,2 ; GET STATUS MOVL# 0,0,SZC ; ;^IS DIRECTORY INITED ? JMP CMERX STA 2,OAC2,3 ; SET INITIAL DCB LDA 0,OAC0,3 ; GET INPUT BYTE POINTER STA 0,CURBP,3 ; SAVE AS CURRENT CKLUP: LDA 0,CURBP,3 ; GET CURRENT BYTE POINTER STA 0,PNBPT,3 ; IS PREVIOUS NAME BYTE POINTE LDA 2,CKTYP,3 ;LOAD MAP SSWITCH JSR NMCKS ; NAME CHECK STA 0,CURBP,3 ; SAVE RETURNED BYTE POINTER LDA 0,CKTYP,3 ; ENTRY TYPE WORD COML 0,0 ; SET CARRY BIT APPROPRIATELY LDA 3,COLON ; GET A ':' SUB# 3,2,SEZ ; IF TERMINATOR IS A : OR ENTRY ; WAS DIRECTORY NAME CHECK, S$KIP RTRN ; OTHERWISE RETURN JSR XSDIR ; SEARCH THE DIRECTORY DCB RING JMP SPCNF ; SPECIFIER NOT FOUND STA 2,OAC2,3 ; FOUND, RETURN THE DCB ADDRESS MOVL 0,0,SNC ; DIRECTORY NAME CHECK ? RTRN ; YES LDA 1,DCBST,2 ; NO, GET STATUS MOVL# 1,1,SZC M ; IS DIRECTORY INITED ? JMP CMERX ; NO, PUNISH LDA 1,OAC1,3 ; YES, RECOVER UNPACK ADDRESS JMP CKLUP ; & CONTINUE SPCNF: MOVL 0,0,SNC ; FILENAME CHECK ? RTRN ; NO, RETURN LDA 2,@CC ; TCB ADDRESS LDA 0,PNBPT,3 ; PREVIOUS NAME POINTER STA 0,TACO0,2 ; RETURN BYTE POINTER FOR ; UNFOUND ; SPECIFIER LDA 2,DSNER ; ERROR CODE JMP ILLC1 DNIEC: ERDNI DSNER: ERDSN DVNIS: ERDNM OPNER: JSR @.SYSER ERUFT ; BRIDGE TO THE OTHER SIDE TFTX: JMP .TFTX ; ROUTINE TO SEARCH THE DIRECTORY DCB CHAIN5 FOR ; A DIRECTORY SPECIFIER MATCH ; ; INPUTS: AC1 - WORD ADDRESS OF UNPACKED SPECIFIER ; ; OUTPUTS: AC2 - DCB ADDRESS IF FOUND ; VACANT DCB OR ZERO IF NOT FOUND ; ; RETURNS: CALL+1 - NOT FOUND ; CALL+2 - FOUND VACDB=TMP SDIRI: RSAVE 1 SDIRR: ISZ ORTN,3 ; ASSUME GOOD RETURN SUB 0,0 STA 0,VACDB,3 ; INITIALLY NO VACANT DCB'S LDA 2,@.DIRR ; START OF DCB CHAIN SDRLP: STA 2,OAC2,3 ; ASSUME THIS ONE IS IT LDA 0,.SFNA ; ADDRESS OFFSET OF SPECIFIER ADD 2,0 ; ADDRESS OF THIS DCB'S SPECIF. LDA 2,SXPLGT ; SPECIFIER LENGTH JSR @.CMPWD ; COMPARE THE STRINGS RTRN ; A MATCH! A MATCH! MOV 0,2 ; INDEX ON SPECIFIER LDA 0,0,2 ; FIRST WORD OF SPECIFIER LDA 2,OAC2,3 ; GET LAST DCB ADDRESS MOV# 0,0,SNR ; IS DCB VACANT ? STA 2,VACDB,3 ; YES, SAVE T HIS ONE'S ADDRESS LDA 2,SFNX,2 ; NEXT IN LINE COM# 2,2,SZR ; END OF CHAIN ? JMP SDRLP ; NO LDA 0,VACDB,3 ; GET VACANT DCB IF ANY STA 0,OAC2,3 ; AND RETURN DSZ ORTN,3 ; YES, RETURN TO CALL+1 RTRN .CMPWD: CMPWD .DIRR: DIRR .SFNA: SFLNA SPLGT: UFTE6X ; ROUTINE TO CHECK A NAME FOR SYSTEM LEGALITY AND UNPACK IT ; ; INPUTS: AC0 - SOURCE BYTE POINTER, RETURNED ; POINTING TO CHARACTER AFTER TEERMINATOR ; AC1 - WORD ADDRESS OF UNPACK AREA ; MUST BE AT LEAST 'SCFNL' WORDS IN LENGTH ; AC2 - 0 = NO MAPPING ; 1 = MAPPING ; ; OUTPUTS: AC2 - TERMINATION CHARACTER LODBP=OAC0 STRBP=TMP ENDTS=STRBP+1 LBSEN=ENDTS+1 DOTSN=LBSEN+1 NMCKS: RSAVE 4 NAMCK: SUB 2,2 STA 2,LBSEN,3 ; SHOW NO LEGAL BYTES SEEN STA 2,DOTSN,3 ; SHOW NO 'DOTS' SEEN MOV 1,2 ; UNPACK AREA WORD ADDRESS LDA 0,UPLGT ; UNPACK LENGTH JSR @.CLEAR ; CLEAR IT MOVZL 1,1 ; UNPACK BYTE POINTER STA 1,STRBP,3 ; SAVE LDA 0,NMLGT ; FILENAME NAME LENGTH ADD 1,0 ; ILLEGAL BYTE ADDRESS FOR NAME STA 0,ENDTS,3 ; SAVE ZLDA 1,OAC0,3 ; GET SOURCE BYTE POINTER STA 1,LODBP,3 ; ALSO ON THE STACK BYTLP: LDA 1,LODBP,3 ; GET SOURCE BYTE POINTER LDA 0,OAC2,3 ; MAPPED ? MOV# 0,0,SNR JMP NMCK1 ; NO .IFE BSW JSR @.MLDBT ; GET A BYTE .ENDC .IFN BSW LDB 1,0 .ENDC NMCK2: ISZ LODBP,3 ; BUMP THE POINTER JSR TFT ; TEST BYTE FOR TERMINATOR JMP NOTRM ; NOT A TERMINATOR STA 0,OAC2,3 ; TERMINATOR FOUND, RETURN IT LDA 0,LBSEN,3 ; LEGAL BYTE SEEN FLAG MOV# 0,0,SZR ; ANY AT ALL ? RTRN ; YES, NAME IS OK JMP ILLCH ; NO, CA INPUT ? JMP TBFL1 ; NO LDA 1,FUDGE ; GET LOWER TO UPPER FUDGE SUB 1,0 ; TURN LOWER TO UPPER CASE STA 0,OAC0,3 ; & RETURN IT TBFL1: LDA 1,UPRA ; GET UPPER CASE A LDA 2,UPRZ ; & UPPER CASE Z SUBZ# 1,0,SZC ; IS UPPER A <= CHAR ? SUBZ# 0,2,SNC ; YES, IS CHAR <= UPPER Z ? JMP ILLCH ; NO, ILLEGAL CHARACTER RTRN ; YES, RETURN LOWRZ: "Z+40 LOWRA: "A+40 UPRZ: "Z UPRA: "A NINE: "9 Z-:zERO: "0 DOLAR: "$ FUDGE: 40 ENDOV .END SOV3.SRB 9)f ; ;READ CORE IMAGE - WITH MULTIPLE BLOCKS ; RTITLE SOV3 .NREL .IFN USW ; UNMAPPED VERSION .ENT RDCI ;READ CORE IMAGE .EXTN DIVI .EXTN RDCER .EXTN FNDCB .EXTN SYSTR .EXTN BLKIN ;BLOCK INPUT .EXTN SFGNP,SFGZP .EXTN SYSFG .EXTN MVWD .EXTzN RELDB .EXTN PT1,PT2 .EXTN RDCI3 .EXTN RDCI4 .EXTN OVCHN .EXTN PSHRD .EXTN TSTEQ ;***************************************** ; NUMBER OF STACK TEMPORARIES USED ; MUST BE THE FIRST WORD IN THE OVERLAY .IFN BSW!MBSW 10 .ENDC ; ; STACK PARAMETER~2S. ; BLKS=TMP NBLKS= TMP+1 RWCA=TMP+2 BUFAD=TMP+3 BUFD1=TMP+4 HIADR=TMP+5 TMPBQ=TMP+5 ;FONEY BQ ADDRESS CELAD=TMP+6 ;CELL ADDRESS MBAD=TMP+6 ;MASTER BUFFER ADDRESS STBLK= TMP+7 AUFT= TMP NCHN= TMP+1 ; ERROR ON I/O CMER3: LDA 2,MBAD,3 JSR @.RELDB 9CMER2: LDA 2,BUFAD,3 ;RELEASE INDEX JSR @.RELDB CMER1: LDA 1,OAC1,3 ;MASTER DEV ? COM# 1,1,SZR RTRN ;NO- JUST GIVE BAD RTN JSR @.TSTEQ ;SEE WHICH FATAL ERROR ERDTO JMP .+3 ;FILE DATA ERROR JSR @.PNIC PNMDT JSR @.PNIC PNMDD .PSHRD: PSHRD .TSTQrEQ: TSTEQ ; READ A CORE IMAGE ; INPUT: AC2 - MASTER DCB ADDRESS ; AC1 - ERROR CHECK ING CODE ; -1 => NO CHECKING ; 0 => START ADDRESS ; 1 => DEBUG ADDRESS ; DBFA1 DCBFA OF CQ - FIRST ADDRESS OF FILE RDCI: MOV 2,1 ;DCB ADDRESS LDA @2,CQ ;QUEUE DCB JSR @.FNDCB ; INITIALIZE THE DCB LDA 1,OAC1,3 ;SEE IF PUSH READ/WRITE COM# 1,1,SZR JMP .+3 ;NO JSR @.PSHRD ;YES- GO SET FA TO REAL ADDR JMP CMER1 JSR @.BLKIN JMP CMER1 ;ERROR STA 0,BUFAD,3 ;BUFFER ADDRESS STA 0,BUFD1,3 ;AGAIN MARTHA hLDA @0,BUFAD,3 ISZ BUFAD,3 ; GET SECOND HALF OF ADDRESS LDA @1,BUFAD,3 ; GOT IT ISZ BUFAD,3 ;BACK TO START LDA @2,CQ ;SDCB ADDRESS LDA 3,OAC1,3 ;SEE IF RTN PATH COM# 3,3,SNR JMP RBIG ;YES-PUSH HAS 2 WD ADDR LDA 3,DCBDC,2 ; DCT ADDRESS LDA 3,DCTCH,3 ; DEVICE CHARACTERISTIC MOVL# 3,3,SZC ; BIG DISK ? JMP RBIG MOV 0,1 ; EALLY LOW ORDER ON SMALL DISK SUB 0,0 ; CLEAR HIGH ORDER LDA 3,CSP DSZ BUFAD,3 RBIG: STA 0,DBCA1,2 ;TO DCB STA 1,DCBCA,2 ; TO DCB JSR @.BLKIN ;READ BOCK ZERO JMP CMER2] ;ERROR STA 0,MBAD,3 ;FIRST BLOCK BUFFER ADDRESS ; SEE IF LOADING A FG LDA 2,CC LDA 1,CTEMP,2 LDA 2,BIAS ; BIAS TO THE UST ADD 0,2 MOV# 1,1,SZR ;SKIP IF NOT FG JMP JRDFG LDA @0,.SFGNP ;NREL LDA @1,.SYSFG ;SEE IF A FG RUNNING MOV# 1,1,SNR RDCC:= LDA @0,.SSTR ;USE SYSTR STA 0,AUFT,3 ;SAVE END LDA 1,USTZM,2 ; ZMAX STA 1,STBLK,3 ; SAVE FOR LATER LDA 1,USTNM,2 ;NMAX LDA 0,USTDA,2 ;SEE IF DEB ADDR COM# 0,0,SZR JMP RDCDB ;YES- LEAVE SYMBOLS ALONE LDA 0,USTES,2 ;SYMBOLS PRESENT ? MOV# 0,0,SZR z JMP RDC1 RDCDB: LDA 0,USTSS,2 ;SYMBOL HIADR NEG 1,1 COM 1,1 ; SUB 1 FROM NMAX USGE 1,0 ; IF NMAX NOT BIG ENOGHT THEN RDC1: MOV 0,1 ; SET SYMOBOL END AS TOP STA 1,HIADR,3 ;SAVE LDA 1,USTCH,2 ;#TASKS+#CHAN LDA 0,C377 AND 0,1,SNR JMP UFERR LDA 0,.UFTEL STA 1,NCHN,3 ;SAVE # CHANNELS NEG 1,3 ;LOOP COUNT ADD 0,1 ;ADD 1 UFT SIZE TO TOTAL INC 3,3,SZR JMP .-2 ;NOT DONE ; AC1 = (UFTEL)N+N..... SIZE OF UFPT+UFT'S LDA 3,CSP LDA 0,AUFT,3 SUB 1,0 ;SUB SIZE FROM END LDA 1,HIADR,3 ;END OF LOAD ADCZ# 1,0,SNC ;FIT ? JMP JRDSE ;FAR OUT STA 0,AUFT,3 ;SAVE UFT STARTING ADDR LDA 3,CC LDA 1,CTEMP,3 MOV# 1,1,SNR ;SEE IF A FG LOAD JMP RUFT1 ;NO-SKIP THE UFT SHUFFLE LDA @1,.SYSFG ;SEE IF FG EXISTS-IF YES NO ; MOVE NEC MOV# 1,1,SZR JMP RUFT1 LDA 2,USTP LDA 0,USTCH,2 ;BG CHANNELS LDA 3,C377 AND 3,0 LDA 1,.UFTEL ;SIZE UFT NEG 0,3 ADD 1,0 INC 3,3,SZR JMP .-2 ; AC0= TOTAL UFPT+UFT SIZE LDA @3,.SFGNP ;FG START LDA 1,USTNM,2 ;END OF PRESENT BG SUB 0,3 ;BOTTOM OF NEW AREA USLE 1,3 ;F IT IN ? JMP RDSE1 ;NO MOV 3,1 MOV 0,2 LDA 3,.PT2 ;BG PTBL LDA 0,PUFPT,3 ;START OF MOVE STA 1,PUFPT,3 ;NEW START JSR @.MVWD ;MOVE BLOCK LDA 2,BIAS LDA 0,MBAD,3 ADD 0,2 JMP RUFT1 C377: 377 .FNDCB: FNDCB .BLKIN: BLKIN .RELDB: RELDB JCME3: JMP CfhMER3 BIAS: UST-SCSTR .SYSFG: SYSFG .SFGNP: SFGNP .SFGZP: SFGZP .SSTR: SYSTR .UFTEL: UFTEL .PT1: PT1 .PT2: PT2 .MVWD: MVWD JRDCC: JMP RDCC JRDFG: JMP RDFG RUFT1: LDA 3,CSP LDA 0,OAC1,3 COM# 0,0,SNR ; CHECKING? JMP RDSV1 ; NO LDA 1,USTSA,2 ; ASSUME STARTING ADDRESS MOVR# 0,0,SZC LDA 1,USTDA,2 ;DEBUG ENTRY REQ COM# 1,1,SZR ; LEAGL? MOV# 1,1,SNR JMP CMNE0 ; NO, ERROR ; SEE IF READING IN FG OR BG RDSV1: LDA 3,CC LDA @0,.SYSFG ;FG PRESENT FLAG LDA 1,CTEMP,3 ;FLAG FOR TYPE RDCI LDA 3,CSP MOV# 1,1 ,SZR JMP RDSV4 ;LOADING FG MOV# 0,0,SNR ;IS THERE A FG NOW ? JMP RDSV8 ;NO-CAN USE WHOLE ADDRESS SPACE LDA @0,.SFGZP ;FG PAGE 0 PARTITION LDA 1,USTZM,2 ;THIS PROGS TOP P0 ADCZ# 1,0,SNC JRDSE: JMP RDSE1 ;NOT TODAY, BILLY POOBAH LDA @0,.SFGNP ;NRE{L FG PARTITION LDA 1,HIADR,3 ;BLK ADJUSTED HI ADDR ADCZ# 1,0,SNC ;TOO BIG JMP RDSE1 ;HEH HEH.... RDSV8: MOV 2,0 ;START OF MOVE LDA 1,WDSBK ; C400 OR USTAD ETC. LDA 2,STRSV ;16 JSR @.MVWD ;MOVE IN 400-415 JSR @.OVCHN ;FINISH MOVE IN SOV7.... eRDCI3 ; LOADING IN A FOREGROUND PROG RDSV4: LDA 0,MBAD,3 ;BUFFER START LDA 1,C22 ; BUFFER STARTS AT 16 ADD 1,0 ; 0 -> WORD 40 OF SAVE FILE LDA 1,.SSV ; DISP TO LOC 40-47 IN PTBL LDA 2,.PT1 ; FORGROUND PTBL ADD 2,1 ; AC1 -> ADDRESS OF LOC 40 IN P\TBL LDA 2,C10 ; 10 WORDS = 40-47 JSR @.MVWD ; MOVE 40-47 TO PTBL LDA 0,MBAD,3 ; BUFFER AGAIN LDA 2,STRSV ;16 SUB 2,0 ;ADJUST BUF ADDR LDA @1,.SFGZP ;START OF P0 ADD 1,0 ;NOW 0 = MOVE START LOC LDA 2,STBLK,3 ; ZMAX FOR FORGROUND JSR @.OVCHN ;f DO MOVE IN NEXT OVERLAY RDCI4 ;NEXT PART CHAINED TO .OVCHN: OVCHN RDSE1: LDA 0,ERMX JMP RDSE2 UFERR: LDA 0,.ERUSZ JMP RDSE2 C22: 22 C10: 10 .SSV: PSSV1 ; DISP TO LOC 40-47 IN PTBL ; LOADING FG-FIND UST INFO AND MOVE INTO BLK 0 BUFFER RDFG: LDA 0a,USTZM,2 ;ZMAX STA @0,.SFGZP ;FOR RDOS LDA 1,USTPC,2 ;NMAX LDA @3,.SYSFG ;FG NOW ? MOV# 3,3,SNR JMP .+4 LDA @3,.SFGNP ;START FG ADCZ# 1,3,SZC ;SEE IF CHAINED CALL TOO BIG JMP RDSE1 ;YES LDA 2,WDSBK LDA 3,USTZM,2 ;SEE IF FG WILL FIT SUBZ# 0,3,SeZC JMP RDSE1 ;NO-ZMAX IN BG TOO HIGH LDA 3,USTNM,2 SUBZ# 1,3,SZC JMP RDSE1 ;NMAX TOO HIGH STA @1,.SFGNP LDA 2,WDSBK ;BLOCK COUNT LDA 3,STRSV ;START SUB 3,1 ;FOR DIV JSR @.IDIV ;GET UST INFO BLK # LDA 2,BUFD1,3 ;INDEX BLK LDA 3,BQDCT,2 ; DCrT ADDRESS LDA 3,DCTCH,3 ; CHARACTERISTIC MOVL# 3,3,SZC ; BIG DISK ? MOVZL 1,1 ; 1/2 AS DENSE ON BIG DISK ADD 1,2 ;POSITION IN INDEX LDA 0,0,2 LDA 1,1,2 ; BOTH HALF OF ADDRESS MOVL# 3,3,SZC ; BIG DISK ? JMP .+3 ; YES, LEAVE ALONE MOV 0,1 SUB 0,0 ; ZERO HIGH ORDER LDA 3,CSP STA 2,BUFAD,3 ; ALL SET NOW LDA @2,CQ STA 0,DBCA1,2 STA 1,DCBCA,2 JSR @.BLKIN JMP JCME3 ;ERROR LDA 2,BIAS ;MAGIC LDA 1,MBAD,3 ;BLK 0 BUFFER ADD 2,1 ;FOR MOVE-POINTS TO UST (400) LDA 2,STRSV ;COUNT-16 JSR @.v MVWD MOV 0,2 ; RELEASE IT JSR @.RELDB MOV 1,2 ;FOR CONTINE JMP JRDCC CMNE0: LDA 0,ERAX JMP RDSE2 ERAX: ERADR ;ILLEGAL STARTING ADDRESS ERMX: ERMEM WDSBK: SCWPB+1 STRSV: SCSTR ;START ADDRESS OF SAVE FILES .IDIV: DIVI RDSE2: JSR @.OVCHN RDCEXR .ERUSZ: ERUSZ .ENDC ; END OF UNMAPPED VERSION .IFN MSW ; MAPPED VERSION .ENT RDCI ;READ CORE IMAGE .EXTN SYSE2 .EXTN RELPB ;RELEASE BUFFER .EXTN FNDCB .EXTN BLKIN ;BLOCK INPUT .EXTN PT1 .EXTN PT2 .EXTN RELDB .EXTN GMBK2,RMBK2 .EXTD BBLK1,FBLK1 .IFE MBSW .EXTD CMAP .ENDC .IFN IOSW ;INFOS:2.00 - CJM - 10/25/76 - IF INFOS .EXTD CMAP,CMAPA,CMAPB,CMAPI .ENDC ;INFOS:2.00 - CJM - 10/25/76 - END CONDITIONAL .EXTN NBUFT,NFUFT .EXTN RDCI2 .EXTN OVCHN .EXTN CPERT .EXTN TSTEQ g.EXTD C31K,MFSTB .EXTN PSHRD .IFN MBSW ; DEFINE TMP USE IN ARDOS 10 .ENDC ; DEFINE THE TEMPS PTEMP=TMP NCHN= TMP+1 RWCA=TMP+2 BUFAD=TMP+3 BUFD1=TMP+4 HIADR=TMP+5 TMPBQ=TMP+5 ;FONEY BQ ADDRESS CELAD=TMP+6 ;CELL ADDRESS MBAD=TMP+6 ;MASTER BUFFER ADDRESS STBLK= TMP+7 CMRE2: LDA 2,BUFD1,3 ;REL INDEX JSR @.RDB2 CMRE1: LDA 1,OAC1,3 ;SEE IF RTN PATH COM# 1,1,SZR RTRN ;NO JSR @.TSTEQ ERDTO ;TIME OUT JMP .+3 ;NOT TIME OUT JSR @.PNIC PNMDT ;TIME OUT PANIC JSR @.PNIC PNMDD ;DIRTY DISK EC2: 2 .PSHRD: PSHRD .TSTEQ: TSTEQ .RDB2: RELDB .FNDCB: FNDCB .BLKIN: BLKIN .PT2: PT2 ; READ A CORE IMAGE ; INPUT: AC2 - MASTER DCB ADDRESS ; AC1=CODE: 0=NORMAL,-1=NO CHK,1B0=CHAINING ; 1B15=DEB START ; AC0 - FIRST ADDRESS OF FILE RDCI: MOV 2,1 ;DCB ADDRESS LDA @2,CQ ;QUEUE DCB JSR @.FNDCB ; INITIALIZE THE DCB LDA 1,OAC1,3 ;SEE IF PUSH READ/WRITE COM# 1,1,SZR JMP .+3 ;NO JSR @.PSHRD ;YES- GO SET FA TO REAL ADDR JMP CMRE1 JSR @.BLKIO ;READ NEXT BLOCK JMP CMRE1 STA 0,BUFD1,3 ;SAVE BASE FOR RELEASE STA 0,BUFAD,3 ;BUFFER ADDRESS LDA @0,BUFAD,3 ;BLK ADDR WD 1 ISZ BUFAD,3 ;PRETENT IT'S A BIG DISK LDA @1,BUFAD,3 DSZ BUFAD,3 ;TO START LDA @2,CQ ;SDCB ADDRESS LDA 3,OAC1,3 ;SEE IF RTN COM# 3,3,SNR JMP RBIG ;YES-HAS 2 WD ADDR LDA 3,DCBDC,2 ;DCT LDA 3,DCTCH,3 ;CHAR MOVL# 3,3,SZC ;BIG DISK ? JMP RBIG ;BIG DISK ; SMALL DISK- BACK UP MOV 0,1 SUB 0,0 RBIG: STA 0,DBCA1,2 ;STORE 0 OR ADDR WD 1 STA 1,DCBCA,2 ;WORD 2 JSR @.BLKIN ;READ BOCK ZERO JMP CMRE2 STA 0,MBAD,3 ;SAVE^ ADDR LDA 3,CC ;SEE WHICH PTBL WORKING IN LDA 2,CTEMP,3 MOVZL# 2,2,SZR ; FG OR BG ? JMP RDFG LDA 2,C2 ; SET UP CTMP4 FOR (R,G)MBLK STA 2,CTMP4,3 LDA 1,.NBUFT ;NUM BG UFT'S LDA 2,.PT2 JMP RDCC RDFG: SUBZL 2,2 STA 2,CTMP4,3 LDA 2,.PT1 LDA 1,.tNFUFT ;NUM FG UFT'S RDCC: STA 2,CAC0,3 ;SAVE IN CELL LDA 2,BIAS ; BIAS TO THE UST ADD 0,2 LDA 0,USTCH,2 LDA 3,C377 AND 3,0,SNR ;MUST BE AT LEAST ONE JMP UFERR ;TRY AGAIN SUBZ# 0,1,SNC ;USER CHAN COUNT TOO BIG ? JMP UFERR ;TIME TO SYSGEN, BILLY LDA 3,CSP STA 0,NCHN,3 ;SAVE LDA 1,USTNM,2 ; NMAX LDA 0,USTDA,2 ;SEE IF DEB ADDR COM# 0,0,SZR JMP RDCDB ;YES- LEAVE SYMBOLS ALONE LDA 0,USTES,2 ;SYMBOLS PRESENT ? MOV# 0,0,SNR JMP RDCDB ;NO MOV 0,1 ;DROP SYMBOLS FROM LOAD JMP RDC1 RDCDB: LDA 0,USTSS,2 ; START OF SYMBOLS NEG 1,1 COM 1,1 USGE 1,0 MOV 0,1 ; LARGER TO AC1 RDC1: STA 1,HIADR,3 ;SAVE FOR BLOCK DETERMINATION LDA 0,OAC1,3 COM# 0,0,SNR ; CHECKING? JMP RDMP LDA 1,USTSA,2 ; ASSUME STARTING ADDRESS MOVR# 0,0,SZC LDA 1,USTDA,2 ? ;DEBUG ENTRY REQ COM# 1,1,SZR ; LEAGL? MOV# 1,1,SNR JMP CMNE0 ; NO, ERROR RDMP: LDA 1,HIADR,3 ;TOP LDA 0,C377L ;CONVERT TO BLOCK ANDS 1,0 MOVZR 0,0 MOVZR 0,0 ;NOW = BLKS INC 0,0 ;ONE MORE STA 0,STBLK,3 ;SAVE LDA 2,CC LDA 2,CAC0,2 ;PTBL LDAz 1,PMSZ,2 ;- # SLOTS MOV# 1,1,SNR ;IF 0 NO SLOTS JMP RDM1 RDM2: LDA 3,PMAP,2 ;NEXT MAP CONTENTS LDA 0,CWPRS AND 0,3 STA 3,PMAP,2 .IFE MBSW SMBK 3 .ENDC INC 2,2 INC 1,1,SZR ;SKIP IF DONE JMP RDM2 ;KEEP LOOKING RDM1: LDA 3,CSP LDA 2,CC ;GET Z.PTBL LDA 2,CAC0,2 LDA 1,PMSZ,2 ;- # SLOTS NEG 1,1 ;MAKE POS LDA 0,STBLK,3 ;END BLK NUMBER SUB# 0,1,SNR ;SKIP IF NOT SAME JMP RDM6 SUBZ 1,0,SZC ;SKIP IF MORE THAN ENUF JMP RDM4 ; REL EXCESS- AC0= -# BLKS LDA 1,PMSZ,2 ;-MAP SIZE SUB 0,1 ;MAKE SMALLER STA 1,PMSZ,2 LDA 1,STBLK,3 ;LAST NEEDED ADD 1,2 ;START OF REL STA 2,PTEMP,3 ; SAVE POINTER TO FIRST FREE RDM5: LDA 1,PMAP,2 JSR @.RMB2 ;REL INC 2,2 INC 0,0,SZR JMP RDM5 LDA 2,PTEMP,3 ; NOW SET UNUSED BLOCKS TO ILLEG JMP RDM11 RDM6: LDA ^2,CC LDA 2,CAC0,2 ;PTBL JSR MFSTB ;MAP BLK 0 .IFN MBSW ;MAPPED BIRD LDA 1,PMST,2 ;RST - GET STATUS SMLD 1 ;RST - DOC 1, BMAP ON ;RST - 330, NOP ON OTHERS. SUB 0,0 MOV 2,3 ;RST - SAVE PTBL. ADDI PMAP,2 ;RST - ADR DISPLACEMENT ;RST - TO PTBC MAP. ELEF 1,32. ;RST - MAKE SURE THE COUNT ;RST - IS RIGHT. LMP XCH 2,3 ;RST - RETRIEVE PTBL. .IFN IOSW LDA 1,PPRI,2 ;RST - GET PTBL PRIORITY. MOVZR# 1,1,SNC ;RST - IS IT BG? STA 2,CMAPA ;RST - YES, PUT PTBL ADR IN ;RST - CMAPA. gMOVZR# 1,1,SZC ;RST - IS IT FG (OR BOTH)? STA 2,CMAPB ;RST - YES,. . . STA 2,CMAP ;RST - SET CURRENT MAP. .ENDC ;INFOS SW. .ENDC ;MBSW SW. SUB 1,1 LDA 3,C31K STA 1,1,3 ;RESET IN SCHED IN ALLOC BLK LDA 1,WDSBK ;400 STA 1,12,3 ;TO USER USTP LDA 0,C377L ;INIT DEV TABLE TO ALL ;PROTECTED LDA 1,CM8 RDM8: LDA 3,PDEV,2 AND 0,3 ;GET LEFT HALF ADC 0,3 ;ALL PROTECTED STA 3,PDEV,2 INC 2,2 INC 1,1,SZR ;DONE ? JMP RDM8 ;NO .IFE MBSW SUB 3,3 STA 3,CMAP ;FORCE A USER MAP IN CASE  ;CHANGED .ENDC JSR @.OVCHN ;CHAIN TO NEXT RDCI2 UFERR: LDA 0,.ERUSZ JMP RDSE2 C377L: 177400 CWPRS: -MPAWP-1 PGMSK: -(MPAPH!MPAWP)-1 .RMB2: RMBK2 .GMB2: GMBK2 .NBUFT: NBUFT .NFUFT: NFUFT C377: 377 .ERUSZ: ERUSZ CM8: -10 .PT1: PT1 BIAS: UST-SCSTR CMNE0: LDA 0,ERAX JMP RDSE2 ;COMMON EXIT .OVCHN: OVCHN ; AC1= PRESENT MAP # BLKS ;AC0= # BLKS TO GET RDM4: LDA 2,CC LDA 3,CTEMP,2 ;SEE WHAT PTBL LDA 2,BBLK1 ;ASSUME BG MOVZL# 3,3,SZR ;SKIP IF BG LDA 2,FBLK1 ;FG SUBZ# 0,2,SNC ;SKIP IF ENUF IN BPARTITION JMP RDSE1 ;SMEM TIME BUNKY... LDA 2,CC LDA 2,CAC0,2 ;PTBL LDA 3,PMSZ,2 ;-MAP SIZE SUB 0,3 STA 3,PMSZ,2 ;LARGER INDEX ADD 1,2 STA 0,BCNT ;LOOP COUNT RDM10: JSR @.GMB2 ;GET BLOCK JMP . ;GET BENT LDA 3,PMAP,2 ;CURRENT SLOT LDA 0,PGMSKM AND 0,3 ;DROP PHYS BLK ADD 3,1 ;ADD IN BLK PICKED UP STA 1,PMAP,2 ;TO MAP INC 2,2 DSZ BCNT ;DONE ? JMP RDM10 ;NO RDM11: LDA 1,PGMSK RDM9: LDA 0,PMAP,2 ;FILL SLOT FOR ILLEG MOVL# 0,0,SZC ;SKIP IF NOT END JMP RDM6 ;YES AND 1,0 ;DROP BLOCK AoDC 1,0 ;ILLEG BLOCK STA 0,PMAP,2 INC 2,2 JMP RDM9 ;NEXT BCNT: 0 ERAX: ERADR ;ILLEGAL STARTING ADDRESS ERMX: ERMEM WDSBK: SCWPB+1 .SE2: SYSE2 .RELPB: RELPB .RELDP: RELDB RDSE1: LDA 0,ERMX RDSE2: LDA 3,CSP LDA 2,MBAD,3 ;RLEASE BUFFERS JSR @.RELDB? LDA 2,BUFD1,3 JSR @.RELPB MOV 0,2 LDA 3,CC LDA 1,CTEMP,3 ;TYPE LOAD LDA 3,CPTAD,3 ;PTBL SUB 0,0 STA 0,PSTAT,3 ;RESET EO MOVL# 1,1,SNC ;SKIP IF CHECKPOINT LOAD JSR @.SE2 ;GET OUT ; CLEAN UP AFTER CP JSR @.OVCHN CPERT .ENDC ; END OF MAPPED PVERSION ENDOV .END SOV4.SRB S Fz .NREL RTITLE SOV4 .ENT OPEN .ENT OPNA .ENT ROPN .ENT EOPN .ENT TOPN .ENT CLS .ENT RSET .ENT ECLR .IFN IOSW ;******************************************************************** .ENT IOPEN .ENT IOCLS .EXTN IOCSA ;IOCS - IOCS RESET FILES R(OUTINE ;********************************************************************* .ENDC .EXTN OVLAY .EXTN PREOV .EXTN DSKO .EXTN ITBL .EXTN RETER .EXTN RETER .EXTN STATUS .EXTN CLEAR .EXTN OVLY1 .EXTN SYSFG .EXTN SRUFD .EXTN CFNAM .EXTN SYSNM .EXTN OICAL .EXTN CMPWD .EXTN IUD .EXTN FLUSH .EXTN RELMB ;***************************************** ; NUMBER OF STACK TEMPORARIES USED ; MUST BE THE FIRST WORD IN THE OVERLAY .IFN BSW!MBSW 6 .ENDC ; INPUT: DCB ADDRESS IN AC2 ; UFT POINTER IN ADC0 ; USER AC1 IN AC1 TOPN: LDA 1,TOCM JMP OPN1 EOPN: LDA 1,EOCM JMP OPN1 OPNA: LDA 1,OACM JMP OPN1 ROPN: LDA 1,ROCM ; READ ONLY COMMAND OFFSET JMP OPN1 OPEN: SUB 1,1 ; 0 IS COMMAND OFFSET OPN1: STA 1,CMND,3 ; SAVE TYPE JSR @.PREOV DSKO ; PRE-LOAD THE DISK OPEN OVERLAY LDA 2,.UFDC ; UFT DCT OFFSET ADD 0,2 ; ADDRESS OF DCT LDA 0,CLRCT ; CLEAR COUNT JSR @.CLR ; CLEAR DCT LDA 2,CC ; CURRENT CELL LDA 2,CTMP2,2 ; GET UFT POINTER TABLE ADDRESS OPN2: STA 2,UFPTR,3 ; IOCS -ADD LABEL FOR IOCS  ; SAVE ADDR FOR LATER LDA 2,OAC2,3 ; RESTORE DCB ADDR LDA 0,OAC0,3 ; & UFT POINTER JSR @.OVLAY STATUS JMP ERR1 ; FILE NOT FOUND STA 2,TMP,3 ; SAVE RETURNED DCB ADDRESS LDA 2,DCBDC,2 ; GET PARENT DCT ADDRESS LDA 1,DCTCD,2 ; GET PARENT DEVICE CO.DE LDA 2,OAC0,3 ; UFT ADDRESS STA 2,AUFT,3 ; SAVE IT LDA 0,UFTDL,2 ; GET DEVICE CODE FROM ENTRY LDA 3,C377 AND 3,0 ; CLEAR HIGH ORDER ADDRESS IN ; UFTDL SUB# 0,1,SNR ; IS IT A DISK ? JMP ISDSK ; YES LDA 3,C40 ; NO, GET DEVICE CODE FUDGE SUJ3BZ# 1,3,SNC ; IS PARENT'S DC < 40 ? ADD 0,3,SKP ; NO, FUDGE FILE'S DC ADD 1,3,SKP ; YES, FUDGE PARENT'S DC SUB# 1,3,SZR ; PRIMARY FILE ON SECONDARY ; PARENT ? SUB# 0,3,SNR ; SECONDARY FILE ON PRIMARY ; PARENT ? JMP ISDSK ; YES IT IS A DISK AFTER ALL DVCOK: LDA 3,.ITBL ; DCT TABLE ADD 0,3 LDA 3,-1,3 ; DCT ADDRESS LDA 0,.IUD ; UNDEFINED DEVICE INDICATOR SUB# 0,3,SNR ; IS DEVICE DEFINED? JMP ERR2 ; NO, GOTCHA ! MOVL 3,3 ; YES, TURN OFF 1B0 MOVZR 3,3 DVISD: STA 3,UFTDC,2 ; SET DCDZT ADDRESS IN UFT LDA 0,DCTCH,3 ; DEVICE CHARACTERISTICS LDA 3,CSP ; RECOVER STACK POINTER LDA 1,OAC1,3 ; GET USER'S MASK COM 1,1 ; INVERT IT AND 1,0 STA 0,UFTCH,2 ; MODIFY APPROPRIATELY LDA 3,TMP,3 ; RETURNED DCB ADDRESS STA 3,UFTDR,2 ; SET INTO UFT LDA 0,UFTDC,2 LDA 1,DCBUN,3 LDA 3,DCBDC,3 SUB# 3,0,SNR ; FILE ON THE SAME PACK? STA 1,UFTUN,2 ; YES, SET UP UNIT NUMBER LDA 3,CSP JMP CLSEX ISDSK: LDA 3,CSP ; STACK POINTER LDA 3,TMP,3 ; DCB ADDRESS LDA 3,DCBDC,3 ; DISK DCT ADDRESS JMP DFVISD ; JION COMMON CODE ERR1: LDA 3,UFPTR,3 ;ADDR UFT POINTER LDA 1,0,3 ADDL 1,1 MOVZR 1,1 ; RESET OPEN IN PROGRESS; SET ; CLOSED MOVOR 1,1 ;CLOSE CHAN STA 1,0,3 RTRN ; PUNT .IFN IOSW ;*****************************************************p*************** IOPEN: SUBZR 2,2 ;SET BIT 0 TO INDICATE STA 2,CMND,3 ;DELAYED PATH AND SAVE IT LDA 2,UFTPO ;GET UFT POINTER OFFSET IN VCB ADD 0,2 ;INDEX VCB JMP OPN2 ;PLAY THE REGULAR TUNE UFTPO: VCBUF ;VCB OFFSET DEFINED IN PARIO ;************ i********************************************************** .ENDC OACM: OA ROCM: RO EOCM: EO TOCM: TO C40: 40 CLRCT: UFTCN-UFTDC+1 .UFDC: UFTDC .CLR: CLEAR .PREOV: PREOV C377: 377 ERR2: LDA 3,CSP LDA 3,UFPTR,3 ;ADDR UFT POINTER LDA 1,0,3 ADDL 1,1 MOV1MZR 1,1 ; RESET OPEN IN PROGRESS; SET ; CLOSED MOVOR 1,1 ;CLOSE CHAN STA 1,0,3 ;TO UFPT'S JSR @.RETER ERDNM CLS: JMP CLS1 ;IOCS - BRIDGE TO SECOND HALF .IFN IOSW IOCLS: JMP IOCL1 ;IOCS - BRIDGE TO SECOND HALF .ENDC ECLR: JMP CLERE ;IOCS - BRIDGE TO SECOND HALF ; I/O RESET RSET: LDA 2,CC ; CURRENT CELL LDA 2,CPTAD,2 ; PROGRAM TABLE ADDRESS LDA 0,PUFPT,2 ; BASE OF UFT POINTERS STA 0,UFPTR,3 ; STORE IN STACK STA 0,AUFT,3 ;SAVE BASE ADDR LDA 2,USTP LDA 0,USTCH,2 ;NUMB TASKS AND CHANS LDA 2,C377 ;MASK OUT NUMB TCBS AND 2,0,SNR ;SKIP IF NOT 0 CHAN JMP RSEXT ;EXIT WITH GOOD RTN STA 0,CNT,3 ; STORE IN STACK RSET1: LDA 2,@UFPTR,3 ; GET UFT ADDRESS MOVL# 2,2,SNC ; IS FILE OPEN JMP RSET2 ; YES ELSE ADDL 2,2,SNC ; IS OPEN IN PROGRESXPS JMP NTOPN ; NO, SO IGNORE UFT ELSE MOVZR 2,2 ; GET UFT ADDRESS WITHOUT MOVZR 2,2 ; OPEN IN PROGRESS BIT RSET2: LDA 1,UFPTR,3 ; CURRENT POINTER ADDRESS LDA 3,AUFT,3 ;BASE OF POINTEPS ADD 3,2 ;REAL UFT ADDR JSR @.OICAL CLS ;CLOSE JMP .+1 NTOP;N: ISZ UFPTR,3 ; BUMP UFPT POINTER DSZ CNT,3 ; ALL CHANNELS? JMP RSET1 ; NO RSEXT: .IFN IOSW ;IOCS - *************************************************************** LDA 3,CC ;IOCS - GET THE CURREN PROCESS ; CELL LDA 2,CPTAD,3 ;IOCS - GET THE PR OGRAM TABLE ; ADDR LDA 0,PFLNK,2 ;IOCS - GET THE FCB LINKS COM 0,0,SNR ;IOCS - SEE IF ANY IOCS FILES ; OPEN JMP RSEX1 ;IOCS - NO .. SO GO ON LIKE ; NORMAL STA 3,CAC2,3 ;IOCS - MAKE THE CELL THE PARAM ; PACKET ADC 0,0 ;IOCS - MAKE A nMINUS ONE STA 0,CAC1,3 ;IOCS - TO TELL THE MAG TAPE ; TO STAY JSR @.OVLAY ;IOCS - OVERLAY CALL IOCSA ;IOCS - IOCS ABORT AND RESET ; ROUTINE RSEX1: LDA 3,CSP ;IOCS - GET THE STACK BACK ;IOCS - ****************************************************************** .ENDC ISZ ORTN,3 ; SUCCESS RETURN RTRN .OVLAY: OVLAY .OICAL: OICAL OVLY=TMP CMND= TMP+1 CNT= CMND+1 UFPTR= CNT+1 AUFT= UFPTR+1 UFTBA=AUFT+1 .ITBL: ITBL .IUD: IUD .IFN IOSW ;******************************************************:*********** ; IOCLS ..... CALL WITH AC2=VCB IOCL1: SUBZL 1,1 ;GET REGULAR COMMAND OFFSET STA 1,CMND,3 ;SAVE IT STA 2,AUFT,3 ;SAVE UFT (VCB) LDA 3,UFTPO ;GET OFFSET ADD 3,2 ;MAKE IT RIGHT JMP CLS2 ;CONTINUE AS USUAL ;***************************************************************** .ENDC ; CLOSE ;INPUT: UFT ADDRESS IN AC2 CLS1: SUBZL 0,0 ;1 STA 0,CMND,3 ;TYPE COMMAND = CLOSE STA 2,AUFT,3 ;UFT MOV 1,2 ; BUMP THE ADDRESS CLS2: LDA 3,CSP STA 2,UFPTR,3 ;SAVE IN CASE ERROR LATER CLSEX: LDA 2,AU>FT,3 ;UFT LDA 0,CMND,3 ;TYPE COMMAND (OFFSET) MOVL# 0,0,SZC ;IOCS - CHECK FOR DELAYED ; PROCESS JMP .DLAY ;IOCS - DELAYED --- IOCS WILL ; HANDLE LDA 2,UFTDC,2 ;DCT LDA 2,DCTDT,2 ;DISPATCH TABLE ADD 0,2 LDA 2,0,2 ;PROC ADDR COM# 2,2,SNR Ƕ; VALID COMMAND ? JMP ILCMD ; NOT TODAY, BILLY POOBAH STA 2,OVLY,3 ;SAVE ON STACK IN CASE OVLY ; NEEDED LDA 0,.OVLY1 ;ASSUME OVLY MOVL# 2,2,SNC ;IF 1B0 NEED OVLAY MOV 2,0 ;GO DIRECTLY LDA 2,AUFT,3 ;RESTORE UFT MOVL 2,2 MOVZR 2,2 ;RESET UFT ADDR 1B0 IF SET LDA 1,OAC1,3 ;REOAD INPUT AC1 MOV 0,3 ;ADDRESS TO JUMP TO SUB 0,0 ;MUST DO FOR DISK FILE OPEN JSR 0,3 ;JUMP TO ROUTINE JMP CLOZIT ; IF ERROR CLOSE CHANNEL ISZ ORTN,3 ; GOOD RETURN NOW DSZ CMND,3 ; WAS THIS A CLOSE ? JMP OPNED  ; NO, FLAG AS OPEN COMPLETE JMP CLOZIT ; YES, FLAG AS CLOSED .RETER: RETER OPNED: LDA 2,UFPTR,3 ; UFT POINTER TABLE ADDRESS LDA 1,0,2 ; POINTER WORD ADDL 1,1 ; SHIFT LEFT TWO BITS MOVZR 1,1 ; RESET IN PROGRESS BIT MOVZR 1,1 ; SHOW AS OPENED S-TA 1,0,2 ; IN TABLE RTRN ILCMD: LDA 0,ILCEC LDA 2,CC STA 0,CTMP2,2 ; RETURN ERROR CODE CLOZIT: LDA 2,UFPTR,3 ;POINTER ADDR LDA 1,0,2 ADDL 1,1 MOVZR 1,1 ; RESET OPEN IN PROGRESS MOVOR 1,1 ; SET CLOSED STA 1,0,2 RTRN .OVLY1: OVLY1 ILCEC: ERICD' .DLAY: ISZ ORTN,3 ;IOCS- MAKE FOR GOOD RETURN RTRN ;IOCS- AND DO IT LNKAT: ATLNK FNLGT: SCFNL .CMPWD: CMPWD .SYSFG: SYSFG .SYSNM: SYSNM .FLUSH: FLUSH .RELMB: RELMB ; ROUTINE TO CLEAR A DIRECTORY ENTRY'S USER COUNT ; ; RESTRAINTS: CALL IS ONLY ACCjEPTED FORM BACKROUND CLI ; WITHOUT AN ACTIVE FOREGROUND PROGRAM ; ; INPUTS: AC0 - BYTE POINTER TO ENTRY NAME ; ; OUTPUTS: NONE ; ; RETURNS: CALL+1 - ERROR....ERROR CODE IN AC2 ; CALL+2 - GOOD RETURN TDCB=TMP BFAD=TDCB+1 CLERE: LDA 1,@.SYSFG ; FOREGRONUND ACTIVE FLAG MOV# 1,1,SZR ; IS THERE A FOREGROUND ? JMP ILLC1 ; YES, ILLEGAL COMMAND LDA 2,CC ; CURRENT CELL LDA 2,CPTAD,2 ; PROGRAM TABLE ADDRESS LDA 1,PTSPN,2 ; PUSH NUMBER MOVZR# 1,1,SZR ; AT THE TOP ? JMP ILLCM ; NO, GOTCHA ! LDA 2,CQ ; CURRENT QUEUE LDA 1,QSUFP,2 ; QUEUE UFT POINTER JSR @.OVLAY ; CHECK & UNPACK NAME CFNAM STA 2,TDCB,3 ; SAVE DCB ADDRESS MOV 1,0 ; UFT TO AC0 JSR @.OVLAY ; LOOK FOR THE ENTRY SRUFD RTRN ; ERROR STA 2,BFAD,3 ; FOUND, SAVE BUFFER ADDRESS MOV 1,2 ; INDEX ON ENTRY LDA 0,UFTAT,2 ; GET ATTRIBUTES LDA 2,LNKAT ; & LINK MASK AND# 0,2,SZR ; IS THIS A LINK ? JMP GDRTN ; YES, NO CLEARS ALLOWED LDA 0,.SYSNM ; SYS.DR NAME POINTER LDA 2,FNLGT ; FILENAME LENGTH JSR @.CMPW ; COMPARE THE NAMES SUBZL 0,0,SKP ; IT'S SYS.DR, FORM +1 SUB 0,0 ; NOT SYS.DR, FORM 0 MOV 1,2 ; ENTRY ADDRESS TO AC2 STA 0,UFTUC,2 ; CLEAR TOTAL USER COUNT STA 0,UFTP2,2 ; RESET .OPEN COUNT ALSO GDRTN: LDA 2,BFAD,3 ;BUFFER ADDRESS JSR @.RELMB ;RELEASE MODIFIED ISZ ORq:TN,3 ; GOOD RETURN NOW JSR @.FLUSH RTRN ILLCM: JSR @.RETER ERICM ILLC1: JSR @.RETER ERFGE ENDOV .END DVINI.SRB S RTITLE DVINI .ENT DKINI .ENT DPINI .EXTN FINIT,CRSFS,SZDSK .EXTN RLSER,RMVBAD .EXTN ENCONT,STLINK .EXTN SRUFD,BLKIN .EXTN SYSNM,MAPNM .EXTN RELMB,RELB .EXTN RETER .EXTN OVLAY .EXTN MVWD .NREL ;****************************************s* ; NUMBER OF STACK TEMPORARIES USED ; MUST BE THE FIRST WORD IN THE OVERLAY .IFN BSW!MBSW LASTEMP-TMP+1 .ENDC ; SUBROUTINE TO INITIALIZE A DISK DEVICE FOR ACCESS ; ; INPUTS: AC0,AC1 - PARTITION BASE ADDRESS ; AC2 - DCB ADDRESS OF SYS.DR ; SIGN %BIT IS INIT CODE - ; 0 = PARTIAL, 1 = FULL ; ; RETURNS: STANDARD ERROR & SUCCESSFUL RETURNS ; FOR DUAL PROCESSOR INTERLOCKING REASONS, THE DCB INIT BIT MUST ; BE SET ALL THE WHILE THE INIT IS IN PROGRESS. OVBA1=TMP OVBAS=OVBA1+1 BLKC1=OVBAS+1 BLKCT=BLKC1+1 ESW=BLKCT+1 BUFP=ESW+1 LASTEMP=BUFP .RETER: RETER K177: 177 SYSDR: SCSYS PPA: SCPPA .BAD: SCBAD MINLEN: BALIST MAXLEN: SCDBS EXTRA: BEXSZ .BEHSZ: BEHSZ .ENCONT:ENCONT .STLINK:STLINK DKINI: SUB 1,1,SKP ;FIXED HEAD INIT, NO ALLOCATE DPINI: SUBZL 1,1 ;MOVING HEAD INIT, ALLOCATE A ; FRAME OF SYS.DR ON FULL INIT MOVL 2,2 ;INIT CODE BIT TO CARRY ADDR 1,1 ;PACK IT INTO B0 STA 1,ESW,3 ;SAVE SWITCH, B0: FULL INIT BIT, ; B15: ALLOCATE BIT MOVZR 2,2 ;GET RID OF THE SIGN BIT STA 2,OAj3C2,3 ;GET RID OF IT FOR GOOD LDA 1,OAC1,3 ;LOW ORDER PARTITION BASE ADDRESS LDA 3,SYSDR ; SYS.DR'S OFFSET ADDZ 3,1,SZC ; CHECK OVERFLOW INC 0,0 STA 0,DBFA1,2 ; SET FIRST ADDRESS STA 1,DCBFA,2 ; SET FIRST ADDRESS JSR @.OVLAY ; GO SIZE DISK SZDSK RTRN ; AN ERROR LDA 3,DCBDC,2 ; DCT ADDRESS LDA 0,DCNB1,3 ; TOTAL BLOCK COUNT LDA 1,DCNBK,3 ; NOW GET TOTAL BLOCK COUNT LDA 3,PPA ADDZ 3,1,SZC ;FIND TRUE TOTAL BLOCK COUNT INC 0,0 LDA 3,CSP ; STACK POINTER STA 0,BLKC1,3 ; SAVE TOTAL BLOCK 'COUNT STA 1,BLKCT,3 ; SAVE TOTAL BLOCK COUNT LDA 0,SFKY1,2 ; GET ASCII UNIT # LDA 1,K177 AND 1,0,SNR ; IS IT A FIZED PLATTER ? JMP DVNOK ; NO CONTINUE LDA 3,DCBDC,2 ; YES MAKE SURE DISK IS A TOP LOADER LDA 1,DCTCH,3 ; CHARACTERISTICS WORD ADDJ ZL# 1,1,SZC ; WELL ?? JMP DVNOK ; YES ALL IS WELL JSR @.RETER ; NO GIVE ERROR DEVICE NOT IN SYSTEM ERDNM DVNOK: LDA 3,DCBDCT,2 ;FIND DCT LDA 0,DCTFO,3 ;FRAMESIZE STA 0,SFMSZ,2 ;SET THE FRAMESIZE IN THE DCB LDA 1,DCBST,2 ;SHOW DCB AS INIT'ED -  LDA 0,INITB ;THIS SERVES AS INTERLOCK IN AND 0,1 ; DUAL PROC WORLD: OTHER SIDE STA 1,DCBST,2 ; CAN'T FULL INIT AFTER WE'VE ; STARTED INIT'ING THE DEVICE LDA 0,DCTBL,3 ;DCT IS STILL IN AC3 LDA 3,CSP ;NOW RESTORE STACK POINTER COM# 0,0,SZR ;BAD BLOCK TABLE SET UP? JMP GOTBTBL ;YES ;SET UP BAD BLOCK TABLE IN CORE: SUB 0,0 LDA 1,.BAD ;ADDRESS OF BAD BLOCK TABLE BLOCK STA 0,DBCA1,2 STA 1,DCBCA,2 JSR @.BLKIN ;GO GET IT JMP ERR STA 0,BUFP,3 ;SAVE BUFFER ADDRESS MOV 0,2 LDA 0,BASTART,|2 LDA 1,BASTART+1,2 ;ADDRESS OF REALLOCATION AREA LDA 2,BASIZE,2 ADDZ 2,1,SZC ;FIND ADDRESS OF END OF IT INC 0,0 LDA 2,BLKC1,3 USLE 0,2 ;IS IT WITHIN THE DISK? JMP BAD4 ;NOPE LDA 2,BLKCT,3 USLE 1,2 ;LOW ORDER, TOO JMP BAD4 LDA 2,BUFP,3 LDA 90,BALEN,2 ;LENGTH-OF-TABLE WORD LDA 1,MINLEN MOVR# 0,0,SNC ;MUST BE EVEN USGE 0,1 ;MUST HAVE AT LEAST A HEADER JMP BAD4 ;INVALID BAD BLOCK TABLE, NO INIT LDA 1,MAXLEN USLE 0,1 ;MUST FIT IN A DISK BLOCK JMP BAD4 LDA 1,EXTRA ;IN-CORE EXTRA HEADESR SPACE ADD 1,0 ;CORE REQUIREMENT FOR TABLE LDA 2,@.ENCONT ADD 2,0 ;POTENTIAL NEW POOL END ADDRESS INTDS ;DON'T LET INT HANDLER GRAB LINKS WHILE WE CHECK LDA 1,@.STLINK ;START OF LINK SPACE USLE 0,1 ;WOULD WE OVERWRITE? JMP NOSPACE ;YOU BET STA 0,@.ENCONT ;NO, NEW END OF CONTIG SPACE INTEN LDA 0,BUFP,3 ;RECOVER BUFFER POINTER LDA 3,OAC2,3 ;PASSED DCB LDA 3,DCBDCT,3 ;UNIT DCT STA 3,BEUNI,2 ;MAKE BACK LINK IN BAD BLOCK TABLE STA 2,DCTBL,3 ;DCT LINK TO BAD BLOCK TABLE LDA 1,.BEHSZ ;HEADER BSIZE ADD 2,1 ;POINT TO IMAGE AREA MOV 0,3 LDA 2,BALEN,3 ;LENGTH OF IMAGE JSR @.MVWD ;MOVE TABLE FROM BUFFER TO CORE POOL ADD 1,2 ;POINT TO LINK WORD ADC 0,0 STA 0,0,2 ;NO LINKS FOR NOW LDA 2,BUFP,3 JSR @.RELB ;RELEASE BUFFER, SO MUCH FOR BAD FBLOCK STUFF LDA 2,OAC2,3 ;GET BACK THAT DCB ADDRESS GOTBTBL:LDA 1,ESW,3 ;GET INIT CODE MOVL# 1,1,SNC ; PARTIAL INIT ? JMP PARIT ; YES LDA 0,OAC0,3 ;PASS PARTITION BASE MOVL 0,0 ;PACK ALLOCATE BIT IN B0 MOVR 1,1 MOVR 0,0 LDA 1,OAC1,3 ;LOW ORDERz OF PART BASE JSR @.OVLAY ;GO DO FULL INIT STUFF FINIT JMP ERR ;ERROR, RESET INIT BIT ETC STA 0,OVBA1,3 ;SAVE RETURNED OVERLAY BASE STA 1,OVBAS,3 ; FOR BOOTSYS.OL JMP PARIT ;REJOIN COMMON PARTIAL PATH BAD4: LDA 0,.ERBAD ;INVALID BAD BLOCK TAB LE ON DISK JMP BERR NOSPACE:INTEN LDA 0,.ERBSPC ;NO SPACE IN CORE POOL BERR: LDA 2,CC STA 0,CERR,2 ;STORE ERROR CODE LDA 2,BUFP,3 JSR @.RELB ;RELEASE BUFFER ERR: LDA 2,OAC2,3 ;MAKE SURE DCB IS IN AC2 JSR @.OVLAY ;FLUSH BUFFERS & REMOVE BAD BLOCK  RMVBAD ; TABLE, IF APPROPRIATE JMP .+1 ;HANG IN THERE LDA 1,DCBST,2 LDA 0,INITB ;UNDO THE INIT - AND 0,1 ; TURN THE NOT-INIT'D BIT ADC 0,1 STA 1,DCBST,2 ; BACK ON JSR @.OVLAY RLSER ;ZAP THE NAME FIELD JMP .+1 RTRN ;ERROR RETURN .OVLAY: OVLAY .ERBAD: ERBAD .ERBSPC:ERBSPC .MVWD: MVWD .BLKIN: BLKIN INITB: -STCMK-1 PARIT: LDA 0,SYSPT ; POINTER TO SYS.DR IN UFD JSR @.OVLAY ; FORMAT SRUFD ; SEARCH FOR SYS.DR JMP ERR ; ERROR, MUST UN-INIT THE DCB MOV 2,0 ; SAVE BUFFER ADDRE2SS LDA 2,OAC2,3 ; GET DCB ADDRESS MOV 1,3 ; ENTRY ADDRESS TO AC3 LDA 1,UFTBC,3 ; LAST BLOCK BYTE COUNT STA 1,SFBC,2 ; TO DCB LDA 1,UFTBK,3 ; LAST BLOCK NUMBER STA 1,SFBK,2 ; TO DCB ISZ UFTUC,3 ; BUMP SYS.DR'S USER COUNT JMP .+2 ; NOT ZERO ISZ UFTUC,3 ; WAS ZERO, MAKE 1 MOV 0,2 ;BUFFER ADDRESS TO AC2 JSR @.RELMB ;RELEASE MODIFIED LDA 2,OAC2,3 ; DCB ADDRESS LDA 0,SFTYPE,2 ;GET DCB TYPE WORD COM# 0,0,SNR ;SUB-DIRECTORY? JMP NOMAP ;YES, DON' INIT THE MAP LDA 0,MAPPT ; MAP.DR POINTER JStR @.OVLAY SRUFD ; SEARCH FOR MAP.DR JMP SERR ; ERROR - GO DEC SYS.DR USE COUNT MOV 2,0 ; SAVE BUFFER ADDRESS LDA 2,OAC2,3 ; DCB ADDRESS LDA 2,SFLK,2 ; MAP DCB ADDRESS MOV 1,3 ; ENTRY TO AC3 LDA 1,UFTBC,3 STA 1,SFBC,2 ; BYTES IN LAST BLOCK LDA 1,UFTBK,3 STA 1,SFBK,2 ; LAST BLOCK NUMBER LDA 1,UFTAD,3 ; FIRST ADDRESS STA 1,DCBFA,2 ; SET IN DCB STA 1,DCBCA,2 ; AS CURRENT TOO LDA 1,UFTDL,3 ; GET HIGH ORDER ADDRESS PART LDA 3,AMSK ANDS 3,1 ; FULL WORD STA 1,DBFA1,2 ; SET AS FIRST STA 1, DBCA1,2 ; AND CURRENT MOV 0,2 ; BUFFER ADDRESS TO AC2 JSR @.RELB ; RELEASE THE BUFFER LDA 2,OAC2,3 ; DCB ADDRESS NOMAP: LDA 2,DCBDC,2 ; DCT ADDRESS LDA 0,DCTCH,2 ; CHARACTERISTICS LDA 2,OAC2,3 ; RESTORE AC2 LDA 1,ESW,3 ; ENTRY SWITCH MOVZL 1,1 ; CLEAR 1B0 IF SET MOVZR 1,1 MOVR 0,0 MOVR 0,0,SZC ; FLOPPY ?? STA 1,ESW,3 ; YES RESTORE ENTRY SWITCH LESS 1B0 LDA 0,OVBA1,3 ; BASE OF OVERLAYS LDA 1,OVBAS,3 ; GET BASE OF OVERLAYS LDA 3,ESW,3 ;GET INIT BIT LDA 2,DCBDR,2 ;SYS.DR DCB ADDRESS MOVL 2,2 MOVL 3,3 ;INIT CODE TO B0 OF DCB ADDRESS MOVR 2,2 JSR @.OVLAY ; & PASS TO CRSFS CRSFS JMP SERR ; ERROR, MUST RESET INIT BIT IN DCB ;AND DECREMENT SYS.DR'S USE COUNT ISZ ORTN,3 ; GOOD RETURN NOW LDA 3,CC ; CURRENT CELL LDA 3,CPTAD,3Rf ; PROGRAM TABLE ADDRESS LDA 0,PPRI,3 ; PROGRAM PRIORITY SUBZR 1,1 ; SET 1B0 MOVR# 0,0,SZC ; BACKROUND ? MOVZR 1,1 ; NO, SET 1B1 LDA 0,DCBUC,2 ; USER COUNT WORD FOR DCB ADD 1,0 ; SET THIS PROGRAMS'S INIT BIT STA 0,DCBUC,2 ; IN DCB RTRN SERR: xLDA 0,SYSPT JSR @.OVLAY ;GO GET SYS.DR ENTRY, AGAIN SRUFD JMP ERR ;OH WELL, WE TRIED ANYWAY MOV 1,3 ;INDEX ON ENTRY DSZ UFTUC,3 ;BACK UP THE USE COUNT JMP .+1 JSR @.RELMB JMP ERR ;NOW RESET DCB BIT .RELMB: RELMB .RELB: RELB SYSPT: SYSNM MA'PPT: MAPNM AMSK: ATMSK ENDOV .END CRSFS.SRB$  RTITLE CRSFS CRSF .ENT CRSFS .ENT RPIPH .ENT CRMPE .EXTN SFTAB .EXTN OVLAY,OICAL .EXTN OVBA1,OVBAS .EXTN NAMCK .EXTN CRINI .EXTN SRUFD .EXTN NSEG .EXTN ITBL .EXTN FNDCB .EXTN BLKIN .EXTN TODD,TODH,TODS .EXTN DIVI .EXTN MDCB .EXTN RELZT),RELMB .EXTN IUD .EXTN TSTEQ .NREL .TXTM 1 ;***************************************** ; NUMBER OF STACK TEMPORARIES USED ; MUST BE THE FIRST WORD IN THE OVERLAY .IFN BSW!MBSW 6 .ENDC ; MAP.DR TEMPLATE MAPPT: .+1 "M*400+"A "P*400+0 0 ( 0 0 "D*400+"R ATPER+ATCHA+ATCON+ATWP ; ATTRIBUTES 0 ; CHARACTERISTICS .UFBK: 0 ; LAST BLOCK NUMBER .UFBC: 0 ; BYTES IN LAST BLOCK .UFAD: 0 ; RELATIVE DEVICE ADDRESS .UFAC: 0 ; YEAR-DAY LAST ACCESSED .UFYD: 0 ; YEAR-DAY CREATED .UFHM: 0 ; 3HOUR-MINUTE CREATED 0 ; TEMP # 1 0 ; TEMP # 2 0 ; USER COUNT .UFDL: 0 ; DEVICE LINK MAPOF: SCMAP .TODD: TODD .TODH: TODH .TODS: TODS .IDIV: DIVI CD60: 60. ; CREATE MAP.DR ENTRY IN SYS.DR ; ; INPUTS: MAP DCB DCBFA DBFA1 - PARTITON BASE ADDRESS ; AC2 - SYS.DR DCB ADDRESS ; ; OUTPUTS: NONE ; ; RETURNS: CALL+1 - ERROR ; CALL+2 - GOOD RETURN ; ; ******* MAP.DR'S SFBK & SFBC ASSUMED TO BE SET UP ******* CRMPE: LDA 2,SFLK,2 ; GET MAP DCB ADDRESS LDA 1,SFBK,2 ; GET LAST BLOCK NUMBER STA 1,.U<12>/ .TT0D: TTIDC .TT1D: TTI1D ENDOV .END RING2.SRB S _P RTITLE RING2 RNG2 .NREL .ENT RDS ;READ SEQUENTIAL .ENT RDL ;REAL LINE MODE .ENT RCHR,DRCHR ;RECEIVE A CHARACHTER .ENT GCHR ;GET CHARACTER .ENT GCH ;OTHER GET CHARACTER .ENT TIRS ;TTI RDS .ENT TIRL ;TTI RDL .EXTN SYSFL ;SYSTM FLAGS WORD .IFE BSW .EXTN MSTBT .ENDC .EXTN OBUF ;OUTPUT TO BUFER .EXTN TTIDC,TTRDC .EXTN PEND ;PEND THE TASK ;***************************************** ; NUMBER OF STACK TEMPORARIES USED ; MUST BE THE FIRST WORD IN THE OVERLAY .IFN BSW!MBSW 5 .ENDC W ; TELETYPE IN - READ SEQUENTIAL ; - READ LINE ; INPUT: DESTINATION BYTE POINTER IN AC0 ; DESIRED BYTE COUNT IN AC1(READ SEQ ONLY) ; UFT ADDRESS IN AC2 ; OUTPUT: NUMBER OF BYTES MOVED IN AC1 ; CALLING SEQUENCE: ; CALL ; TIRS (TIRL) ; END OF FILEE RETURN ; NORMAL RETURN TIRS: MOVZ 0,0 ;ZERO CARRY SWITCH TO SETKM JSR .SETKM ; GO CLEAR ECHO BIT JMP RDS ; DO READ SEQUENCIAL TIRL: MOVO 0,0 ; SET UP FOR ECHO JSR .SETKM ; SET ECHO BIT JMP RDL ; GENERALIZED READ SEQUENTIAL ROUTINE ; UFNT ADDRESS IN AC2 ; DESTINATION BYTE POINTER IN AC0 ; DESTINATION BYTE COUNT IN AC1 ; CALLING SEQUENCE: ; CALL ; RDS ; EXCEPTIONAL RETURN (PARTIAL COUNT IN AC1) ; NORMAL RETURN ; SUCCESSIVE CALLS TO "RETRIEVE A CHARACTER" ARE MADE ; UNTIL THE COUNT? IS SATISFIED OR THE TIMEOUT RTN INDICATES EOF. RDS: NEG 1,1,SNR ; IS COUNT ZERO? JMP RDS1 ; YES, JUST RETURN STA 1,BCNT,3 ; SAVE COUNT IN STACK SUB 1,1 ; TYPE CODE SEQUENTIAL JMP RDCMN ; COMMON CODE RDS1: ISZ ORTN,3 RTRN ; GENERALIZED RET(RIEVE A CHARACTER ROUTINE ; INPUT: CONTROL TABLE ADDRESS IN AC2 ; CALLING SEQUENCE: ; CALL ; RCHR ; TIMEOUT RETURN ; NORMAL RETURN ; OUTPUT: CHARACTER IN AC0 (BITS 0-7 ZERO) RCHRX: RSAVE 1 RCHR: SUB 1,1,SKP ;ENTRY TYPE SWITCH DRCHR: SUBZL 1,1 ;ENTK}RY TYPE FOR TWO BYTES STA 1,TMP,3 ;SAVE IT ON STACK RETRY: LDA 3,CQ ;CURRENT Q LDA 3,QSTAT,3 ;STATUS OF TASK LDA 1,.TSAB ;ABORT MASK AND# 1,3,SZR ;SHOULD WE ? RTRN ;YES - GET OUT. INTDS ;DISABLE INTERRUPTS JSR@ .OBUF ;FETCH A CHARACTER JMP NOCHR ;NONE THERE INTEN ;ENABLE INTERRUPTS STA 0,OAC0,3 ;RETURN BYTE TO CALLER ISZ ORTN,3 ;TAKE NORMAL RETURN DSZ TMP,3 ;TEST ENTRY TYPE RTRN ;SINGLE BYTE - JUST RETURN INTDS ;YES - GET SECOND BYTE JSR@ .OBUF ;... JMP . ;CAN THIS HAPPEN ? t INTEN LDA 1,OAC0,3 ;FIRST BYTE MOVS 1,1 ;TO LH ADD 1,0 ;ADD IN RIGHT BYTE STA 0,OAC0,3 ;RETURN TO CALLER RTRN NOCHR: LDA 0,DCTTO,2 ;TIME OUT CONSTANT LDA 1,DCTBD,2 ;BEAD ADDRESS IS UNPEND KEY JSR@ .PEND ;GIVE UP FOR AWHILE RTRN ;TIMEOUT JMP _RETRY ;TRY AGAIN .PEND: PEND .OBUF: OBUF .TSAB: TSAB ; TELETYPE IN GET CHARACTER ; CALLING SEQUENCE: ; CALL ; GCHR ; RETURN ; AC2= DCT ADDR ; OUTPUT: CHARACTER RETURNED IN AC0 GCHRX: RSAVE GCHR: LDA 1,KECHF ;ECHO FLAG MASK INTDS ; DIABLE INTS CLDA 3,DCTQS,2 ;BEAD STATUS AND 3,1,SZR ;ENHO OFF SUB 1,3 ; SHUT ECHO OFF INTEN ; TURN INTS ON STA 3,DCTQS,2 ;SET TEMPORAIRLY JSR RCHRX ; GET A CHARACTER JMP GCHR1 ; INTERRUPT RETURN LDA 2,C177X AND 2,0 ; MASK TO SEVEN BITS STA 0,OAC0,3 ; RE6vTURN IN AC0 LDA 2,OAC2,3 ; GET BACK DCT ADDR GCHR1: INTDS ; DIABLE INTS LDA 0,DCTQS,2 ; GET BEAD STATUS ADD 1,0 ; RESET ECHO BIT TO FORMER VALUE INTEN ; TURN INTS BACK ON STA 0,DCTQS,2 ; STORE BACK BEAD STATUS RTRN ; SUCCESSFULLY C177X: 177 KECHF: BSECH MECHF: -BSECH-1 GCH: LDA 1,MECHF ; ECHO FLAG MASK INTDS ; DISABLE INTERRUPTS LDA 0,DCTQS,2 ; BEAD STATUS AND 1,0 ; SHUT OFF ECHO INTEN ; ENABLE INTS STA 0,DCTQS,2 ; STORE BACK BEAD STATUS JSR GCHRX LDA@ 2,CC STA 0,TAC0,2 ISZ ORTYN,3 RTRN .SETKM: JMP SETKM ; GENERALIZED READ LINE ROUTINE ; INPUT: UFT ADDRESS IN AC2 ; DESTINATION BYTE POINTER IN AC0 ; CALLING SEQUENCE: ; CALL ; RDL ; EXCEPTIONAL RETURN ; NORMAL RETURN ; OUTPUT: COUNT READ IN AC1  ; READ LINE WILL SUCCEfSSFULLY TERMINATE AFTER READING (AND ; STORING) EITHER: ; 1.) A CARRIAGE RETURN ; 2.) A FORM FEED ; 3.) A NULL ; READ LINE WILL TAKE THE EXCEPTIONAL RETURN ON ; 1.) A TIMEOUT (EOF) ; 2.) A PARITY ERROR (IN THE LAST CHARACTER STORED) ; OR 3.) AN EXCESSIVE LINE LENGTH ; LINE FEEDS AND RUBOUTS ARE UNCONDITIONALLY IGNORED RDL: SUBZL 1,1 ; TYPE CODE LINE RDCMN: STA 1,RDTYP,3 LDA 0,UFTCH,2 ; CHARACTERISTICS STA 0,CHAR,3 ; STORE IN STACK LDA 2,UFTDC,2 ; DCT ADDRESS TO AC2 LDA 1,NRDL ; TURN RDL BIT (USEfD BY $CDR INTDS ; DIABLE INTERRUPTS LDA 0,DCTQS,2 ; GET BEAD STATUS AND 0,1 ; ONLY) OFF. $CDR .RDL'S ARE HANDLED ; BY CDROV. INTEN ; ENABLE STA 1,DCTQS,2 ; PUT BACK RDL0: LDA 0,OAC0,3 STA 0,RLBP,3 ; SAVE THE READ BYTE PTR RDL1: JSR RCHRX ; [YGET A CHARACTER JMP RDL7 ; TIMEOUT LDA 1,RDTYP,3 ; TYPE MOV 1,1,SNR JMP RDL3A ; SEQUENTIAL STA 0,ICHR,3 ; LINE, SAVE CHARACTER LDA 1,C177 ; SEVEN BIT MASK AND 1,0 ; MASK TO 7 BITS LDA 1,CHAR,3 ;CHARACTERISTICS LDA 3,RCKEY ;KEY BOARD CHAR. AN1D# 1,3,SNR JMP RDL3 ; NOT A KEYBOARD DEVICE JSR TEQ ; KEYBOARD, TEST SPECIAL CHARS "Z-100 ; EOF CODE JMP RDL7 ; YES, END OF FILE JSR TUEQ ; TEST FOR CHAR DELETE 177 JMP RDL15 ; NO LDA 1,RLBP,3 ; YES, BACK UP RETURN POINTER LDA 0,OAC0,3 SUB|# 0,1,SZR ; AT BEGINNING? DSZ RLBP,3 ; NO, BACK IT UP JMP RDL1 NRDL: -BSRDL-1 ; CHECK TO SEE IF LOWER TO UPPER CASE CONVERSION NEEDED FOR TTY RDL15: LDA 3,LOWUP ; CHECK IF USER WANTS CONVERSION AND# 1,3,SNR ; IF NO CONVERSION THEN JMP RDL2 ; GO CHECK FOR LINE DELETE LDA 1,LOWA ; DO CONVERSION OF LDA 3,LOWZ ; LOWER CASE CHARACTERS TO SUBZ# 1,0,SZC ; IF CHAR IS NOT A LOWER CASE SUBZ# 0,3,SNC ; THEN EXECUTE JMP RDL2 ; THIS JUMP ELSE LDA 3,C40 ; DO THE SUB 3,0 ; CONVERT TO UPPER CASE RDLS2: JSR TEQ ; IS IT LINE DELETE? "\ JMP RDL0 ; YES, START AGAIN RDL3: JSR TEQ ; TEST FOR RUBOUT C177: 177 JMP RDL1 ; YES, IGNORE JSR TEQ ; TEST FOR LINE FEED 12 JMP RDL1 ; YES, IGNORE RDL3A: LDA 1,RLBP,3 ; NO, STORE THE CHARACTER .IFE BSW JSxR @.MSTBT .ENDC .IFN BSW STB 1,0 .ENDC ISZ RLBP,3 ; BUMP BYTE POINTER LDA 1,RDTYP,3 ; TEST TYPE MOV 1,1,SNR JMP RDL9 ; SEQUENTIAL LDA 1,CHAR,3 ; CHARACTERISTICS LDA 3,.DCPC ; PARITY CHECK ? AND# 1,3,SNR JMP RDL4 ; NO LDA 3,CSP ; STACK POINTER LDA 1,ICHR,3 ; INPUT CHAR MOVZS 1,1 ; BYTE TO LEFT HALF NEG 1,3 COM 3,3 ; FORM N-1 ANDC 3,1,SZR JMP .-3 ; WAIT TILL ZERO ADD# 1,1,SZC ; WELL, HOW DID WE DO JMP RDL10 ; LOUSY RDL4: JSR TEQ 15 ; CARRIAGE RETURN? JMP RDL8 ; YES, TERMINATE JSR TEQ 14 ; FORM FEED? JMP RDL8 ; YES, TERMINATE JSR TEQ ; TEST FOR A NULL 0 JMP RDL8 ; YES, GET OUT LDA 1,RLBP,3 ; CHECK FOR LINE TOO LONG LDA 0,OAC0,3 SUB 0,1 ; LENGTH SO FAR LDA 0,LGMAX SUBZ# 0,1,SNC JMP RDL1 ; NO, GET NEXT CHARACBTER LDA 2,LLMER ; LINE LIMIT ERROR RDL5: MOV 2,0 LDA 2,CC STA 0,CTMP2,2 ; RETURN ERROR CODE RDL6: LDA 0,OAC0,3 ; COMPUTE BYTES READ LDA 1,RLBP,3 SUB 0,1 STA 1,OAC1,3 ; RETURN IN AC1 RTRN .DCPC: DCPCK LLMER: ERLLI LGMAX: SCLLG RDL7: LDA 2,EOFEķR ; END OF FILE JMP RDL5 RDL9: ISZ BCNT,3 ; SEQUENTIAL COUNT EXPIRED? JMP RDL1 ; NO RDL8: ISZ ORTN,3 ; YES, BUMP RETURN JMP RDL6 RDL10: LDA 3,CSP LDA 2,PARER ; PARITY ERROR JMP RDL5 EOFER: EREOF .IFE BSW .MSTBT: MSTBT .ENDC PARER: ERPAR RCK:EY: DCKEY LOWUP: DCLTU ; CONVERT LOWER TO UPPER CASE CHARACTERISTIC LOWA: "A+40 ; LOWER CASE A LOWZ: "Z+40 ; LOWER CASE Z C40: 40 ; DEFINE THE STACK TEMPROARIES CHAR= TMP ; LEAVE AT DISP "TMP" !! BCNT= CHAR+1 RDTYP= BCNT+1 RLBP= RDTYP+1 ICHR= RLB'mP+1 SETKM: RSAVE 0 LDA 0,UFTCH,2 ; UFT CHARACTERISTICS LDA 2,UFTDC,2 ; GET ADDRESS OF DCT LDA 1,ECHF ;ECHO MASK LDA 3,.DCKEY ; KEYBOARD CHARACTERISTIC AND 0,3,SZR ; KEYBOARD MODE SUPPRESSED ? COM 1,3 ; NO SET ECHO BIT INTDS ; DIABLE INTERRYhUPTS LDA 0,DCTQS,2 ;BEAD STATUS WORD AND 1,0,SZC ;BIT OFF ADD 3,0 ; SET ECHO BIT IF NOT SUPPRESSED INTEN ; ENABLE INTS STA 0,DCTQS,2 ; STORE STATUS RTRN ECHF: -BSECH-1 .DCKEY: DCKEY ; TEST CHARACTER IN AC0 FOR EQUALITY/INEQUALITY ; JSR TEQ/'TUEQ ; ^TEST CHARACTER ; _TRUE RETURN ; _FALSE RETURN TEQ: MOVZ 3,3,SKP ; BIAS CARRY FOR TYPE TUEQ: MOVO 3,3 RSAVE 0 .IFE BSW!MBSW LDA 1,@ORTN,3 ; GET TEST CHARACTER .ENDC .IFN BSW!MBSW LDA 2,ORTN,3 ; GET RETURN PC LDA 1,0,2 ; GET TEST CHARACTER - .ENDC ISZ ORTN,3 ; BUMP PAST INPUT PARAM SUB# 0,1,SNR ; TEST FOR EQUALITY MOVC 0,0 ; YES, COMPLEMENT MODE MOV# 0,0,SNC ; NOW TEST ISZ ORTN,3 ; FALSE RTRN ENDOV .END RING3.SRB r*5 RTITLE RING3 RNG3 .NREL .ENT ACHR ; ACCEPT A CHRACTER .ENT WRS ; WRITE SEQUENTIAL .ENT WRL ; WRITE LINE MODE .ENT PCH .EXTN SYSER ; SYSTEM .EXTN IBUF ; INPUT TO BUFFER .EXTN PEND ; PEND THE CURRENT TASK .EXTN UNPEND ; UNPEND A TASK .E8XTN SPOLQ ; SPOLER UNPEND ADDRESS .EXTN SPOLF ; SPOOL GO FLAG .EXTN RDCBK ; READ THE CURRENT BLOCK .EXTN RDNBK ; READ THE NEXT BLOCK .EXTN RELMB ; RELEASE MODIFIED .EXTN STSPL ; START A SPOOL .EXTN MNSTK .EXTN SYSFG .EXTN TSTEQ .EXTN SPLDL -;***************************************** ; NUMBER OF STACK TEMPORARIES USED ; MUST BE THE FIRST WORD IN THE OVERLAY .DO ?ABSW 4 .ENDC ; GENERALIZED ACCEPT A CHARACTER ROUTINE ; INPUT: CHARACTER IN AC0 ; CONTROL TABLE ADDRESS IN AC2 ; CALLING SEQUENCE: ; CALL ; ACHR ; NORMAL RETURN ; THIS ROUTINE USES THE DEVICE CONTROL TABLE ADDRESS TO ENABLE A ; CHARACTER IN AC0 TO BE OUPTUT TO THE PHYSICAL DEVICE. BFAD=TMP DCBBC=DCBFA+1 PCH: ACHR: INTDS LDA 1,DCTON,2 ; SPOOL-ON DCB ADDRESS SEQZ 1 ; ISle DEVICE SPOOLING? JMP SPLNG ; YES XXJSR IBUF ; TRY FOR THE BUFFER SKIP ; BUFFER IS FULL JMP ACHRT ; MADE IT - GET OUT XLDA 0,= MNSTK ; SEE IF ONLY 1 STACK MOVZR 0,0,SNR JMP NOSPL ; ONLY 1 STACK-NO SPOOLING XLDA 1,SYSFG ; FG FLAG SNEZ 1 ; FG RUNNING ? JMP YEASP ; SKIP IF NO-OK TO SPOOL MOVR 0,0,SNR JMP NOSPL ; ONLY 2 STACKS YEASP: LDA 1,DCTCH,2 ; GET CHARACTERISTICS XLDA 0,= DCSPC ; SPOOL MASK AND 0,1,SZR ; IS DEVICE SPOOLABLE? JMP SPLIT ; YES, SPOOL IT! NOSPL: ADC 0,0 ; NO, LONG TIMEOUT LDA 1,DCTBD,2 ; BEAD ADDRESS IS UNPEND KEY XXJSR PEND JMP . ; ERROR RETURN IS A GOTCHA LDA 0,OAC0,3 ; RECOVER THE CHARACTER LDA 3,CQ ; CURRENT Q LDA 3,QSTAT,3 ; TASK STATUS XLDA 1,= TSAB ; ABORT MASK AND# 1,3,SNR ; ABORT ? JMP ACHR ; NO, TRY BUFFER AGAIN XXJSR SYSER SPLIT: INTEN ; SPOOL IT! LDA 0,OAC0,3 CALLF STSPL ; START A SPOOL JMP TFOOS ; ERROR - TEST FOR OUT OF SPACE JMP GDRTN ; GOOD RETURN SPLNG: MOV 1,2 ; INDEX ON SPOOL ON DCB SUBZR 0,0 ; 100000 INTEN STA 0,DCBSpT,2 ; SET 'SPOOL I/O' BIT LDA 0,DCBBC,2 ; GET BYTE COUNT XLDA 1,= (SCWPB-1)*2 USLT 0,1 ; IS CURRENT BLOCK FULL? JMP CBFUL ; YES XXJSR RDCBK ; NO, DRAG IT IN JMP SPLER ; SPOOL ERROR JMP COMCD CBFUL: SUB 0,0 XXJSR RDNBK ; READ THE NEXT ONE JMP SPLER ; SPOOL ERROR STA 0,DCBBC,2 ; RESET THE BYTE COUNT COMCD: STA 1,BFAD,3 ; SAVE BUFFER ADDRESS SUB 0,0 ; +0 STA 0,DCBST,2 ; RESET 'SPOOL I/O' BIT LDA 0,OAC0,3 ; RETRIEVE THE CHARACTER LDA 1,DCBBC,2 ; BYTE COUNT ISZ DCBBC,2 ; BUMP THE COUNT LDA 2,BFAD,3 ; GET THE BUFFER ADDRESS MOVZL 2,2 ; MAKE A BASE BYTE POINTER ADD 2,1 ; + BYTE COUNT = BYTE POINTER STB 1,0 ; STORE CHAR IN THE BUFFER LDA 2,BFAD,3 ; BUFFER ADDRESS AGAIN XXJSR RELMB ; & RELEASE MODIFIED XLDA 0,= SPOLQ ; UNPEND THE SP\OOLER XJSR UNPEND ; TO KEEP IT GOING XISZ SPOLF ; INC SPOOLER GO FLAG NOP ACHRT: INTEN ; ENABLE INTERRUPTS GDRTN: ISZ ORTN,3 RTRN TFOOS: XXJSR TSTEQ ERSPC RTRN ; WRONG ERROR JMP ACHR ; OUT OF SPACE - USE THE DEVICE SPLER: XXJSR TSTEQ ; TtEST FOR SYSTEM DEADLOCK ERSDL RTRN ; WRONG ERROR LDA 2,OAC2,3 ; RECOVER DCT ADDRESS CALLF SPLDL ; RESOLVE DEADLOCK RTRN ; IN THE BAG LDA 0,OAC0,3 ; RECOVER THE CHARACTER JMP ACHR ; NOW TRY TO PUT IT OUT ; GENERALIZED WRITE SEQUENTIAL ROUTINE ' ; INPUT: UFT ADDRESS IN AC2 ; BYTE POINTER IN AC0 ; BYTE COUNT IN AC1 ; CALLING SEQUENCE: ; CALL ; WRS ; EXCEPTIONAL RETURN (NEVER TAKEN) ; NORMAL RETURN ; SUCCESSIVE CALLS TO "ACCEPT A CHARACTER" ARE MADE UNTIL THE ; COUNT IS SATISFIED. WRS: NE>G 1,1,SNR ; COUNT ZERO? JMP GDRTN ; YES, RETURN STA 1,WRBC,3 ; SAVE BYTE COUNT STA 0,WRBP,3 ; SAVE BYTE POINTER LDA 2,UFTDC,2 ; DCT ADDRESS WRSLP: LDA 1,WRBP,3 ; LOAD BYTE POINTER MLDB 1,0 ; LOAD A BYTE ISZ WRBP,3 ; BUMP BYTE POINTER JSR OCHR ;z OUTPUT THE CHAR JMP WRLER ISZ WRBC,3 ; DONE YET ? JMP WRSLP ; NO - GO BACK  JMP WRLLD ; GO HOME LPOOL ; ENTRY TO ACHR USED BY THE OVERLAY, HAS SAME CALLING ; REGISTER ASSIGNMENT AS ACHR. OCHR: RSAVE 1 ; INTERNAL ADDRESS JMP ACHR ; GO OUTPUT :[THE CHAR ; GENERALIZED WRITE LINE ROUTINE ; INPUT: BYTE POINTER IN AC0 ; UFT ADDRESS IN AC2 ; CALLING SEQUENCE: ; JSR WRL ; EXCEPTIONAL RETURN (STATUS IN AC2) ; NORMAL RETURN ; WRITE LINE WILL SUCCESSFULLY TERMINATE AFTER WRITING ; 1.) A CARRIAGE6 RETURN ; OR 2.) A FORM FEED ; TERMINATION WILL OCCUR IF A NULL IS DETECTED, BUT WITHOUT WRITING IT ; CHECKS OF THE DEVICE CHARACTERISTICS DETERMINE ; WHETHER TO PERFORM THE FOLLOWING: ; 1.) COMPUTE PARITY ON OUTPUT ; 2.) WRITE NULLS AFTER FORM FEEDS ; 3.cf) WRITE LINE FEEDS AFTER CARRIAGE RETURNS ; 4.) SIMULTE TABS ; 5.) WRITE RUBOUTS AFTER TABS ; 6.) CR BEFORE FF ; WRITE LINE WILL TAKE THE EXCEPTIONAL RETURN ON ; 1.) AN EXCESSIVE LINE LENGTH CHAR=TMP ; CHARACTERISTICS WRBC=CHAR+1 WRBP=WRBC+1 WRL: ShTA 0,WRBP,3 ; BYTE POINTER LDA 0,UFTCH,2 ; CHARACTERISTICS STA 0,CHAR,3 ; SAVE THEM LDA 2,UFTDC,2 ; DCT ADDRESS WRL0: LDA 3,CSP ; RESTORE STACK POINTER WRL1: LDA 1,WRBP,3 ; BYTE POINTER MLDB 1,0 ; GET A BYTE ISZ WRBP,3 ; BUMP BYTE POINTER XLDA 1,:= 177 ; LINE AND 1,0,SNR ; MASK TO SEVEN BITS JMP WRLDN ; DONE IF ZERO BYTE XLDA 1,= 40 ; IF CHAR IS A CONTROL USGE 0,1 ; CHAR THEN JMP WRLCN ; GO HANDLE IT ELSE XLDA 3,= "A+40 ; IF IS NOT LOWER CASE THEN USGE 0,3 ; JUST GO OUT THE JMP WRL2  ; CHARACTER ELSE JSR TCHRF ; CHECK FOR LOWER CASE DCLTU ; TO UPPER CASE CONVERT JMP WRL2 ; NO XLDA 3,= "Z+40 ; IF IS LOWER CASE USGT 0,2 ; LETTER THEN CONVERT SUB 1,0 ; TO UPPER WRL2: ; SAME ENTRY POINT AS WRLOUT WRLOUT: LDA 1,DCTCC,2 ; GEnT COLLUMN COUNT XLDA 3,= SCLLG ; IF WE ARE OVER THE EDGE USLT 1,3 ; THEN GIVE AN ERROR JMP WRLLM ; TO THE USER ELSE JSR TCHRF ; IF USER DOES NOT WISH DCC80 ; TO OUTPUT PAST 80 JMP WRLO1 ; COLUMNS THEN XLDA 3,= 80. ; CHECK IF PAST THAT AND USLT 1,3 ; IF WE ARE THEN JMP WRLO2 ; DON'T OUTPUT CHAR WRLO1: JSR CPAR ; COMPUTE PARITY & OUTPUT CHAR JMP WRLER ; QUIT ON ERROR WRLO2: ISZ DCTCC,2 ; INC COLLUMN COUNT JMP WRL0 ; AND CONTINUE LOOPING WRLLM: SUB 0,0 ; LINE LIMMIT ERROR STA 0,DCTCCB,2 ; ZERO COLUMN COUNT ERROR ERLLIM ; RETURN ERROR WRLLD: SUB 0,0 ; LINE FINISHED, STA 0,DCTCC,2 ; ZERO COLUMN COUNT WRLDN: ISZ ORTN,3 ; GIVE SUCCESS RETURN WRLER: LDA 1,WRBP,3 ; RETURN # OF CHARS LDA 0,OAC0,3 ; OUTPUT TO THE CALLER SUB 0,1 STA 1,ndOAC1,3 ; IN HIS AC1 RTRN ; COMPUTE PARITY IF NECESSARY AND OUTPUT CHARACTER ROUTINE ; ; DESTROYS AC1 & CARRY ; RETURNS AC3 = CSP ; CALL +1 IF ERROR ; CALL +2 IF OK ; ; INPUT: AC0 = CHAR WITHOUT PARITY CPAR: STA 3,PARET ; SAVE RETURN JSR TCHRF ; SEE IF PARITY WANTED DCPCK ; PARITY CHARACTERISTICS BIT JMP XIT ; NO PARITY WANTED- OUTPUT CHAR MOVZS 0,1 ; CHAR TO LEFT BYTE AC1 NEG 0,3 ; SUBTRACT 1 FROM CHAR & MOVE TO AC3 COM 3,3 ; CHAR = CHAR -1 ANDC 3,0,SZR ; CHAR .AND. CHAR-[1 JMP .-3 ; COUNT TIMES TO 0 ADDR 1,1 ; MOVE PARITY TO BIT 0 MOVS 1,0 ; MOVE CHAR TO RIGHT BYTE AC0 XIT: LDA 3,PARET ; GET RETURN FOR "OCHR" JMP OCHR ; PASS IT ON & OUTPUT CHAR PARET: .BLK 1 WRLCN: XLDA 1,= 11 ; IF CONTROL CHAR IS TAB SNE 0,1 ; THEN JMP WRLTB ; BRANCH ELSE XLDA 1,= 15 ; CHECK FOR CR SUB 0,1,SNR JMP WRLCR ; YES MOVZR# 1,1,SZR ; FORM FEED (14) JMP WRL2 ; NO, JUST GO OUT THE CHAR ELSE INC 0,0 ; 15 JSR CPAR ; COMPUTE PARITY AND OUTPUT CHAR JMP WRLER ; ERROR XLDA 0,= 14 ; FF JSR OCHR ; OUT THE FF (PARITY ALREADY OK) JMP WRLER ; QUIT ON ERROR JSR TCHRF ; IF USER DOES NOT WANT NULLS DCNAF ; AFTER FORM FEED THEN JMP WRLLD ; DONE ELSE SUB 0,0 ; PUT OUT 20 NULLS XLDA 1,= -20 ; AFTER IT WRLF1: JSR OCHR y; OUT THE NULL JMP WRLER ; DIE ON ERROR INC 1,1,SZR ; LOOP TILL JMP WRLF1 ; ALL OUT THEN JMP WRLLD ; DONE WRLCR: JSR CPAR ; OUT THE CR, WITH PAR IF NEEDED JMP WRLER ; QUIT ON ERROR JSR TCHRF ; IF USER WANTS LF AFTER DCLAC ; CR THEN JMP WR'LLD XLDA 0,= 12 ; OUTPUT LF (PARITY ALREADY OK) JSR OCHR JMP WRLER JMP WRLLD WRLTB: JSR TCHRF ; IF USER WANTS TABS DCCGN ; OUTPUT DIRECTLY THEN JMP WRLT2 ; THEN DO IT ELSE XLDA 0,= 40 ; SIMULATE TAB WITH SPACES WRLT1: JSR CPAR ; OUT A SPACE, WITH PAR IF NEEDED JMP WRLER ISZ DCTCC,2 ; COUNT THE COLUMN LDA 3,DCTCC,2 ; IF NOT AT TAB STOP XLDA 1,= 7 AND# 3,1,SZR ; THEN CONTINUE TILL WE HAVE JMP WRLT1 JMP WRL0 ; TABING DONE, CONTINUE WRLT2: JSR TCHRF ; CHECK IF TAB MUST BE DCRAT ; FXOLLOWED BY A RUBOUT JMP WRLOUT ; IF NOT THEN JUST OUT IT ELSE JSR CPAR ; OUT IT FOLLOWED BY JMP WRLER XLDA 0,= 177 ; A RUBOUT JMP WRL2 ; TEST CHARACTERISTIC IN "CHAR" AGAINST BIT FOLLOWING CALL TCHRF: RSAVE 0 .DO ?ANSW LDA 0,CHAR-SLGT,3 ; FIND CHARACTERISTIC MASK LDA 1,@ORTN,3 ; GET TEST BIT .ENDC .DO ?ABSW LDA 2,OSP,3 LDA 0,CHAR,2 LDA 2,ORTN,3 ; ADDRESS MAY HAVE CARRY SET LDA 1,0,2 ; GET TEST BIT .ENDC ISZ ORTN,3 ; BUMP RETURN AND# 0,1,SZR ; IS IT SET ? ISZ ORTN,3 ; YES - TAKE NORM2 UNIT DCB. JSR @.GSTAT ; GET STATUS STA 0,STAT,3 ; SAVE STATUS FOR LATER LDA 1,RDYMK ; GET UNIT READY/REWINDING MASK AND# 0,1,SNR ; IS STATUS EITHER ONE ? JMP USLER ;? NO, UNIT SELECTION ERROR MOVR# 0,0,SZC ; YES, IS UNIT READY ? JSR @.REWND ; YES, REWIND IT USLOK: LDA 0,ESW,3 ; GET ENTRY SWITCH LDA 3,OAC2,3 ; GET THE DCB ADDRESS INTDS ; SHUT INTS OFF LDA 1,DCBST,3 ; GET STATUS WORD STA 0,DCBCB,3 ; IS CURRENT POSITION MOVL 1,1 ; SHIFT LEFT COM# 0,0,SZR ; RELEASE ENTRY ? MOVZR 1,1,SKP ; NO, SHOW UNIT AS INIT'D MOVOR 1,1 ; YES, SHOW UNIT IS RELEASED INTEN ; TURN INTS BACK ON STA 1,DCBST,3 ; RETURN STATUS TO DCB COM# 0,0,SZR ; INIT ENTRY ? MOVL 3,3$0,SNC ; FULL INIT ? JMP NRTRN ; NO LDA 3,CSP LDA 0,STAT,3 ; YES, GET STATUS LDA 1,WPRMK ; WRITE PROTECT MASK AND# 0,1,SZR ; IS UNIT WRITE PROTECTED ? JMP WPERR ; YES, CAN'T FULL INIT JSR @.WTEOF JMP ERR1 ; ERROR JSR @.WTEOF ; WRITE 2 EOF'S JMP ERR1 ; ERROR JSR @.REWND ; REWIND THE UNIT NRTRN: JSR @.RELDB ; RELEASE THE BUFFER ISZ ORTN,3 ; GOOD RETURN NOW RTRN ERR1: LDA 2,OAC2,3 ;SHOW IS RELEASED (INIT/F FAILED) INTDS ; DISABLE INTS LDA 1,DCBST,2 ADDOR 1,1 JMP RESTORE WPERR: JSLR @.RELDB ; RELEASE THE BUFFER JSR @.RETER ; WRITE PROTECT ERROR CODE ERWPR OPER: JSR @.RETER ; OPENED ERROR ERNIR USLER: LDA 0,ESW,3 ;CHECK ENTRY TYPE COM# 0,0,SNR JMP USLOK ; IF RELEASING THEN IGNORE JSR @.RELDB ; RELEASE THE BUFFER JMP SmELER ; RETURN THE ERROR CODE RDYMK: RW+UR .REWND: REWND .GSTAT: GSTAT WPRMK: WP OMSK: STOPN ENDOV .END MTAUC.SRB 3U RTITLE MTAUC MTUC .ENT MTOPN ; OPEN .ENT MTOPA ; OPEN FOR APPENDING .ENT MTOPD ; OPEN FOR DIRECT I/O .EXTN ASBUF ; ASSIGN A BUFFER .EXTN RELDB ; RELEASE A BUFFER .EXTN SFRCD ; SPACE FORWARD A RECORD .EXTN SFFIL ; SPACE FORWARD A FILE y .EXTN SBRCD ; SPACE BACK A RECORD .EXTN SBFIL ; SPACE BACK A FILE .EXTN REWND ; REWIND THE TAPE .EXTN GSTAT ; GET TAPE STATUS .EXTN RETER ; SYSTEM ERROR RETURN .EXTN PEND ; SYSTEM TIMED WAIT .NREL ;**********************************l******* ; NUMBER OF STACK TEMPORARIES USED ; MUST BE THE FIRST WORD IN THE OVERLAY .IFN BSW!MBSW 4 .ENDC ; DEFINE SPECIAL DISPLACEMENTS UFFIL= UFTCA ; FILE NUMBER UFBUF= UFTNA ; BUFFER ADDRESS DCFIL= UFFIL-UFTDC ; DCB FILE # DCBUF= UFBUF-U6FTDC ; DCB BUFFER ADDRESS ; DEFINE DEVICE STATUS BITS ER= 1B0 ; ERROR DL= 1B1 ; DATA LATE RW= 1B2 ; UNIT IS REWINDING IL= 1B3 ; ILLEGAL STATUS DN= 1B4 ; RECORDING DENSITY,1=HIGH,0=LOW PR= 1B5 ; PARITY ERROR ET= 1B6 ; END OF TAPE ENCOUNTEREwD EF= 1B7 ; END OF FILE LP= 1B8 ; LOAD POINT ( BOT ) UT= 1B9 ; UNIT TYPE,1=9 TRACK,0=7 TRACK BT= 1B10 ; BAD TAPE WP= 1B13 ; UNIT IS WRITE PROTECTED OC= 1B14 ; ODD CHARACTER UR= 1B15 ; UNIT READY ; CHECK DIGIT IN AC0, BITS 0-7, FOR ASCII 60Ԗ-71 ; ; OUTPUT: AC1 - D-60 ; ; RETURNS: CALL+1 - NOT IN RANGE ; CALL+2 - IN RANGE DIGCK: LDA 1,M400 ANDS 0,1 LDA 0,ZERO ; ASCII ZERO SUB 0,1 ; REDUCE TO BINARY LDA 0,C11 ADCZ# 0,1,SNC ; TEST LEGALLITY JMP 0,3 ; OK - RETURN IFLN: JSR@ .RET ; NBOK - BOUNCE HIM ERFNM M400: -400 .RET: RETER C11: 11 ZERO: 60 C377: 377 ; ASSIGN A BUFFER ; ; INPUT: AC2 - DCB ADDRESS ; ; OUTPUT: AC0 - BUFFER ADDRESS ASTBF: RSAVE 0 JSR @.ASBF STA 1,OAC0,3 ; RETURN THE ADDRESS MOV 1,3 LDA 0,DCFIL,2 ; GET FILE #  LDA 1,FNOFS ; FILE # OFFSET ADD 1,3 ; ADDRESS OF LINK WORD STA 0,0,3 ; PUT FILE NUMBER IN IT STA 0,1,3 ; AND IN THE EXTRA WORD RTRN FNOFS: 377 C177: 177 .ASBF: ASBUF DCBOF: UFTDC .PEND: PEND CURBO: DCBCB ; OPEN A MAG TAPE FILE ; ; INPUT: AC2 - UFT ADDRESS ; ; RETURNS: CALL+1 - ERROR RETURN ; CALL+2 - SUCCESS RETURN TYP = TMP+1 POS = TMP+2 GFLG = TMP+3 MTOPD: SUBZL 0,0 ;OPEN FOR DIRECT I/O = 1 JMP MTBEG MTOPN: SUB 0,0,SKP ; OPEN = 0 MTOPA: ADC 0,0 ; APPENDING = -1 MTBEG: STA 0,TYP,3 ; SAVE IN THE STACK ADC 0,0 ; -1 STA 0,UFBUF,2 ; SHOW NO BUFFER ASSIGNED STA 0,UFTCB,2 ; AND DCB IS BEFORE FIRST BLOCK SUB 0,0 ; +0 STA 0,GFLG,3 ; I'VE GOT A LOVELY BUNCH OF ; COCONUTS ! LDA 0,UFTFN+1,2 ; SECOND WORD OF FILENAME MOV# 0,0,SZR ; HAD BETTER BE ZERO JMP IFLN ; SNEAKY LITTLE BASTARD LDA 0,UFTFN,2 ; ASCII FILE # DIGITS JSR DIGCK LDA 0,UFTFN,2 ; GET FILENAME AGAIN LDA 2,C177 ; MASK ANDS,2,0,SNR ; ONLY ONE DIGIT? JMP OPN ; YES MOVZL 1,2 ; NO, FORM DIGIT*10 MOVZL 2,2 n ADDZL 1,2 JSR DIGCK ADD 2,1 ; FILE # IN AC1 OPN: LDA 3,CSP ; PLACE TO HANG YOUR NADS  ; SWEATSHIRT STA 1,TMP,3 ; SAVE IN STACK LDA 2,OAC2,3 ; UFT ADDRESS SUBZR 0,0 ; 100000 = READ STATUS STA 0,UFTST,2 ; SET READ STATUS FOR ; POSITIONING vLDA 0,C377 ; WORD COUNT STA 0,UFTCH,2 ; TO UFT LDA 0,DCBOF ADD 0,2 ; FORM DCB ADDRESS STA 1,DCFIL,2 LDA 3,DCBDR,2 ; UNIT'S DCB ADDRESS LDA 1,DCBST,3 ; GET UNIT'S STATUS MOVL# 1,1,SNC ; IS UNIT INIT'D ? JMP OPN1 ; YES ELSE UNNSY: JSR@ .RETR ; TELL USER GOT NOT INIT ERRROR ERDNM .RETR: .RETER OPN1: LDA 1,CURBO ; YES, GET CURRENT BLOCK # ; OFFSET ADD 3,1 ; ADDRESS OF CURRENT BLOCK WORD LDA 3,CSP ; RECOVER STACK POINTER STA 1,POS,3 ; SAVE IN STACK JSR ASTBF ; ASSIGN A BUFFER STA 0,DCBUF,2 ; SAVE THE BUFFER ADDRESS MOV 0,2 JMP STAT2 ; GO CHECK FOR CONTROL-A STATS: INTDS ; INTERRUPT DISABLE BEFORE PEND SUBZL 0,0 ; SET TO WAIT A SECOND SUB 1,1 ; TO SEE IF MAG TAPE HAS JSR @.PEND ; REWOND JMP .+1 ; TIMEOUT RETURN STAT2: JSR( .ABCHK ; CHECK FOR ABORT JSR @.GSTAT ; GET STATUS LDA 1,TYP,3 ; MAGIC ENTRY WORD NEGL# 1,1,SZC ; IS IT A DIRECT I/O? JMP NOCK ; YES - SKIP DENSITY CHECK LDA 1,DNSTY AND# 0,1,SNR ; HIGH DENSITY? JMP .IPUSE ; DENSITY = LO, GOTCHA! NOCK: LDA 1,RDYMK AND# 0,1,SZR ; UNIT READY OR REWINDING? JMP RDYTS ; YES, TEST FOR READY ISZ GFLG,3 ; NO, WAS IT BEFORE ? JMP .IPUSE ; NO, THAT'S A GOTCHA ! RDYTS: ADC 1,1 ; -1 STA 1,GFLG,3 ; TO FLAG WORD MOVR# 0,0,SNC ; YES, IS IT READY ? JMP STATS ; NeO, WAIT FOR IT LDA 2,BQDCB,2 ; GET DCB ADDRESS LDA 1,WPERR ; YES, GET WRITE PROTECT MASK AND# 0,1,SZR ; IS UNIT WRITE PROTECTED ? ISZ UDBAT,2 ; YES, SET THE BIT LDA 1,C100 ; NINE TRACK STATUS BIT AND# 1,0,SZR ; IS IT JMP NINET ; NINE TRACK - S KIP GARBAGE LDA 1,DCBST,2 ; DCB STATUS LDA 0,.ST7T ; SEVEN TRACK FLAG ADD 0,1 ; SET IT STA 1,DCBST,2 ; RESTORE STATUS NINET: LDA 3,DCBDR,2 ; GET DEVICE DCB LDA 1,DCBST,3 ; CHECK STATUSFOR PREVIOUS OPEN LDA 0,OMSK LDA 3,CSP LDA 2,DCBUF,2 ; GET BUFFER ADDRESS BACK AND# 1,0,SZR ; OPEN ? JMP OER ; ALREADY OPENED LDA 1,TMP,3 ; REQUESTED FILE # MOV# 1,1,SZR ; WANT FILE # 0 ? JMP NOT0 ; NO LDA 0,TYP,3 ;PICK UP MODE WORD COM# 0,0,SNR ;SKIP IF OPENING JMP NOT0 ; APPENDING IGNORE STA 1,@POS,3 ; YES, SET POSITION TO ZERO JSR @.REWND ; JUST REWIND JMP SUCES ; POSITIONED!! REPOS: SUB 0,0 ; SET POSITION TO 0 STA 0,@POS,3 JSR @.REWND ; AND GO REWIND NOT0: LDA 0,@POS,3 ;PICK UP CURRENT POSITION COM# 0,0,SNR ; POSITION LOST ? JMP REPOS ; YES- GO REWIND SUB 0,1,SZR ; FORM POSITION COUNT JMP DIREC ; DETERMINE DIRECTION TO MOVE LDA 0,TYP,3 ;AC0 <- FILE OPEN TYPE COM# 0,0,SZR ;CORRECT FILE, SKIP IF APPENDING JMP OPPOS ; OPENING-- POSITION BACK JMP APPOS ; APPENDING-- POS2ITION FORWARD DIREC: STA 1,TMP,3 ;SAVE REQUENSTED POSITION MOVL# 1,1,SNC ;TEST DIRECTION JMP MVFWD ; GO FORWARD DLOOP: JSR @.SBFIL ; SPACE BACKWARD & DECREMENT POS AND 0,1,SZR DSZ @POS,3 ;UPDATE POSITION JMP .+1 JSR EFCHK ISZ TMP,3 ;SKIP IF ARRIVED JMP DLOOP ; NOPE--LOOP LDA 0,TYP,3 ;TEST OPEN TYPE COM# 0,0,SNR ; YES, APPENDING? JMP SUCES ; YES, ALL DONE OPPOS: JSR @.SBFIL ;SPACE BACKWARD ONE FILE JSR EFCHK JSR @.SFRCD ; SPACE FORWARD OVER EOF JMP THERE MVFWD: JSR @.SBRCD ;SPACE BACKWARD ONE RECORD AND# 1,0,SNR JMP FSTART ; NOPE-- SKIP EOT LOGICAL CHECK JSR @.SFRCD ;ALWAYS EOF EXIST HERE JSR EFCHK FLOOP: JSR @.SFRCD ;NO, SPACE FORWARD ONE RECORD AND 1,0,SZR JMP FILDE ; EOF, FILE DOSN'T EXIST FSTART: JSR @.SFFIL h ;SPACE FORWARD AND INC AND 0,1,SZR ISZ @POS,3 ;BUMP POSITION JSR EFCHK DSZ TMP,3 ;SKIP IF ARRIVED JMP FLOOP LDA 0,TYP,3 ; COM# 0,0,SZR ;APPENDING? JMP SUCES ; NO-- ALL DONE APPOS: JSR @.SFFIL ; YES- SPACE FORWARD ONE FILE JSR EFCHK JSR"Q @.SBRCD ; THEN BACK OVER EOF THERE: JSR EFCHK SUCES: LDA 2,BQDCB,2 LDA 2,DCBDR,2 ;DEVICE DCB LDA 1,DCBST,2 LDA 0,MASKIT AND 0,1 ; ? LDA 0,OMSK ADD 0,1 ;SET OPEN BIT STA 1,DCBST,2 ISZ ORTN,3 LDA 0,TYP,3 ;MAGIC WORD TIME AGAIN NEGL# 0,0,SNC  z;DIRECT I/O? RTRN ;NO LDA 2,OAC2,3 ;UFT LDA 2,UFBUF,2 ;BUFFER TO RELEASE JSR@ .RLDB ;YES - RELEASE THE BUFFER LDA 2,OAC2,3 ;UFT ADDRESS ADC 0,0 ; -1 STA 0,@POS,3 ; DESTROY POSITION IN CASE MTDIO ; MOVES OVER FILE MARK-- ; FORCE REWIND NEXT OPEN. STA 0,UFBUF,2 ;TO BUFFER ADDRESS IN DCB LDA 0,UFTST,2 ;STATUS LDA 1,RWDS ;DIRECT I/O STATUS BIT ADD 1,0 ;SET IT STA 0,UFTST,2 ;AND CHANGE STATUS RTRN .ABCHK: JMP ABCHK ; GO CHECK FOR ABORT MASKIT: -1-STEOT-STOPN WPERR: WP .IPUSE: JMP IPUSE ; REPORT UNIT IMPROPERLY SELECTED .REWND: REWND .ST7T: ST7T .GSTAT: GSTAT C100: 1B9 .EF: EF OMSK: STOPN DNSTY: DN RDYMK: RW+UR CTSAB: TSAB QUICK: 0 ; EFCHK- ; MAKE SURE END OF FILE WAS HIT, AND TASK NOT ABORTED BY ^A ; AC0 = DEVICE STATUS - DESTROYED j; AC1 = EOF BIT - DESTROYED ; AC2 = BUFFER - SAVED ; AC3 WILL BE RETURNED = CSP EFCHK: AND# 0,1,SNR ; EOF ? JMP KILL ; NO- ERROR ABCHK: ; ENTRY TO CHECK ABORT ONLY STA 3,QUICK LDA 3,CQ LDA 1,QSTAT,3 ; CHECK OUR TASK'S STATUS LDA 3,CSP LDA 0,CTSFbAB AND# 0,1,SNR ; SKIP IF ABORT JMP @QUICK ; NO- NORMAL RETURN KILL: JSR @.RLDB ; RELEASE BUFFER JSR @.RETER ; ERROR- FILE POSITION ERSCP IPUSE: JSR@ .RLDB ; FIRST, RELEASE THE BUFFER JSR@ .RETER ERSEL RWDS: STRWD ;DIRECT I/O BIT IN DCB STATUS .SFFIL: SFFIL .SBFIL: SBFIL .SBRCD: SBRCD .SFRCD: SFRCD .RLDB: RELDB .ET: ET FILDE: JSR @.SBRCD ; INSURE CORRECT POSITION JSR EFCHK JSR @.RLDB ;RELEASE THE BUFFER JSR @.RETER ERDLE OER: JSR @.RLDB ; RELEASE BUFFER JSR @.RETER ; ERROR RETURN %ERDOP .RETER: RETER ENDOV .END TUON.SRB ST RTITLE TUON .IFN BSW!MBSW .LDB= LDB 1,0 ;BYTE INSTRUCTIONS .STB= STB 1,0 .ENDC NOB .EXTN LDBT,STBT .MACRO .LDB ;PRETEND WE HAVE THEM JSR @.LDBT % .MACRO .STB JSR @.STBT % [NOB] .ENT TUON ;TURN TUNING ON .EXTN TOON ;THE TUNER, LIVES IN TUVNOV .EXTD .TCRSEG,.VBF0,.VBF1 ;DISPLACEMENTS IN .EXTD .TUFP,.TUF1,.TUFDSP ; THE TOONER .EXTN TUSW ;RESIDENT SWITCH (IN TABLE) .EXTN TUNING ;TUNING ENABLE SWITCH FROM SYSGEN .EXTN TUVSW ;OVERLAY SWITCH FROM SYSGEN .EXTN MAKE,SRUFD,OVLAY,MDCB,OSNAM,OVBAS,OVBA1 .EXTN BLKIN,SETMOD,RELB,RLMPB,RELPB .EXTN MVBYT,FNDCB,TSTEQ,RETER .NREL .TXTM 1 Z=. TRET=TMP XFLAG=TRET ;EXISTED/CREATED FLAG OSZ=XFLAG+1 ;SIZE OF TUNE FILE TUNR=OSZ+1 ;BUFFER ADDRESS OF TUNOV TAD=TUNR+1 ;ADDRESS OF TUNE FILE TAD1=%TAD+1 SVUFP=TAD1+1 ;ADDRESS OF TUNE FILE DIRECTORY ENTRY SVUF1=SVUFP+1 SVUFDSP=SVUF1+1 ;****************************************** ; NUMBER OF STACK TEMPORARIES USED ; MUST BE THE FIRST WORD OF THE OVERLAY .IFN BSW!MBSW 10 .ENDC ;ROUTINE TO MOVEG A FILENAME ;AC0 POINTS TO NAME ;AC1 BYTE POINTER TELLS WHERE TO PUT IT, AND IS RETURNED ; POINTING JUST PAST THE MOVED NAME MVNAM: LDA 2,CSP STA 3,TRET,2 ;SAVE RETURN LDA 2,FNLB ;MAX FILENAME LENGTH JSR @.MVBYT ADD 2,1 ;POINT TO THE END MV1: SUBZLW 2,2 SUB 2,1 ;BACK UP ONE .LDB MOV 0,0,SNR ;IS BYTE NULL? JMP MV1 ;YES, BACK ANOTHER INC 1,1 ;NO - MOVE PAST IT JMP @TRET,3 ;& RETURN NOTUNING: JSR @.RETER ERICM .RETER: RETER .OSNAM: OSNAM .NAMD: NAME-Z .SFLNA: SFLNA FNL=2*(UFTEX-UFTFN) FN%LB: FNL COLON: ": C4: 4 .DTU: DTU-Z DTU: .TXT /.TU/ .MVBYT: MVBYT CONT: ATCON .IFE BSW!MBSW .LDBT: LDBT .STBT: STBT .ENDC .OVLAY: OVLAY .TSTEQ: TSTEQ .RLMPB: RLMPB TOP: ATMSK .OVBAS: OVBAS .OVB1: OVBA1 .MDCB: MDCB .FNDCB: FNDCB .TUNING:TUNING ;TUNING ENABLE SWITCH FROM SYSGEN: ; 0 = NO, 1 = YES OVSW: TUVSW ;FROM SYSGEN: -1 NO OVERLAY COUNTS, -3 YES ; ;TUNING TURN ON (FROM SYSTEM CALL .TUON) ; TUON: LDA 0,.TUNING ;TUNING ENABLE SWITCH COM# 0,0,SNR ;ALLOW TUNING TODAY? JMP NOTUNING ;NOT FOR YOU, B SAM LDA 0,@.TUSW ;RESIDENT SWITCH COM# 0,0,SZR ;TUNING ALREADY ON? JMP JGDRET ;YES, CALL IS NOP LDA 0,@CRSEG ;FIND OURSELVES LDA 1,.NAMD ;FIND NAME AREA ADDZL 0,1 LDA 0,@.MDCB LDA 2,.SFLNA ;NEGATIVE DISPLACEMENT ADDOL 2,0 ;FIND MASTER DIRECT&ORY NAME JSR MVNAM ;GET A COPY FOR OURSELVES LDA 0,COLON .STB ;TQACK ON A COLON INC 1,1 LDA 0,.OSNAM MOVZL 0,0 ;SYSTEM NAME BYTE POINTER JSR MVNAM ;TACK ON SYS NAME, TOO LDA 0,.DTU LDA 2,@CRSEG ADDZL 2,0 ;BYTE POINTER TO DTU LDA 2,C4 JSR 0 @.MVBYT ;TACK ON '.TU', NULL LDA 0,@CRSEG LDA 1,.NAMD ADDZL 1,0 ;BYTE POINTER TO TUNE FILE NAME LDA 1,OVSW ;-3=OVERLAY COUNTS, -1=NO NEG 1,1 ;FILE IS 3 OR 1 BLOCKS LONG LDA 2,CONT ;CONTIGUOUS JSR @.OVLAY ;CREATE A TUNING FILE MAKE SUB 1,1,SKP ;ERROR, SET EXIST FLAG JMP CREATE ;NO ERROR JSR @.TSTEQ ;INSPECT THE ERROR  ERCRE ;FILE EXISTS? RTRN ;OH NO CREATE: STA 1,XFLAG,3 ;SAVE FLAG: 0=EXISTED, LDA 2,CQ ; NONZERO=CREATED LDA 0,QSUFP,2 ;POINT TO UFT BUILT BY MAKE LDA 2,@.MDCB JS-dR @.OVLAY ;FIND THE DIRECTORY ENTRY SRUFD JMP . ;NOT THERE WHEN WE JUST CREATED IT??! MOV 1,0 SUB 2,0 ;DISPLACEMENT TO DIRECTORY ENTRY STA 0,SVUFDSP,3 ;SAVE LDA 0,BQCA,2 ;ADDRESS OF DIRECTORY ENTRY STA 0,SVUFP,3 ;SAVE, SAVE LDA 0,BQCA1,2 STA 0,SVUF1,3 MOV 1,3 ;INDEX ON ENTRY ISZ UFTUC,3 ;SHOW AS IN USE LDA 0,UFTBK,3 ;NUMBER OF BLOCKS LDA 3,CSP ;REMEMBER THAT (EXISTING FILE STA 0,OSZ,3 ; MAY NOT HAVE OVERLAY COUNTS) MOV 1,3 ;FIND ENTRY AGAIN LDA 0,UFTDL,3 LDA 1,UFTAD,3 ;FILE'S ADDRESS JSR @.RLMPB ;NOW RELEASE ENTRY BLOCK LDA 2,TOP ANDS 2,0 STA 0,TAD1,3 ;REMEMBER THAT, TOO STA 1,TAD,3 LDA 2,XFLAG,3 ;SEE IF FILE WAS CREATED MOV# 2,2,SNR JMP ALREADY ;NO - IT WAS ALREADY THERE ZZZ: LDA 3,.TOON ;OVERLAY ADDRESS OF TUNOV LDA 1,O~VMSK ANDZL 1,3 MOVS 3,3 ;OVERLAY NUMBER OF TUNOV LDA 1,@.OVBAS ;ADDRESS OF OVERLAY FILE LDA 0,@.OVB1 ADDZ 3,1,SZC ;WOULD YOU BELIEVE ADD INC 0,0 ; THE TWO TOGETHER? LDA 2,@CQ ;GRAB A DCB STA 0,DBFA1,2 STA 1,DCBFA,2 LDA 1,@.MDCB JSR @.FNDCB JSR @.BLKIN ;READ IN THE TUNER RTRN STA 0,TUNR,3 ;REMEMBER WHERE HE IS MOV 0,2 LDA 0,BQST,2 LDA 1,MKSETUP ;MUST INVALIDATE CURRENT ADDRESS AND 1,0 STA 0,BQST,2 LDA 0,TAD1,3 ;TUNE FILE ADDRESS, REMEMBER? LDA 1,TAD,3 STA 0,BQCA1,2 ;SWAP ADDRESS - TUNOV IS NOW THE STA 1,BQCA,2 ; TUNE FILE'S 1ST BLOCK (ASSUME ; THE OTHER SIDE NEVER TRIES TO ; WRITE IN THIS BLOCK; THUS NO ; DUAL PROCESSOR LOCK IS NEEDED) ALREADY:LDA 2,@CQ ;GRAB A DCB STA 0,DBFA1,2 ;TUNING FILE ADDRESS STA 1,DCBFA,2 LDA 1,@.MDCB JSR @.FNDCB LDA 0,XFLAG,3 ;DID FILE ALREADY EXIST? MOV# 0,0,SZR JMP GOTTU ;NO - ALREADY HAVE FIRST BLOCK JSR @.BLKIN ;YES, DRAG IN FIRST BLOCK RTRN STA 0,TUNR,3 ;THIS IS WERE THE TUNER IS MOV 0,2 ;TAKE A PEEK LDA 0,.VBF0,2 ;SHOULD BE -1 WHEN TUNING OFF COM# 0,0,SNR ;WELL? JMP GOTTU ;THAT'LL DO JSR @.RELPB ;NO - NOT A VALID TUNE FILE STA 2,XFLAG,3 ;PRETEND IT DOESN'T EXIST JMP ZZZ ;(MAYBE HE CRASHED WHILE ; TURNING TUNING ON, OR IT'S A ; TUNE FILE OF DIFFERENT REV) JGDRET: JMP GDRET .TUSW: TUSW GOTTU: LDA 2,TUNR,3 LDA 0,SVUFP,3 ;BLOCK ADDRESS OF TUNE FILE'S LDA 1,SVUF1,3 ; DIRECTORY ENTRY STA 0,.TUFP,2 ;SAVE IN TOONER FOR TUOFF STA 1,.TUF1,2 LDA 0,SVUFDSP,3 ;DISPLACEMENT TO DIRECTORY ENTRY STA 0,.TUFDS,2 STA 2,.TCRSEG,2 ;LET TOONER KNOW WHERE HE IS JSR @.SETMOD ;MY, HOW YOU'VE CHANGED ;GOT TUNE FILE 1ST BLOCK - NOW SEE ABOUT THE OTHERS LDA 2,OVSW COM# 2,2,SNR ;SEPARATE OVERLAY COUNTS? JMP ONDONE ;NO LDA 2,OSZ,3 ;DOES THE FILE HAVE MOV# 2,2,SNR ;THE EmXTRA BLOCKS? JMP ONDONE ;NO LDA 2,@CQ ;RECOVER DCB ISZ DCBCA,2 ;FIND NEXT BLOCK JMP .+2 ISZ DBCA1,2 JSR @.BLKIN ;READ NEXT BLOCK = 1ST OVLAY BLK JMP ERRT ;UH OH, MUST RELEASE TUNER LDA 3,TUNR,3 STA 0,.VBF0,3 ISZ DCBCA,2 ;AND THE NEXT (2ND) D JMP .+2 ISZ DBCA1,2 JSR @.BLKIN JMP ERRV ;SPECIAL ERROR-MUST RELEASE VBF0 LDA 2,TUNR,3 STA 0,.VBF1,2 ONDONE: LDA 0,.TOON ;TOONER'S OVERLAY ADDRESS LDA 1,DISPL AND 1,0 ;GET THE DISPLACEMENT LDA 1,TUNR,3 ADD 1,0 ;MAKE TOONER'S ABSOLUTE ADDRESS : STA 0,@.TUSW ;STORE TUNER'S ADDRESS, AND GDRET: ISZ ORTN,3 ; TURN TUNING ON RTRN ERRV: LDA 2,TUNR,3 LDA 2,.VBF0,2 JSR @.RELB ERRT: LDA 2,TUNR,3 JSR @.RELB RTRN MKSETUP:-QTDSU-1 .BLKIN: BLKIN .RELB: RELB .SETMOD:SETMOD .RELPB: RELPB .TOON: TOON OV{6MSK: 77600 DISPL: 177 NAME: .BLK (FNL+1+FNL+1+2+1+1)/2 ;SPACE FOR 'MASTERDEVICE:SYSNAME.TU' LASTWORD=. ENDOV .END CDROV.SRB 6( RTITLE CDROV .NREL .ENT CDRRL .EXTN RETER .EXTN DRCHR,OVLAY .IFE BSW .EXTN MSTBT .ENDC ;************************************************ ; ; NUMBER OF STACK TEMPS IS FIRST WORD IN OVERLAY. .IFN BSW!MBSW NTMPS .ENDC ; ; CARD READER READ ASCzDII LINE ; INPUT: AC2 - UFT ADDRESS ; AC0 - DESTINATION BYTE POINTER ; OUTPU: AC1 - BYTE COUNT READ ; AC2 - ERROR CODE IF EOF OR OTHER ABNORMAL RETURN ; STACK TEMPS USAGE LNPTR=TMP ;OUTPUT BYTE POINTER SDCT=LNPTR+1 ;SAVE DCT ADDRESS BPTMP=SDCT+1 w;TMP TO SAVE BYTE POINTER NTMPS=BPTMP-TMP+1 ;TOTAL TMPS USED ON STACK CDRRL: MOV 0,1 ;BYTE POINTER TO AC1 STA 1,LNPTR,3 ;SAVE ON STACK DSZ LNPTR,3 ;DECREMENT IN CASE OF BLANK CARD LDA 2,UFTDC,2 ;DCT ADDRESS STA 2,SDCT,3 ;SAVE ON STACK FOR QUICK RuEFERENCE INTDS ; QUIET PLEASE LDA 0,DCTQS,2 ; QUEUE STATUS LDA 2,.BSRDL ; ADD READ LINE STATUS TO BEAD AND# 2,0,SNR ; IF NOT ALREADY THERE ADD 2,0 LDA 2,SDCT,3 STA 0,DCTQS,2 INTEN RDLP: LDA 2,SDCT,3 ;DCT ADDRESS JSR @.OVLAY ;READ A COLUMN DRPCHR ;READ TWO BYTES JMP CTLA ;TIMEOUT OR ABORT MOVL# 0,0,SZC ;EOC ? JMP DONE ;YES - PROCESS END OF CARD MOV# 0,0,SZR ;BLANK ? STA 1,LNPTR,3 ;NO - UPDATE LAST NONBLANK BYTE LDA 2,EOFCD ;SEE IF EOF SUB# 0,2,SNR ;IS IT ? JMP EOFFD ;YES - PROC ESS EOF JMP CDRTR ;NOW GO TRANSLATE TO ASCII EOFFD: LDA 0,OAC0,3 ; COL 1 ? SUB# 1,0,SZR ; WELL ? JMP CDRTR ; NO TRANSLATE AND CONTINUE LDA 2,SDCT,3 ;RELOAD DCT ADDRESS EOFC1: JSR @.OVLAY ;EOF FOUND - READ TO EOC DRCHR JMP RMEOF ;SCRAM MOVL# m0,0,SNC ;IS IT ? JMP EOFC1 ;NO - KEEP TRYING RMEOF: LDA 0,DCTQS,2 ; REMOVE END OF FILE STATUS FOR LDA 1,.BSEOF ; NEXT TIME AROUND .IFE BSW!MBSW COM 1,1 AND 1,0 .ENDC J ANC 1,0 [J] STA 0,DCTQS,2 ; RESTORE STATUS CTLA: SUB 0,0 STA 0,OAC1,3 ;RETUfXRN BYTE COUNT OF 0 FOR EOF JSR @.RETER ; TAKE ERROR RETURN EREOF .BSRDL: BSRDL .BSEOF: BSEOF .RETER: RETER DONE: ISZ ORTN,3 ;BUMP RETURN ADDRESS ISZ LNPTR,3 ; BUMP FOR INSERT OF CR LDA 2,OAC2,3 ; UFT ADDRESS LDA 2,UFTCH,2 ; CHARACTERISTICS LDA 0,.DCSTB AND# 2,0,SZR ; SUPPRESS TRAILING BLANKS ? LDA 1,LNPTR,3 ; NO USE CURRENT BYTE POINTER DONE1: LDA 0,OAC0,3 ;INPUT BUTE POINTER ADC 1,0 ;SUBTRACT WITH ADDITION OF CR NEG 0,0 ;MAKE POSITITVE STA 0,OAC1,3 ;RETURN COUNT TO AC1 LDA 2,CD73 ;7"d3 COUNT SUBZ# 0,2,SZC ; MORE THAN 73 CHARS ? JMP BYPS ; NO BYPASS COL 73 TEST LDA 2,OAC2,3 ;UFT ADDRESS LDA 2,UFTCH,2 ;DEVICE CHARS LDA 0,LGTTS ;CHAR INHIBIT MASK AND# 0,2,SZR ;TEST ? JMP BYPS ;NOT SET - SKIP IT LDA 1,CD72 ; SET COUNT TO 73  LDA 0,OAC0,3 ; BY SETTING POINTER APPRP ADD 0,1 JMP DONE1 ; PRETEND WE HAD 72 COLS ONLY BYPS: LDA 0,CR ;FINAL CR .IFE BSW JSR @.MSTBT .ENDC .IFN BSW STB 1,0 .ENDC RTRN .IFE BSW TRTN: JSR @.MSTBT ;STUFF BYTE INTO USER SPACE .ENDC J TRTN: STBk 1,0 [J] INC 1,1 ;BUMP BYTE POINTER JMP RDLP ;GO FOR NEXT COLUMN CD73: 73. ;SIZE OF SMALL CARD CD72: 72. .OVLAY: OVLAY LGTTS: DCC80 .DCSTB: DCSTB CR: 15 ;YOU KNOW WHAT EOFCD: 7777 ;CARD EOF IS ALL HOLES .IFE BSW .MSTBT: MSTBT .ENDC ; ; ASCII CARD CODE TO 7 BIT ASCII CONVERTER ; ; INPUT: ; AC0: 12,11,0,1,2,3,4,5,6,7,8,9 (CARD COLUMN) ; ;OUTPUT: ; AC0: ASCII CODE ; ; X= 12,11,0,8,9 ; Y= 1,2,3,4,5,6,7 ; CDRTR: STA 1,BPTMP,3 ; SAVE INPUT AC1 LDA 1,C7003 ;MASK FOR X AND 0,1 ;X SPLIT BY 7 8BITS SUBOR 1,0 ;AC0: Y*2  LDA 2,C7000 ;MASK FOR 12,11,0 AND 1,2 ;(12,11,0)*512 SUB 2,1 ;(8,9) MOVS 2,2 ;(12,11,0)*2 MOVZL 2,2 ;(12,11,0)*4 ADDL 2,1 ;X*2 ADDZL 1,1 ;X*8 LDA 2,.TABP ;START OF TABLE LDA 3,@CRSEG ADDZL 3,2 ADD 2,1 ;TABLE INDEX TO EIGHT CHARACTERS MOVS 0,0,SNR ;IS Y NULL ? JMP NULL ;YESS INC 1,1 ;CONVERT Y TO BINARY MOVZL 0,0,SNC ;SHIFT LOOKING FOR A ONE JMP .-2 ;KEEP GOING MOV# 0,0,SNR ;DONE - ANY MORE ONES ? JMP NULL LDA 1,.ILLGP ;YES - CONVERT TO ILLEGAL ADDZL 3,1 NULL: LDA 0,C377 ;BYTE MASK MOVZR 1,2,SNC ;STANDART LOAD BYTE MOVS 0,0 LDA 1,0,2 AND 0,1,SNC MOVS 1,1 MOV 1,0 LDA 3,CSP LDA 1,BPTMP,3 ; RESTORE AC1 JMP TRTN ; RETURN C377: 377 C7003: 7003 C7000: 7000 .MACRO MUD ** I=1 ** J=2 ** .DO ".ARGC/2 ^I*400+^J ** I=I+2 ** J=J+2 ** .ENDC % .ILLGP: ILLGP .TABP: .+1 MUD 40 "1 "2 "3 "4 "5 "6 "7 MUD "9 "\ 26 "\ "\ "\ "\ 4 MUD "8 140 ": "# "@ 47 "= "" ILLGP: MUD "\ "\ "\ "\ 24 25 "\ 32 MUD "0 "/ "S "T "U "V "W "X MUD "Z "\ "\ "\ "\ 12 27 33  MUD "Y "\ 134 54 "% 137 "> "? MUD "\ "\ "\ "\ "\ 5 6 7 MUD "- "J "K "L "M "N "O "P MUD "R 21 22 23 "\ 10 "\ "\ MUD "Q "\ "] "$ "* ") "_; "^ MUD 30 31 "\ "\ 34 35 36 37 MUD 175 176 "S+40 "T+40 "U+40 "V+40 "W+40 "X+40 MUD "Z+40 "\ "\ "\ "\ "\ "\ "\ MUD "Y+40 "\ "\ "\ "\ "\ "\ "\ MUD "\ "\ "\ "\ "\ "\ "\ "\ MUD "& "A "B "C "D "E "F "G MUD "I 1 2 3 "\ 11 "\ 177 MUD "H "\ "[ ". "< "( "+ "! MUD "\ "\ "\ 13 14 15 16 17 MUD 173 "A+40 "B+40 "C+40 "D+40 "E+40 "F+40 "G+40 MUD "I+40 "\ "\ "\ "\ "\ "\ "\Z MUD "H+40 "\ "\ "\ "\ "\ "\ "\ MUD "\ 0 "\ "\ "\ "\ "\ "\ MUD 174 "J+40 "K+40 "L+40 "M+40 "N+40 "O+40 "P+40 MUD "R+40 "\ "\ "\ "\ "\ "\ "\ MUD "Q+40 "\ "\ "\ "\ "\ "\ "\ MUD "\ 20 "\ "\ "\ "\ "\ "\ MUD "\ "\ "\ "\ "\ "\ "\ "\ MUD "\ "\ "\ "\ "\ "\QF "\ "\ MUD "\ "\ "\ "\ "\ "\ "\ "\ MUD "\ "\ "\ "\ "\ "\ "\ "\ ENDOV .END WDBLK.SRB * RTITLE WDBLK .ENT WDBLK ;ALLOCATE A FREE DISK BLOCK .ENT CRINI ;SYSTEM CREATE ENTRY .ENT CRINL ;CRINI WITH LOCK .ENT FCRET ;CONTINUATION OF OTHER CREATES .EXTN SRUFE .EXTN RELB,RELMB .EXTN OVLAY .EXTN BLKIN .EXTN PEND .EXTN UNPEND .EXTN SPO=OL .EXTN RETE2,RETER .EXTN TSTEQ .EXTN MDCB .EXTN FNDCB .EXTN MVWD .EXTN FLUSH .EXTN DUNLOCK ;DUAL PROCESSOR UNLOCK .EXTN IPBQ .EXTN TODD,TODH,TODS,DIVI .IFE BSW!MBSW .EXTN MPY .ENDC .NREL ;***************************************** ; NUMB,ER OF STACK TEMPORARIES USED ; MUST BE THE FIRST WORD IN THE OVERLAY .IFN BSW!MBSW 10 .ENDC ; CRINI ENTRY POINT IS USED BY THE SYSTEM TO ADD ; PRE-DEFINED ENTRIES TO THE DIRECTORY ; ; INPUTS: AC1 - WORD ADDRESS OF UFD, SIGN BIT SET MEANS ; PUT CURbRENT TIME IN IT ; AC2 - DCB ADDRESS OF RECEIVING SYS.DR ; ; OUTPUTS: AC0 - UNLOCK KEY (CRINL ONLY) ; ; RETURNS: CALL+1 - ENTRY ALREADY EXISTS ; CALL+2 - SUCCESSFUL RETURN ; BLKCT= TMP ;NOTE - THESE TEMP DEFINITIONS BLKAD= BLKCT+1 ; MUST MATCH THE DEFINITIONS FTAC= BLKCT+1 ; IN THE CREATE OVERLAY SBAD= FTAC+1 FTYD= FTAC+1 DULKY= FTYD+1 ; LOCK KEY FROM SRUFE FTHM= FTYD+1 TPSUF= FTHM+1 TPDCB= TPSUF+1 ATRBS= TPDCB+1 BLKA1= ATRBS+1 ESW= ATRBS MXECT= BLKAD CRINL: SUB 0,0,SKP ;LEAVE DIRECTORY BL=OCK LOCKED CRINI: SUBZL 0,0 ;UNLOCK BEFORE RETURN STA 0,ESW,3 MOVL 1,0 MOVZR 0,0 ;CLEAR SIGN BIT STA 0,TPSUF,3 ; SAVE INPUTTED UFD POINTER STA 2,TPDCB,3 ; & INPUTTED DCB ADDRESS MOVL# 1,1,SNC ;WANTS CREATION DATE? JMP NOTIM ;NO MOV 0,2 LDA 0,@C.TODD ;TIME OF DAY - DAYS STA 0,UFTAC,2 ; IS TIME LAST ACCESSED STA 0,UFTYD,2 ; & TIME CREATED LDA 1,@.TODS ;TIME OF DAY SECONDS LDA 2,C60 ;SECONDS/MINUTE JSR @.IDIV ;FIND MINUTES THIS HOUR LDA 0,@.TODH ;HOURS THIS DAY MOVS 0,0 ;TO LEFT BYTE ADDM 1,0 ;MINUTES IN RIGHT BYTE LDA 2,TPSUF,3 ;UFT ADDRESS STA 0,UFTHM,2 MOV 2,0 LDA 2,TPDCB,3 NOTIM: JSR @.OVLAY SRUFE ; SEARCH FOR THIS ENTRY JMP CRIER ; TEST THE ERROR JSR @.RELB ; FOUND, RELEASE THE BUFFER JSR @.RETER ;RETURN ALREADY EXIST ERROR ERCRE CRIER: STA 2,DULKY,3 ; SAVE LOCK KEY JSR @.TSTEQ ;FILE NOT EXIST? ERDLE RTRN ; NO SOMETHING ELSE JMP FCRT2 ;YES, JUMP IN COMMON CODE ; THIS CODE IS TO FINISH A CREATE CALL ; INITIATED IN THE CREATE OVERLAY FCRET: SUBZL 0,0 ;MUST ALWANYS UNLOCK STA 0,ESW,3 ;REMEMBER THAT LDA 1,BLKAD,3 ; GET DEVICE ADDRESS LDA 0,BLKA1,3 ; DEVICE ADDRESS HIGH ORDER FCRT2: LDA 2,@CQ ; QUEUE DCB STA 0,DBFA1,2 ; SET FIRST ADDRESS STA 1,DCBFA,2 ; LOW ORDER LDA 1,TPDCB,3 ; DCB ADDRESS JSR @.FNDCB ; FULL INIT THE DCB JSR @.BLKIN ; GET THE ENTRY BLOCK JMP CERTN ; ERROR MOV 0,2 ; INDEX ON THE BUFFER STA 0,SBAD,3 ; SAVE ADDRESS TOO ISZ 0,2 ; ONE MORE ENTRY LDA 1,HECOS ; HIGHEST ENTRY COUNT OFFSET ADD 1,2 ; HIGHEST ENTRY COUNT ADDRESS LDA 1,0JO,2 ; HIGHEST ENTRY COUNT LDA 0,@SBAD,3 ; CURRENT ENTRY COUNT SUBZ# 0,1,SNC ; NEW HIGHEST ? STA 0,0,2 ; YES LDA 2,SBAD,3 ; RECOVER BUFFER ADDRESS LDA 0,MAXCT ; MAX ENTRY COUNT STA 0,MXECT,3 ; SAVE IN THE STACK LDA 1,ENTLG ; ENTRY LENGTH INC 2,25,SKP ; POINT TO FIRST ENTRY VACLP: ADD 1,2 ; MOVE TO NEXT NETRY LDA 0,UFTFN,2 ; FIRST WORD OF ENTRY MOV# 0,0,SNR ; VACANT ENTRY ? JMP VACNT ; YES DSZ MXECT,3 ; NO, TRIED ALL POSSIBILITIES ? JMP VACLP ; NO, KEEP LOOKING JSR @.PNIC ; YES, SOMEBODY RAPED PNSDE ; MY SYS.DR !!! VACNT: LDA 0,TPSUF,3 ; QUEUE UFT IS 'FROM' MOV 2,1 ; ENTRY ADDRESS IS 'TO' LDA 2,ENTLG ; WORD COUNT IN AC2 JSR @.MVWD ; MOVE THE ENTRY TO THE BUFFER LDA 2,SBAD,3 ;GET THE BUFFER ADDRESS JSR @.RELMB ;RELEASE MODIC+FIED JSR @.FLUSH ISZ ORTN,3 ; GOOD RETURN DSZ ESW,3 ;LOCK/UNLOCK SWITCH: UNLOCK? JMP LVLKD ;NO - LEAVE LOCKED CERTN: LDA 0,DULKY,3 ;PICK UP UNLOCK KEY COM# 0,0,SZR ;ANYTHING THERE? JSR @.DUNLOCK ;YES, DO IT RTRN LVLKD: LDA 0,DULKY,3 ;LOCK KEY i STA 0,OAC0,3 ;RETURN IT TO CALLER RTRN ;RETURN TO CALLER .TODD: TODD .TODH: TODH .TODS: TODS .IDIV: DIVI C60: 60. .OVLAY: OVLAY ENTLG: UFDEL .FLUSH: FLUSH .MVWD: MVWD HECOS: SCWPB-1 .FNDCB: FNDCB MAXCT: SCWPB-1/UFDEL .TSTEQ: TSTEQ .RETER: RETER .BLKIfN: BLKIN .DUNLOCK:DUNLOCK ; WITHDRAW ONE FREE BLOCK ; ; AC0 - FIRST BLOCK ADDRESS HIGH ORDER (RETURNED) ; AC1 - FIRST BLOCK ADDRESS LOW ORDER (RETURNED) ; AC2 - DCB ADDRESS OF FILE ; STACK DISPLACMENTS MAPX = OAC1 MAPX1 = OAC0 CA = TMP MAPDC = CA+1 WRDCT = MAPDC+1 MSKTM = WRDCT+1 WDBLK: LDA 2,DCBDR,2 ; THIS FILE'S SYS.DR DCB LDA 2,SFLK,2 ; SYSTEM FILE LINK STA 2,MAPDC,3 ; SAVE MAP DCB ADDRESS LCKLP: MOV 2,1 ; MAP DCB IS PEND KEY INTDS ;KEEP IVT INTERRUPTS OUT IN CASE ;THIS IS A D-UAL PROCESSOR SYSTEM LDA 0,MPLCK,2 ; MAP LOCK WORD MOV 0,0,SNR ; IS MAP LOCKED? JMP LCKOK ; NO, LOCK OK LDA 0,LKTIM ;FINITE WAIT IN CASE OTHER SIDE ;GOES DOWN & IVT UNLOCKS JSR @.PEND ; YES, PEND, WAITING FOR ; UNLOCKED MAP JMP LCKLP ; T(IMEOUT - TEST STATE OF MAP JMP LCKLP ; UNPENDED - TEST STATE OF MAP LCKOK: ADC 0,0 STA 0,MPLCK,2 ; LOCK THE MAP INTEN LDA 0,DCBCB,2 ; GET CURRENT BLOCK NUMBER STA 0,DCBLA,2 ; SET INTO LAST FOR EOF CHECK JMP START SPERR: LDA 1,SPCER ; OUT OF SPACE ERROR LDA 0,@.SPOL ; COUNT OF SPOOLERS MOV# 0,0,SNR ; IS ANYBODY SPOOLING ? JMP ERGO ; NO, OUT OF FILE SPACE MOVZR# 0,0,SNR ; YES, MORE THAN ONE ? JMP TIMOT ; NO - DEADLOCK IS INEVITABLE LDA 0,TIMCN ; TIME OUT CONSTANT LDA 1,C2 ; PEND WAITINGd FOR FREE BLOCK INTDS JSR @.PEND ; PEND WAITING FOR A FREE BLOCK JMP TIMOT ; TIME OUT ERROR LDA 0,DCBCB,2 ; GET CURRENT BLOCK JMP START ; LOOK AT MAP AGAIN TIMOT: LDA 3,DCBDR,2 ; GET SYSDR DCB ADDRESS LDA 0,@.MDCB ; GET MASTER DEVICE DCB ADDRESS # LDA 1,SDLER ; SYSTEM DEADLOCK ERROR SUB# 0,3,SZR ; IS IT REALLY ? LDA 1,SPCER ; SPACE ERROR ERGO: SUB 0,0 STA 0,MPLCK,2 ; UNLOCK THE MAP MOV 2,0 ; MAP DCB IS UNPEND KEY JSR @.UNPEND ; WAKE UP ANY WAITERS MOV 1,2 ; ERROR CODE TO AC2 JSR @.RET2 RH ; RETURN THE ERROR .SPOL: SPOOL .PEND: PEND SPCER: ERSPC SDLER: ERSDL TIMCN: SCMER .MDCB: MDCB .RELMB: RELMB .RELB: RELB LKTIM: C2: 2 ERR1: LDA 3,CC LDA 1,CERR,3 ; GET ERROR CODE JMP ERGO ; FINISH CLEAN UP BLKLP: INC 2,2 ; BUMP POSITION ISZ MAPX,3'p ; BUMP THE ADDRESS COUNTER JMP .+1 ; IN CASE OF WRAP AROUND ON GIANT DISK DSZ WRDCT,3 ; ANY WORDS LEFT? JMP WRDLP ; YES LDA 2,CA,3 ; NO, GET BUFFER ADDRESS JSR @.RELB ; & RELEASE IT LDA 2,MAPDC,3 ; MAP DCB ADDRESS ISZ DCBCB,2 ; BUMP CURRENT2F BLOCK LDA 0,DCBCB,2 ; GET CURRENT BLOCK NUMBER LDA 1,SFBK,2 ; & LAST BLOCK NUMBER SUBZ# 0,1,SZC ; IS CURRENT <= LAST ? JMP VALBK ; YES, VALID BLOCK SUB 0,0 ; NO, BEYOND THE END STA 0,DCBCB,2 ; RESET TO BEGINNING VALBK: LDA 1,DCBLA,2 ; & LAST BLOCWKK NUMBER SUB# 0,1,SNR ; WRAPPED AROUND ? JMP SPERR ; YES, YOU'RE OUT OF SCHLITZ START: LDA 1,DCBFA,2 ; NO, GET START OF MAP LDA 3,DBFA1,2 ; HIGH ORDER ADDZ 1,0,SZC ; OVERFLOW ? INC 3,3 ; YEP STA 3,DBCA1,2 ; SET INTO DCB STA 0,DCBCA,2 JSR @.BLKIxN ; READ CURRENT BLOCK JMP ERR1 ; ERROR STA 0,CA,3 ; SAVE CORE ADDRESS LDA 0,DCBCB,2 ; GET CURRENT BLOCK # MOVS 0,1 ; CURRENT BLOCK * 400 STA 1,MAPX,3 ; INITIALIZE THE ADDRESS COUNTER LDA 1,SFBK,2 ; GET LAST BLOCK NUMBER SUB 1,0,SZR ; AT THE EN'D ? JMP NOEOF ; NO LDA 1,SFBC,2 ; GET BYTES IN LAST BLOCK MOVZR 1,1,SKP ; LAST BLOCK WORD COUNT NOEOF: LDA 1,BLKSZ ; FULL BLOCK WORD COUNT STA 1,WRDCT,3 ; INIT THE WORD COUNT LDA 2,CA,3 ; GET THE CORE ADDRESS WRDLP: LDA 0,0,2 ; GET A WORD .IFE BSW!MBSW COM# 0,0,SNR ; ANY ZEROS? .ENDC .IFN BSW!MBSW COM 0,0,SNR ; ANY FREE SECTORS .ENDC JMP BLKLP ; NO .IFE BSW!MBSW SUBZ 1,1 ; YES, FORM BIT MASK BITLP: MOVR 1,1 ; SHIFT MASK RIGHT AND# 0,1,SZR ; FREE BLOCK? JMP BITLP ; NO, TRY NEXT ONE ADD 1,0 .ENDC .IFN BSW!MBSW SUB 1,1 ; SET BIT COUNT TO ZERO LRB 0,1 ; FIND FIRST FREE SECTOR COM 0,0 ; RESTORE TO POSITIVE FORM FOR STORE .ENDC STA 0,0,2 ; ALLOCATE THE BLOCK STA 1,MSKTM,3 ; SAVE BIT MASK/COUNT LDA 2,CA,3 ; BUFFER ADDRESS  JSR @.RELMB ;RELEASE MODIFIED ISZ ORTN,3 ; GOOD RETURN NOW LDA 1,MAPX,3 ; GET BLOCK*400+WORD LDA 2,C16. ; 16. BLOCKS/WORD .IFE BSW!MBSW JSR @.MPY LDA 2,MSKTM,3 ; GET THE BIT MASK DNL: MOVZL 2,2,SNR ; SHIFT IN REVERSE TO GET BIT # JMP DONE INCZ 1,1,SZC ; ADD TO ADDRESS INC 0,0 ; HAD OVERFLOW JMP DNL .MPY: MPY .ENDC .IFN BSW!MBSW LDA 0,MSKTM,3 ; GET THE BIT COUNT IN WORD MUL ; MULTIPLY AND ADD .ENDC DONE: LDA 2,OAC2,3 ; DCB ADDRESS LDA 2,DCBDR,2 ; SYS.DR'S DCB ADDRESS LDA 2,SFLK,2 m; MAP.DR'S DCB ADDRESS LDA 3,DCBFA,2 ; FIRST ADDRESS OF MAP LDA 2,DBFA1,2 ; HIGH ORDER ADDZ 3,1,SZC ; ADD MAP ADDRESS TO RELATIVE ADDRESS INC 0,0 ; OVERFLOW ADD 2,0 ; GOT IT ALL LDA 2,MAPOS ; MAPS PARTITION ADDRESS NEG 0,0 ; PREPARE TO BORROW 0SUBZ 2,1,SNC ; FORM TRUE LOGICAL ADDRESS COM 0,0,SKP ; UNDERFLOW NEG 0,0 ; EVERYTHING OK LDA 3,CSP ; STACK POINTER STA 0,MAPX1,3 ; SAVE HIGH ORDER STA 1,MAPX,3 ; SAVE LOW ORDER LDA 3,OAC2,3 ; INPUTTED DCB LDA 3,DCBDR,3 ; POINTER TO SYS.DR DCB LDA 3,SFLK,3 ; MAP DCB SUB 0,0 STA 0,MPLCK,3 ; UNLOCK THE MAP MOV 3,0 ; MAP DCB IS UNPEND KEY JSR @.UNPEND MOV 0,2 ;INDEX ON DCB LDA 0,DCBST,2 XLDA 1,= STLKW AND# 1,0,SNR ;LOCK WAITING? RTRN SUB 1,0 ;YES, CLEAR THE BIT STA 0,DCBST,2 LDA 0,.vIPBQ ; AND WAKE IPB PROCESS JSR @.UNPEND RTRN .UNPEND: UNPEND BLKSZ: SCDBS MAPOS: SCMAP C16.: 16. .RET2: RETE2 .IPBQ: IPBQ LPOOL ENDOV .END SPOLR.SRB Z RTITLE SPOLR SPLR .ENT STSPL .ENT SPLPS .EXTN SPOOL ; SPOOL COUNT .EXTN SPOLF ; SPOOL CONTINUE FLAG .EXTN PEND ; PEND .EXTN CREL ; CELL RELEASE .EXTN DEBLK ; DEPOSIT A BLOCK .EXTN RDCBK ; READ CURRENT BLOCK .EXTN IBUF ; INPUT TO DEVICE gUBUFFER .EXTN SPOLQ ; SPOOLER QUEUE .EXTN OVLAY ; OVLAY .IFE BSW!MBSW .EXTN LDCHR ; LOAD A CHARACTER .EXTN STCHR ; STORE A CHARACTER .ENDC .EXTN MDCB .EXTN RDNBK .EXTN FIDCB ; FULL DCB INIT .EXTN GCELL ; GET A CELL .EXTN UNPEND ; UNPEND .YjEXTN GPATH,FPATH ; GET AND FREE SPOOLER PATH .EXTN SPPTH ; SPOOLER PATH CONTROL WORD .EXTN RELMB ; RELEASE MODIFIED BUFFER .EXTN STDCC ; START OF SPOOLABLE DCT'S .EXTN RELB ; RELEASE BUFFER .EXTN RELZT ; RELEASE IMMEDIATE .EXTN TWINK .EXTN SMNXuT .NREL SPON=TMP SPOF=SPON+1 SPDCT=SPOF+1 ; SPOOL DCT BFAD=SPDCT+1 DACT=BFAD+1 ADACT=DACT+1 ; DEACTIVATE ALLOWED THIS PASS DCBBC=DCBFA+1 ;***************************************** ; NUMBER OF STACK TEMPORARIES USED ; MUST BE THE FIRST WOR.:D IN THE OVERLAY .IFN BSW!MBSW 6 .ENDC STSPL: JSR @.GCELL JSR CLPND ; NO CELLS, PEND STA 2,SPON,3 ; SAVE IN STACK JSR @.GCELL ; GET SPOOL-OFF DCB JSR CLPND ; NO CELLS, PEND STA 2,SPOF,3 ; SAVE IN STACK SUB 0,0  ; WHAT CAN I SAY ? STA 0,DBFAjg1,2 ; +0 FIRST ADDRESS STA 0,DCBFA,2 LDA 1,@.MDCB ; MASTER DCB JSR @.FIDCB ; FULL INIT 'OFF' DCB LDA 2,SPON,3 ; STA 0,DBFA1,2 ; +0 FIRST ADDRESS STA 0,DCBFA,2 JSR @.FIDCB ; & 'ON' DCB SUBZL 0,0 ; +1 STA 0,DCBBC,2 ; IS 'ON' BYTE COUNT JSR @.RDNBK ; NOW GET A BLOCK TO WORK WITH JMP RDERR ; ERROR - WIPE YOURSELF ISZ ORTN,3 ; GOOD RETURN NOW MOV 1,2 ; SAVE BUFFER ADDRESS IN AC2 MOVZL 1,1 ; FORM INITIAL BYTE POINTER LDA 0,OAC0,3 ; RECOVER THE CHARACTER .IFE BSW!MBSW JSR @.STBYT ; STORE ~IT IN THE BUFFER .ENDC .IFN BSW!MBSW STB 1,0 ; STORE IT IN THE BUFFER .ENDC JSR @.RELMB ; RELEASE MODIFIED LDA 2,SPON,3 ; 'ON' DCB LDA 2,DCBDR,2 ; SYS.DR DCB ISZ DCBUC,2 ; SHOW ONE MORE OPEN FILE LDA 2,SPON,3 ; 'ON' DCB AGAIN LDA 3,SPOF,3 ; 'OGFF' DCB LDA 0,DCBFA,2 ; 'ON' FIRST ADDRESS STA 0,DCBFA,3 ; IS 'OFF' FIRST ADDRESS ALO STA 0,DCBCA,3 ; & 'OFF' CURRENT ADDRESS LDA 0,DBFA1,2 ; DON'T FORGET HIGH ORDER STA 0,DBFA1,3 STA 0,DBCA1,3 SUB 0,0 ; 000000 STA 0,DCBBC,3 ; 'OFF' INITIAL BYTE CȆOUNT STA 0,DCBCB,3 ; 'OFF' CURRENT BLOCK # LDA 3,CSP ; STACK POINTER LDA 2,OAC2,3 ; DCT ADDRESS LDA 0,SPON,3 ; SPOOL-ON DCB ADDRESS STA 0,DCTON,2 ; IN THE DCT LDA 0,SPOF,3 ; SPOOL-OFF DCB STA 0,DCTOF,2 ; ALSO ISZ @.SPOL ; BUMP THE SPOOL COUNT LDA 2,.SPQ ; START OF SPOOL QUEUE LDA 0,QSTAT,2 LDA 1,ACTST ; SEE IF ACTIVE NOW AND# 1,0,SZR ; IF NO SKIP JMP SPQAC ; YES QWESC: LDA 0,.TWINK ; PPC TO WAKE UP ROUTINE STA 0,PPC,2 RTRN SPQAC: LDA 0,.SPQ ; SPOOL QUEUE IS PEND KEY JSR @.UNPND RTRN .TWINK: TWINK ACTST: TSACT .IFE BSW!MBSW .STBYT: STCHR .ENDC .MDCB: MDCB .FIDCB: FIDCB .GCELL: GCELL .RELMB: RELMB .PEND: PEND ; PEND WAITING FOR A CELL CLPND: MOV 3,2 ; MOVE RETURN TO AC2 ADC 0,0 ; LONG TIME OUT ADCZR 1,1 ; CELL WAIT PEND KEY INTDS ; MUST DISABLE JSR @.PEND JMP .+1 ; IGNORANCE IS BLISS ADCZL 3,3 ; -2 ADD 2,3 ; CALL+1-2 = CALL-1 JMP 0,3 ; RETURN THERE RDERR: LDA 2,SPON,3 ; 'ON' CELL JSR @.CREL ; GIVE IT BACK LDA 2,SPOF,3 ; 'OFF' CELL JSR @.CREL ; GIVE IT BACK TOO RTRN ; RETURN TO CALL+1 SPRTN: JSR @.FPATH ; FREE SPOOLER DATABASE SPPTH LDA 2,.SPQ SUB 0,0 STA 0,QSTAT,2 ; INACTIVE TASK LDA 0,.SMNXT ; PUT NULL ADDR IN PC STA 0,PPC,2 RTRN .SMNXT: SMNXT .GPATH: GPATH ; GET CONTROL OF PATH .FPATH: FP!ATH ; FREE PATH .SPLFG: SPOLF SPLWT: LDA 1,.SPQ ; WAIT TO BE UNPENDED OR TIME OUT INTDS LDA 2,@.SPLFG ; IF SOMEONE WANTS SPOOLER TO SNEZ 2 ; CONTINE THEN DO SO JSR @.PEND ; ELSE WAIT A WHILE SUB 1,1,SKP ; TIME OUT, OK TO DEACTIVATE SPLPS: SUBZL י1,1 ; SET DON'T DEACTIVATE THIS TIME INTEN ; MAKE SURE WE IS MOVING STA 1,ADACT,3 JSR @.GPATH SPPTH ; GET CONTROL OF SPOLLER PATH LDA 0,@.STDC ; START OF DCT CHAIN STA 0,SPDCT,3 ; INTO THE STACK LDA 0,@.SPOL ; SPOOL COUNT MOV 0,0,SNR ; ANYONPE SPOOLING ? JMP SPRTN ; NO SUB 0,0 ; ZERO THE SPOLR MUST STA 0,@.SPLFG ; FLAG BEFORE SCANNING DCTSH: SUB 0,0 STA 0,DACT,3 ; NOT DEACTIVATING YET STA 0,BFAD,3 ; & BUFFER ADDRESS LDA 2,SPDCT,3 ; GET NEXT POSSIBLE SPOOLER LDA 1,DCTOF,2 ; SPOOL OFF DWCB ADDRESS MOV 1,1,SZR ; IS DEVICE SPOOLING? JMP BYTLP ; YOU'D BETTER BELIEVE IT! NXTDC: LDA 0,DCTSL,2 ; GET LINK STA 0,SPDCT,3 ; NEW DCT ADDRESS MOV 0,0,SZR ; END OF CHAIN? JMP DCTSH ; NO JSR @.FPATH ; DONE SO FREE THE SPOOLER PATH SPPTH ; S&O SPKILL CAN GET IN SUBZL 0,0 ; MAX TIME TO WAIT TO BE UNPENDED JMP SPLWT ; GO WAIT FOR THINGS TO DO .STDC: STDCC .RDNBK: RDNBK .CREL: CREL .UNPND: UNPEND BYTLP: LDA 3,DCTON,2 ; SPOOL-ON DCB LDA 2,DCTOF,2 ; SPOOL-OFF DCB LDA 0,DCBCB,3 ; CURRENT O/N BLOCK LDA 1,DCBCB,2 ; CURRENT OFF BLOCK SUB# 0,1,SZR ; SAME BLOCK ? JMP MTST ; NO, TEST FOR EMPTY BLOCK LDA 0,DCBBC,3 ; YES, GET ON BYTE COUNT LDA 1,DCBBC,2 ; & OFF BYTE COUNT SUB 0,1,SNR ; ARE BYTE COUNTS EQUAL ? JMP DACTIV ; YES, DEACTIVATE *THE SPOOL BFTST: LDA 0,DCBST,3 ; GET 'ON' DCB STATUS LDA 3,CSP ; RECOVER THE STACK POINTER MOVL# 0,0,SZC ; IS 'ON' SIDE EXTENDING ? JMP BAGIT ; YES, DON'T PROCESS NOW LDA 1,BFAD,3 ; NO, GET BUFFER ADDRESS MOV 1,1,SZR ; IS THERE A CURRENT BUFFER ? : JMP HAVE1 ; YES JSR @.RDCBK ; NO, READ CURRENT BLOCK JMP STMER ; SYSTEM ERROR HAVE1: STA 1,BFAD,3 ; SAVE BUFFER ADDRESS LDA 3,SPDCT,3 ; SEE IF KILLED LDA 0,DCTON,3 ; ON DCB LDA 3,CSP MOV# 0,0,SNR ; SKIP IF STILL AROUND JMP BUFUL ; BAG IT MOVZQlL 1,1 ; BYTE ADDRESS LDA 0,DCBBC,2 ; SPOOL-OFF BYTE COUNT ADD 0,1 ; FORM BYTE POINTER .IFE BSW!MBSW JSR @.LDBYT ; GET THE BYTE .ENDC .IFN BSW!MBSW LDB 1,0 ; GET THE BYTE .ENDC LDA 2,SPDCT,3 ; RECOVER THE DCT INTDS ; NO INTERRUPTIONS ISZ ADiACT,3 ; DON'T ALLOW DEACT THIS PASS JSR @.IBUF JMP BUFUL ; BUFER FULL RTURN LDA 3,DCTOF,2 ; SPOOL-OFF DCB ISZ DCBBC,3 ; BUMP THE BYTE COUNT INTEN ; LET OTHERS GO JMP BYTLP ; WILL NOT INTERRUPT BUFUL: INTEN ; LET MY INTERRUPTS GO LDA 2,BFAD,3 ; BUFFER ADDRESS JSR @.RELB ; RELEASE BUFFER JMP SRCH ; SEARCH THE DCT'S .SPQ: SPOLQ .SPOL: SPOOL  MTST: LDA 0,DCBBC,2 ; OFF BYTE COUNT LDA 1,BYTPB ; MAX BYTES/BLOCK ADCZ# 0,1,SZC ; ANY BYTES LEFT ? JMP BFTST ; YES, PUT THEM OUT LDA 3,CSP ;> NO, GET STACK POINTER STA 2,SPOF,3 ; SAVE OFF DCB RELBK: LDA 2,BFAD,3 ; BUFFER ADDRESS MOV# 2,2,SZR ; IS THERE A BUFFER ASSOCIATED ? JSR @.RELZT ; YES, RELEASE LDA 2,SPOF,3 ; OFF DCB SUB 1,1 ; PICK A NUMBER, ANY NUMBER LDA 0,DACT,3 ; GET DEACTIVATE FLAG MOV# 0,0,SZR ; ARE WE DEACTIVATING ? JMP HAVE2 ; YES JSR @.RDNBK ; NO, READ NEXT BLOCK JMP STMER ; SYSTEM ERROR STA 1,BFAD,3 ; SAVE BUFFER ADDRESS HAVE2: LDA 1,DCBCA,2 ; GET CURRENT ADDRESS MOV# 0,0,SNR ; DE-ACTIVATING? LDA 1,DCBLA,2 ; tNO, DEPOSIT THE LAST ONE LDA 3,DBCA1,2 ; NOW HIGH ORDER MOV# 0,0,SNR LDA 3,DBLA1,2 MOV 3,0 ; MOVE HIGH ORDER TO AC0 JSR @.OVLAY DEBLK ; GIVE THE BLOCK BACK JMP STMER ; SYSTEM ERROR LDA 0,DACT,3 STA 0,DCBBC,2 ; SET BYTE COUNT TO ZERO LDA 3,SPD=CT,3 ; CURRENT DCT ADDRESS LDA 3,DCTON,3 ; SPOOL 'ON' DCB ADDRESS MOV# 0,0,SNR  ; DE-ACTIVATING ?????? JMP BFTST ; NO, CARRY ON JEEVES DSZ @.SPOL ; DECREMENT THE SPOOL COUNT JMP .+1 LDA 3,CSP ; STACK POINTER LDA 2,SPON,3 LDA 3,DCBDR,2 ; SYS.DR DCB ADDRESS DSZ DCBUC,3 ; ONE LESS OPEN FILE JMP .+1 JSR @.CREL LDA 2,SPOF,3 JSR @.CREL ; RELEASE THE CELLS LDA 0,SPDCT,3 ; GET DCT ADDRESS JSR @.UNPND ; UNPEND FOR DEADLOCKS SRCH: LDA 2,SPDCT,3 ; DCT ADDRES JMP NXTDC ; SERACH DACTIV: LDA 0,DCBKST,3 ; GET 'ON' DCB STATUS MOVL# 0,0,SNC ; IS SPOOL BEING EXTENDED ? JMP DACOK ; NO, DEACTIVATE OK BAGIT: LDA 3,CSP LDA 2,BFAD,3 ; YES, GET CURRENT BUFFER MOV# 2,2,SZR ; IS THERE ONE ? JSR @.RELB ; YES, RELEASE JMP SRCH ; NOW, LOOK SOME MORE DACOK: SUB 0,0 STA 0,DCBBC,3 ; ZERO BYTE COUNTS STA 0,DCBBC,2 ; IN CASE WE DON'T DEACTIVATE LDA 3,CSP LDA 0,ADACT,3 ; IF DEACTIVATES NOT ALLOWED SEQZ 0 ; THIS PASS THEN JUST GO ON JMP BAGIT ; TO NEXT LDA 2,SPDCT,3 ; CURRENT DCT LDA 0,DCTON,2 ; 'ON' (dDCB STA 0,SPON,3 ; SAVE IN STACK LDA 0,DCTOF,2 ; 'OFF' DCB STA 0,SPOF,3 ; INTO THE STACK STA 1,DCTON,2 ; CLEAR THE 'ON' DCB STA 1,DCTOF,2 ; & 'OFF' IN THE DCT ISZ DACT,3 ; SET DEACTIVATE FLAG JMP RELBK ; RELEASE THE LAST BLOCK BYTPB: (SCWPB-1)*2 ɹ ; BYTES PER BLOCK .RDCBK: RDCBK .OVLAY: OVLAY .IFE BSW!MBSW .LDBYT: LDCHR .ENDC .IBUF: IBUF .RELB: RELB .RELZT: RELZT STMER: JSR @.PNIC ; NOW BAG IT PNSPL ; THE SPOOLER'S NAVEL ENDOV .END CODER.SRB q :J RTITLE CODER CODR .ENT NCODE .ENT DCODE .ENT SPLST .ENT SPKIL .ENT SSPKL .ENT SPDIS .ENT SPEBL .EXTN ASBUF .EXTN MVWD .EXTN SPLPS .EXTN STDCC .EXTN STOUT .EXTN SPOOL .EXTN SPOLQ .EXTN SPPTH ; SPOOL PATH LOCK WORD .EXTN GPATH ; GET A UPATH .EXTN FPATH ; FREE A PATH .EXTN PFLTB .EXTN ITBL .EXTN RDCBK .EXTN RDNBK .EXTN OVLAY .EXTN CREL .EXTN DEBLK .EXTN SYSER .EXTN CFNAM .EXTN SRDCT .EXTN SRUFD .EXTN SMNXT .EXTN DEQUE .EXTN UNPEND .NREL ;***************************************** ; NUMBER OF STACK TEMPORARIES USED ; MUST BE THE FIRST WORD IN THE OVERLAY .IFN BSW!MBSW 6 .ENDC ; DEFINE STACK TEMPORARIES SRADR= TMP+1 DSADR= SRADR+1 CONCT= DSADR+1 LPCNT= CONCT+1 FILWD= LPCNT+1 ; SCAN VECTOR TABLE DEVICES 1-76 INCLUSIVE. ; ; CALLED ONCE, BEFORE "CLIBT" STARTED. ; THERE ARE NO .IDEF'S IN VECTOR TABLE ; ; SPOOLER TASK COMES HERE WHEN ACTIVATED VIA "TWINK" ; TO LINK SPOOLABLE DEVICES' DCT'S TOGETHER. ENTCT=TMP INDCT=ENTCT+1 SPDCT=INDCT+1 SPLST: LDA 0,.IVFA ; FWA OF INTERRUPT VECTOR STA 0,INDCT,3 ; SAVE IN STACK  LDA 1,.IVLA ; LAST ADDRESS OF INTERRUPT ; VECTOR SUB 0,1 ; LENGTH OF INTERRUPT VECTOR STA 1,ENTCT,3 ; SAVE IT SUB 0,0 ; UNARY ZERO STA 0,SPDCT,3 ; INIT THE DCT WORD LDA 1,SPLMK ; SPOOLABLE MASK DCTLP: LDA 2,@INDCT,3 ; GET NEXT DCT ADDRESS COM# 2,2,SNR ; IS THIS DRIVER LOADED ? (NOVA) JMP NXTET ; NO, GET NEXT ENTRY MOVZL 2,2,SBN ; MAYBE - TEST FOR ZERO ENTRY OR ; ECLIPSE DRIVER NOT LOADED. JMP NXTET ; ZERO ENTRY - DISREGARD MOVZR 2,2 LDA 0,DCTCH,2 ; GET CHARACTERISTICS AND 1,0,SNR ; IS DEVICE SPOOLABLE? JMP NXTET ; NO LDA 0,SPDCT,3 ; YES, GET DCT WORD MOV 0,0,SZR ; CHECH PREVIOUS DCT ADDRESS STA 0,DCTSL,2 ; LINK 'EM STA 2,SPDCT,3 ; UPDATE DCT NXTET: ISZ INDCT,3 ; BUMP ITHE INDIRECT DSZ ENTCT,3 ; ANY ENTRIES LEFT? JMP DCTLP ; YES LDA 0,SPDCT,3 ; NO, GET LAST DCT ADDRESS STA 0,@.STDC ; AND SAVE SUB 0,0 STA 0,@.SPOL ; CLEAR SPOOL COUNT SPRTN: LDA 2,.SPQ ; SPOOL QUEUE LDA 0,.SPLS ; START UP ADDRESS STA 0,QCNT,2 ; SET INTO THE QUEUE SUB 0,0 ; 0 = INACTIVE STA 0,QSTAT,2 ; INTO QUEUE STATUS LDA 0,.SMNXT STA 0,PPC,2 RTRN .SMNXT: SMNXT .SPQ: SPOLQ .SPOL: SPOOL .STDC: STDCC .SPLS: SPLPS SPLMK: DCSPO .IVFA: ITBL .IVLA: PFLTB ; DON'T INCLUDE TTI/TTR, ; NOVA 3 STACK OVERFLOW, DCT'S, ; AT END OF VECTOR TABLE. ; KILL A SPOOL ; INPUT: DCT ADDRESS IN AC2 ; ; OUTPUTS: NONE ; ; RETURNS: CALL+1 - ERROR ; CALL+2 - GOOD RETURN SPON=TMP SPOF=SPON+1 BUFAD=SPOF+1 SPKIL: JSR @.OVLAY SRDCT ; FIND THE DCFT ADDRESS RTRN ; ERROR LDA 0,DCTCH,2 ; CHARACTERISTICS LDA 1,SPMSK ; AND 0,1,SNR ; IS DEVICE SPOOLABLE ? JMP ILCMD ; NO, DUMMY SSPKL: JSR @.GPATH ; GET CONTROL OF SPOOLER SPPTH ; PATH SO IT CAN'T INTERFERE INTDS ; SHUT OF INTS LDA 1,DCTBD,2 ; DEQUEUE DEVICE JSR @.DEQUE ; BEAD IF ACTIVE. LDA 0,DCTQS,2 LDA 1,.BSCTS ; CONSOLE CTRL-S BIT AND 0,1 STA 1,DCTQS,2 ; CLEAR IT. SUB# 0,1,SZR ; WAS IT SET ? JSR @.STOUT ; YES- GOOSE DEVICE LDA 3,CSP ; RESTORE STACK POINTER LDA 0,DCTON,2 MOV 0,0,SNR ; ANY SPOOL ? JMP GDRTN ; NO STA 0,SPON,3 ; SAVE ON-DCB IN STACK DSZ @.SPOL ; DECREMENT THE SPOOL COUNT JMP .+1 LDA 0,DCTOF,2 ; SPOOL-OFF DCB STA 0,SPOF,3 ; & SPOOL OFF DCB SUB 0,0 STA 0,DCTON,2 STA 0,DCTOF,2 ; CLEAR DCB WORDS INTEN/ ; ENABLE NOW LDA 3,CSP ; YOU'D THINK CSP WOULD BE ; RETURNED LDA 2,SPOF,3 ; SPOOL OFF DCB LDA 3,DCBDR,2 ; SYS.DR'S DCB ADDRESS DSZ DCBUC,3 ; ONE LESS OPEN FILE JMP .+1 JSR @.RDCBK ; READ CURRENT BLOCK JMP CRELS ; ERROR...RELEASE THE CELLSE JMP .+3 ; ONLY USED ONCE KILLP: JSR @.RDNBK ; READ NEXT BLOCK JMP CRELS ; ERROR..... STA 1,BUFAD,3 ; SAVE BUFFER ADDRESS ON STACK LDA 0,DBCA1,2 LDA 1,DCBCA,2 ; CURRENT BLOCK ADDRESS JSR @.OVLAY DEBLK JMP CRELS ; ERROR.... LDA 2,BUFAD,3 ; BUFF!7ER ADDRESS SUB 0,0 STA 0,BQDCT,2 ; CLEAR DCT ADDRESS STA 0,BQST,2 ; & STATUS STA 0,BQUSC,2 ; & USER COUNT LDA 2,SPOF,3 ; DCB LDA 0,DBNA1,2 ; NEXT ADDRESS LDA 1,DCBNA,2 MOV# 0,0,SZR ; IS THERE A NEXT ? JMP KILLP MOV# 1,1,SZR ; WELL ? JMP KILLP eB; YESY CRELS: LDA 2,SPON,3 ; SPOOL ON DCB JSR @.CREL ; RELEASE LDA 2,SPOF,3 JSR @.CREL GDRTN: INTEN ; LET THE WORLD GO ROUND JSR @.FPATH ; FREE UP THE SPOOLER PATH SPPTH ; SO OTHERS CAN SPOOL ISZ ORTN,3 ; GOOD RETURN NOW RTRN ; NOW RETURN  .STOUT: STOUT .FPATH: FPATH .GPATH: GPATH .BSCTS: -BSCTS-1 .DEQUE: DEQUE .UNPEND:UNPEND ; ; BRIDGE TO THE DECODER ; DCODE: JMP .DCODE NCODE: JMP .NCODE ; ; SPDIS/SPEBL CODE ; ENTSW=TMP SPDIS: SUBZL 1,1,SKP ; SPOOL DISABLE ENTRY SPEBL: SUB 1,1 +; SPOOL ENABLE ENTRY STA 1,ENTSW,3 ; SAVE ENTRY TYPE JSR @.OVLAY SRDCT ; FIND THE DCT RTRN ; ERROR LDA 0,DCTCH,2 ; DEVICE CHARACTERISTICS LDA 1,SPMSK ; SPOOLABLE MASK AND# 0,1,SNR ; IS DEVICE SPOOLABLE ? JMP ILCMD ; NO, THAT'S AN ILLEGAL COM>MAND MOVL 0,0 ; SHIFT ENABLE BIT TO CARRY DSZ ENTSW,3 ; TEST THE ENTRY MOVOR 0,0,SKP ; WAS ENABLE, SET THE BIT MOVZR 0,0 ; DISABLE, RESET THE BIT STA 0,DCTCH,2 ; RETURN CHATACTERISTIC TO DCT ISZ ORTN,3 ; ITS A GOOD ONE RTRN ; GOODNIGHT SWEET ÄPRINCE ILCMD: JSR @.SYSER ERICD SPMSK: DCSPO ; ROUTINE TO ENCODE 7 TRACK DATA ; INPUT: AC0 - FIRST BUFFER ADDRESS ; OUTPUT: AC1 - SECOND BUFFER ADDRESS .NCODE: MOV 0,2 ; INDEX ON FIRST BUFFER LDA 2,BQDCB,2 ; DCB ADDRESS JSR @.ASB0 ; ASSIGN A GSECOND BUFFER STA 1,OAC1,3 ; RETURN SECOND BUFFER ADDRESS MOV 0,2 ; REINSTATE FIRST BUFF ADDRESS LDA 2,OFSET ; HALF RECORD DISPLACEMENT ADD 2,0 ; SOURCE ADDRESS INC 2,2 ; CORRECT NUMBER OF TRANSFERS JSR @.MVWD ; MOVE SECOND HALF OF RECORD ; ITO THE SECOND BUFFER LDA 2,OAC0,3 ; FWA OF FIRST BUFF LDA 0,FWOFS ; FILE # WORD OFFSET ADD 2,0 ; ADDRESS OF FILE # WORD STA 0,FILWD,3 ; SAVE IN THE STACK LDA 0,@FILWD,3 ; GET THE FILE NUMBER JSR CODIT ; ENCODE FIRST BUFFER STA 0,@FILWD,3 ; RESTORffE FILE # MOV 1,2 ; FWA OF SECOND BUFFER LDA 0,FWOFS ADD 2,0 STA 0,FILWD,3 LDA 0,@FILWD,3 JSR CODIT STA 0,@FILWD,3 RTRN .OVLAY: OVLAY CODIT: RSAVE 5 LDA 0,OFSET ; GET OFFSET ADD 0,2  STA 2,SRADR,3 ; FORM SOURCE ADDRESS INC 0,0 STA 0,CONCT,3 _m; FORM CONVERSION COUNT ADD 0,2 STA 2,DSADR,3 ; FORM DESTINATION ADDRESS NCOD1: ADCZL 0,0 ; -2 STA 0,LPCNT,3 ; SET THE LOOP COUNT LDA 0,@SRADR,3 ; GET A WORD NCOD2: LDA 1,RMASK ; RIGHT MASK AND 0,1 ; BITS 12-15 OR 4-7 ADDL 0,0 ADDL 0,0 ; SHIFT LXEFT 4 PLACES LDA 2,LMASK ; LEFT MASK AND 2,0 ; BITS 8-11 OR 0-3 ADD 1,0 STA 0,@DSADR,3 ; STORE ENCODED WORD DSZ DSADR,3 ; MOVE DESTINATION BACK LDA 0,@SRADR,3 ; GET ANOTHER WORD MOVS 0,0 ; AND SWAP IT ISZ LPCNT,3 ; DONE 2 WORDS YET? JMP NCOD2{ ; NO DSZ SRADR,3 ; YES DSZ CONCT,3 ; CONVERSION DONE? JMP NCOD1 ; NO RTRN .RDNBK: RDNBK .RDCBK: RDCBK .CREL: CREL .SYSER: SYSER FWOFS: BQXTA OFSET: 177 RMASK: 17 LMASK: 7400 .ASB0: ASBUF .MVWD: MVWD ; ROUTINE TO DECODE 7 TRACK DATA ; INPUTz1: AC0 - FIRST BUFFER ADDRESS ; AC1 - SECOND BUFFER ADDRESS .DCODE: MOV 0,2 JSR UNCOD ; DECODE FIRST BUFFER MOV 1,2 JSR UNCOD ; DECODE IT MOV 0,1 MOV 2,0 ; FROM ADDRESS LDA 2,OFSET ; HALF RECORD OFFSET ADD 2,1 ; "TO" ADDRESS INC 2,2 JSR @.8MVWD ; MOVE WORDS RTRN UNCOD: RSAVE 5 STA 2,SRADR,3 ; SOURCE ADDRESS STA 2,DSADR,3 ; DESTINATION ADDRESS LDA 0,OFSET ; HALF RECORD OFFSET INC 0,0 STA 0,CONCT,3 DCOD1: SUB 0,0 STA 0,TMP,3 ; CLEAR TEMPORARY ADCZL 0,0 ; -2 STA 0,LPCNT,3 ; SET LOhOP COUNTER DCOD2: LDA 0,@SRADR,3 ; GET A WORD LDA 1,RMASK ANDS 0,1 ; BITS 12-15 OR 4-7 LDA 2,LMASK ; LEFT MASK AND 0,2 ; BITS 8-11 OR 0-3 ADDZL 2,2 ADDZL 2,2 ; SHIFT RIGHT 4 PLACES ADD 2,1 ; FORM DECODED BYTE LDA 0,TMP,3 ; WORD BEING DECODED  ADDS 1,0 ; ADD IN DECODED BYTE STA 0,TMP,3 ; AND SAVE IT ISZ SRADR,3 ; BUMP THE SOURCE POINTER ISZ LPCNT,3 ; 2 BYTES DECODED? JMP DCOD2 ; NO STA 0,@DSADR,3 ; YES, STORE AT DESTINATION ISZ DSADR,3 ; BUMP THE DESTINATION POINTER DSZ CONCT,3 ; START, 1=> DEBUG) ; 1B0= CHAINING ; AC2 IS PASSED TO LOADED PROG IN AC2 CMN: LDA @2,CC ;TCB LDA 1,TPRST,2 ;UNPEND BEFORRE WRITING MOVL 1,1 MOVZR 1,1 STA 1,TPRST,2 SUB 1,1 CMNBG: STA 1,TYPE,3 ;TYPE *CMN LDA 2,CC LDA 2,CPTAD,2 ;PTBL MOVL# 1,1,SZC ;CP LOAD ? LDA 2,PLNK,2 ;GET PT2 ADDR (ASSUME 2 = ; PT1...) STA 2,PTAD,3 ;SAVE LDA @3,CC LDA 1,TAC1,3 ;SEE IF CHAINING MOVL# 1,1,SZC JMP CMN1 ;YES-DON'T CHECK LDA 1,PFLAG,2 ;CHECK DIRTY BIT MOVR# 1,1,SZC ; JMP JCME3 ; QTY OR ELSE, DON'T ALLOW LDA 1,PTSPN,2 ; CURRENT PUSH NUMBER LDA 3,MAXPN ;MAX PUSH LEVEL LDA 2,PPRI,2 ;SEE IF FG MOVZR# 2,2,SNR LDA 3,FMAXP ;USE FG BASE SUBZ# 3,1,SZC JMP JCME2 ;TOO FAR ; NOTE- IF NON-MAPPED SYSTEM F'cG PUSH = -1 CMN1: LDA 3,CSP LDA 1,TYPE,3 ;FLAG = CELL TMP FLAG LDA 3,CC MOV# 1,1,SZR ;SKIP IF NORMAL LOAD JMP .+4 LDA 2,CPROG,3 ;SEE IF FG MOVZR# 2,2,SNR ;SKIP IF BG SUBZL 1,1 ;FG LOAD STA 1,CTEMP,3 ;SET TYPE OF LOAD FLAG LDA 3,0,3 ;TCB LDA 1,TAC1,3 ;FLAG WORD LDA 2,TAC2,3 ;AC2 FOR PASSING LDA 3,CSP STA 1,OAC1,3 ;FOR FUTURE GENERATIONS STA 2,PASS,3 ;SAVE AC2 FOR NEW PROG LDA 2,CQ LDA 1,QSUFP,2 ;TASK SUFT JSR @.OV2 CFNAM ;VALIDATE NAME MOV 1,0 ;SUFT JSR @.OV2 STATUS JMP JCERX ;E4RROR EXIT STA 2,TDCB,3 ;DCB ADDR MOV 0,2 ; UFT ADDRESS LDA 0,UFTAD,2 ; FIRST DEVICE ADDRESS STA 0,TFA,3 ; SAVE IT LDA 1,C377L ; HIGHORDER ADDRESS MASK LDA 0,UFTDL,2 ; HIGH ORDER WORD ANDS 1,0 ; MASK & SWAP TO RIGHT BYTE STA 0,TFA1,3 ; SAVE THISb TOO LDA 1,UFTAT,2 ; GET THE FILE ATTRIBUTES LDA 0,SAVAT ; "S" ATTRIBUTE AND 0,1 ; CLEAR CARRY SUBO 0,1,SZR ;BOTH MUST BE SET JMP JCME1 ; ERROR, NOT A SAVE FILE LDA 0,TYPE,3 ;EXFG ? MOVZL# 0,0,SZR JMP CMN4 ;YES LDA @2,CC LDA 1,TAC1,2 MOVZL#zn 1,1,SNC ;SKIP IF NOT CHAINED JMP CMN6 .IFN MSW MOVL# 0,0,SZC JMP CMNE2 ;FG JUST PASSED SOME GAS .ENDC JSR @.OVLAY RSET JMP .+1 CMN6: LDA 2,PTAD,3 ; PROGRAM TABLE ADDRESS LDA 1,PTPBA,2 ; PARTITION BASE ADDRESS LDA 0,PTPB1,2 ; HIGH ORDER PARTITI)ON BASE ; ADDRESS LDA 2,.SCPSH ;PUSH DIRECTORY RELATIVE ADDR ADDZ 2,1,SZC ;ABSOLUTE PUSH ADDRESS INC 0,0 LDA 2,@CQ ; SET FIRST ADDRESS STA 0,DBFA1,2 ; SET HIGH ORDER STA 1,DCBFA,2 ; NOW LOW ORDER STA 0,WRBL1,3 ; SAVE IT ON STACK STA 1,WRBLK,3 LDA 1,OAC1,3 ; INPUT AC1 LDA 2,@.MDCB ; MASTER DCB MOVL# 1,1,SZC ; CHAINING ? JMP CMN4 ; IF YES, DON'T WRITE CORE IMAGE JSR @.OVLAY WRCI JMP JCERX ;ERROR CMN4: LDA 2,@CQ LDA 0,TFA1,3 ; SETDCB FOR CALL STA 0,DBFA1,2 LDA 0,TFA,3 STA 0,DCBFA,2 LDA 2,TDCB,3 ;MASTER DCB FROM STATUS LDA 1,OAC1,3 JSR @.OVLAY RDCI JMP JRCER ;ERROR ISZ ORTN,3 ; SUCCESS LDA 1,OAC1,3 ; USER'S AC1 LDA 3,PTAD,3 LDA 2,CSP LDA 0,TYPE,2 ;SEE IF EXFG MOVZL# 0,0,SZR ; SKIP IF NO JMP CMN2 ; YES .IFN MSW MOVL#Gf 0,0,SZC JMP CMN7 ;EXBG .ENDC STA 0,@CC ; NO, CLEAR TCB ADDRESS MOVL# 1,1,SNC ; CHAINING ? ISZ PTSPN,3 ; NO, BUMP PUSH LEVEL LDA 0,USTP JMP CMN3 ;TRY AND AVOID IT...... .SYSFG: SYSFG CMNE3: LDA 2,.ERFGE JMP CERX JCMN1: JMP CMN1 JCME2: JMP CKMNE2 ;LONDON BRIDGES FALLING DOWN... JCME3: LDA 2,.ERNSE ;NOT SWAPPABLE JMP CERX CMN3: .IFN MSW MOV 3,2 ;PTBL ADDR CMN3A: LDA 0,USTP ;USE 31K+ UST ADDR .ENDC JSR @.OVCHN CCMN CMNE2: LDA 2,.ERCM3 JMP CERX JCERX: JMP CERX2 SAVAT: ATRAN+ATSAV 2 JCME1: JMP CMNE1 CMPSW: PSBRK+PSCP CMN2: LDA 2,.PT1 ; FOREGROUND PROGRAM TABLE ISZ @.SYSFG ; FG ACTIVE FLAG LDA 0,CTSL ;WANT TO TIME SLICE ? AND# 0,1,SZR ISZ @.PRISW ;YES-SET FLAG LDA 0,PTPBA,3 ;SAME BASE STA 0,PTPBA,2 LDA 0,PTPB1,3 STA 0,PTPBվ1,2 LDA 3,PDDCB,3 ;DEFAULT DCB STA 3,PDDCB,2 ;SET FOR FG ADCZR 0,0 ;SET 1B0 FOR FG INITED PARTITION MOVOR 0,0 ;MASK = COMPLEMENT LDA 1,DCBUC,3 AND 0,1 ADC 0,1 STA 1,DCBUC,3 .IFE MSW LDA 0,PUSTP,2 ;UST ADDR JMP CMN3 .ENDC .IFN MSW JMP CMN3A W3 .ENDC .SCPSH: SCPSH .MDCB: MDCB .OVLAY: OVLAY .PT1: PT1 CTSL: 1B1 .PRISW: PRISW CMNE1: LDA 2,.ERSV1 CERX: LDA 3,CC STA 2,CTMP2,3 ;PASS ERROR CODE CERX2: LDA 3,CSP LDA 3,PTAD,3 ;PTBL LDA 0,PSTAT,3 ;RESET EO LDA 1,CMPSW AND 1,0 STA 0,PSTAT,3 ;RESEST STATUS .IFN MSW LDA 3,CSP LDA 1,TYPE,3 ;SEE IF EXBG MOVL# 1,1,SNC ;SKIP IF EXBG .ENDC RTRN .IFN MSW JSR @.OVCHN CPERT .ENDC .OVCHN: OVCHN JRCER: JMP RCER ;HIPPITY HOP .ERNSE: ERNSE ;NOT SWAPPABLE .ERCM3: ERCM3 .ERSV1: ERSV1 .ERFGE: ERFGE TDCB= TMP TFA= TMP+1 TYPE= TMP+2 PTAD= TMP+3 PASS= TMP+4 WRBLK= TMP+5 TFA1= TMP+6 WRBL1= TMP+7 .IFN MSW CMN7: ISZ PTSPN,3 ;BUMP PUSH LDA 0,CTSL ;RESET EO AND# 0,1,SZR ISZ @.PRISW ;SET PRISW IF NEEDED LDA 2,.PT1 ;FLIP DDCB LDA 0,PDDCB,2 STA 0,PDDCB,3 JMP CMN3 .ENDC ; ERROR ON READ CORE IMAGE ; IF EXFG, JUST GIVE BAD RTN TO BG CALLER ; IF A CHAINED REQ, GO BACK TO NEXT LEVEL UP ; IF NORMAL EXEC OR EXBG, READ CALLER'S IMAGE BACK AND ERTN RCER: LDA 1,TYPE,3 ;TYPE REQ MOVR# 1,1,SZC ;SKIP INF NOT EXFG JMP JCERX LDA 1,OAC1,3 ;USER LOAD FLAG MOVL# 1,1,SZC ;SEE IF CHAINED TO JMP RCER2 ;YES LDA 2,@CQ LDA 0,WRBLK,3 STA 0,DCBFA,2 LDA 0,WRBL1,3 STA 0,DBFA1,2 ADC 1,1 ;RTN TYPE RDCI LDA @2,.MDCB ;MASTER DCB JSR @.OVLAY RDCI JMP . ;TH 0? JMP GOTYR ;NO - THIS IS THE YEAR INC 2,2 ;YES- TRY NEXT YEAR JMP LP1 GOTYR: ADD 1,0 ;MAKE 0 + AGAIN LDA 3,C366 SUB# 3,1,SZR ;IS THIS YEAR A LEAP YEAR? JMP LP21 ;NO LDA 3,C29 ;YES STA 3,MTBL+2 ;GIVE FEB 29 DAYS LUP21: LDA @1,CRSEG ;BASE ADDR OF OVERLAY LDA 3,.MTBL ;OFFSET IN OVERLAY FOR MONTH ; TABLE ADD 1,3 ;ADD FOR ADDR OF MTBL LP2: INC 3,3 ;NEXT MONTH LDA 1,0,3 ;GET NUMBER OF DAYS IN THIS ; MONTH SUB 1,0 ;SUB # OF DAYS IN THIS MONTH NEGL# 0,0,SWZC ;# OF DAYS LEFT > 0? JMP LP2 ;YES - GET NEXT MONTH GOMTH: ADD 1,0 ;NO - THIS IS THE MONTH LDA 1,.MTBL SUB 1,3 ;CORRECT FOR OFFSET LDA @1,CRSEG ;CORRECT FOR OVERLAY BASE ; ADDRESS SUB 1,3 ;MAKE MONTH NUMBER CORRECT MOV 3,1 ;AND PUT IN AC1& LDA @3,CC STA 0,TAC0,3 STA 1,TAC1,3 STA 2,TAC2,3 JMP EXIT C365: 365. C366: 366. C28: 28. C29: 29. C13: 13. .TODD: TODD .MTBL: MTBL MTBL: 0 ;TABLE OF DAYS IN MONTHS 31. ;JANUARY 28. ;FEBRUARY 31. ;MARCH 30. ;APRIL 31. ;MAY 30. ;JUNE 31. ;JULY 31. ;AUGUST 30. ;SEPTEMBER (A GOOD MONTH) 31. ;OCTOBER 30. ;NOVEMBER 31. ;DECEMBER ;SDAY - SET DATE ; TAKES AS INPUT AC0 - DAY ; AC1 - MONTH ; AC2 - YEAR-1968 ; SETS TODD WITH CORRECT JULIAN DATE SDAY: LDA @3,CC LDA 0,TAC2,3 ;GET YEAR INPUT NEGL# 0,0,SNC ;>0? JMP TIMER ;NO GOING BACKWARDS IN TIME LDA 1,MAXYR SUBZ# 0,1,SNC ;BIGGER THAN WE CAN HANDLE? JMP TIMER ;YUPP LDA 1,C28 MOVZR 0,0,SZC ;LEAP YEAR? MOVZR 0,0,SKP ;NO - GET YEAR/4 MOVZR 0,0,SZC ;IS THE Y^EAR A LEAP YEAR? INC 0,0,SKP ;NO, 1 MORE LP YR TO CORRECT FOR LDA 1,C29 ;YES STA 1,MTBL+2 ;SET FEB TO CORRECT NBR OF DAYS LDA 2,C365 SD1: DSZ TAC2,3 ;DECREMENT YEAR COUNT ADD 2,0,SKP ;ADD IN DAYS FOR THIS YEAR ADD 2,0,SKP ;INCLUDING YEAR 0 JMP SD1 LDA @2,CRSEG ;DONE WITH YEARS LDA 1,.MTBL ;GET ADDR OF MONTHS TABLE ADD 1,2 ;FORM ACTUAL ADDR LDA 1,TAC1,3 ;GET INPUT MONTHS LDA 3,C13 MOV# 1,1,SZR ;>0? SUBZ# 3,1,SZC ;<13? JMP TIMER ;NO - TSK TSK ADD 2,1 ;SET AC1 AS END POINTER LP3: SUBN-# 1,2,SNR ;AT END? JMP SD2 ;YES - GO ON LDA 3,0,2 ;NO - GET NUMBER OF DAYS IN ; THIS MONTH ADD 3,0 ;ADD TO RUNNING TOTAL INC 2,2 ;INCREMENT POINTER JMP LP3 ;AND DO NEXT MONTH SD2: LDA @3,CC ;GET TCB POINTER BACK LDA 1,TAC0,3 ;DAY INPUT LD"hA 3,0,2 ;DAYS IN THIS MONTH MOV# 1,1,SZR ;INPUT 0? SUBZ# 1,3,SNC ;OR > DAYS IN THIS MONTH? JMP TIMER ;YES YES ADD 0,1 ;ADD IT IN TOO STA @1,.TODD ;PUT IN CURRENT DAY HOLDER EXIT: LDA 3,CSP ISZ ORTN,3 ;NORMAL RETURN RTRN MAXYR: 77777/366. .OVL4AY: OVLAY .RET1: RETER TIMER: JSR @.RET1 ERTIM ; RESOLVE A DIRECTORY LINK ENTRY ; ; INPUTS: AC0 - CURRENT DCB ADDRESS ; AC1 - LINK ENTRY'S BUFFER ADDRESS ; AC2 - LINK ENTRY ADDRESS ; ; OUTPUTS: AC0 - RESOLUTION ENTRY DCB ADDRESS ; AC1 - RESOLUTION ENTRY BUFFER ADDRESS ; AC2 - RESOLUTION ENTRY ADDRESS ; QUEUE UFT - NAME OF RESOLUTION FILE ; ; RETURNS: CALL+1 - RESOLUTION UNSUCCESSFUL ; CALL+2 - RESOLUTION SUCCESSFUL LNKCT=TMP+1 LNKRS: LDA 1,LNKDP ; GET RESOLUTION DEPTH CONSTANT STA 1,LNKCT,3~ ; SAVE COUNTER LNKLP: LDA 2,OAC2,3 ; GET ENTRY ADDRESS LDA 0,UFLAD,2 ; FIRST DIRECTORY WORD MOV# 0,0,SNR ; IS ONE SPECIFIED ? JMP USEPRI ; NO, USE PRIMARY FOR DEVICE LDA 0,.UFLD ; YES, GET OFFSET ADD 2,0 ; FORM SPECIFIER ADDRESS LDA 2,CQ ; CURRENT QUEUE LDA 1,QSUFP,2 ; QUEUE UFT ADDRESS LDA 2,SPLT ; SPECIFIER LENGTH JSR @.MVWD ; MOVE SPECIFIER TO QUEUE UFT JSR @.OVLAY ; LOOK FOR THE DIRECTORY SDIRR JMP NODIR ; NO DEARY, NOT WITHOUT A DIRRY LDA 0,DCBST,2 MOVL# 0,0,SZC ;INIT'D? JMP NYOINI ;NOPE FOUND: LDA 3,CSP ; GET STACK POINTER STA 2,OAC0,3 ; RETURN DCB ADDRESS LDA 1,SFLK,2 ; FOUND - GET MAP.DR LINK WORD COM 1,1,SZR ; IS THERE A MAP.DR ? JMP SAMDR ; YES, KEEP ON TRUCKIN' ISZ ORTN,3 ; RETURN TO CALL+2 LDA 0,OAC2,3 ; GET :[ENTRY ADDRESS LDA 2,.UFLN ; ALIAS NAME OFFSET ADD 0,2 ; ADDRESS OF ALIAS IF ANY STA 2,OAC2,3 ;RETURN ALIAS ADDRESS RTRN ;PACK UP ALL YOUR CARES & WOES. SAMDR: LDA 2,OAC2,3 ; ENTRY ADDRESS MOV 2,0 ; IN AC0 ALSO LDA 1,UFLAN,2 ; FIRST WORD OF ALMIAS MOV# 1,1,SNR ; IS ALIAS SPECIFIED ? JMP NOALS ; NO LDA 0,.UFLN ; YES, GET OFFSET ADD 2,0 ; ALIAS ADDRESS NOALS: LDA 2,CQ LDA 1,QSUFP,2 ;MOVE NAME TO QUEUE UFT LDA 2,FNL ; IN CASE WE'RE DOING THIS JSR @.MVWD ; FOR CREATE LDA 2,OAC0,3 ;GET 'DCB ADDRESS JSR @.OVLAY SRUFD ; LOOK FOR RESOLUTION JMP ENTNF ; ENTRY NOT FOUND MOV 2,0 ; BUFFER ADDRESS TO AC0 LDA 2,OAC1,3 ; PREVIOUS ENTRY BUFFER ADDRESS JSR @.RELPB ; RELEASE THE BUFFER STA 0,OAC1,3 ; SAVE CURRENT BUFFER ADDRESS STA 1,OAC2uD,3 ; RETURN ENTRY ADDRESS IN AC2 MOV 1,2 ; ENTRY TO AC2 LDA 0,UFTAT,2 ; ENTRY'S ATTRIBUTES LDA 1,LNKMK ; LINK MASK AND# 0,1,SNR ; IS THIS A LINK JMP DESFD ; NO, DESTINATION FOUND ISZ LNKCT,3 ; YES, BUMP & TEST COUNT JMP LNKLP ; STILL OK LDA 0,LLVER ; LINK DEPTH EXCEEDED JMP ERET ; ERROR RETURN DESFD: LDA 1,NRSAT ; NO RESOLUTION MASK AND# 0,1,SZR ; RESOLUTIN POSSIBLE ? JMP ENTNA ; NO, ERROR RETURN LDA 0,UFTLK,2 ; MAYBE, LOOK AT LINK ACCESS WORD AND# 0,1,SZR ; IS RESOLUTION STILL POSS `IBLE ? JMP ENTNA ; NOT TODAY, RALPH ISZ ORTN,3 ; YES, RETURN TO CALL+2 RTRN NODIR: LDA 0,.NODIR ;UNKNOWN DIRECTORY JMP ERET NOINI: LDA 0,.NOINI JMP ERET ENTNF: LDA 0,DLEER JMP ERET ENTNA: LDA 0,ENAER JMP ERET DNIS: LDA 0,DNSER ERET: LDA 3,CSP ; |STACK PIONTER !!! LDA 2,OAC1,3 ; BUFFER ADDRESS JSR @.RELPB ; RELEASE IT MOV 0,2 ; ERROR CODE TO AC2 JSR @.RETE2 ; RETURN ERROR LNKDP: -10. DLEER: ERDLE DNSER: ERDSN LLVER: ERLDE ENAER: ERENA .NODIR: ERDSN .NOINI: ERDNI LNKMK: ATLNK NRSAT: ATNRS S%PLT: UFTEX FNL: SCFNL .RELPB: RELPB .UFLD: UFLAD .UFLN: UFLAN .RETE2: RETE2 .DIRR: DIRR .MVWD: MVWD ; FIND PRIMARY PARTITION DCB USEPRI: LDA 2,@.DIRR ; START OF DCB CHAIN LDA 3,OAC0,3 ; INPUT DCB ADDRESS SRLUP: LDA 0,DCBDC,2 ; DCT ADDRESS LDA 1,DCBDC,3 SUB# 0,1,SZR ; SAME ? JMP NEXT1 ; NO LDA 0,SFTYPE,2 ; SEE IF PRIMARY PARTITION LDA 1,SFTYPE,3 ; CHECK, IF WE ARE LOOKING COM# 1,1,SZR ; FROM OTHER THAN SUB DIR JMP NEXT0 ; THEN HOOK TO PRIMARY ELSE COM# 0,0,SNR ; IF WE IS LOOKING AT SUB DIR JO$MP NEXT1 ; THEN COULD NEVER BE ELSE LDA 0,SFLK,2 ; CHECK IF WE IS LOOKING AT LDA 1,SFLK,3 ; PART SUBDIR IN, IF NOT SEQ 0,1 ; THEN WE MUST GO JMP NEXT1 ; TRY AGAIN ELSE JMP NEXT2 ; WE GOT WHAT WE CAME FOR NEXT0: MOV# 0,0,SZR ; WELL ? JMP NEXT1 y ; NO TRY NEXT ONE NEXT2: LDA 0,DCBST,2 ; FOUND IT SEE IF INIT'D MOVL# 0,0,SZC ; WELL ? JMP NOINI ; NO - GIVE NOT INITED ERROR JMP FOUND ; YES NEXT1: LDA 2,SFNX,2 ; NEXT DCB COM# 2,2,SNR ; IS THERE ONE ? JMP DNIS ; NO JMP SRLUP ; YE"QS, KEEP LOOKING ENDOV .END SOV10.SRB 8B RTITLE SOV10 SV10 ; SYSTEM OVERLAY # 10 ; ; INIT .NREL .ENT INIT .ENT RMVBAD ; REMOVE BAD BLOCKS .EXTN NAMCK .EXTN SDIRR .EXTN STATUS .EXTN DKINI .EXTN OVLAY .EXTN OVLY1 .EXTN RETE2 .EXTN MVWD .EXTN FNDCB .EXTN CLEAR .EXTN PPDCB .EXT+vN FLUSH .EXTN MDCB .EXTN CFNAM .EXTN BLIST .EXTN ENCONT .EXTN BFLUSH ;***************************************** ; NUMBER OF STACK TEMPORARIES USED ; MUST BE THE FIRST WORD IN THE OVERLAY .IFN ABSW 7 .ENDC ; ; ROUTINE TO FLUSH DEVICE BUFFERS AND REMOVE BAD BLOCK TABLE. ; CALLED BY DVRLS AND BY DVINI IF ERROR OCCURS DURING INITIALIZATION. ; REFER TO GBLKNO FOR DESCRIPTION OF BAD BLOCK POOL ORGANIZATION. ; ;INPUTS: AC2 - SYS.DR DCB ADDRESS ; ;RETURNS: STANDARD ERROR & SUCCESSFUL RETURNS ; SVM'SK=TMP DEST=SVMSK+1 FROM=DEST+1 RMVBAD: LDA 0,SFTYPE,2 ;WHAT TYPE OF DIRECTORY COM# 0,0,SNR ;SUBDIRECTORY? JMP RMRET ;YES, NOTHING TO DO ; WE FLUSH DEVICE BUFFERS EVEN IF ONLY RELEASING A SUBPARTITION ; OUT OF BOUNTEOUS BENEVOLENCE TO NON-IPB SHARED@ DISK USERS LDA 1,DCBDC,2 ;DCT LDA 0,DCBUN,2 ; & UNIT # JSR @.BFLUSH ;GET RID OF ALL MY BUFFERS RTRN ;ERROR ;NOTE: ALL I/O HAS SETTLED AT THIS POINT LDA 0,SFTYPE,2 MOV# 0,0,SZR ;IS IT A SUBPARTITION? JMP RMRET ;YES, DON'T REMOVE BAD BLOCK T*ABLE LDA 2,DCBDCT,2 ;UNIT DCT LDA 1,DCTBL,2 ;BAD BLOCK TABLE LINK COM# 1,1,SNR ;IS THERE ONE? JMP RMRET ;NO (THIS CAN HAPPEN IF WE ARE ; CALLED BY DVINI ERROR PATH) STA 1,DEST,3 ;YES, REMEMBER WHERE IT IS ADC 0,0 STA 0,DCTBL,2 ;EVERYBODY ELSE )FORGET MOV 1,2 LDA 0,BELEN,2 ;PICK UP IMAGE LENGTH ADD 0,2 LDA 0,EXTRA ;SIZE OF HEADER + LINK ADD 0,2 ;MAKE POINTER TO NEXT TABLE STA 2,FROM,3 ;REMEMBER THAT LDA 2,-1,2 ;PICK UP LINK OF OUR TABLE JMP LNKIN ;FREE UP THE TABLE'S OVERFLOW LIST LN KLP: LDA 1,BLLK,2 ;POINTER TO NEXT NODE INTDS ;DON'T LET FIXWRITE INTERFERE LDA 0,@.BLIST ;HEAD OF FREE LINK (NODE) LIST STA 0,BLLK,2 ;PUT THIS NODE ON THE LIST STA 2,@.BLIST INTEN MOV 1,2 ;INDEX ON NEXT NODE TO RELEASE LNKIN: COM# 2,2,SZR ;END OmF OVERFLOW LIST? JMP LNKLP ;NOPE LDA 1,DEST,3 ;POINTER TO OUR TABLE LDA 2,FROM,3 ;POINTER TO NEXT TABLE JMP SQIN ;REMOVE MAIN (CONTIGUOUS) PORTION OF TABLE BY MOVING THE REST OF ; THE POOL DOWN ON TOP OF IT, ONE BAD BLOCK TABLE AT A TIME SQUASH: LD A 2,BEUNI,2 ;UNIT DCT LDA 3,DCTPD,2 ;REAL DEVICE DCT LDA 0,DCTMS,3 ;DEVICE MASK LDA 3,CSP COM 0,0 INTDS LDA 1,CMSK STA 1,SVMSK,3 ;SAVE CURRENT MASK AND 0,1 ;MASK OUT THE TABLE'S DEVICE ADC 0,1 STA 1,CMSK MSKO 1 INTEN LDA 1,DEST,3 ;STORE NEW BQAD BLOCK TABLE POINTER STA 1,DCTBL,2 ; IN UNIT DCT LDA 0,FROM,3 ;FROM ADDRESS IN AC0 FOR MVWD MOV 0,2 ;INDEX ON NEXT TABLE LDA 2,BELEN,2 LDA 1,EXTRA ADD 1,2 ;ITS LENGTH LDA 1,DEST,3 ;DESTINATION JSR @.MVWD ;MOVE TABLE DOWN ADD 2,1 STA 1,DEST,3T ;NEXT DESTINATION ADD 0,2 ;NEXT TABLE STA 2,FROM,3 LDA 0,SVMSK,3 INTDS STA 0,CMSK ;RESTORE MASK MSKO 0 INTEN SQIN: LDA 0,@.ENCONT USGE 2,0 ;DONE ALL THE MOVING NECESSARY? JMP SQUASH ;NOT YET STA 1,@.ENCONT ;NEW END OF SQUASHED POOL RMRET: GISZ ORTN,3 ;GOOD RETURN RTRN DNIS: LDA 2,DMNER JSR @.RETE2 .OVLY1: OVLY1 DMNER: ERDNM .BFLUSH:BFLUSH EXTRA: BEXSZ .BLIST:BLIST .ENCONT:ENCONT .MVWD: MVWD ; ROUTINE TO INITIALIZE A DIRECTORY FOR ACCESS ; ; INPUTS: AC0 - BYTE POINTER TO DIRECTORY NAME STRING ; AC2 - DCB ADDRESS CURDB=OAC2 PBA1=TMP ; THIS OFFSET USED TWICE CURBP=TMP+1 UNPKA=CURBP+1 TERM=UNPKA+1 VACDB=TERM+1 BFAD=VACDB+1 PBA=BFAD ATBTS=BFAD+1 ; DCB USER COUNT PROGRAM FLAGS ; 1B0=BACKROUND ; 1B1=FOREGROUND NOINIT: STINI INIT: STA 0,CURBP,3 ; SAVE INPUT AS CURRENT BYTE ; POINTER STA 2,CURDB,3 ; SAVE INPUT DCB AS CURRENT LDA 2,CQ ; CURRENT QUEUE LDA 1,QSUFP,2 ; UNPACK ADDRESS STA 1,UNPKA,3 ; SAVE UNPACK ADDRESS INTLP: LDA 0,CURBP,3 ; CURRENT BYTE POINTER LDA h1,UNPKA,3 ; UNPACK ADDRESS SUBZL 2,2 ;MAPPED JSR @.OVLAY NAMCK ; CHECK & UNPACK NAME STA 0,CURBP,3 ; SAVE UPDATED BYTE POINTER STA 2,TERM,3 ; & THE TERMINATOR JSR @.OVLAY SDIRR ; SEARCH THE DCB RING JMP NOTFD ; NOT FOUND, JUMP DOWN & LOOK d ; AROUND INIT2: STA 2,CURDB,3 ; GOT IT! SAVE IT LDA 1,DCBST,2 ; GET STATUS MOVL# 1,1,SNC ; IS IT INIT'D ? JMP INTED ; YES LDA 0,NOINIT ; NO INIT MASK AND# 1,0,SZR ; IS INIT POSSIBLE ? JMP DNIS ; NO, TOO BAD JMP INTOK ; NO, INIT IS OK .OVLAY: j<12>! FGWD: "F BGWD: "B LNFD: 12 C6: 6 C4: 4 STSWD: BSFBF ; RELEASE BUFFER UPON REQUEST ; COMPLETION CRMASK: 15 .TTODCT: TTODCT .ASBUF: ASBUF .IFN MSW .MLDBT: MLDBT .ENDC EXCP: "! SPAC: 40 .IFE BSW!MBSW .LDBT: LDBT .STBT: STBT .ENDC ENDOV .END SOV15.SRB S[ RTITLE SOV15 SV15 .NREL .ENT CDIR .ENT CPART .EXTN CFNAM .EXTN CLEAR .EXTN OVLAY .EXTN SRUFD .EXTN CRINI,CRINL .EXTN DUNLOCK ;DUAL PROCESSOR .EXTN WDCBK,DEBLK .EXTN CRMAP .EXTN CSYSD .EXTN CRMPE .EXTN RETER .EXTN DELFIL .EXTN MAPNM .;EXTN FNDCB .EXTN RELPB .EXTN TSTEQ ;***************************************** ; NUMBER OF STACK TEMPORARIES USED ; MUST BE THE FIRST WORD IN THE OVERLAY .IFN BSW!MBSW 10 .ENDC ; ROUTINE TO CREATE A PARTITON OR SUB-DIRECTORY ; ; INPUTS: AC0 - B;YTE POINTER TO NAME ; AC1 - NUMBER OF BLOCS FOR A PARTITON ;  OR IGNORED FOR A SUB-DIRECTORY BLKCT=TMP BFAD=BLKCT+1 TDCB=BFAD+1 NDCB=TDCB+1 FRSAD=NDCB+1 QUFT=FRSAD+1 FRSA1=QUFT+1 ULKY=FRSA1+1 CDIR: SUBZL 1,1 ; INITIAL DIRECTORY SIZE = 1 JMP CREAT ; MAKE ONE SIZMS: 177760 PARSZ: 48. ENTLG: UFDEL .CLEAR: CLEAR EXTSN: "D*400+"R CPART: LDA 2,@CC ; TCB ADDRESS LDA 1,TAC1,2 ; USER'S AC1 (SCHEDULER DOESN'T PASS IT) LDA 0,SIZMS ; TRUNCATE MOD 16 AND 0,1 LDA 0,PARSZ ; MINIMUM PARTITION SIZE ADCO 1,0,SNC ; IS SIZE SUFFICIENT ? JMP CPERR ; NO CREAT: STA 1,BLKCT,3 ; SAVE NECESSARY BLOCK COUNT LDA 2,CQ ; CURRENT QUEUE LDA 2,QSUFP,2 ; QUEUE UFD ADDRESS STA 2,QUFT,3 ; SAVE UFT ADDRESS LDA 0,ENTLG ; SIZE OF UFT JSR @.CLEAR ; CLEAN IToh OUT MOV 2,1 ; UFT ADDRESS TO AC1 LDA 0,OAC0,3 ; BYTE POINTER TO NAME JSR @.OVLAY ; GET BASE DCB ADDRESS CFNAM ; & UNPACK NAME LDA 0,SFLK,2 ;MAP LINK COM# 0,0,SNR ;IS THERE ONE? JSR ILCM ;NO PARTITIONS ON MAG TAPE STA 2,TDCB,3 ; SAVE DCB ADD{RESS LDA 3,QUFT,3 ; UFT ADDRESS TO AC3 LDA 0,EXTSN ; DIRECTORY EXTENSION STA 0,UFTEX,3 ; SET INTO UFT MOV 3,0 ; UFT ADDRESS TO AC0 JSR @.OVLAY SRUFD ; LOOK FOR THE ENTRY JMP TSTER ; SOME ERROR - TEST IT JMP FAEER ; FILE ALREADY EXISTS ERROR CRTOK: LDA 0,SFEL+SFLK,2 ; DCB TYPE WORD LDA 1,BLKCT,3 ; PICK UP BLK CNT, =1 IF SUBDIR MOV# 0,0,SNR ; PRIMARY PARTITION DCB ? JMP LEGAL ; YES, CAN CREATE ANYTHING MOVL# 0,0,SZC ; NO, SUB-DIRECTORY DCB ? JMP LEVER ; YES, CAN CREATE NOTHING MOV9ZR# 1,1,SZR ; NO, CAN ONLY CREATE DIRECTORY JMP LEVER ; CAN'T MAKE SUB-SUB-PARTITIONS LEGAL: JSR @.OVLAY WDCBK ; ALLOCATE SPACE (AC1=COUNT) RTRN ; ERROR STA 1,FRSAD,3 ; SAVE FIRST ADDRESS STA 0,FRSA1,3 ; SAVE START ADDRESS LDA 2,QUFT,3 ; UFTS ADDRESS STA 1,UFTAD,2 ; PUT ADDRESS IN UFT MOVS 0,0 ; INTO LEFT BYTE STA 0,UFTDL,2 ; SAVE IT LDA 1,BLKCT,3 ; SIZE NEG 1,0 COM 0,0 STA 0,UFTBK,2 ; SET BLOCK COUNT LDA 0,BLKSZ ; BLOCK SIZE STA 0,UFTBC,2 ; INTO BYTE COUNT LDA 0,PARAT ; PARTITIONO ATTRIBUTES MOVZR# 1,1,SNR ; IF BLOCK COUNT=1, CDIR ENTRY LDA 0,DIRAT ; DIRECTORY ATTRIBUTES STA 0,UFTAT,2 ; TO UFT MOV 2,1 ; UFT TO AC1 LDA 2,TDCB,3 ; SYS.DR'S DCB ADDRESS LDA 3,DCBDC,2 ; PARENT'S DCT LDA 0,DCTCD,3 ; PARENT'S DEVICE CODE MOV 1,\3 ; UFT ADDRESS LDA 1,UFTDL,3 ; START ADDRESS IN LEFT BYTE ADD 0,1 ; ADD IN DEVICE CODE STA 1,UFTDL,3 ; SET IN DEVICE LINK LDA 3,CSP LDA 1,QUFT,3 ; UFT ADDRESS ADDOR 1,1 ;SET SIGN BIT: WANT TIME SET UP JSR @.OVLAY CRINL ; CREATE THE ENTRY, & LOCK IT JMP BACKSPC ;ERROR ON THE CREATE - MUST ; RELEASE WITHDRAWN SPACE STA 0,ULKY,3 ;SAVE LOCK KEY LDA 2,@CRSEG ; THIS OVERLAY'S BASE ISZ BQUSC,2 ; LOCK ME IN LDA 0,MPDBP ; MAP DCB POINTER ADD 2,0 ; TRUE DCB ADDRESS LDA 1,SYDBP ; SYS.D+KR DCB POINTER ADD 1,2 ; TRUE SYS.DR DCB ADDRESS STA 2,NDCB,3 ; SAVE ON THE STACK STA 0,SFLK,2 ; LINK THEM TOGETHER LDA 0,FRSAD,3 ; RECOVER FIRST ADDRESS STA 0,DCBFA,2 ; SET AS FA. NOTE: LDA 0,FRSA1,3 ; THIS ASSUMES SCSYS=0 STA 0,DBFA1,2 ; HIGH ORDEOR, TOO LDA 1,TDCB,3 ; & PARENT'S DCB JSR @.FNDCB ; FULL INIT IT STA 2,DCBDR,2 ; POINT TO TEMPLATE MOV 1,3 ;PARENT DCB LDA 0,SFMSZ,3 ;COPY PARENT FRAME SIZE STA 0,SFMSZ,2 ;TO NEW SYS.DR DCB LDA 0,DBFA1,2 ; GET FIRST ADDRESS LDA 1,DCBFA,2 LDA 3,MA>POF ADDZ 3,1,SZC ;FIND MAP.DR BASE ADDRESS INC 0,0 LDA 2,SFLK,2 ; MAP DCB STA 0,DBFA1,2 ; SET IN FIRST ADDRESS OF MAP STA 1,DCBFA,2 LDA 3,CSP LDA 1,NDCB,3 ;RECOVER TEMPLATE DCB ADDRESS JSR @.FNDCB ; FULL INIT IT STA 1,DCBDR,2 ; POINT TO TEMPLATE MOV 1,2 ; PHAQUE SYS.DR DCB LDA 0,BLKCT,3 ; ENTRY SWITCH MOVZR# 0,0,SNR ; CDIR ENTRY ? JMP CDRET ; YES LDA 1,BLKCT,3 ; TOTAL BLOCK COUNT SUB 0,0 ;HIGH ORDER ALWAYS ZERO JSR @.OVLAY CRMAP ; CREATE A MAP JMP ERTN ; ERROR JMP MKSYS ; NOW CREATE SYS.DR ILCM: JSR @.RETER ERIDS CPERR: JSR @.RETER ;PARTITION SIZE TOO SMALL ERD2S .OVLAY: OVLAY LEVER: JSR @.RETER ERDDE ; DIRECTORY DEPTH EXCEEDED FAEER: JSR @.RELPB JSR @.RETER ERCRE TSTER: JSR @.TSTEQ ; TEST FOR FILE NOT FOUND ERDL[bE RTRN ; WRONG ERROR - BAG IT JMP CRTOK ; CORRECT ERROR - PROCEED CDRET: LDA 2,TDCB,3 ; PARENT'S SYS.DR DCB LDA 0,SFLK,2 ; PARENT'S MAP DCB MOV 1,2 ; TEMPLATE DCB STA 0,SFLK,2 ; LINK TEMPLATE TO PARENT'S MAP MKSYS: JSR @.OVLAY ; MAKE SYS.DR WIT HOUT CSYSD ; PRE-ALLOCATION JMP ERTN ; ERROR LDA 1,BLKCT,3 ; ENTRY SWITCH MOVZR# 1,1,SNR ; CDIR ENTRY ? JMP CPSMP ; YES, CREATE PSEUDO-MAP JSR @.OVLAY ; NO, CREATE REAL MAP.DR ENTRY CRMPE JMP ERTN ; ERROR ISZ ORTN,3 ; GOOD RETURN NOWk) NRET: LDA 2,@CRSEG ; THIS OVERLAY'S BASE DSZ BQUSC,2 ; UNLOCK NOW URET: LDA 0,ULKY,3 ;PICK UP UNLOCK KEY JSR @.DUNLOCK ;UNLOCK DIRECTORY BLOCK RTRN CPSMP: LDA 0,MAPPT ; MAP.DR NAME POINTER LDA 2,TDCB,3 ; PARENT'S DCB JSR @.OVLAY SRUFD ; FIND PARENT'S MAP ENTRY JMP NRET ; CAN'T FIND IT - TROUBLE MOV 2,0 ; SAVE BUFFER ADDRESS LDA 2,NDCB,3 ; NEW DCB JSR @.OVLAY CRINI ; CREATE DUPLICATE MAP ENTRY JMP .+2 ; ERROR ISZ ORTN,3 ; GOOD RETURN NOW MOV 0,2 ; BUFFER TO AC2 JSR @.RELPB ; RELEASE IT JMP NRET PARAT: ATPAR+ATDIR+ATCON DIRAT: ATDIR+ATRAN BLKSZ: SCDBS*2 MPDBP: MPDCB SYDBP: SYDCB MAPPT: MAPNM MAPOF: SCMAP .FNDCB: FNDCB .RELPB: RELPB .RETER: RETER .TSTEQ: TSTEQ .DUNLOCK: DUNLOCK BACKSPC:LDA 0,FRSA1,3 LDA 1,FRSAD,3 ;START AT FIRST BLOCK BKSP1: JSR @.OVLAY ;RETURN A BLOCK DEBLK RTRN ;WHAT CAN I SAY? INC 1,1,SNR ;GET READY FOR NEXT INC 0,0 ;OVERFLOW DSZ BLKCT,3 ;GOT EM ALL? JMP BKSP1 ;NOT YET RTRN  ;GET OUT ERTN: LDA 2,@CRSEG ; MY BASE ADDRESS DSZ BQUSC,2 ; UNLOCK THIS OVERLAY LDA 0,OAC0,3 ; RECOVER BYTE POINTER JSR @.OVLAY DELFIL ; DELETE THE FILE JMP URET ; WE'ER UP TO OUR ASS IN JMP URET ; ALLIGATORS NOW ! ; - STILL, MUST UNLOCK ; PSEUDO DCB PAIR .BLK SFDCB-SFMSZ SYDCB: .BLK DCBFA-DCBIyDC+1 .BLK SFDCB-SFLK MPDCB: .BLK DCBFA-DCBDC+1 END=. ENDOV .END SOV16.SRB `  RTITLE SOV16 SV16 .NREL .ENT IDEF .IFN MSW .ENT DSET .ENDC .ENT DDIS,DEBL .EXTN SYSFG .EXTN SYSER .EXTN CFPU .EXTN ITBL .IFN MSW .IFE MBSW .EXTD CMAP .ENDC .EXTD MAPCC .EXTN UITBL .EXTN MDCH1,MDCH2 .ENDC .EXTN FPUSV .EXTN IUD .IFN BSW!MBSW .EXTN UDEX .ENDC ;***************************************** ; NUMBER OF STACK TEMPORARIES USED ; MUST BE THE FIRST WORD IN THE OVERLAY .IFN BSW!MBSW 1 .ENDC ; CALL TO EITHER ENABLE OR DISABLE A DEV ACCESS ; AC0= CODE DDIS: SUB 3,3t,SKP DEBL: SUBZL 3,3 LDA 1,LLDC ;SEE IF CODE VALID SUBZ 0,1,SNC ;VALIDATE JMP IDER2 ;EAT MOV# 0,0,SNR JMP IDER2 ;A REAL 0 MOV# 1,1,SNR ;SKIP IF NOT 77 JMP DC1 LDA 1,CNFPU ;SEE IF FPU ADCZ# 0,1,SZC JMP DC1 ;NO ;FPU DEV- SET/RESET RDOS STATEK FLAG LDA 2,CC LDA 1,CPROG,2 ;SEE IF FG ADCZL 2,2 ;MASK FOR BG MOVZR# 1,1,SNR ADCZR 2,2 ;FG LDA@ 1,.FPUSV ;SAVE NEEDED WORD AND 2,1 ;RESET MOV# 3,3,SZR ;SKIP IF RESET IS FUNCTION ADC 2,1 ;SET BIT STA@ 1,.FPUSV LDA 2,CC LDA 2,CPTAD,2 .IFNz ANSW MOVZL# 1,1,SBN ;SKIP IF BOTH ENABLED .ENDC .IFN ABSW MOVZL# 1,1,SEZ ; IF BOTH ENABLED THEN JMP DC0 ; SKIP INIT OF FPU ELSE FTD ; DISABLE TRAPPING FSS 0,0 ; AND INIT FP REGS FSS 1,1 FSS 2,2 FSS 3,3 .ENDC STA@ 2,.CFPU ;SET FIRST TO U}SE AS CURRENT DC0: .IFN MBSW JMP IEX2 ;ALL DONE IF MAPPED BIRD .ENDC DC1: .IFE MSW JMP IEX2 ;EXIT .ENDC .IFN MSW MOV# 3,3,SZR ;GO SET/RESET AND EXIT JMP DRSET JMP DSET .ENDC C377: 377 CNFPU: FPU1 LLDC: CPU .FPUSV: FPUSV IDER2: INTEN JSR@ .SER1 ERDNM .CFPU: CFPU ; SUBROUTINE TO FIND DEV PROTECT SLOT ; AC0= DEV CODE ON ENTRY .IFN MSW DSET: SUB 1,1,SKP DRSET: SUBZL 1,1 LDA 3,CSP STA 1,TMP,3 ;SAVE TYPE LDA 3,C377 ;GET JUST DEVICE CODE AND 3,0 LDA 3,CC LDA 3,CPTAD,3 MOVZR 0,1 ;DIVB BY 8 MOVZR 1,1 MOVZR 1,1 LDA 2,.PDEV ADD 3,2 ;SLOT ADDR ADD 1,2 ;ADD DEV LDA 3,C7 ;GET BIT AND 0,3 LDA 1,CIMSK ;BIT PATTERN TO SHIFT NEG 3,3,SNR ;BIT COUNT JMP DSET1 MOVOR 1,1 ;DEV BIT MOVES LEFT INC 3,3,SZR JMP .-2 DSET1: LDA 0,0,2 ;S;ET OR RESET BIT AND 1,0 LDA 3,CSP DSZ TMP,3 ;SEE IF SET ADC 1,0 ;YUP STA 0,0,2 .IFE MBSW SUB 0,0 STA 0,CMAP ;FORCE MAP .ENDC .IFN B?MSW SMST 0 ;TO MAP .ENDC .ENDC IEX2: INTEN LDA 3,CSP ISZ ORTN,3 RTRN .IFN MSW .PDEV: PDEV C7: 7 CIMSK: '177577 .ENDC ;DEFINE A USER DEVICE IN THE INTERRUPT VECTOR TABLE ; USER AC0=DEV CODE, AC1=DCT (1B0=1 => DATA CHANNEL DEVICE ; AND AC2=NUMBER OF NEEDED SLOTS IN DCH MAP) IDEF: LDA@ 2,CC ;TCB LDA 3,.ITBL ;VECTOR TABLE ADDR LDA 0,TAC0,2 ;DEV ADD 0#,3 ; TABLE ADDRESS+1 LDA 1,LLDC ; LAST LEGAL DEVICE CODE SUBZ# 0,1,SNC ; IS DEVICE CODE <= 77 ? JMP .+2 ;ERROR MOV# 0,0,SNR ;= 0 JMP IDER2 ;GOTCHA LDA 1,-1,3 ;CURRENT VECTOR LDA 2,.IUD SUB 1,2 ;SOMEONE HOME? MOVZL# 2,2,SZR ;(IGNORE SIGN BIT) JMP IDER1 ;TWO'S A CROWD .IFN MSW ; FIND A SLOT IN USER INT TABLE INTDS ;RDOS CAN'T BEAR TO LOOK LDA 2,.UITB ;BASE COM# 2,2,SNR JMP IDER1 ;SYSGEN TIME AT THE RANCH IDEF2: LDA 1,UIDCD,2 ;FREE ? MOV# 1,1,SNR JMP IDEF3 ;YES COM# 1,1,SNR ;OUT OF SLOTS ? JMP IDER1 ;YES INC 2,2 INC 2,2 .IFN MBSW ADI 4,2 .ENDC JMP IDEF2 .ENDC S JMP IDEF4 [S] .SER1: SYSER .IFN MSW ; BRIDGE TO OBLIVION .DRSET: JMP DRSET IDEF3: MOV 3,1 ;SAVE 3 LDA 3,CC LDA 3,CPROG,3 ;SEE IF FG MOVZR# 3,3,SNR ;wSKIP IF NO ADDOR 0,0 ;FLAG DEV CODE STA 0,UIDCD,2 ;TO TABLE STA 2,TSLOT ;REMEMBER ADDRESS IN UITBL MOV 1,3 ;RESTORE AC3 .IFN MBSW MOVL 2,2 MOVOR 2,2 ;SET 1B0 IN UITBL POINTER ADI 2,2 ;POINT TO DCT IN UITBL ENTRY STA 2,-1,3 ;PUT THAT IN ITBL  .ENDC .ENDC IDEF4: LDA@ 2,CC LDA 1,TAC1,2 ;USER DCT .IFN MSW LDA 2,TAC2,2 ;IF DCH - NUMBER OF NEEDED SLOTS NEG 2,2 MOVZL 1,1,SNC ;DEVICE USE DCH? SUB 2,2 ;NO - FORCE TO ZERO STA 2,SLOTS ;AND REMEMBER FOR LATER .ENDC .IFE MSW MOVZL 1,1 .ENDC6 .IFE BSW!MBSW MOVZR 1,1 ;INSURE DCT HAS 1B0 RESET STA 1,-1,3 ;TO TABLE .ENDC .IFN BSW MOVOR 1,2 ;SET 1B0 STA 2,-1,3 ;PUT IN ITBL LDA 1,.UDEX ;ADDRESS OF COMMON USER INT ; ROUTINE LDA @3,CC ; GET TCB ADDRESS LDA 3,TAC0,3 ; DEV CODE FROM USER TCB LDA 0,C77 ; CPU DEVICE CODE SUB# 0,3,SZR ; POWER UP .IDEF ? STA 1,0,2 ;PUT IN FIRST WORD OF USER DCT .ENDC .IFN MBSW LDA 2,TSLOT ;ADDRESS IN UITBL MOVZR 1,3 ;USER DCT ADDRESS STA 3,UIDCT,2 ; STORE FOR LATER PSH 2,2 ; SAVE AC2 JSR %MAPCC ; SET UP THE MAP POP 2,2 ; RESTORE AC2 LDA 3,UIDCT,2 ; RECOVER DCT ADDRESS MLDA 1,DCTMS,3 ;MASK (FROM USER SPACE DCT) STA 1,UIMSK,2 ;STORE IN DCT IN UITBL MLDA 1,DCTIS,3 ;USER INT HANDLER ADDRESS STA 1,UIDIS,2 ;TO DCT LDA 1,.UDEX ; SET COMMON INTERUPT SERVICE ADDRESS STA 1,UIDEX,2 ; UITBL .ENDC .IFE MSW JMP IEX2 .ENDC .IFN MSW LDA 3,CC LDA 3,CPTAD,3 LDA 1,PFLAG,3 MOVR 1,1 MOVOL 1,1 STA 1,PFLAG,3 ;SET DIRTY BIT LDA 1,PDEV+7,3 ;LAST DEV MOVR 1,1 ;ENABLE CPU MOVZL 1,1 .IFN B?MSW SMST 1 ;SET IN MAP SLOT TOO .ENDC STA 1,PDEV+7,3 LDA 2,SLOTS ;NUMBER OF SLOTS IN DCH MAP FOR ; DEVICE MOV# 2,2,SNR ;=0? JMP NODCH ;YES - DEVICE DOES NOT USE DATA ; CHANNEL LDA 3,C16 LDA@ 0,WORD1 ;GET FIRST WORD OF BIT MAP - ; MUST FIND ADC 2,2 ;CORRECT NUMBER OF CONTINGUOUS ; SLOTS ST: MOV# 0,0,SNR ;THIS WORD EXHAUSTED? JMP GTSXT ;YES - TRY NEXT WORD LDA 1,SLOTS ;GET COUNT OF NEEDED SLOTS INC 2,2 ;RUNNING COUNTER OF SLOT NUMBER MOVZL 0,0,SNC ;NEXT SLOT OPEN? JMP .-12 ;NO - KEEP LOOKING ST1: INC 2,2 ;YES - UPDATE RUNNING COUNTER INC 1,1,SNR ;AND SEE IF WE HAVE ENOUGH JMP GOTIT ;YES MOVZL 0,0,SZC ;NO - IS NEXT SLOT OPEN? JMP ST1 ;YES - KEEP COUNTING SUB# 3,2,SZR ;NO - AT END OF WORD? JMP ST ;NO - RESTART COUNT LDA@ 0,WORD2 ;GET MDCH2 MOV# 0,0,SNR ;ANYTHING THERE? JMP IDER3 ;NO - ERROR MOVZL 0,0,SNC ;LOOK FOR OPEN SLOTS JMP RETWO ;NOT OPEN - RESTART COUNT INC 2,2 ;RUNNING COUNTER INC 1,1,SZR ;COUNT OF AVAILABLE SLOTS JMP .-4 ;AND KEEP LOOKING JMP GOTIT ;FOUND ENOUGH GTSXT: LDA@ 0,WORD2 LDA 2,C15 ;START AT BEGINNING OF SECOND ; WORD RETWO: MOV# 0,0,SNR ;ANY THERE? JMP IDER3 ;NO - CAN'T BE ENOUGH LDA 1,SLOTS ;RESET COUNT OF GOOD SLOTS INC 2,2 ;INC RUNNING POINTER MOVZL 0,0,SNC  ;AVAILABLE? JMP .-2 ;NO INC 2,2 INC 1,1,SNR ;FOUND ONE - ENOUGH? JMP GOTIT ;YES MOVZL 0,0,SZC ;NO-KEEP LOOKING JMP .-4 MOVZL 3,3 ;MAKE AC3=32. SUB 3,2,SZR ;AT END? JMP RETWO ;NO JMP IDER3 ;YES - NOT ENOUGH AVAILABLE ; SLOTS .ENDC i IDER1: INTEN JSR@ .SER1 ERIBS .ITBL: ITBL .IUD: IUD .IFN BSW C77: 77 ; CPU DEVICE CODE .ENDC .IFN MSW .UITBL: UITBL SLOTS: 0 TSLOT: 0 GOTIT: LDA 1,SLOTS ADD 1,2 ;NUMBER OF FIRST OF SET OF ; AVAILABLE SLOTSS NEG 2,0 NEGS 1,1 ADD 1,2 ;L'dH = NUMBER OF SLOTS LDA 3,TSLOT ;ADDRESS IN UITBL STA 2,UIDCH,3 ;REMEMBER INFO LDA 1,SLOTS ;MUST RESET BITS OF ALLOCATTED ; SLOTS ADC 2,2 ADCO 3,3 MOVZR 2,2 MOVR 3,3 INC 1,1,SZR ;CORRECT NUMBER OF ZEROES? JMP .-3 MOVOR 2,2 ;POSITION NUMBEC(R OF HOLES MOVR 3,3 INC 0,0,SZR ;AT FIRST POS? JMP .-3 ;NO - KEEP SHIFTING LDA@ 0,WORD1 AND 2,0 STA@ 0,WORD1 ;WITH RESET BITS LDA@ 1,WORD2 ;GET SECOND WORD AND 3,1 ;TURN OFF CORRECT BITS STA@ 1,WORD2 ;AND REMEMBER IT LDA 3,TSLOT ;ADDR IN RjUITBL LDA 0,UIDCD,3 ;GET DEVICE CODE JMP .DRSET ;ENABLE BIT FOR MAP AND EXIT NODCH: LDA 3,TSLOT STA 2,UIDCH,3 ;ZERO DCH ASSIGNMENTS JMP .DRSET .ENDC .IFN BSW!MBSW .UDEX: @UDEX .ENDC .IFN MSW IDER3: LDA 3,TSLOT LDA 1,UIDCD,3 ; GET DEVICE CODE LDA 2,.ITBL ; INTERUPT VECTOR TABLE ADD 1,2 ; POINT TO ENTRY (ALMOST) LDA 1,.IUD ; UNKNOWN INTERUPT VECTOR OR -1 STA 1,-1,2 ; TOLD YOU ADDRESS WAS ALMOST THERE SUB 1,1 STA 1,UIDCD,3 ;RETURN SPACE IN UITBL STA 1,UIDCH,3 INTEN JSR@ ..SER1 ERDCHE ;"NOT ENOUGH ROOM IN DATA ; CHANNEL MAP" .ENDC .IFN MSW C15: 15. C16: 16. WORD1: MDCH1 WORD2: MDCH2 ..SER1: SYSER .ENDC ENDOV .END FILS2.SRB S ! RTITLE FILS2 FLS2 .NREL .ENT DELPP ; PARTITION/SUB-DIRECTORY DELETE .ENT RNAM ; FILE RENAMER ; PRE-PROCESSOR .EXTN SRUFD .EXTN OVLAY .EXTN SYSNM .EXTN MAPNM .EXTN RELZT,RELMB .EXTN CMPWD .EXTN FIDCB .EXTN GCELL .EXTN CREL .EXTN RDBLK .EXTN MVWD .EXTN TRDEL .EXTN PEND .EXTN CFNAM .EXTN CRINI .EXTN CSTAT .EXTN FLUSH .EXTN SDIRR .EXTN TSTEQ ;***************************************** ; NUMBER OF STACK TEMPORARIES USED ; MUST BE THE FIRST WORD IN THE OVERLAY .IFN BSW!MBSW 0l10 .ENDC ; ROUTINE TO RENAME A FILE IN A DIRECTORY ; ; INPUTS: AC0 - OLD NAME BYTE POINTER ; TAC1 - NEW NAME BYTE POINTER ; ; OUTPUTS: NONE ; ; RETURNS: CALL+1 - ERROR...ERROR CODE IN AC2 ; CALL+2 - GOOD RETURN ; ; ERROR CODES: ERCRE ; ERDIR ;  ERFIU ; ERDE1 ; ERDIU TNEWP=TMP TDCB=TNEWP+1 SBAD=TDCB+1 NAMPT=SBAD+1 RNAM: LDA 2,CQ ; CURRENT QUEUE LDA 1,QSUFP,2 ; QUEUE UFT POINTER STA 1,NAMPT,3 ; SAVE ON STACK JSR @.OVLAY CFNAM ; CHECK & UNPACK OLD NAME STA 2,TDCB,3 ; SAVE OLD FILE'S;{ DCB MOV 1,2 ; INDEX ON UNPACKED NAME LDA 0,UFTEX,2 ; GET OLD EXTENSION LDA 2,DREXT ; AND .DR EXTENSION SUB# 0,2,SZR ; POSSIBLE DIRECTORY ENTRY JMP NODIR ; NO, PROCEED JSR @.OVLAY ; YES, LOOK IN MAIN MEMORY SDIRR JMP NODIR ; NOT THERE JMP DISRIU ; FOUND, DIRECTORY IN USE ERROR NODIR: LDA 0,NAMPT,3 ; GET POINTER TO UNPACKED NAME LDA 2,TDCB,3 ; & DCB ADDRESS JSR @.OVLAY CSTAT ; GET STATUS WITHOUT LINKING JMP FNFE1 ; FILE NOT FOUND ERROR MOV 0,2 ; INDEX ON UFT LDA 0,UFTAT,2 ; ATTRIBUTE&S LDA 1,LNKAT ; LINK ATTRIBUTE AND# 0,1,SZR ; IS THIS A LINK ? JMP RNMOK ; YES, RENAME OK LDA 1,UFTUC,2 ; NO, GET USER COUNT MOV# 1,1,SZR ; IS FILE IN USE ? JMP FIUER ; YES, CAN'T RENAME NOW LDA 1,PERM ; NO, GET PERMENANT ATTRIBUTE AND# 0,1,SZR ; IS THIS A PERMENANT FILE ? JMP PERER ; YES, NO RENAMES, RAJ RNMOK: LDA 2,@CC ; TCB ADDRESS LDA 0,TAC1,2 ; NEW NAME BYTE POINTER LDA 1,NAMPT,3 ; QUEUE UFT POINTER JSR @.OVLAY CFNAM ; UNPACK NEW NAME IN OLD UFD LDA 0,TDCB,3 ; OLD DCB SUB# 0,2,SZR ; BOTH IN SAME DIRECTORY ? JMP ILDEV ; NO, YOU CAN'T DO THAT JSR @.OVLAY CRINI ; CREATE NEW ENTRY WITH OLD INFO JMP RETEN ; ERROR - RETURN TO CALL+1 LDA 0,OAC0,3 ; OLD NAME POINTER AGAIN JSR @.OVLAY CFNAM ; UNPACK AGAIN MOV 1,0 ; UFD ASDDRESS TO AC0 JSR @.OVLAY SRUFD ; SEARCH FOR OLD ENTRY JMP RETEN ; ERROR - BAG IT MOV 1,3 ; ENTRY TO AC3 SUB 1,1 ; +0 STA 1,UFTFN,3 ; CLEAR FIRST WORD OF ENTRY DSZ 0,2 ; ONE LESS ENTRY JMP .+1 ; MAY NOT BE ZERO JMP GRET ; FLUSH & GO HOME hZ FNFE1: LDA 0,FNFEC ; FILE NOT FOUND ERROR CODE JMP ERET ILDEV: LDA 0,UCDTE ; YOU CAN'T DO THAT ERROR JMP ERET DIRIU: LDA 0,DIUE1 ; DIRECTORY IN USE JMP ERET FIUER: LDA 0,FIUEC ; FILE IN USE ERROR JMP ERET PERER: LDA 0,PEREC ; CAN'T ALTER A PpbERMENANT FILE JMP ERET ERET: LDA 2,CC ; CURRENT CELL STA 0,CTMP2,2 ; RETURN ERROR CODE JMP RETEN ; FLUSH & GET OFF THE POT GRET: JSR @.RELMB ;RELEASE MODIFIED ISZ ORTN,3 ; GOOD (CALL+2) RETURN NOW RETEN: JSR @.FLUSH ; FLUSH AGAIN RTRN ; THIS fIS YOUR BASIC SUBROUTINE ; RETURN UCDTE: ERDIR FIUEC: ERFIU PEREC: ERDE1 DIUE1: ERDIU DREXT: "D*400+"R PERM: ATPER LNKAT: ATLNK .OVLAY: OVLAY FNFEC: ERDLE .FLUSH: FLUSH .RELMB: RELMB ; PRE-PROCESSING CODE USED FOR DELETION OF PARTITIONS ; AND DIRECTORIES ; ; INPUTS: AC0 - ATTRIBUTES ; AC1 - ENTRY ADDRESS ; AC2 - DCB ADDRESS ; STACK PARAMETERS BFAD=TMP ;BUFFER ADDRESS ENTCT=BFAD+1 SAVAT=ENTCT+1 DIRDL=SAVAT+1 ENTAD=DIRDL+1 FRSAD=ENTAD+1 QUFT=FRSAD+1 FRSA1=QUFT+1 TUFT=OAC1 TPDCB=OAC"Q2 DELPP: MOV 1,2 ; ENTRY ADDRESS TO AC2 LDA 0,UFTDL,2 ; DEVICE LINK LDA 1,C377L ; USE ADDRESS MASK MOVS 1,1 AND 0,1 ; GET DEVICE LINK STA 1,DIRDL,3 ; SAVE IT LDA 1,C377L ; NOW GET ADDRESS ANDS 1,0 ; HIGH ORDER LDA 1,UFTAD,2 ; LOW ORDER FIRST ADDRESS LDA 2,CQ ; CURRENT QUEUE LDA 2,QSUFP,2 ; QUEUE UFT POINTER STA 0,DBFA1,2 ; STORE IN DCB TO BE INITIALIZED STA 1,DCBFA,2 LDA 1,TPDCB,3 ; PARENT'S DCB JSR @.FIDCB ; INIT THE QUEUE DCB (UFT) LDA 0,.SYSNM ; POINTER TO SYS.DR'S NAME JSR @.OVLAY SRUFD ; LOOK FOR SYS.DR RTRN ; ERROR STA 2,BFAD,3 ; SAVE BUFFER ADDRESS MOV 1,2 ; ENTRY TO AC2 LDA 0,UFTUC,2 ; GET SYS.DR'S USER COUNT MOV# 0,0,SZR ; IS IT ZERO ? JMP DIUER ; NO, DIRECTORY IN USE ERROR LDA 0,OAC0,3 ; INPUT ATTRIBUTES LDA 1,PARMK ; PARTITION MASK AND# 0,1,SZR ; IS THIS A PARTITION ? JMP DONE ; YES, ALL DONE MOV 2,0 ; 'FROM' ADDRESS LDA 2,CQ ; CURRENT QUEUE LDA 1,QSUFP,2 ; 'TO' ADDRESS STA 1,QUFT,3 ; SAVE UFT ADDRESS LDA 2,ENTLG ; ENTRY LENGTH JSR @.MVWD ; INIT THE ENTRY'S UFT LDA 2,BFAD,3 ; ENTRY'S BUFFER ADDRESS JSR @.RELZT ; RELEASE IT MOV 1,2 ; INDEX ON UFT LDA 0,UFTAD,2 ; GET FIRST ADDRESS FROM UFD STA 0,UFTFA,2 ; SET INTO UFT DCB LDA 0,UFTDL,2 ; GET HIGH ORDER PART LDA 1,C377L ; AND MASK ANDS 1,0 ; SAVE HIGH ORDER - SWAP TO RIGHT BYTE STA 0,UFFA1,2 ; SET HIGH ORDER INTO UFT DCB MOV 2,0 ; UFT UFD TO AC0 LDA 2,@CQ ; QUEUE DCB ADDRESS LDA 1,TPDCB,3 ; PARENT SYS.DR DCB JSR @.FIDCB ; INIT QUEUE DCB MOV 0,2 ; UFT UFD TO AC2 SUB 0,0 STA 0,TUFTBN,2 ; CLEAR CURRENT BLOCK STA 0,UFTBP,2 ; & BYTE POINTER LDA 0,BLKSZ ; BLOCK SIZE STA 0,UFTCH,2 ; SET INTO CHARACTERISTICS SUBZR 0,0 ; 1B0 STA 0,UFTST,2 ; SET STATUS TO READ LOOP0: LDA 0,UFTBN,2 ; CURRENT BLOCK NUMBER LDA 1,UFTBK,2 ; LAST LOGICAL BLOCK # SUBZ# 0,1,SNC ; IS CURRENT <= LAST ? JMP DONE1 ; NO, MUST BE DONE JSR @.RDBLK ; YES, READ NEXT BLOCK JMP ERTST ; ERROR RETURN, TEST IT ERROK: ISZ UFTBN,2 ; BUMP CURRENT BLOCK NUMBER STA 0,BFAD,3 ; SAVE BUFFER ADDRESS MOV 0,2 ; INDEX @:ON BUFFER LDA 0,0,2 ; GET ENTRY COUNT MOV# 0,0,SNR ; ANY ENTRIES ? JMP BLKDP ; NO, BLOCK DEPLETED  STA 0,ENTCT,3 ; YES, SAVE ENTRY COUNT INC 2,2 ; POINT TO FIRST ENTRY ENTLP: STA 2,ENTAD,3 ; SAVE ENTRY ADDRESS LDA 0,0,2 ; FIRST WORD OF ENTRY MOVt# 0,0,SNR ; IS ENTRY VALID ? JMP VACEN ; NO LDA 0,UFTAT,2 ; YES, GET ATTRIBUTES STA 0,SAVAT,3 ; & SAVE FOR LATER LDA 1,LNKMK ; LINK MASK AND# 0,1,SZR ; IS THIS A LINK ENTRY ? JMP NEXEN ; YES, NOTHING TO DELETE LDA 0,UFTDL,2 ; NO, GET DEVICE LINK LDA 1,C377L MOVS 1,1 AND 1,0 ; WE WANT ONLY THE DEVICE CODE LDA 1,DIRDL,3 ; & PARENT'S DEVICE LINK SUB# 0,1,SZR ; SAME DEVICE ? JMP NEXEN ; NO, CAN'T DELETE MOV 2,0 ; ENTRY ADDRESS TO AC0 LDA 1,.SYSNM ; SYS.DR NAME LDA 2,FNL ; FILE NAME LENGTH JSR @.CMPW ; COMPARE TO SYS.DR JMP NEXEN ; IT'S SYS.DR, DON'T DELETE LDA 1,.MAPNM ; MAP.DR NAME JSR @.CMPW ; COMPARE TO MAP.DR JMP NEXEN ; IT'S MAP.DR, CAN'T DELETE MOV 0,2 ; UFT TO AC2 LDA 0,UFTDL,2 ; DEVICE LINK LDA 1,C377L ANDS 1,0 ; pFIRST ADDRESS HIGH ORDER LDA 1,UFTAD,2 ; FIRST ADDRESS GETCL: JSR @.GCELL ; GET A CELL JMP NOCEL ; NONE THERE, WAIT FOR ONE STA 0,DBFA1,2 ; FIRST ADDRESS STA 1,DCBFA,2 ; LOW ORDER LDA 1,TPDCB,3 ; PARENT'S DCB JSR @.FIDCB ; FULL INIT CELL LDA 1,SAwVAT,3 ; SAVED ATTRIBUTES LDA 0,ENTAD,3 ; ENTRY ADDRESS IN BUFFER JSR @.OVLAY TRDEL ; TRICK DELETE CALL JMP EDONE ; ERROR ON DELETION JSR @.CREL ; GIVE THE CELL BACK NEXEN: DSZ ENTCT,3 ; TEST ENTRY COUNT JMP .+2 ; STILL SOME LEFT JMP BLKDP ; T HIS ONE IS DONE LDA 2,ENTAD,3 ; ENTRY ADDRESS VACEN: LDA 1,ENTLG ; ENTRY LENGTH ADD 1,2 ; NEXT ENTRY'S ADDRESS JMP ENTLP BLKDP: LDA 2,BFAD,3 ; BUFFER ADDRESS JSR @.RELZT ; RELEASE IT LDA 2,QUFT,3 ; RECOVER UFT ADDRESS JMP LOOP0 C377L: 377*400 PAqRMK: ATPAR .MVWD: MVWD .RELZT: RELZT .FIDCB: FIDCB .SYSNM: SYSNM DONE: LDA 2,BFAD,3 JSR @.RELZT DONE1: ISZ ORTN,3 RTRN EDONE: JSR @.CREL ; RELEASE THE CELL JMP ERTN ; BAG IT ERTST: JSR @.TSTEQ ; TEST ERROR CODE FOR EQUALLITY EREOF RTRN ; NOT aEQUAL - BAGIT JMP ERROK ; GOOD DIUER: LDA 0,DIUEC ; DIRECTORYIN USE ERROR CODE LDA 2,CC ; CURRENT CELL STA 0,CTMP2,2 ; RETURN ERROR CODE IN CELL ERTN: LDA 2,BFAD,3 JSR @.RELZT RTRN NOCEL: STA 1,FRSAD,3 ; SAVE FIRST ADDRESS STA 0,FRSA1,3 ; SAVE" FIRST ADDRESS ADC 0,0 ; LONG TIMEOUT ADCZR 1,1 ; CELL PEND KEY INTDS ; MUST DISABLE JSR @.PEND JMP .+1 LDA 0,FRSA1,3 ; RESTORE FIRST ADDRESS LDA 1,FRSAD,3 JMP GETCL LNKMK: ATLNK BLKSZ: SCDBS ENTLG: UFDEL FNL: SCFNL DIUEC: ERDIU .MAPNM: MAPNM `l.CMPW: CMPWD .RDBLK: RDBLK .GCELL: GCELL .CREL: CREL .PEND: PEND .TSTEQ: TSTEQ ENDOV .END SOV17.SRJJ (4 RTITLE SOV17 SV17 .NREL .ENT IRMV .ENT SCLUP .IFN MSW .ENT SCLUM .ENDC .IFE MSW .EXTN SFGNP .ENDC .IFN BSW!MBSW .EXTN UDEX .ENDC .EXTN SYSFG .EXTN ITBL .EXTN OVCHN .EXTN RETER .EXTN UTOTL,DTOTL .EXTN TSECI .EXTN CREL .EXTN CMN .EXTN TTIDC .EXTN FPUSV .EXTN IUD .IFN MSW .EXTN UITBL .EXTN DSET .EXTN MDCH1,MDCH2 .EXTD RMBLK .EXTD GMBLK .ENDC ;***************************************** ;  NUMBER OF STACK TEMPORARIES USED ; MUST BE THE FIRST WORD IN THE OVERLAY .IFN BSW!NMBSW 0 .ENDC ; THIS ROUTINE CLEANS UP A PROCESS WHEN IT'S RTNING OR PUSHING SCLUP: LDA 3,CC LDA 1,CPROG,3 ADCZL 0,0 MOVZR# 1,1,SNR ADCZR 0,0 LDA @2,.FPUSV AND 0,2 ;RESET FUP SAVE BIT STA @2,.FPUSV LDA @2,.TSECI ;RESET BIT IF SET FOR 1 SEC ;w RESCHED AND 0,2 STA @2,.TSECI ; FOR OP MESSAGE INTDS LDA 0,FTST ; FOREGROUND TERMINATED MOVZR# 1,1,SZR ; IS IT ? LDA 0,BTST ;BG BIT LDA 2,.TTIDC ; GET DCT SUBZL 1,1 STA 1,DCTOF,2 ;CLEAR COL COUNTER LDA 1,OFSET ; DUMMY IT UP TO LOOK LIKE CELL ADD 2,1 ; GOT IT STA 1,LCC SUB 1,1 ;INIT TO NO OTHER ACTIVE PTBL STA 1,ROFLG LDA 2,DCTOP,2 ; GET APOINTER AGAIN LLOOP: COM# 2,2,SNR ;SKIP IF NOT END JMP OUT LDA 1,RQST,2 ; IS THIS ONE ? AND# 0,1,SNR JMP AA LDA 1,RQLK,2 ; GOT A HOT ONE LDA 3,\!LCC STA 1,RQLK,3 ; NEXT POINTER LDA 1,D133 ; IS IT ACTIVE LDA 3,RQCNT,2 SUBZ# 1,3,SNR JMP ZZ SUB 1,1 LDA 3,.TTIDC STA 1,DCTT3,3 ; RESET STATE ZZ: JSR @.CREL ; GIVE IT UP LDA 2,LCC UP: STA 2,LCC LDA 2,RQLK,2 JMP LLOOP AA: ISZ ROFLG ;SET OTHER< PROCESS ACTIVE JMP UP OFSET: DCTOP-RQLK D133: 133. .CREL: CREL .FPUSV: FPUSV .TSECI: TSECI LCC: 0 .TTID: TTIDC BTST: BSBOP FTST: BSFOP ROFLG: 0 EWRD: CMN OUT: SUB 0,0 LDA 3,.TTIDC LDA 1,ROFLG ;IF NON 0 OTHER PROC ACTIVE MOV# 1,1,SNR STA 0,DCTT3,3 ^;0 RDOP FLAGS IN CASE ^E REC LDA 2,CC LDA 3,CPTAD,2 ;PROG TABLE STA 0,PDFR,3 ;CLEAR DELAYS STA 0,PDEN,3 STA 0,PDTOT,3 STA 0,PCMST,3 ;NO COMMON .IFE MSW LDA 2,CENT2,2 ;DON'T CLEAR DIRTY ON .EXEC LDA 0,EWRD ;2ND PROC ENTRY PT (UNIQUE) SUB# 2,0,SNRN1 ;SKIP IF NOT EXEC SUBZL 0,0,SKP SUB 0,0 LDA 1,PFLAG,3 AND 1,0 STA 0,PFLAG,3 .ENDC LDA 1,PDCNT,3 ;ACTIVE COUNT STA 0,PDCNT,3 LDA @0,.DTOTL SUB 1,0 STA @0,.DTOTL .IFN MSW LDA 1,CNTRP ;GET MASK LDA 0,EWRD LDA 2,CENT2,2 ;CHECK FOR PUSH (.EXECZ) SUB# 2,0,SNR INC 1,1 ;ADD TO MASK ON PUSH LDA 0,PFLAG,3 AND 1,0 STA 0,PFLAG,3 ;CLEAR ALL BUT TRAP, ;DON'T CLEAR DIRTY ON PUSH .ENDC .IFN MBSW LDA 0,CNLEF ;DISABLE LEF BTZ 3,0 .ENDC LDA 1,PCLAC,3 ;USER CLOCK MOV# 1,1,SNR JMP SCL4 ;NONsE DEF DSZ @.UTOTL JMP .+1 SUB 0,0 STA 0,PCLAC,3 ;USER CLOCK SCL4: .IFN MSW LDA 1,PPRI,3 ;FG OR BG MOVZR# 1,1,SNR ;FG? MOVOR 0,0 ;YES -SET 1B0 LDA 3,.UITBL ;GET ADDR OF UITBL COM# 3,3,SNR ;IS IT THERE? JMP SCLX ;NO- SKIP JUNK SCL1: LDA 2,UIDCND,3 ;GET DEVICE CODE FROM UITBL MOV# 2,2,SNR ;SOMETHING THERE? JMP NXTD ;NO - LOOK AT NEXT ONE COM# 2,2,SNR ;END OF TABLE? JMP SCLX ;YES ADDL# 0,2,SZC ;YES - SAME PRI AS ME? JMP NXTD ;NO - SKIP IT LDA 1,.ITBL ADD 1,2 ;SLOT IN TABLE LDA 1,.I:UD STA 1,-1,2 ;PUT IN ITBL MOV 3,2 ;ADDRESS IN UITBL TO AC2 JSR RTSLT ;RETURN DCH SLOTS IN MDCH WORDS LDA 3,CC LDA 3,CPTAD,3 ; PROGRAM TABLE ADDRESS JMP SCL4 ;START OVER AGAIN NXTD: INC 3,3 ;INC UITBL POINTER INC 3,3 ;TWO WORD TABLE .IFN MBS9W ADI 4,3 ;SIX WORD TABLE .ENDC JMP SCL1 .ENDC .IFE MSW LDA 2,.ITBL ;ITBL BASE LDA 3,CM100 ;LOOP COUNT STA 3,LCNT SCL12: LDA 1,-1,2 ;SLOT VECTOR .IFE BSW MOVL# 1,1,SZC ;SKIP IF NOT RDOS DEVICE .ENDC .IFN BSW ANDI 77777,1 ; GET RID OF SIgGN BIT MOV 1,3 ; MOVE FOR INDEXING LDA 3,0,3 ;GET FIRST WORD OF DCT LDA 0,.UDEX ;USER DEVICE ROUTINE SUBOL 0,3,SZR ;SKIP IF USER DEVICE .ENDC JMP SCL11 LDA 0,USTP ;THIS CALLER'S BASE ADDR LDA @3,.SYSFG MOV# 3,3,SNR ;SKIP IF FG ACTIVE JMP SCL13 ;NOT ACTIVE- MUST BE OUR DEV LDA @3,.SFGNP ;FG BASE SUB# 0,3,SZR ;SKIP IF FG CLEANUP JMP SCL14 ;BG SUBZ# 1,3,SZC ;SEE IF > FG BASE JMP SCL11 ;NO - BG DEV, LEAVE ALONE JMP SCL13 ;CLEAR IT SCL14: ADCZ# 1,3,SNC ;< FG BASE ? JMP SCL11 ;NO- F1G DEV, LEAVE ALONE SCL13: LDA 0,.IUD ;FREE DEVICE INDICATOR STA 0,-1,2 SCL11: INC 2,2 ISZ LCNT ;DONE ? JMP SCL12 ;NO .ENDC SCLX: INTEN RTRN ; BRIDGE TO THE GOLDEN HINDE IRMV: JMP MRMV .IFN MSW SCLUM: LDA 2,CC LDA 2,CPTAD,2 ;PTBL LDA 1,PEMAP,"2 ;ANY BLKS DEF ? MOV# 1,1,SNR RTRN ;NO VIRTUAL BLKS RBL1: LDA 1,PEMAP,2 MOV# 1,1,SNR ;IF 0 ALL DONE JMP EARST ;YUP JSR RMBLK ;REL BLK SUB 1,1 STA 1,PEMAP,2 INC 2,2 ;TO NEXT JMP RBL1 ; ALL DONE- RESTORE BLKS TO WINDOW FOR DATA AND OVLY SPAC]E EARST: LDA 2,CC LDA 2,CPTAD,2 SUB 1,1 STA 1,PEOCT,2 ;CLEAR CNTS STA 1,PEDCT,2 LDA 1,PVST,2 ;OVLY SPACE DEF ? MOV# 1,1,SNR JMP VDATA ;NO LDA 0,PVEND,2 ;END SUB 1,0 ;# SLOTS GBL2: STA 0,LCNT ADD 1,2 ;= STARTING SLOT GBL1: JSR GMBLK ;GET ONE JMP . LDA 0,PMAP,2 ;OLD BLK AND CONSTANT LDA 3,C377L AND 3,0 ADD 1,0 ;ADD BLK JUST PICKED UP STA 0,PMAP,2 INC 2,2 DSZ LCNT ;DONE ? JMP GBL1 ;NO ; CHECK FOR VIRTUAL DATA AREA VDATA: LDA 2,CC LDA 2,CPTAD,2 LDA 1,PMWIN,2 ;WINDOW OR 0 IF NOT DEF  SUB 0,0 STA 0,PVST,2 ;0 OVLY AND DATA DEF STA 0,PMWIN,2 MOV# 1,1,SNR ;DATA AREA ? RTRN ;NO-ALL DONE LDA 0,PMWSZ,2 ;SIZE JMP GBL2 ;COMMON- RTN TO VDATA WILL EXIT .ENDC .UTOTL: UTOTL .IUD: IUD .ITBL: ITBL .DTOTL: DTOTL C377L: 177400 LCNT: 0 .IFyN BSW!MBSW .UDEX: UDEX .ENDC .IFE MSW .SFGNP: SFGNP CM100: -100 .ENDC .IFN MSW .UITBL: UITBL CNTRP: 1B1 .ENDC .IFN MBSW CNLEF: 9. .ENDC .IFN MSW ; RTSLT - ZEROES UIDCD AND UIDCH IN THE UITBL ENTRY ; ; IF THE DEVICE USED THE DATA CHANNEL, ; RET@URNS THE SLOTS IN THE DCH MAP BY SETTING ; THE APPROPRIATE BITS IN MDCH1 AND MDCH2 ; ; CALLED WITH THE ADDRESS ; OF THE ENTRY IN UITBL IN AC2 ; DESTROYS ALL AC'S ; RETURNS LOTS OF USELESS GARBAGE ; RTSLT: SUB 0,0 LDA 1,UIDCH,2 ;FOR FUTURE REFEREN JCE STA 0,UIDCD,2 ;CLEAR TABLE ENTRY STA 0,UIDCH,2 MOV# 1,1,SNR ;DCH DEVICE? JMP 0,3 ;NO - JUST RETURN STA 3,RTRET ;YES - MUST RELEASE SLOTS LDA 3,C377 MOVS 3,2 AND 1,3 ;NUMBER OF FIRST ASSIGNED SLOT NEG 3,3 ;WILL BE USED AS COUNT ANDS 1,2 ;DNUMBER OF ASSIGNED SLOTS NEG 2,2 ;HIM, TOO SUB 1,1 MOVOR 0,0 MOVR 1,1 ;SHIFT IN ONES FOR NUMBER OF ; SLOTS INC 2,2,SZR ;ENOUGH? JMP .-3 ;KEEP SHIFTING MOVZR 0,0 MOVR 1,1 ;NOW POSITION OF FIRST SLOT INC 3,3,SZR JMP .-3 ;EL LOOPO LDA @2,WORD0 ;MDCH1 ADD 0,2 ;SET BITS STA @2,WORD0 ;AND STORE LDA @3,WORD1 ;MDCH2 ADD 1,3 STA @3,WORD1 JMP @RTRET ;RETURN RTRET: 0 WORD0: MDCH1 WORD1: MDCH2 .ENDC ; REMOVE A USER DEVICE FROM THE VECTOR TABLE ; USER AC0 = DEV CODE MRMV: LDA @2,CC ;T)CB LDA 3,.ITBL ;VECTOR TABLE LDA 0,TAC0,2 ;DEV LDA 1,LLDC ; LAST LEGAL DEVICE CODE SUBZ 0,1,SNC ;IS DEV TOO BIG JMP IDER2 ;IF YES MOV# 0,0,SNR ;TOO SMALL JMP IDER2 ADD 0,3 ;TABLE ADDR +1 LDA 2,-1,3 ;GET DEVICE DCT ADDRESS .IFE BSW!MBSW MOM$VL# 2,2,SZC ;IF SYS DEV 1B0=1 .ENDC J LDA 2,0,2 ;FIRST WORD OF DCT LDA 1,.UDEX ;USER DEVICE ADDR SUBOL 1,2,SZR ;SKIP IF USER DEVICE [J] JMP IDER2 ;PUNISH .IFN MSW INTDS .IFE MBSW STA 3,RLOC ;SAVE SLOT ADDR .ENDC .IFN MBSW PSH 3,3 .ENDC LDA 2,.UITB ;USER INT BASE LDA 1,C377 IRM2: LDA 3,UIDCD,2 ;SEE IF MATCH AND 1,3 SUB# 3,0,SNR JMP IRM3 ;YES INC 2,2 INC 2,2 .IFN MBSW ADI 4,2 .ENDC JMP IRM2 IRM3: LDA 3,CC LDA 3,CPROG,3 ;SEE IF RIGHT CALLER LDA 1,UIDCD,2 MOVL# 1,1,SNC MOVZRuL 3,3,SZR ;SKIP IF FG-INT DEV IS BG-ERR MOVZR# 3,3,SZR ;SKIP IF FG OR IF BG FELL THRU JMP IDER2 ;SLAP .IFE MBSW LDA 3,RLOC .ENDC .IFN MBSW POP 3,3 .ENDC .ENDC LDA 1,.IUD STA 1,-1,3 ;RELEASE ITBL SLOT .IFE MSW LDA 3,CSP ISZ ORTN,3 RTRN .ENDC .IFN MSW .IFE MBSW STA 0,RLOC ;YES - MUST RELEASE IT .ENDC .IFN MBSW PSH 0,0 .ENDC JSR RTSLT ;RETURN THE SLOTS AND UITBL ; ENTRY .IFE MBSW LDA 0,RLOC ;RECOVER DEVICE CODE .ENDC .IFN MBSW POP 0,0 .ENDC IREX: JSR @.OVCHN DSET .ENDCrN IDER2: INTEN JSR @.RETER ERDNM .RETER: RETER LLDC: CPU C377: 377 .SYSFG: SYSFG .OVCHN: OVCHN ENDOV .END SOV18.SRB < RTITLE SOV18 SV18 .NREL .ENT MDRLS .ENT HBOOT .EXTN OVCHN,RLBOT,RLBXT,RPIPH .EXTN OVLAY,OVLY1,OICAL .EXTN RETE2,RETER .EXTN CFNAM .EXTN RSET,TUOFF .EXTN SRUFD .EXTN SYSNM,OSNAM .EXTN RELMB,RELZT .EXTN QUENT .EXTN WAIT .EXTN MDCB .EXTN DIRR .EXTN BQ .EXTN SYSFG .EXTN SPOLQ .EXTN SPOOL .EXTN STDCC .EXTN SSPKL .EXTN PT1 .EXTN TSTEQ .IFN MSW .EXTD MFSTB .ENDC ;***************************************** ; NUMBER OF STACK TEMPORARIES USED ; MUST BE THE FIRST WORD IN THE OVERLAY .IFN BSW!MBSW 7 .ENDC ; ROUTINE TO PRODUCE AN ORDERLY SYSTEM SHUTDOWN ; & INVOKE HIPBOOT FROM A PRIMARY DEVICE ; ; INPUTS: TAC0 - BYTE POINTER TO SPECIFIER NAME ; ; OUTPUTS: NONE ; ENTSW=TMP+1 DEVCD=ENTSW+1 UNIT=DEVCD+1 SFFLG=UNIT+1 ASCUN=SFFLNG+1 TDCB=ASCUN+1 MDRLS: SUBZL 0,0,SKP HBOOT: SUB 0,0 STA 0,ENTSW,3 ; SAVE ENTRY SWITCH SUB 1,1 STA 1,SFFLG,3 ;INIT SAVE FILE FLAG LDA 2,@.MDCB ;IN CASE RELEASE OF MASTER MOV# 0,0,SZR ; RELEASE OF MASTER ? JMP MDSET ; YES, GO SET UP SEEK TO ZEROJ LDA 2,@CC ; TCB ADDRESS LDA 0,TAC0,2 ; USER'S AC0 LDA 2,CQ ; CURENT QUEUE LDA 1,QSUFP,2 ; QUEUE UFT POINTER JSR @.OVLAY CFNAM ; CHECK & UNPACK SPECIFIER LDA 0,SFLK,2 ;MAP LINK COM# 0,0,SNR ;GOT ONE? JSR ILCDER ;CAN'T BOOT TO MAG TAPE STA 23,TDCB,3 ; SAVE DCB ADDRESS MOV 1,3 ; INDEX ON UNPACK ADDRESS LDA 0,.SV  ; GET .SV EXTENSTION STA 0,UFTEX,3 ; TACK IT ON MOV 3,0 ; UFD TO AC0 JSR @.OVLAY SRUFD ; LOOK FOR .SV JMP SVNFD ; ERROR - TEST IT ADC 0,0 ; -1 JSR @.RELZT ; NOW R}ELEASE THE BUFFER STA 0,SFFLG,3 ; SHOW SAVE FILE FOUND LDA 2,TDCB,3 ; DCB ADDRESS MDSET: LDA 1,DCBUN,2 ; UNIT # STA 1,UNIT,3 ; SAVE IN STACK LDA 0,SFKY1,2 ; GET ASCII VALUE MOV 0,0,SNR ; BINARY ZER0 ? LDA 0,LASC0 ; YES MAKE IT ASCII ZER0 STA 0,ASCG0UN,3 ; SAVE ASCII UNIT NUMBER LDA 2,DCBDC,2 ; GET HOLD OF DCT LDA 0,DCTCD,2 ; DEVICE CODE JMP DEVKN+1 ; UNIT NUMBER ALREADY SAVED SDEVKN: LDA 2,C40 ; MAKE IT SECONDARY DEVICE CODE ADD 2,0 DEVKN: STA 1,UNIT,3 ; SAVE UNIT NUMBER STA 0,DEVCD,3 ; SAVE DŚEVICE CODE JMP DETPT ; NOW DETERMINE THE PATH SVNFD: JSR @.TSTEQ ERDLE RTRN ; WRONG ERROR ; NO KNOWN FILE, TRY DEVICE SPECIFIERS TRYDV: LDA 2,CQ ; CURRENT QUEUE LDA 2,QSUFP,2 ; QUEUE UFT POINTER LDA 1,1,2 ; GET UNIT NUMBER STA 1,ASCUN,3 ; SAzVE IN STACK LDA 0,LASC0 ; ASCII 0 (LEFT BYTE) SUBS 0,1 ; TRUE UNIT NUMBER LDA 2,UFTFN,2 ; GET SPECIFIER LDA 0,DK ; & ASCII 'DK' SUB 2,0,SZR ; IS SPECIFIER = 'DK' ? JMP MHD ; NO, TRY MOVING HEAD DISK LDA 0,.DSK ; PRIMARY FHD DEVICE CODE MOVZR# 1,1,SZR ; UNIT 0 OR 1 ? RTRN ; NO, YOU'R IN THE BAG MOVZR# 1,1,SZC ; YES, IS IT UNIT # 1 ? JMP SDEVKM ; GET SECONDARY DEVICE CODE JMP DEVKN ; FINISH UP CL4: 4*2 CL7: 17 DZ: 'DZ' DK: 'DK' DP: 'DP' DS: 'DS' LASC0: '0' .SV: 'SV' .MDCB: MDCB .TSTEQ: TSTEQ KF: 'F' .DSK: DSK .DKP: DKP .DZP: DZP .DSP: DSP MHD: LDA 0,DZ ; GET ASCII 'DZ' SUBO 2,0,SZR ; IS SPECIFIER 'DZ' JMP MDS1 ; NO LDA 0,.DZP ; GET DEVICE CODE JMP MHD2 ; GO GET UNIT NUMBER MDS1: LDA 0,DS ; GET ASCII 'DS' SUBO 2,0,SZR JMP MHD1 ; NO LDA 0,.DSP ; GET DEVICE CODE JMP MHD2 ; GO GET UNIT NUMBER MHD1: LDA 0,DP ; GET ASCII 'DP' SUBO 2,0,SZR ; IS SPECIFIER = 'DP' ? RTRN ; NO ; NOTE CARRY IS ZERO HERE LDA 2,KF ; MAY BE FIXED DISK SUBZ# 2,1,SZC ; WELL IS IT SUBZ 2,1 ; YES TAKE OUT F LDA 0,.DKP ; YES, GET PRIMARY DEVICE CODE MHD2: MOVL 1,1 ; UNIT #*2+F BIT LDA 2,CL7 ; & A LOGICAL 7 SUBZ# 1,2,SNC ; LEGAL LOGICAL UNIT # ? RTRN ; NOPE LDA 2,CL4 ; YES, GET A LOGICAL UNIT 4 ADCZ# 1,2,SZC ; USING PRIMARY D EIVCE ? JMP DEVKN ; YES, PROCEED SUB 2,1 ; TRUE LOGICAL UNIT # OF SECONDARY ; DEVICE JMP SDEVKN C40: DKP1-DKP ; INPUT VERIFIED - NOW DETERMINE THE PATH DETPT: LDA 2,CC ; CURRENT CELL LDA 2,CPTAD,2 ; PROGRAM TABLE ADDRESS LDA 0,PTSPN,2 ; GET PUSH NUMBER FROM PROG ; TABLE LDA 1,@.SYSFG ; FOREGROUND FLAG MOVZR# 0,0,SZR ; CALLED FROM CLI LEVEL ? JMP SPLTS ; NO, TEST THE SPOOLER MOV# 1,1,SZR ; YES, IS FOREGROUND RUNNING ? JMP ILLCM ; YES, THAT'S A NO-NO ; TEST FOR ACTIVE SPOOLS SPLTS: LDA 2,.SPOLQ ; SPOOL QUEUE ADDRESS ADC 3,3 ; -1 STA 3,POLNK,2 ; STOP ANY USER PROCESSING LDA 2,@.SPOOL ; ACTIVE SPOOL COUNT MOV# 2,2,SNR ; WHAT'S HAP'NIN JMP TUKIL ; NOTHING, KILL TUNING MOVZR# 0,0,SNR ; SPOOLS ACTIVE - CALLED FROM ; CLI ?  JMP ASPER ; YES, ACTIVE SPOOL ERROR LDA 2,@.STDCC ; NO, GET START OF SPOOL DCT'S KILLP: JSR @.OVLAY SSPKL JMP .+1 ; EAT ANY ERRORS LDA 2,DCTSL,2 ; NEXT DCT MOV# 2,2,SZR ; ANYTHING THERE ? JMP KILLP ; YES, KEEP GOING ; TURN TUNING OFF TUKIL: JSR @.OVLAY TUOFF JMP OTHER JMP RLDIR ; NO, RELEASE DIRECTORIES .RELZT: RELZT ILCDER: JSR @.RETR ERICD .RETR: RETER .OVLAY: OVLAY ; RELEASE ALL ACTIVE DIRECTORIES RLDIR: LDA 2,@.DIRR ; GET START OF DIRECTORY CHAIN DCBLP: LDA 1,@.MDCB ; & MASTER %\DCB SUB# 1,2,SNR ; IS THIS THE MASTER DCB ? JMP NOINT ; YES, DON'T TEST FOR INIT LDA 1,DCBST,2 ; NO, GET DIRECTORY STATUS MOVL# 1,1,SZC ; IS DIRECTORY INIT'D ? JMP NOINT ; NO ADDL# 1,1,SZC ; YES, IS IT RELEASABLE ? JMP NOINT ; NOPE LDA 1,SFLK,2 ; YES, GET MAP.DR LINK COM# 1,1,SZR ; IS THERE A MAP.DR ? JMP DSKDV ; YES, SOME KIND OF DISK DEVICE LDA 3,DCBDC,2 ; NO, GET DCT ADDRESS LDA 1,DCTRS,3 ; GET RELEASE PROCESSOR LDA 3,CSP ; RECOVER STACK POINTER STA 1,TMP,3 ; SAVE PROCESSOR ADDRESS ON ; STACK JSR @.OVLY1 ; GO RELEASE IT JMP .+1 ; EAT ANY ERRORS JMP NOINT ; TRY NEXT DCB DSKDV: JSR @.OICAL RLSE ; RELEASE THE DIRECTORY JMP OTHER ; UNKNOWN ERROR - BAG IT NOINT: LDA 2,SFNX,2 ; GET NEXT DCB IN CHAIN COM# 2,2,SZR ; IS THERE ONE ? JMP DCBLP ; YES, EXAMINE IT ; NOW RELEASE THE MASTER DIRECTORY RLMDB: LDA 2,@.MDCB ; GET MASTER DCB ADDRESS JSR @.OICAL ; RELEASE SYS.DR RLSE JMP OTHER ; OTHER ERROR ; CLOSE ALL OPEN CHANNELS NOW ; NOTE - NO ERROR RETURNS POSSIBLE BEYOSND THIS POINT LDA 0,.PT1 ; FOREGROUND PROGRAM TABLE LDA 1,@.SYSFG ; FOREGROUND ACTIVE FLAG MOV# 1,1,SNR ; IS IT ACTIVE ? JMP NXPTB ; NO, TRY NEXT PROGRAM TABLE NXRST: LDA 2,CC ; CURRENT CELL STA 0,CPTAD,2 ; SHOW BACKROUND ACTIVE .IFN MSW MOV 0,; 2 JSR MFSTB .ENDC JSR @.OVLAY RSET ; CLOSE CHANNELS JMP .+1 ; EAT ANY ERRORS NXPTB: MOV 0,2 ; PT ADDRESS TO AC2 LDA 0,POLNK,2 ; GET THE LINK COM# 0,0,SZR ; LAST TABLE ? JMP NXRST ; NO ; FORCE ALL MODED BUFFERS TO THEIR HOME DEVICES RELBFS:  LDA 1,IOP ; GET I/O IN PROGRESS MASK LDA 2,.BQ ; AND START OF BUFFER CHAIN FLUSH: LDA 0,BQST,2 ; GET BUFFER STATUS AND# 0,1,SZR ; IS I/O IN PROGRESS ? JMP WFI ; YES, WAIT FOR IT MOVR# 0,0,SNC ; NO, IS IT MODIFIED ? JMP NXBUF ; NO, TRY NEXT BUFFEޣR JSR @.QUENT ; YES, QUEUE IT WFI: JSR @.WAIT ; NOW WAIT FOR IT JMP .+1 ; DEVICE TIMEOUT JMP .+1 ; NO ERRORS NXBUF: LDA 2,BQNXT,2 ; NEXT BUFFER IN CHAIN MOVL# 2,2,SNC ; END OF CHAIN ? JMP FLUSH ; NO ; GO TO SOV30 IF FIXED-HEAD DISK, ELSE SOV22 rjLDA 0,DEVCD,3 ; DEVICE CODE XLDA 1,= 37 ; PRIMARY CODE MASK AND 1,0 ; PRIMARY DEVICE CODE LDA 1,.DSP ; FIXED-HEAD DISK DEVICE CODE SUB# 1,0,SZR ; SKIP IF THIS IS A FIXED HEAD DISK JMP SV22X ; GO TO SOV22 JSR @.OVCHN ; CHAIN TO REST OF CODE RL}BXT SV22X: JSR @.OVCHN ; CHAIN TO REST OF CODE RLBOT LDA 2,CC LDA 2,CTMP2,2 STA 2,.+2 ; STICK ERROR CODE IN YOUR EAR, ; FELLA JSR @.PNIC ; NOW, OPEN UP THE ROOF IGOR, ; AND ; LET THE LIGHTNING IN ! OTHER: LDA 2,CC ; CURRENT CELL LDA 2,CERR,2 ; PICK UP ERROR CODE JMP ERGO+1 ; GIVE IT BACK ASPER: JSR ERGO ERSFA ; SPOOL FILE(S) ACTIVE ILLCM: JSR ERGO EROPD ERGO: LDA 2,0,3 ; PICK UP THE ERROR CODE LDA 0,.PT1 ; FOREGROUND PROGRAM TABLE ; ADDRESS LDA 3,.SPOLQ ; SPOOLER'S QUEUE STA 0,POLNK,3 ; HOOK THE USER BACK UP JSR @.RETE2 ; & GIVE THE ERROR CODE TO THE ; CALLER .SPOLQ: SPOLQ .SPOOL: SPOOL .PT1: PT1 .STDCC: STDCC .OICAL: OICAL .DIRR: DIRR .SYSFG: SYSFG .RETE2: RETE2 IOP: QTIOP .BQ: BQ .QUENT: QUENT .WAIT: WAITQ .RELMB: RELMB .SYSNM: SYSNM .OVCHN: OVCHN .OVLY1: OVLY1 .OSNAM: OSNAM OL: 'OL' LPOOL RLSE: LDA 0,.SYSNM JSR @.OVLAY SRUFD ; SEARCH FOR SYS.DR RTRN ; EAT THE ERROR MOV 1,3 ; INDEX ON ENTRY LDA 0,UFTUC,3 MOV# 0,0,SZR DSZ UFTUC,3 ; ONE LESS U0SER JMP .+1 JSR @.RELMB LDA 2,OAC2,3 ;PASS DCB JSR @.OVLAY ;RELEASE PERIPHERAL ENTRIES RPIPH RTRN ISZ ORTN,3 ; NO ERRORS, GOOD RETURN RTRN ENDOV .END WDCBK.SRB R:' RTITLE WDCBK .ENT WDCBK .EXTN DMPLOCK,DMPUNLOCK .EXTN GCELL,CREL .EXTN PEND,UNPEND .EXTN RETER,RETE2 .EXTN RELB,RELMB .EXTN BLKIN,MPY .NREL ;********************************** ; NUMBER OF STACK TEMPORARIES ; MUST BE FIRST WORD OF OVERL|AY .IFN BSW!MBSW 10 .ENDC ; ; WITHDRAW N CONTIGUOUS FREE BLOCKS FROM A MAP ; ; INPUTS: AC1 - NUMBER OF BLOCKS TO BE WITHDRAWN ; AC2 - ADDRESS OF SYS.DR DCB OF PARTITION TO TAKE FROM ; ; OUTPUTS: AC0 & AC1 - HI & LO ORDER RESPECTIVELY OF THE ADDRESS ;6n OF FIRST BLOCK OF CONTIGUOUS SERIES ; ; STACK DISPLACEMENTS MAPX1= OAC0 MAPX= OAC1 CA= TMP BLKCT= CA+1 SRCH= BLKCT+1 FBFF= SRCH+1 CELAD= FBFF+1 WRDCT= CELAD+1 CBAD= WRDCT+1 BKCTS= CBAD+1 TDCB=FBFF ; CELL (DYNAMIC STACK FRAME EXTENDER)r DISPLACMENTS TWRDCT= 0 CCB= 1 CWC= 2 MASK= 3 MAPDC= 4 MWOFS= 5 WDCBK: MOV# 1,1,SNR ; REALLY WANT ANY BLOCKS? JMP ZERO ; COME NOW, BE SERIOUS STA 1,BKCTS,3 ; SAVE REQUESTED COUNT STA 1,BLKCT,3 ; INIT BLOCK COUNT LDA 2,DCBDR,2 ; LDA 2,SFLK,2 '; SYSTEM FILE LINK STA 2,TDCB,3 ; SAVE MAP DCB ADDRESS LCKLP: MOV 2,1 ;SAVE IT FOR PENDING, ETC. INTDS ;KEEP IVT INTERRUPTS OUT IN CASE ;THIS IS DUAL PROCESSOR SYSTEM LDA 0,MPLCK,2 ; MAP LOCK WORD MOV 0,0,SNR ; IS MAP LOCKED? JMP LCKOK ; NO, LOCK OK LDA 0,LKTIM ;FINITE WAIT IN CASE OTHER SIDE ;GOES DOWN & IVT UNLOCKS JSR @.PEND ; YES, PEND, WAITING FOR ; UNLOCKED MAP JMP LCKLP ; TIMEOUT - TEST STATE OF MAP JMP LCKLP ; UNPENDED - TEST STATE OF MAP LCKOK: ADC 0,0 STA 0,MPLCK,/2 ; LOCK THE MAP INTEN CELOK: JSR @.GCELL ; GET A CELL JMP CLPND ; NO CELLS,PEND STA 2,CELAD,3 ;SAVE CELL ADDRESS JSR @.DMPLOCK ;MUST LOCK THE MAP ON THE OTHER ;SIDE (AC1=DCB ADDR, AC2=CELL ADDR) LDA 1,TDCB,3 ;IN CASE WE PENDED ON CELL STA 1,>:MAPDC,2 ; MAP DCB INTO CELL SUB 0,0 STA 0,SRCH,3 ; CLEAR SEARCH FLAG STA 0,FBFF,3 ; & FREE BLOCK FOUND FLAG MOV 1,2 ; MAP DCB ADDRESS TO AC2 LDA 1,DCBCB,2 ; GET CURRENT CURRENT BLOCK STA 1,DCBNA,2 ; HIDE IT FOR LATER STA 0,DCBCB,2 ; INIT CURRENT BLOCK # TO 0 JMP START CLPND: MOV 1,2 ; MAP DCB TO AC2 ADC 0,0 ; LONG TIME OUT ADCZR 1,1 ; OUT OF CELLS PEND KEY INTDS ; MUST DISABLE JSR @.PEND JMP .+1 ; EAT THE TIME OUT JMP CELOK ZERO: JSR @.RETER ERZCB LKTIM: 3 .RETER: RETER .PEND: mPEND .GCELL: GCELL .DMPLOCK:DMPLOCK BLKLP: INC 2,2 ; BUMP POSITION DSZ WRDCT,3 ; ANY WORDS LEFT? JMP WRDLP ; YES LDA 1,SRCH,3 ; NO, GET SEARCH FLAG LDA 2,CA,3 ; CORE ADDRESS OF BUFFER MOV 1,1,SNR ; SEARCHING? JMP SRHNG ;YES JSR @.RELMB ; NO , RELEASE MODIFIED JMP .+2 ;LET'S NOT RELEASE TWICE SRHNG: JSR @.RELB ; YES SEARCHING LDA 2,CELAD,3 ; CELL ADDRESS LDA 2,MAPDC,2 ; MAP DCB ADDRESS ISZ DCBCB,2 ; BUMP CURRENT BLOCK LDA 0,DCBCB,2 ; CURRENT BLOCK NUMBER LDA 3,SFBK,2 ; GET LAST BLOCK UNUMBER SUBZ# 0,3,SZC ; VALID BLOCK ? JMP VALBK ; YES SUB 0,0 ; NO STA 0,DCBCB,2 ; RESET TO BEGINNING VALBK: MOV# 1,1,SZR ; SEARCHING ? JMP START ; NO MOV# 0,0,SNR ; YES, SEARCHED ENTIRE MAP ? JMP SPERR ; YES, YOU'RE OUTA SZHLITZ START: LDA 1,DCBFA,2 ; GET FIRST ADDRESS LDA 3,DBFA1,2 ; FIRST ADDRESS HIGH ORDER ADDZ 1,0,SZC ; FORM ADDRESS FOR THIS BLOCK INC 3,3 ; OVERFLOW UP COUNT STA 3,DBCA1,2 ; SET INTO CURRENT STA 0,DCBCA,2 ; SET INTO CURRENT ADDRESS JSR @.BLKIN ; READ CURRENT BLOCKe JMP ERR1 ; ERROR STA 0,CA,3 ; SAVE CORE ADDRESS LDA 0,DCBCB,2 ; GET CURRENT BLOCK NUMBER LDA 1,SFBK,2 ; GET LAST BLOCK NUMBER SUB 1,0,SZR ; AT THE END ? JMP NOEOF ; NO LDA 1,SFBC,2 ; YES, GET LAST BLOCK BYTE COUNT MOVZR 1,1,SKP ; WORDS IN LAST BLOCK NOEOF: LDA 1,BLKSZ ; GET FULL BLOCK WORD COUNT LDA 2,CELAD,3 ; CELL ADDRESS STA 1,WRDCT,3 ; INIT THE WORD COUNT STA 1,TWRDCT,2 ; AND SAVE IN CELL ALSO LDA 2,CA,3 ; GET BUFFER ADDRESS WRDLP: LDA 0,0,2 ; GET A WORD SUBZ 1,1 ; YES, FOR BIT MASK BITLP: MOVR 1,1,SNR ; ANY BITS LEFT? JMP BLKLP ; NO AND# 0,1,SNR ; FREE BLOCK? JMP FOUND ; YES ISZ FBFF,3 ; NO DSZ FBFF,3 ; RESET THE FREE BLOCK FOUND JMP .-1 ; FLAG LDA 0,BKCTS,3 ; GET REQUESTED COUNT STA 0,BLKCT,3 ; RESET BLOCK COUNT LDA 0,0,2 ; RECOVER MAP WORD JMP BITLP FOUND: ISZ SRCH,3 DSZ SRCH,3 ; SEARCHING? JMP SET ; NO, SET THE BIT ISZ FBFF,3 DSZ FBFF,3 ; FIRST FREE BLOCK? JMP LPTST ; NO ISZ FBFF,3 ; YES, SET THE FLAG STA 2,CBAD,3 ; SAVE CURRENT BUFFER ADDRESS  LDA 2,CELAD,3 ; CELL LDA 0,WRDCT,3 ; CURRENT WORD COUNT STA 0,CWC,2 ; SAVE IN THE CELL STA 1,MASK,2 ; SAVE MASK IN CELL LDA 1,TWRDCT,2 ; GET TOTAL WORD COUNT FOR BLOCK SUB 0,1 ; OFFSET INTO THIS BLOCK STA 1,MWOFS,2 ; SAVE IN CELL LDA 3,MAPDC,2 ; MAP DCB ADDRESS LDA 1,DCBCB,3 ; GET CURRENT BLOCK NUMBER STA 1,CCB,2 ; SAVE IN CELL FOR RESET LDA 1,MASK,2 ; RECOVER THE MASK LDA 3,CSP ; & THE STACK POINTER LDA 2,CBAD,3 ; GET POINTER INTO BLOCK LDA 0,0,2 ; RECOVER THE CURRENT WORD MOVZ 0,0 ; 9SET CARRY = 0 JMP LPTST ; WHIP, WHIP .RELB: RELB .BLKIN: BLKIN .UNPEND:UNPEND ; OH, FOR DIRECT ADDRESSING .RELMB: RELMB BLKSZ: SCDBS ICBER: ERICB SPERR: LDA 1,ICBER ; CONTIGUOUS BLOCK ERROR ERR: MOV 2,0 ;SAVE DCB ADDRESS LDA 3,CSP LDA 2,CELAD,3Վ ;GET CELL ADDRESS MOVOL 1,1 ;SIGNAL PRESENCE OF ERROR JMP DONE2 ;GO UNLOCK & RETURN ERR1: LDA 2,CELAD,3 LDA 2,MAPDC,2 LDA 3,CC LDA 1,CERR,3 JMP ERR SET: ADD 1,0 STA 0,0,2 LPTST: DSZ BLKCT,3 ; FOUND ENUF BLOCKS? JMP BITLP ; NO LDA 0,SRCH,3 ; YES, GET THE SEARCH FLAG MOV 0,0,SZR ; SEARCHING? JMP DONE ; NO LDA 2,CA,3 ; BUFFER ADDRESS JSR @.RELB ; RELEASE PREFFERED ISZ SRCH,3 ; YES, SET TO NO LDA 3,CELAD,3 ; CELL ADDRESS LDA 2,MAPDC,3 ; MAP DCB LDA 1,CCB,3 ; FROZEN CURRENT BLOCK # STA 1,DCBCB,2 ; RESET DCB LDA 0,DCBFA,2 ; FIRST ADDRESS LDA 3,DBFA1,2 ; FORM FROZEN BLOCK ADDRESS ADDZ 1,0,SZC ; OVERFLOW INC 3,3 ; YEP STA 3,DBCA1,2 ; SET AS CURRENT STA 0,DCBCA,2 ; RESET DCB MOVS 1,1 ; BLOCK * 400 LDA 3,CSP LDA 3,CELAD,3 ; GET CELL ADDRESS LDA 0,MWOFS,3 ; OFFSET INTO THIS BLOCK ADD 0,1 ; (CA-FA)*400+OFFSET JSR @.BLKIN ; READ THE BLOCK AGAIN JMP ERR1 ; ERROR STA 0,CA,3 ; SAVE THE CORE ADDRESS STA 1,MAPX,3 ; FULL WORDS IN USE LDA 0,BKCTS,3 ; REQUESTED BLOCK COUNT STA 0,BLKCT,3 ; RESET BLOCK COUNTER LDA 2,CELAD,3 ; CELL ADRRESS LDA 1,CWC,2 ; FROZEN WORD COUNT STA 1,WRDCT,3 ; RESET THE FRAME'S WORD COUNT LDA 0,MWOFS,2 ; OFFSET INTO ORIGINAL BLOCK LDA 1,MASK,2 ; RECOVER ORIGINAL MASK LDA 2,CA,3 ; GET THE COATRE ADDRESS ADDZ 0,2 ; FROZEN MAP WORD ADDRESS LDA 0,0,2 ; FROZEN MAP WORD (WHAT ELSE?) JMP FOUND ; NOW SET ALL THE BITS DONE: LDA 2,CA,3 ; BUFFER ADDRESS JSR @.RELMB ; RELEASE MODIFIED ISZ ORTN,3 ; GOOD RETURN NOW LDA 1,MAPX,3 ; BLOCK ADDRESS% LDA 2,BPWD ; FORM BLOCK ADDRESS JSR @.MPY LDA 2,OAC2,3 ; DCB ADDRESS LDA 2,DCBDR,2 ; SYS.DR'S DCB ADDRESS LDA 2,SFLK,2 ; MAP.DR'S DCB ADDRESS LDA 3,DBFA1,2 ; FIRST ADDRESS OF MAP HIGH ORDER LDA 2,DCBFA,2 ; FIRST ADDRESS OF MAP ADDZ 2,1,SZC ; ADD MAP ADDRESS TO RELATIVE ADDRESS INC 0,0 ; GET THAT OVERFLOW ADD 3,0 ; GOT IT ALL LDA 3,CSP ; RESTORE STACK POINTER LDA 2,MAPOS ; -(MAP PARTITION OFSET) NEG 0,0 SUBZ 2,1,SNC ; OVERFLOW ? COM 0,0,SKP ; YES, DECREMENT HIGH ORDER ADDRESS NEG 0,03 ; RESTORE HIGH ORDER LDA 2,CELAD,3 LDA 2,MASK,2 ; MASK ADJ: MOVZL 2,2,SZC ; MOVE MASK IN REVERSE DIRECTION JMP DONE1 ; NON-ZERO CARRY IS END INCZ 1,1,SZC ; ADD 1 TO ADDRESS INC 0,0 ; CATCH OVERFLOW JMP ADJ ; BACK TO NORMAL DONE1: LDA 2,CELAD,3 ; GET CELL ADDRESS STA 0,MAPX1,3 ; RETURN FIRST BLOCK STA 1,MAPX,3 ; BOTH PARTS LDA 3,OAC2,3 ; INPUTTED DCB LDA 3,DCBDR,3 ; POINTER TO SYS.DR DCB LDA 3,SFLK,3 ; MAP DCB LDA 0,DCBNA,3 ; RECOVER HIDDEN CURRENT BLOCK STA 0,DCBCB,3 ; AND RESET SUB 1,81 ;SIGNAL NO ERROR MOV 3,0 ;SAVE DCB ADDRESS DONE2: JSR @.DMPUNLOCK ;UNLOCK THE MAP ON THE OTHER SIDE ; (AC2=CELL ADDR, AC0=DCB ADDR) JSR @.CREL ;THROW THE CELL AWAY MOV 0,2 ;MAP DCB, REMEMBER? SUB 3,3 STA 3,MPLCK,2 ;UNLOCK MAP ON OUR SIDE JSvR @.UNPEND MOVZR 1,2,SZC ;LOOK AT ERROR FLAG, ERROR? JSR @.RET2 ;YES, RETURN THE ERROR RTRN ;NO, GOOT RETURN BPWD: 16. .MPY: MPY MAPOS: SCMAP .CREL: CREL .RET2: RETE2 .DMPUNLOCK: DMPUNLOCK ENDOV .END DONE: LDA 2,CA,3 ; BUFFER ADDRESS JSR @H.RELMB ; RELEASE MODIFIED ISZ ORTN,3 ; GOOD RETURN NOW LDA 1,MAPX,3 ; BLOCK ADDRESS LDA 2,BPWD ; FORM BLOCK ADDRESS JSR @.MPY LDA 2,OAC2,3 ; DCB ADDRESS LDA 2,DCBDR,2 ; SYS.DR'S DCB ADDRESS LDA 2,SFLK,2 ; MAP.DR'S DCB ADDRESS LDA 3,DBFA1,2 ; FIRST ADDRESS OF MAP HIGH ORDER LDA 2,DCBFA,2 ; FIRST ADDRESS OF MAP ADDZ 2,1,SZC ; ADD MAP ADDRESS TO RELATIVE ADDRESS INC 0,0 ; GET THAT OVERFLOW ADD 3,0 ; GOT IT ALL LDA 3,CSP ; RESTORE STACK POINTER LDA 2,MAPOS ; -(MAP PARTITION OFSET) NEG 0,0 SUBZ 2,1,SNC ; OVERFLOW ? COM 0,0,SKP ; YES, DECREMENT HIGH ORDER ADDRESS NEG 0,0 ; RESTORE HIGH ORDER LDA 2,CELAD,3 LDA 2,MASK,2 ; MASK ADJ: MOVZL 2,2,SZC ; MOVE MASK IN REVERSE DIRECTION JMP DONE1 ; NON-ZERO CARRY IS END INCZ 1,1,SZC ; ADD `1 TO ADDRESS INC 0,0 ; CATCH OVERFLOW JMP ADJ ; BACK TO NORMAL DONE1: LDA 2,CELAD,3 ; GET CELL ADDRESS STA 0,MAPX1,3 ; RETURN FIRST BLOCK STA 1,MAPX,3 ; BOTH PARTS LDA 3,OAC2,3 ; INPUTTED DCB LDA 3,DCBDR,3 ; POINTER TO SYS.DR DCB LDA 3,SFLK,3 ; MuAP DCB LDA 0,DCBNA,3 ; RECOVER HIDDEN CURRENT BLOCK STA 0,DCBCB,3 ; AND RESET SUB 1,1 ;SIGNAL NO ERROR MOV 3,0 ;SAVE DCB ADDRESS DONE2: JSR @.DMPUNLOCK ;UNLOCK THE MAP ON THE OTHER SIDE ; (AC2=CELL ADDR, AC0=DCB ADDR) JSR @.CREL ;THROW THE CELL3] AWAY MOV 0,2 ;MAP DCB, REMEMBER? SUB 3,3 STA 3,MPLCK,2 ;UNLOCK MAP ON OUR SIDE JSR @.UNPEND MOVZR 1,2,SZC ;LOOK AT ERROR FLAG, ERROR? JSR @.RET2 ;YES, RETURN THE ERROR RTRN ;NO, GOOT RETURN BPWD: 16. .MPY: MPY MAPOS: SCMAP .CREL: CREL .RET2:% RETE2 .DMPUNLOCK: DMPUNLOCK .END SOV19.SRB + ; ; WRITE BREAK FILE WITH MULTIPLE BLOCKS ; ; QTY OPEN/CLOSE .NREL RTITLE SOV19 SV19 .ENT WBRKF ;WRITE CORE IMAGE .EXTN DIVI .EXTN WRB .IFE MSW .EXTN RELB,RELMB .EXTN BLKIN .ENDC  .IFN MSW .EXTD MFSTB .ENDC ;*******************************'********** ; NUMBER OF STACK TEMPORARIES USED ; MUST BE THE FIRST WORD IN THE OVERLAY .IFN BSW!MBSW 0 .ENDC ; WRITE A CORE IMAGE ; INPUT: AC2 - UFT OF BREAK FILE ALL SETUP BY STATUS ; OUTPUTS: ; AC0 - LAST BLOCK BYTE COUNT ; AC1 - FILE BLOCK COUNT WBRKF: LDA 2,CC ; GET ADDR OF CURRENT CELL SUB 0,0 ; ZERO CTEMP IN IT STA 0,CTEMP,2 ; SO WRITE BLOCK WILL START AT 1ST BLK .IFN MSW LDA 2,CPTAD,2 ; PICK UP PROGRAM TABLE ADDRESS JSR MFSTB ;MAP SO UST CAN BE REF LDA 3,CSP .ENDC LDA 2,USTP LDA 1,USTNM,2 ; NMAX LDA 2,USTSS,2 USGT 1,2 INC 2,1 LDA 0,STRSV ;START OF SAVE SUB 0,1 ;WORDS TO WRITE LDA 2,WDSBK ;WORDS PER BLOCK JSR @.DIVI ;DIVIED STA 1,OAC1,3 ;FULL BLOCKS MOVZL 0,0,SZR ;REMAINDER TO BYTES INC 1,1 ;EXTRA BLOCK MOV# 0,0.,SZR ; SKIP IF NO BYTES JMP WBRK1 ; GOT BYTES SO OK DSZ OAC1,3 ; DEC # OF FULL BLOCKS LDA 0,BTSBK ; SAY LAST BLOCK IS FULL WBRK1: STA 0,OAC0,3 ;RETURN # OF BYTES  LDA 0,STRSV ; GET START ADDRESS OF AREA TO WRITE LDA 2,OAC2,3 ; PICK UP UFT ADDRESS AGAIN JSR @.WRBK ; WRITE OUT CORE IMAGE RTRN ; RETURN ON OUTPUT ERROR .IFE MSW LDA 3,.UFTDC ; CALCULATE DCB ADD 3,2 ; ADDRESS LDA 0,DCBFA,2 ; GET FIRST BLOCK ADDRESS LDA 1,DBFA1,2 STA 0,DCBCA,2 STA 1,DBCA1,2 ; AND STORE AS BLOCK TO ACCESS JSR @.BLKIN ; GET INDEX BLOCK RTRN ; ERROR MOV 0,2 ; MOVE BUFFER POINTER ADDRESS LDA 0,0,2 ; GET FIRST BLOCK ADDRESS LDA 1,1,2 JSR @.RELB ; RELEASE BUFFER LDA 2,OAC2,3 ; GET UFT ADDRESS LDA 3,.UFTDC ; GET DCB ADD 3,2 ; ADDRESS LDA 3,DCBDC,2 ;i(DCT LDA 3,DCTCH,3 ;CHAR MOVL# 3,3,SNC ;SKIP IF BIG DISK MOV 0,1 ; AC0 -> AC1 : 0 -> AC0 MOVL# 3,3,SNC SUB 0,0 STA 0,DBCA1,2 ;TO DCB STA 1,DCBCA,2 ;PUT IN CA JSR @.BLKIN ;GET THE BLOCK RTRN ; ERROR LDA 3,CC ;CELL LDA 3,CPTAD,3 ;PTBL MOV 0,a2 ;BUFFER ADDRESS LDA 0,PSSV1,3 ; SAVED USER 40 STA 0,HRBEG-SCSTR,2 ; TO CORE IMAGE LDA 0,PSSV2,3 ; AND UP TO USER 47 STA 0,HRBEG+1-SCSTR,2 LDA 0,PSSV3,3 STA 0,HRBEG+2-SCSTR,2 LDA 0,PSSV4,3 STA 0,HRBEG+3-SCSTR,2 LDA 0,PSSV5,3 STA 0,HRBEG+4-SCI3STR,2 LDA 0,PSSV6,3 STA 0,HRBEG+5-SCSTR,2 LDA 0,PSSV7,3 STA 0,HRBEG+6-SCSTR,2 LDA 0,PSSV8,3 STA 0,HRBEG+7-SCSTR,2 JSR @.RELMB ;RELEASE MOD .ENDC ISZ ORTN,3 ; GOOD RETURN RTRN STRSV: SCSTR .DIVI: DIVI WDSBK: SCDBS BTSBK: SCDBS*2 .WRBK: WRB .IKRFE MSW .BLKIN: BLKIN .RELB: RELB .RELMB: RELMB .UFTDC: UFTDC ; DISPLACEMENT IN UFT OF DCB .ENDC ; THE FOLLOWING ARE OFFSETS INTO THE UFT FOR ; STORAGE WORDS USED BY THIS PROGRAM ;**** NOTE: ANY CHANGE SHOULD BE MADE IN ;**** QTYDR,QTYMD,SOV19,QrTYOV,SOV5,ALMDB,ALM1D QTRXP=UFTFN ;RECEIVE BYTE POINTER ; 0 NO READ QTORG=UFTFN+1 ;INITIAL RECEIVE BYTE POINTER QTTXP=UFTFN+2 ;TRANSMIT BYTE POINTER ; 0 NO WRITE QTRXT=UFTFN+3 ;READ CALLER TCB ; 1B0 + ERROR CODE QTXON=UFTFN+4 ;XON/daXOFF FOR TELETYPE READER ; -1 DON'T PUT OUT ANYTHING QTTBL=UFTEX ;ADDR OF TABLE ENTRIES INTO QTYTB QTTXT=UFCA1 ;TRANSMIT TCB QTRXS=UFTBN ;READ SEQUENTIAL LIMIT ; 0 READ LINE QTTXS=UFTBP ;WRITE SEQUENTIAL LIMIT ; 0 WRITE LINE  ;READ BUFFER QRSRT= UFTCA ;START OF BUFFER QREND= UFTCB ;END OF BUFFER QRGET= UFEA1 ;GET DATA POINTER QRSND= UFTEA ;SEND DATA POINTER ;WRITE BUFFER QWSRT= UFNA1 ;START OF BUFFER QWEND= UFTNA ;END OF BUFFER QWGET= UFLA1 ;GET DATA POINTER >RQWSND= UFTLA ;SEND DATA POINTER ;HOLD WORDS QECHO= UFFA1 ;HOLD FOR ECHOING ;-1 NO ECHO ;1B0 INHIBITS RECEIVES ; ON EMPTY BUFFER, WAKES UFT ; FLAGS CLOSING CHANNEL QXPND= UFTFA ;HOLD FOR EXPANDING ; -1 NO EXPANSION ; !y -2 DON'T GET DATA (CLOSING) QWCOL= UFTCN ;COLUMN COUNTER FOR TABBING ; 1B0 INDICATES WRITER BUSY QRBUF= 7 ;READ BUFFER QRBEN= 16 QWBUF= 17 ;WRITE BUFFER QWBEN= 20 ;NOTE-- BOTH BUFFERS MUST ;BE FREE OF ALL OTHER USE IF QRBUF NE UFTLK BUFFER ASSIGNMENT ERROR IF QRBEN NE UFTP1 BUFFER ASSIGNMENT ERROR IF QWBUF NE QRBEN+1 BUFFER ASSIGNMENT ERROR IF QWBEN NE UFTUC BUFFER ASSIGNMENT ERROR NLNS= 64. ;NUMBER OF LINES, ASSUMED 64. THROUGHOUT UFTTB= 0 ;UFT TABLE ; 0 INDICATES UNPOPENED ; 1B0 INDICATES FOREGROUND CHANNEL ; -1 INDICATES END OF TABLE ALMCH= NLNS+2+1 ;ALM LINE CHARACTERISTICS TABLE ; +2 FOR LINE 64 ; +1 FOR TERMINATOR ;RESERVED WORDS RSV1= UFTUN ;LINE NUMBER ; 1B0 FLAGS LINE 64 RSVm2= UFTCH RSV3= UFTDR RSV4= UFTDC RSV5= UFTST RSV6= UFTDL RSV7= UFTAT ;THE FOLLOWING IS HIDDEN, ; IT VERIFIES THE UFT ** .NOLOC 1 ** SUM1= QTRXP+(QTORG)B14+(QTTXP)B13+(QTRXT)B12+(QTTXT)B11+(QTRXS)B10+(QTTXS)B9 ** SUM2= (QRSRT)B8+(QREND)Bś7+(QRGET)B6+(QRSND)B5+(QWSRT)B4+(RSV5)B3+(RSV6)B2 ** SUM3= (QWSND)B15+(QECHO)B14+(QXPND)B13+(QWCOL)B12+(QWEND)B11+(QWGET)B10+(QRBUF)B9 ** SUM4= (QRBEN)B8+(QWBUF)B7+(QWBEN)B6+(RSV1)B5+(RSV2)B4+(RSV3)B3+(RSV4)B2 ** CK1SUM= SUM1+SUM2 ** CK2SUM= SUM3+SUM4 ** ** .IFE (CK1SUM==21202)&(CK2SUM==141353) **CK1SUM :; UFT OFFSETS HAVE CHANGED. CHECK FOR CLEAN **CK2SUM :; BUFFERS (QRBUFF AND QWBUFF) IN QTYOV AND QTYDR ** .ENDC ** .NOLOC 0 RBUFF: QRBUF ;START OF READ BUFFER RBEND: QRBEN ;END OF READ BUFFER WBUFJF: QWBUF ;START OF WRITE BUFFER WBEND: QWBEN ; END ; OPEN PROCESSING ; AC2 = UFT .ENT QTOPN .EXTN RETER, QTYTB .NREL .ENT QTCLS QTCLS: JMP .QTCLS QTOPN: LDA 0,UFTFN+1,2 ;WD 2 OF FILENAME MOV# 0,0,SZR ;MUST BE ZERO JMP OPNER ;WHEN YO>U'RE NOT, YOU'RE NOT LDA 0,UFTFN,2 ;GET FILE POSITION WORD JSR DIGCK ;CHECK FIRST POSITION DIGIT ; DIGIT IN AC1 LDA 0,UFTFN,2 ;GET WORD AGAIN AND SECOND DIGIT LDA 3,C177 ;GET MASK ANDS 3,0,SNR ; NEXT DIGIT JMP QTOP1 ;ONE DIGIT (AC1) MOVZL+b 1,2 ;FIRST DIGIT * 2 MOVZL 2,2 ; * 4 ADDZL 1,2 ; * 10 JSR DIGCK ;CHECK NEXT DIGIT ADD 2,1 ;LINE NUMBER TO AC1 LDA 3,CSP ;RESTORE UFT LDA 2,OAC2,3 QTOP1: LDA 3,CC ;MUST DECIDE IF PROG IS FG OR BG LDA 0,CPROG,3 ;=1 IF FG, =2 IF BG MOVZR# 0,0,TSZC ;FG OR BG? ADDOR 2,2 ;FG--SET 1B0 MOVZR 0,0 ;SET CARRY IF FOREGROUND LDA 3,CPTAD,3 ;PTBL LDA 0,PFLAG,3 MOVR 0,0 ;SET DIRTY (PRESERVES CARRY) MOVOL 0,0 STA 0,PFLAG,3 LDA 3,.QTYTB ;GET TABLE ADDRESS ADD 1,3 ;GET SLOT IN TABLE LDA 0,.NLNS D;CHECK LINE NUMBER USLE 1,0 JMP OPNER ; TOO LARGE-- ERROR SEQ 1,0 ;SKIP IF LINE 64 JMP NOT64 MOV# 1,1,SNC ;SKIP IF FOREGROUND JMP SET64 INC 1,1 ;BUMP LINE TO 65 (IN CASE USE FOR ACCESS) INC 3,3 ;BUMP TABLE SET64: ADDOR 1,1 ;1B0 FLAGS LINE 64 NOT64: STA 1,UFTUN,2 ;STORE LINE NUMBER STA 3,QTTBL,2 ;SET TABLE ENTRY ADDRESS LDA 0,UFTTB,3 ;AC0 <- UFT SLOT MOV# 0,0,SZR ;SOMETHING THERE? JMP ALOPN ;YES - CHECK FOR SAME GROUND INTDS ;CONFLICT FROM INTERRUPT WORLD ;AC0= 0 ;INIT UFT FO=R QTY STATE VARS STA 2,UFTTB,3 ;SAVE UFT POINTER IN SLOT STA 0,QTRXP,2 ;ZERO RECEIVE BYTE POINTER STA 0,QTTXP,2 ;ZERO TRANSMIT BYTE POINTER STA 0,QWCOL,2 ;ZERO COLUMN COUNT AND WRITER FREE STA 0,QTRXT,2 ;ZERO ERROR SAVE (REC TCB) STA 0,QTRXS,2 ;SO ECeHOING WILL INITIALLY OCCUR ADC 0,0 ;INIT HOLD WORDS STA 0,QXPND,2 STA 0,QECHO,2 STA 0,QTXON,2 ; AND XON/XOFF CONTROL ;SET UP READ AND WRITE BUFFERS LDA 0,RBUFF ;AC0 <- READ BUFFER START MOVL# 1,1,SNC ;CHECK FOR LINE 64 JMP BYTEB ; NO--BYTE BUFFERED ADD 2,0 ;AC0 <- READ BUFFER LDA 3,WBEND ;AC3 <- END OF BUFFER ADD 2,3 JMP QRET ;STUFF EM AND RETURN BYTEB: ADDZL 2,0 ;AC3 <- READ BUFFER LDA 3,RBEND ;AC3 <- END OF READ BUFFER ADDOL 2,3 ; LDA 1,WBUFF ADDZL 2,1 ;WRITE BUFFER ANlD STUFF STA 1,QWSRT,2 STA 1,QWSND,2 LDA 1,WBEND ADDOL 2,1 ;COMPUTE END OF BUFFER STA 1,QWEND,2 ; AND STUFF STA 1,QWGET,2 QRET: STA 0,QRSRT,2 ;SET UP READ BUFFER STA 0,QRSND,2 STA 3,QREND,2 STA 3,QRGET,2 JMP IRET ;AND RETURN ;CONVERT AND CHECK DIGIT IN AC0 DIGCK: LDA 1,M400 ;GET MASK ANDS 0,1 ;SWAP BYTE LDA 0,ZERO ;GET ASCII ZERO SUB 0,1 ;REDUCE TO BINARY LDA 0,C9 ;GET LIMIT ADCZ# 0,1,SNC ;TEST RANGE JMP 0,3 ;RETURN OPNER: JSR @.RETER ;BAD NAME FOUND - GIVE ERROR ERFNM ALOPN:x MOVL 0,0 ;1B0 TO CARRY ADD# 2,2,SNC ;CHECK FOR MATCHING 1B0 JMP NRET ;BITS SAME - OK JSR @.RETER ;NOPE--IN USE BY OTHER GROUND ERFIU M400: -400 ZERO: "0 C9: 9. .NLNS: NLNS C177: 177 .RETER: RETER .QTYTB: QTYTB ; CLOSE PROCESSING, AC2= UFT ! ; .ENT QTCLS .EXTN PEND .NREL .QTCLS: LDA 3,QTTBL,2 ;GET TABLE ENTRY INTDS ;POSSIBLE RACE, PEND ASSUMES DISABLED LDA 0,UFTTB,3 ;GET ENTRY SUBOL 2,0,SZR ;SEE IF SAME AS CALLING UFT JMP IRET ;NO - JUST RETURN LDA 0,QTRXP,2 ;RECEIVE BYTE PTR  MOV 2,1 ;SAVE UFT ADDRESS THRU SUBR LDA 2,QTRXT,2 ;RECEIVE TCB PTR JSR QTUPD ;UNPEND TASK IF THERE MOV 1,2 LDA 0,QWCOL,2 ;CHECK FOR EMPTY BUFFER MOVL# 0,0,SNC JMP FREE ; YES-- FREE THE CHANNEL SUBZR 0,0 ;SET UP QECHO TO FLUSH BUFFER STA 0,QECo:HO,2 INCOL 0,0 ; WAIT 3 SECONDS ONLY JSR @.PEND JMP .+1 ; COULD TIME OUT BEFORE LDA 0,QTTXP,2 ;TRANSMIT BYTE POINTER MOV 2,1 ;SAVE UFT LDA 2,QTTXT,2 ;ZAP TRANSMIT TCB IN CASE PEND QUITS ON US JSR QTUPD MOV 1,2 ;RESTORE UFT FREE: LDA 3,QTTBL,25 ;GET TABLE ENTRY SUB 1,1 ;ZERO CHANNEL SLOT STA 1,UFTTB,3 ;IF WE HAVE JUST CLOSED THE LAST ;OPEN QTY LINE IN THIS GROUND, THEN ;CLEAR THE DIRTY BIT MOV 2,1 ;SAVE UFT LDA 2,.QTYTB ;CHANNEL TABLE LP: LDA 0,UFTTB,2 ;GET ENTRY, IF ANY COM# 0,0,SNR ;END OF TABLE? JMP EOTB ;YES, STOP MOV 0,0,SZR ;LINE OPEN? JMP GGND ;YES, CHECK IF SAME GROUND UP: INC 2,2 ;CURRENTLY 1 ENTRY PER LINE, ;SO INC TO NEXT ENTRY JMP LP GGND: LDA 3,CC LDA 3,CPROG,3 ;1=FG, 2=BG  MOVR# 3,3,SNC ;SKIP IF FG A0DDOR 0,0 ;REVERSE BIT 0 FOR BG MOVL# 0,0,SZC ;SKIP IF WRONG GROUND JMP PIR ;CAN'T CLEAR DIRTY JMP UP ;ENTRY AT EOTB MEANS ALL QTY LINES ;ARE NOW CLOSED IN THIS GROUND, SO ;CLEAR DIRTY EOTB: LDA 3,CC LDA 3,CPTAD,3 LDA 0,PFLAG,3 ADCZL 2,2 ;MASK OUT ONLY DIRTY AND 2,0 STA 0,PFLAG,3 PIR: MOV 1,2 ;RESTORE UFT IRET: INTEN ;RELIEF NRET: LDA 3,CSP ISZ ORTN,3 ;GOOD RETURN RTRN QTUPD: MOV# 0,0,SNR ;ACTIVE? JMP 0,3 ;NO - JUST RETURN LDA 0,TPRST,2 ;YES - GET TASK STATUS ADDOR 0,0 ;CLEAR 1B0 STA 0,TPRST,2 ;UPDATE STATUS DSZ TPC,2 ;GIVE USER BAD RETURN DSZ TPC,2 LDA 0,.ERCLO ;AND SPECIAL ERROR CODE STA 0,TAC2,2 JMP 0,3 .PEND: PEND .ERCLO: ERCLO ENDOV .END SOV20.SRB R7e RTITLE SOV20 SV20 .NREL .IFN MSW .ENT CPRTN,CMNB,CPABT .ENT CPERT .EXTN CMNBG,CPUSH,CPDDR,CPFLG,WRMSO .EXTN CPFPS,FPUSV,PRISW,OVCHN .EXTN CPAMS .EXTN CFPU .EXTN PENDR .EXTN TTIQ .EXTN QEBWT .EXTN MVWD .EXTN UNPEND,RDCI,CPEXM,MDCB .EXTN PT1,PT2,MVWD,MTMVW,MFMVW .EXTD CMAP,C31K .EXTN CPDSV .EXTN OVLAY,SYSFL,SYSER ;***************************************** ; NUMBER OF STACK TEMPORARIES USED ; MUST BE THE FIRST WORD IN THE OVERLAY .IFN BSW!MBSW 10 .ENDC ; INITIAL CHECKPOINT PROC 4qBEFORE CORE IMAGE LOAD ; AC1= USER FLAGS- ONLY FLAG IS 1B1= BG RUNS AT = PRI ; CPFLG BITS: 1B15= CP IN EFFECT ; 1B14= OLD BG PRI = ; 1B0= OLD BG HAD FP USE CMNB: LDA 2,.PT2 LDA 3,CC LDA 3,CPTAD,3 ;CALLER SUB# 3,2,SNR ;IF BG SLAP FINGER JMP JCPER L-DA 3,PDCNT,2 ;# DELAYS LDA 1,PCLAC,2 ;USER CLOCK ? ADD 3,1 LDA@ 3,.CPFLG ADD# 3,1,SZR ;IF ANY NON 0 CAN'T DO JMP JCPER ;CAN'T OBLIGE .IFN MSW LDA 1,PVST,2 ;IF ANY VIRTUAL USE, CAN'T CP LDA 0,PMWIN,2 SUB# 0,1,SZR JMP CPERR .ENDC LDA 1,PFLAG,2  ;SEE IF A DIRTY PROG MOV# 1,1,SZR ;CAN'T IF DIRTY JCPER: JMP CPERR ;YES ; LOAD AC2 WITH PTBL- SOME ENTRIES DON'T HAVE IT IN AC2 WRT: LDA 2,.PT2 ;PTBL LDA 1,PSTAT,2 LDA 0,CEO AND# 1,0,SZR ;SKIP IF WE CCAN PROC JMP CMWT ;LOOP ISZ@ .CPFLG ;SET F_LAG LDA 3,.TTIQ INTDS LDA 0,QSTAT,3 MOV# 0,0,SNR JMP CMB1 ;TTI NOT ACTIVE LDA 3,QCURR,3 LDA 3,CPTAD,3 SUB# 3,2,SZR JMP CMB1 ;TTI NOT READING FOR BG ; CHANGE KEY TO CPFLG AND PEND LDA 3,.TTIQ LDA 1,.CPFLG STA 1,QKEY,3 ADC 1,1 STA 1,QTIME,3 ;CVERY LONG PEND LDA 1,QCURR,3 ;CURRENT STA 1,QSUFP,3 ;SAVE SUB 1,1 STA 1,QCURR,3 ;FLAG STATE AND FOOL SOV5 LDA 1,QSTAT,3 MOVR 1,1 MOVOL 1,1 ;PEND STA 1,QSTAT,3 CMB1: INTEN JSR@ .OVLAY ;WAIT QEBWT LDA 1,PDDCB,2 ;DDCB STA@ 1,.CPDDR ;SAVE LDA 1,PTSPN,2 ;SAVE PUSH LEVEL STA@ 1,.CPUSH LDA@ 1,.FPUSV ;SEE IF FPU ACTIVE MOVR# 1,1,SNC JMP CME1 ;SAVE FPU STATE IN CP AREA ; IF CURRENT FP CONTENT IS BG, DUMP FPU TO CP AREA ; IF CONTENTS IS FG, THEN MOVE PTBL AREA TO CP AREA DSZ@ .FPUSV ;RESET BG HAS FPU BIT JMP .+1 LDA@ 0,.CFPU SUB# 0,2,SNR JMP FPDMP ;MUST GET FROM BOX LDA 0,.ADDFP ;ADDR FP IN PTBL LDA 1,.CPFPS ;SAVE AREA .IFE MBSW LDA 2,C9 ;NINE WORDS .ENDC .IFN MBSW ELEF 2,18. .ENDC JSR@ .MVWD JMP CMFP ; DUMP FPU TO CPFPS FPDMP: d.IFE MBSW LDA 2,.CPFPS DOBS 2,FPU2 ;FPAC TO TABLE LDA 0,C4 ADD 0,2 ;BUMP ADDR SKPBZ FPU JMP .-1 NIOC FPU2 ;TMP TO FPAC SKPBZ FPU JMP .-1 DOBS 2,FPU2 ;TO TBL SKPBZ FPU JMP .-1 DIAC 1,FPU ;GET STATUS SKPBZ FPU JMP .-1 STA 1,4,2 ;TO TBL ]| .ENDC .IFN MBSW LDA 0,CSL ;SAVE PRESENT SL AND SP IN ACS LDA 1,SP ADDI PFPSV-1,2 ;= STATE SAVE START STA 2,SP ADCZR 2,2 ;NO OVERFLOW CHECK STA 2,CSL FPSH ;PUSH STATE STA 0,CSL ;RESTORE STA 1,SP .ENDC CMFP: LDA@ 0,.CPFLG ;SET FP BIT IN CPFLG ADDOR 0,0,SKP CME1: LDA@ 0,.CPFLG ;FLAG WORD LDA@ 1,.PRISW ;SEE IF CURRENT BG PRI = FG MOVZL 1,1,SZR ;SKIP IF NO ADD 1,0 ;SET FLAG FOR RESTORE STA@ 0,.CPFLG SUB 0,0 STA@ 0,.PRISW ;INIT PRISW LDA 0,.ADDEV LDA 1,.CPDSV ;SAVE AREA FOR DEV STAT L.DA 2,C8 JSR@ .MVWD ;SAVE IT SUBZR 1,1 ;FLAG FOR SOV8 LDA@ 2,CC LDA 0,TAC0,2 ;NAME POINTER JSR@ .OVCHN CMNBG ;LOAD IN AND RUN CPRTN: JMP .CPRTN ; ABORT A CHECHPOINT CPABT: LDA@ 0,.CPUSH ;WHERE IT'S AT LDA 3,.PT2 STA 0,PTSPN,3 ;RESET LEVEL LDAA 0,PTPB1,3 ;BASE ADD WD 1 LDA 1,PTPBA,3 ;WD 2 LDA 3,.SCBPB ;PUSH INDEX ADDR ADDZ 3,1,SZC ;ADDR -LOOK FOR OVERFLOW INC 0,0 ;A BIG DISK I HOPE..... LDA@ 2,CQ ;Q DCB STA 0,DBFA1,2 ;SET FA STA 1,DCBFA,2 ADC 1,1 ;RTN FLAG LDA@ 2,.MDCB ;MASTER JS+R@ .OVLAY RDCI JMP . ;IF ERROR IT PANICED LDA@ 1,.CPAMS ;INT MSG JMP CPRCM CPERT: SUB 0,0 ;MASK - RESET ALL JMP CPRC2 ;COMMON .PT2: PT2 CEO: PSEW .CPUSH: CPUSH .CFPU: CFPU .CPDDR: CPDDR .FPUSV: FPUSV .CPFLG: CPFLG .PRISW: PRISW .CPEXM: CPEXM .MDCiB: MDCB .OVCHN: OVCHN .CPFPS: CPFPS .SYSFL: SYSFL .TTIQ: TTIQ .UNPEND: UNPEND .SER: SYSER .OVLAY: OVLAY .CPAMS: CPAMS CPERR: LDA 1,PSTAT,2 ;RESET CP LDA 0,CMCP AND 0,1 STA 1,PSTAT,2 JSR@ .SER ERNTE CMWT: JSR .+2 ;RTN TO AC3 JMP WRT ;REAL RTN STA$ @ 3,CSP JMP@ .+1 PENDR C4: 4 CMCP: -PSCP-1 C8: 8. C9: 9. .CPDSV: CPDSV .MVWD: MVWD .ADDEV: .GADD PT2,PDEV .ADDFP: .GADD PT2,PFPSV .SCBPB: SCBPB ; RETURN FROM CHECKPOINT .CPRTN: LDA@ 1,.CPEXM ;CP DONE MSG CPRCM: JSR@ .OVLAY WRMSO JMP .+1 ;SORRY.... SUB 1,1 STA@ 1,CC ;NO TCB UNPEND LDA 0,CCPF ;MASK-IF ERROR MASK WILL BE ; DIFFERENT ; ENTRY HERE ON ERROR DURING CHECKPOINT LOAD CPRC2: LDA@ 1,.CPDDR ;OLD DDCB LDA 2,.PT2 STA 1,PDDCB,2 ;RESTORE LDA 1,PSTAT,2 ;RESET ALL BUT CP AND 0,1 STA 1,PSTAT,2 LDA@ 1,.CPFLG ;FP SAVED ? MOVL# 1,1,SNC JMP CPR1 ;NO ; RESTORE FPU STATE ; IF CPPU= PT1 THEN MOVE TO PT2 PTBL ; IF CFPU = PT2,THEN LOAD FPU LDA@ 1,.FPUSV ;RESTORE BG BIT MOVR 1,1 MOVOL 1,1 STA@ 1,.FPUSV LDA@ 1,.CFPU LDA 3,.CPFPS ;STATE AREA  SUB# 1,2,SNR JMP FPLD ;LOAD BOX MOV 3,0 ;FP STATE AREA LDA 1,.ADDFP ;PTBL ADDR .IFE MBSW LDA 2,C9 ;NINE WORDS .ENDC .IFN MBSW ELEF 2,18. .ENDC JSR@ .MVWD JMP CPR1 ; LOAD FPU FPLD: .IFE MBSW LDA 0,C4 ADD 3,0 ;ADDR TMP DOBP 0,FPU2 ;MOVE zTO FPAC SKPBZ FPU JMP .-1 NIOP FPU2 ;MOVE TO TMP SKPBZ FPU JMP .-1 DOBP 3,FPU2 ;MOVE IN REAL FPAC SKPBZ FPU JMP .-1 LDA 1,10,3 ;STATUS DOA 1,FPU ;SET STATUS .ENDC .IFN MBSW LDA 0,CSL ;SAVE PRESENT SL AND SP IN ACS LDA 1,SP ADDI PFPED,2 d ;= STATE SAVE END STA 2,SP ADCZR 2,2 ;NO OVERFLOW CHECK STA 2,CSL FPOP ;POP STATE STA 0,CSL ;RESTORE STA 1,SP .ENDC CPR1: LDA@ 1,.CPFLG MOVR 1,1 ;SEE IF PRISW WAS SET MOVR# 1,1,SZC ;SKIP IF NO ISZ@ .PRISW ;SET LDA 0,.CPDSV ;OLD DEV STAT  LDA 1,.ADDEV ;PTBL ADDR LDA 2,C8 ;8 WORDS JSR@ .MVWD ;MOVE IT SUB 1,1 STA@ 1,.SYSFL ;CLEAR ANY LINGERING FARTS STA@ 1,.CPFLG STA@ 1,.CPUSH .IFE MBSW STA 1,CMAP ;FORCE REMAP .ENDC LDA 3,.TTIQ LDA 1,QCURR,3 ;SEE IF WE MUCKED WITH IT MOV# 1,1,SZR RTRN ;NO LDA 1,QSUFP,3 ;RESTORE CURRENT CELL STA 1,QCURR,3 INTDS LDA 0,.CPFLG ;KEY JSR@ .UNPEND INTEN RTRN CCPF: PSCP .ENDC .IFE MSW .BLK 1 .ENDC ENDOV .END SOV21.SRB R; RTITLE SOV21 SV21 .NREL .TXTM 1 .ENT MCCLS,MCRDS,MCWRS,MCRCL .EXTN UPQUE,SYSER .EXTN MCTBL,MCRBL .EXTN XDOB,XNOC,XDOA,XNOS,XDOBS .EXTN XDOC .EXTN RETE2 .IFN MSW .EXTN SWAMP .ENDC ;***************************************** ; NUMBER OF STACK TEMPORARIES USED ; MUST BE THE FIRST WORD IN THE OVERLAY .IFN BSW!MBSW 5 .ENDC ; ONCE AGAIN WE ARE ABOUT TO BUILD A ; FAKE BUFFER HEADER IN THE UFT SO BE CAREFUL ; IF ANY BUFFER HEADER, UFT, OR DCT PARAMETERS CHANGED ; THIS CODE IS ******! ; OFSETS INTO THE UFT MCTOT= UFTEX-1 ; TIME OUT TRIES MCDEV= UFTEX ; DEVICE REQUESTED SHIFTED FOR ; STATUS WORD MCMSA= UFTLK ; (BQDCB) FOR MAP PTAD+PMAP MCLK= UFTBK ; UFT LINK MCDBN= UFTBC ; BINARY # OF DEVICE REQUESTED MCTCB= UFTAD ; USER TCB ADDRESS MCBQST= UFTAC ; (BQST) STATUS WORD OF FAKE BUFFER HEADER MCTAD= UFTYD ; PROGRAM TABLE ADDRESS MCINU= UFTHM ; DEVICE IN USE FLAG MCCNT= UFTP1 ; REQUEST WORD COUNT MCADR= UFTUC ; (BQARD) USER STARTING ADDRESS MCDBA= UFTDL ; (BQBF) FAKE BUFFER START CONTAINS . ; IT SHOULD BE NOTED THAT A BUFFER IS BUILT ; INTO THE DCT AND IF ANY DCT DISPLACEMENTS CHANGE THE ; WHOLE WORLD IS IN TROUBLE QBAD= DCTRL ; BUFFFER AREA FOR TRANSMITS QQCNT= DCTRD ; NUMBER OF WORDS IN REQUEST RFLAG= DCTIN ] ; STATE FLAG FOR RECEIVER TFLAG= DCTIN ; STATE FLAG FOR TRANSMITTER UNFLG= DCTRS ; PROTOCOL FLAG FOR REC QPTR= DCNBK ; ACTIVE ELEMENT ON QUEUE **; ERROR TRAPS IN CASE DISPLACEMENTS CHANGE ** .NOCON 1 ; DON'T SHOW UNLESS NEEDED ** .DO MCDBA-MCBQS<>0BQBF-BQST ** LDA:; DISPLACEMENT ERROR MCDBA,MCBSQ ** .ENDC ** .DO MCDBA-MCADR<>BQUST-BQADR ** LDA:; DISPLACEMENT ERROR MCDBA,MCADR ** .ENDC ** .DO QQCNT-QBAD<>1 ** LDA:;DISPCACEMENT ERROR QQCNT,QBAD ** .ENDC ** .DO MCDBA-MCMSA<>BQBF-BQDCB ** LDA:; DISPLACEMENT ERROR MCDBA,MCMSA ** .ENDC ** .NOCON 0 ; STACK DISPLACEMENTS (NOTE FIRST THREE MUST ; REMAIN WHERE THEY ARE. THEY ARE COMMON TO SOV21, ; SOV24, AND MCADR. .DCT= TMP+0 DBUF= .DCT+1 TYPE= DBUF+1 TABL= TYPE+1 OFUFT= TABL+1 ; CLOSE CODE FOR MCA2 MCRCL: LDA 0,.MCRBL ; CLOSE ON RECEIVER SUBZ 1,1 JMP .+3 MCCLS: LDA 0,.MCTBL ; CLOSE ON TRANSMITTER SUBZL 1,1 ; IN CASE OF RESTART STA 1,TYPE,3 ; SAVE TYPE OF CLOSE STA 0,TABL,3 ; SAVE DEVICE TABLE MOV 0,3 ; USE FOR OFSET ; CLEAR DEVICE TABLE INP:TDS LDA 1,MCDBN,2 ; GET DEVICE BINARY # ADD 1,3 ; GET SLOT IN TABLE SUBZ 0,0 STA 0,0,3 ; CLEAR SLOT ; NOW DEQUE REQUEST LDA 0,UFTDC,2 ; GET DCT ADDRESS LDA 3,CSP STA 0,.DCT,3 ; SAVE DCT ADDRESS ON STACK MOV 0,3 LDA 0,DCCRQ,3 ; GET FRST ELEMENT O(N QUEUE COM# 0,0,SNR ; ACTIVE ? JMP OUT ; ENABLE INTERRUPTS AND LEAVE SUB# 0,2,SZR ; THIS THE ONE ? JMP QLLP ; NO,STEP DOWN QUEUE LDA 0,MCLK,2 ; GET NEXT ELEMENT POINTER STA 0,DCCRQ,3 ; QUEUE IS REARRANGED JMP GIN2 ; RESTART IF NECESSARY QLLP: MOV 0,3 LDA 0,MCLK,3 ; GET NEXT ELEMENT COM# 0,0,SNR ; DONE ? JMP OUT SUB# 0,2,SZR ; MATCH ? JMP QLLP LDA 0,MCLK,2 ; GET LINK STA 0,MCLK,3 ; NOW ITS DEQUED ; AC2 HAS UFT TAKEN OF QUEUE GIN2: LDA 3,CSP SUBZ 0,0 ; CLEAR IN USE FLAG STA 0,MCINU,2 STA 2,OFUFT,3 ; SAVE UFT LDA 3,.DCT,3 ; GET DCT BACK LDA 1,QPTR,3 ; GET ACTIVE ELEMENT SUB# 1,2,SZR ; ACTIVE ? JMP ABTST ; NO, CHECK ABORT ; NOW CLEAR DEVICE AND RESTART IF NECESSARY SUBZ 0,0 STA 0,QPTR,3 ; SHOW INACTIVE LDA 0,DCTCD,3 ; GET DEV\ICE CODE LDA 1,.NOC ; CLEAR INST ADD 1,0 STA 0,.+1 0 ; CLEAR DEVICE ; SEE IF RESTART NECESSARY LDA 3,CSP LDA 3,.DCT,3 LDA 0,DCCRQ,3 ; GET QUEUE POINTER COM# 0,0,SNR ; RESTART ? JMP ABTT ; TRY ABORT JSR MCST ; START DEVICE ABTT: LDA 3,CSP L@DA 2,OFUFT,3 ; GET DEQUEDED ELEMENT BACK ; NOW TEST FOR ABORT ABTST: COM# 2,2,SNR ; WAS ANYTHING ACTIVE ? JMP OUT ; ENABLE INTERRUPTS AND LEAVE ; GIVE ERROR RETURN TO UFT IN AC2 AND UNPEND LDA 3,MCTCB,2 ; GET TCB LDA 0,CLOER ; CLOSE ERROR STA 0,TAC2k:,3 ; RETURN TO USER DSZ TPC,3 DSZ TPC,3 LDA 0,TPRST,3 ; CLEAR TCB STATUS ADCZR 1,1 AND 1,0 STA 0,TPRST,3 LDA 3,MCTAD,2 ; GET PROGRAM TABLE ADDRESS LDA 0,PSTAT,3 ; GET STATUS AND 1,0 STA 0,PSTAT,3 SUBZL 0,0 ; KICK SCHEDULER STA 0,@.UPQUE OUT: INTEN LDA 3,CSP ISZ ORTN,3 ; GOOD RETURN RTRN MCBY: JMP @.ERT2 .ERT2: RETE2 .MCTBL: MCTBL .MCRBL: MCRBL CLOER: ERCLO .NOC: NIOC 0 ; CLEAR DEVICE .UPQUE: UPQUE .SYSER: SYSER TMSK: 377*400 ; COMMON CODE FOR RDS WRS MCWRS: SUBZL 2,2,SKP ; SHOW WRITE REQUEST MCRDS: SUBZ 2,2 STA 2,TYPE,3 ; SAVE CALL TYPE LDA 2,OAC2,3 ; GET UFT ADDRESS BACK LDA 2,MCINU,2 ; GET IN USE FLAG MOV# 2,2,SZR JMP IN LDA 2,OAC2,3 MOVZR 0,0 ; MAKE BYTE POINTER WORD POINTER STA 0,MCADR,2 ; SAVE IT IN UFT MOVZR 1,1,SZC ; # BYTES -> WORDS INC 1,1 ; GET THE LAST BYTE STA 1,MCCNT,2 ; SAVE IT IN UFT ADD 0,1 ; GET LAST WORD ADDRESS ADC 0,0 ; SET LINK STA 0,MCLK,2 ; LAST UFT ON QUEUE LDA 0,TYPE,3 ; READ OR WRITE REQUEST MOV# 0,0,SZR JMP INLIN ; WRITE ; CHECK TO MAKE3 SURE THIS REQUEST WONT WRITE ABOVE USER'S MAX LDA 3,USTP ; USER STATUS POINTER LDA 0,USTNM,3 ; LAST ADDRESS AVAILABLE TO USER SUBZ# 1,0,SNC JMP RDER0 ; OVER NMAX INLIN: LDA 0,MCCNT,2 ; MUST HAVE <4000 WORDS IN ; TRANSFER LDA 1,C4000 SUBZ# 0,1,SNC ; TEST IT JMP RDER1 ; OVER MAX TRANSFER ALLOWED LDA 3,CC ; GET TCB ADDRESS LDA 3,CATCB,3 STA 3,MCTCB,2 ; PUT IN UFT LDA 0,UFTCH,2 ; SEE IF USER SPECIFIED TIME OUT SUB 1,1 ; DEFAULT TIME OUT TRIES MOVR# 0,0,SZC ; SPECEFIED ? JMP BYPAS ; USQE DEFAULT TIME OUT LDA 1,TAC2,3 ; GET TIME OUT TRIES LDA 0,TMSK ; TIME OUT TRIES LEFT BYTE OF ; AC2 ANDS 0,1 ; * 20 MOV 1,0 ADDZL 1,0 ; *4 ADDZL 0,1 ; *10 MOVZL 1,1 ; *20 BYPAS: STA 1,MCTOT,2 ; SAVE LDA 3,CC ; RESTORE CURRENT CELL ADDRESS$ ; IN AC3 LDA 0,CPTAD,3 ; GET PROG TABLE ADDRESS .IFN MSW LDA 1,.PMAP ADD 0,1 STA 1,MCMSA,2 LDA 1,.QTIND STA 1,MCBQST,2 .ENDC STA 0,MCTAD,2 ; PUT IN UFT .IFN MSW LDA 0,DOFST ADD 2,0 STA 0,MCDBA,2 ; SAVE DUMMY BUFFER ADDRESS .ENDC SUB 0,0 ; PEND USER VIA CURRENT CELL STA 0,@CC ; GOT HIS TCB LDA 3,CSP ; TO GET RIGHT DCT ISZ MCINU,2 LDA 2,UFTDC,2 ; GET DCT STA 2,.DCT,3 ; SAVE DCT ADDRESS INTDS ; WANT TO POKE AROUND ON QUEUE LDA 1,DCCRQ,2 ; IS DEVICE ACTIVS ? COM# 1,1,SNR ; ? 'JMP MCSTG ; NO,HAVE TO START IT MOV 1,2 ; ACTIVE PUT ON END OF QUEUE LDA 1,MCLK,2 ; FIND END OF QUEUE COM# 1,1,SZR JMP .-3 ; TRY AGAIN LDA 0,OAC2,3 ; GET UFT ADDRESS STA 0,MCLK,2 ; PUT ON QUEUE INTEN ; DONE WITH DCT JMP OUTGO IN: LDA 2,MC1 ; ERROR UFT ALREADY IN USE JMP MCBY RDER0: RDER1: LDA 2,MC0 JMP @.ERT2 MC0: ERRD ; ATTEMPT TO READ INTO SYSTTEMS ; AREA C4000: 4096. MC1: ERMCA .IFN MSW .PMAP: PMAP .QTIND: QTIND DOFST: MCDBA .ENDC MCSTG: LDA 0,OAC2,3 ; PUT REQUEST ON QUEUE STA 1b0,DCCRQ,2 JSR MCST OUTGO: LDA 3,CSP ISZ ORTN,3 ; GOOD RETURN RTRN ; THIS CODE IS TO START A DEVICE MCST: STA 3,MCSTR LDA 3,CSP LDA 2,.DCT,3 ; SHOW ACTIVE REQUEST LDA 0,DCCRQ,2 STA 0,QPTR,2 INTEN ; LETS HEAR FROM THE OTHERS SUB 1,1 ; SET THE @STATE OF DRIVER STA 1,TFLAG,2 ; TO INITIAL PROTOCOL STATE LDA 1,OFST ; MAKE DUMMY BUFFER ON STACK ADD 3,1 STA 1,DBUF,3 ; SAVE FOR ALL IO CALLS LDA 1,TYPE,3 ; READ OR WRITE REQUEST MOV# 1,1,SNR JMP MCST1 ; READ LDA 2,QPTR,2 ; GET UFT LDA 0,MCDEV, 2 ; DEVICE TO TRANSMIT TO LDA 2,DBUF,3 ; DUMMY BUFFER ADDRESS JSR @.XDOC ; SET STATUS REGISTER LDA 3,CSP LDA 2,.DCT,3 ; SET UP FOR OTHER IO CALLS LDA 3,DCCRQ,2 ; SEE IF DIRECT IIO LDA 0,UFTCH,3 ; GET CHARACTERISTICS MOVZL# 0,0,SZC JMP MCST1 ; NOT DIRECT LDA 0,B2 ; PUT TRANSMITTER IN STATE 2 STA 0,TFLAG,2 ; PUT TRANSMITTER IN STATE 2 .IFE MSW LDA 0,MCADR,3 ; DIRECT GET CORE ADDRESS JMP .+2 ; GET AROUND DUMMY ADDRESS .ENDC .IFN MSW LDA 0,DCHMP,2 ; MAPPED USE DATA CHANNEL MAP ; FOR CORWE ADDRESS LDA 1,DCHNM,2 LDA 2,MCDBA,3 ; DUMMY BUFFER ADDRESS IN UFT JMP MAPR .ENDC MCST1: LDA 0,QBAD,2 ; SYSTM CALL BUFFER .IFN MSW LDA 0,DCHMP,2 LDA 1,DCHNM,2 LDA 2,QBAD,2 MAPR: JSR @.SWAMP .ENDC LDA 3,CSP ; GET CSP BACK LDA 2,DBUF,3 JSR @.XDOA ; SET ADDRESS REGISTER LDA 3,CSP LDA 0,TYPE,3 ; READ OR WRITE MOV# 0,0,SNR ; WELL JMP MCRC ; READ LDA 2,OAC2,3 ; GET UFT LDA 1,MCCNT,2 ; GET SIZE , IT MAY BE DIRECT NEG 1,1 LDA 0,UFTCH,2 ; CHARACTERISTIC MOVZL# 0,0,SNC ; DIRECT ? MOV 1,0,S)KP ; YES MCRC: ADC 0,0 LDA 2,DBUF,3 ; DUMMY BUFFER ADDRESS JSR @.XDBS ; SET B REG AND START JMP @MCSTR ; RETURN MCSTR: 0 .XDOA: XDOA .XDBS: XDOBS .XDOC: XDOC OFST: .DCT-BQDCT .IFN MSW .SWAMP: SWAMP .ENDC B2: 2 ENDOV .END SFTAB.SRB Sb RTITLE SFTAB .NREL .ENT SFTAB ; THIS IS THE DATA OVERLAY USED FOR CONSTRUCTING ; PERIPHERAL DEVICE ENTRIES IN A DIRECTORY AT INIT TIME ; ; EACH ENTRY CONSISTS OF 3 DATA LOCATIONS DEFINED AS FOLLOWS: ; ; OFFSET CONTENTS ; ; 0 RELATIVE POINTER TO `NAME STRING ; 1 ATTRIBUTES ASSOCIATED WITH FILE ; 2 DEVICE LINK (LOGICAL DEVICE CODE) .TXTM 1 ; PACK NAME STRINGS LEFT TO RIGHT SFTAB: SYSP ATPER+ATCHA+ATCON 0 TTIP ATPER+ATCHA+ATWP 100 ; LOGICAL DEVICE CODE OF TTI TTOP ATPER+ATCHA+ATRP TTO TTRP ATPER+ATCHA+ATWP 101 ; LOGICAL DEVICE CODE OF TTR TTPP ATPER+ATCHA+ATRP TTO PTRP ATPER+ATCHA+ATWP PTR PTPP ATPER+ATCHA+ATRP PTP LPTP ATPER+ATCHA+ATRP LPT CDRP ATPER+ATCHA+ATWP CDR PLTP ATPER+ATCHA+ATRP PLT DPIP yATPER+ATCHA+ATWP DPI DPOP ATPER+ATCHA+ATRP DPO TTI1P ATPER+ATCHA+ATWP 102 ; LOGICAL DEVICE CODE OF TTI1 TTO1P ATPER+ATCHA+ATRP TTO1 TTR1P ATPER+ATCHA+ATWP 103 ; LOGICAL DEVICE CODE OF TTR1 TTP1P ATPER+ATCHA+ATRP TTO1 PTR1P ATPER+ATCHA+ATWP PTR1 PTP1P ATPER+ATCHA+ATRP PTP1 LPT1P ATPER+ATCHA+ATRP LPT1 CDR1P ATPER+ATCHA+ATWP CDR1 PLT1P ATPER+ATCHA+ATRP PLT1 0 ; END OF TABLE **********************  SYSP: .TXT /BOOTSYS.OL/ TTIP: .TXT /$TTI/ TTOP: .TXT /$TTO/ TTRP: .TXT /$TTR/ TTPP: .TXT /$TTP/ PTRP: .TXT /$PTR/ PTPP: .TXT /$PTP/ LPTP: .TXT /$LPT/ CDRP: .TXT /$CDR/ PLTP: .TXT /$PLT/ DPIP: .TXT /$DPI/ DPOP: .TXT /$DPO/ TTI1P: .TXT /$TTI1/ TTO1P: .TXT /$TTO1/ TTR1P: .TXT /$TTR1/ TTP1P: .TXT /$TTP1/ PTR1P: .TXT /$PTR1/ P`6 TP1P: .TXT /$PTP1/ LPT1P: .TXT /$LPT1/ CDR1P: .TXT /$CDR1/ PLT1P: .TXT /$PLT1/ ENDOV .END SOV22.SRB 9< RTITLE SOV22 SV22 .NREL .ENT RLBOT ; SECOND PART OF MASTER DEVICE ; RELEASE/BOOT CODE .EXTN OVTAB ; SYS AREA FOR USER DEFINED ; FILE NAME .SV .EXTN TFTX ; CHECK FOR TERMINATOR .EXTN MFMVB ; MEMORY MOVE ROUTINE ;*****************f************************ ; NUMBER OF STACK TEMPORARIES USED ; MUST BE THE FIRST WORD IN THE OVERLAY .DO ABSW 7 .ENDC ; SECOND PART OF MASTER DEVICE RELEASE/BOOT CODE ; CHAINED TO BY SOV18 ENTSW=TMP+1 ; NON-ZERO IF RELEASE OF MASTER DEVCD=ENTSW+1 ; DEVICE CODE UNIT=DEVCD+1 ; UNIT # * 2 SFFLG=UNIT+1 ; SAVE FILE FLAG BYTCT=SFFLG ; BYTE COUNTER TEMPORARY ASCUN=SFFLG+1 ; ASCII UNIT # FROM=ASCUN+1 ; BYTE POINTER TEMPORARY RLBOT: LDA 0,SFFLG,3 ; GET SAVE FILE FLAG SNEZ 0 ; IS THERE ONE ? eJMP HIPIT ; NO LDA 2,@CC ; TCB ADDRESS LDA 0,TAC0,2 ; USER'S AC0 STA 0,FROM,3 ; IS FROM MOV 0,1 ; MOVE POINTER TO AC1 SUB 0,0 STA 0,BYTCT,3 ; INITIALIZE BYTE COUNT CNTLP: MLDB 1,0 ISZ BYTCT,3 ; BUMP THE COUNT INC 1,1 ; & THE BYTE POINTER CALLO TFTX ; TEST FOR TERMINATOR JMP CNTLP ; NOT A TERMINATOR XLDA 2,= ": ; GET A ':' SNE 0,2 ; FALSE TERMINATOR ? JMP CNTLP ; YEP LDA 1,.SYS ; GET POINTER INTO SYSTEM MOVZL 1,1 ; FORM BYTE POINTER STA 1,.SYS ; SAVE FOR LATER LDA 0,FROM,3 ; USER AREA POINTER LDA 2,BYTCT,3 ; BYTE COUNT XXJSR MFMVB ; WRITE OVER THE MAD BOMBER'S ; CODE ADD 2,1 ; NEW BYTE POINTER XLDA 0,= 15 ; GET A CARRIAGE RETURN STB 1,0 HIPIT: INTDS XLDA 1,= MSGPT ; GET MESSAGE POINTER LDA 3,@CRSEG ; & THIS OVERLAY'S R BASE ADDZL 3,1  ; FORM TRUE BYTE POINTER JMP MSGL1 MSGLP: LDB 1,0 INC 1,1 ; NEXT BYTE SNEZ 0 ; IF ZERO BYTE THEN DONE JMP BOOTIT ; NULL - MESSAGE IS DONE DOAS 0,TTO ; NOT NULL, SEND THE CHARACTER MSGL1: SKPBZ TTO ; WAIT FOR DONE JMP .-1 JMP MSGLP ; DO ANOTHER ONE ; FILL CORE WITH HALTS SMOTHER:XLDA 0,= STA 0,3,2 ; PUT HALT ROUTINE IN LOW CORE STA 0,0 XLDA 0,= INC 2,2 STA 0,1 XLDA 0,= HALT ; DOC 0,CPU SUB 2,2 ; +0 STA 2,2 ; JMP TO 0 JMP 0 ; TRY IT OUT ** .TXTM 1 ** .NOLOC 1 MSGP|T: .TXT /<15><12>MASTER DEVICE RELEASED<15><12>/ ** .NOLOC 0 LPOOL .SYS: OVTAB ; SYSTEM AREA TO WRITE OVER WITH USER ; DEFINED SAVE FILE NAME(NEXT SYSTEM) ; ROUTINE TO BOOTSTRAP A CORE IMAGE OR HIPBOOT .DO ANSW ; ANY NOVA .MACRO XCT ** STA ]^1,.+1 ** 0 % .ENDC ; SHUT OFF MAP & IORST MACHINE BOOTIT: LDA 3,CSP .IFN MN3SW SUB 0,0 DOA 0,MAP ; SHUT OFF MAP LDA 0,@1 ; TRIGGER SHUT OFF .ENDC IORST ; RESET THE WORLD LDA 0,DEVCD,3 ; GET DEVICE CODE JSR GODEV ; GO TO CORRECT BOOT READER ; TABLE OF DEVICE CODES FOR EACH DISK TYPE DSK ; FIXED HEAD DISK DSK1 JMP FHDBT DKP ; MOVING HEAD DISK DKP1 JMP MHDBT DZP ; ZEBRA DISK DZP1 JMP ZEBBT -1 ; END OF TABLE -1 JMP SMOTHER ; DIE ; JUMP TO CORRECT DISK ROUTINE GODEV: MOV 3,2 ; SAVE TABLE POINTER LDA 3,CSP ; RESTORE STACK POINTER GOD1: LDA 1,0,2 ; GET DEVICE CODE COM# 1,1,SZR ; SKIP ON END OF TABLE OR SNE 0,1 ; OR ON CORRECT DEVICE JMP 2,2 ; CODE, GO TO DEVICE READ LDA 1,1,2 ; CHECK OTHER DEVICE CODE SNE 0,1 ; hIF GOTIT THEN JMP 2,2 ; GO DO IT ELSE XLDA 1,= 3 ; ELSE TRY NEXT ADD 1,2 ; ENTRY IN TABLE JMP GOD1 ; READ THE FIRST SECTOR FROM THE NOVA DISK INTO PAGE ZERO FHDBT: LDA 2,ZDOA ; DOA SKELETON ADD 0,2 SUB 1,1 ; READ INTO PAGE ZERO XCT 2 ; DOA 1,vXX - DISK ADDRESS LDA 2,ZDOBS ; DOBS SKELETON ADD 0,2 XCT 2 ; DOBS 1,XX - READ INTO PAGE ; ZERO LDA 2,ZSKPBZ ; SKIP BUSY ZERO SKELETON ADD 0,2 XCT 2 ; SKPDN XX JMP .-1 ; DETERMINE WHERE TO ENTER THE BOOT CODE BOTCM: LDA 0,ENTSW,3 ; LOOK AT ENTRY SWITCH SEQZ 0 ; RELEASE OF MASTER? JMP SMOTHER ; YES LDA 0,ASCUN,3 ; ASCII UNIT # STA 0,SCAUN ; GIVE TO HIPBOOT LDA 0,UNIT,3 ; GET UNIT # STA 0,SCUN ; GIVE IT TO HIPBOOT LDA 0,.SYS ; BYTE POINTER FOR HIPBOOT LDA 1,SFFLG,3 ; SAVE FILE FLAG SNEZ 1 ; SAVE FILE FOUND ? JMP SCNGO ; NOPE (ENTRIES TO BOOT) JMP SCGO ; JUMP IN ; READ THE FIRST SECTOR FROM THE MHD INTO PAGE ZERO MHDBT: LDA 1,UNIT,3 ; GET UNIT NUMBER XLDA 2,= 2B4 ; GET HEAD 2 BIT MOVZR 1,1,SZC ; ONLY TOP LOADER FIXED DISKSM HAVE ADD 2,1 ; ODD HEAD NUMBERS MOVZR 1,1 ; POSITION IT MOVR 1,1 MOVR 1,1 STA 1,UNIT,3 ; SAVE UNIT # FOR LATER XLDA 2,= 17 ; SECTOR COUNT ADD 2,1 ; COMPLETE COMMAND WORD LDA 2,ZDOC ; DOC SKELETON ADD 0,2 XCT 2 ; DOC 1,XX - SELECT THE UNIBQBF-BQST ** LDA:; DISPLACEMENT ERROR MCDBA,MCBSQ ** .ENDC ** E.DO MCDBA-MCADR<>BQUST-BQADR ** LDA:; DISPLACEMENT ERROR MCDBA,MCADR ** .ENDC ** .DO QQCNT-QBAD<>1 ** LDA:;DISPCACEMENT ERROR QQCNT,QBAD ** .ENDC ** .DO MCDBA-MCMSA<>BQBF-BQDCB ** LDA:; DISPLACEMENT ERROR MCDBA,MCMSA ** .ENDC ** .NOCON 0 ; IN ; AC0 TRA0LNSMITTER DEVICE CODE ; OUT ; AC1 UNIT NUMBER  GMCA: LDA 1,C6 ; PRIMARY DEVICE CODE SUB# 0,1,SNR ; PRIMARY ? JMP GOOP ; YES LDA 1,C46 ; SECONDARY DEVICE CODE SUB# 0,1,SNR ; SECONDARY ? JMP GOOS ; OK JSR @.RETR ; ILLEGAL DEVICE CODE ERICD ; O~PEN CODE FOR MCA TABL=TMP MCROP: LDA 0,.MCRBL ; RECEIVER OPEN JMP OPIN MCOPN: LDA 0,UFTFN,2 ; TRANSMITTER TABLE CAN''T HAVE ; 0 LDA 2,C60 MOVS 2,2 ; IF ZERO IN LEFT BYTE SUBZ# 0,2,SNR ; IS IT ZERO ? JMP MCE0 ; YEP, RETURN ERROR LDA 2,OAC2,23 ; GET UFT BACK LDA 0,.MCTBL ; TRANSMITTER TABLE OPIN: STA 0,TABL,3 ; SAVE ON STACK ; CONVERT UFT FILE NAME TO BINARY TO GET DEVICE # LDA 1,MSK LDA 0,UFTFN,2 ; GET PACKED WORD MOVS 0,0 ; GET LEFT BYTE FIRST AND 1,0 LDA 3,C60 ; GET BINARY DIGIT SUBZ 3,0 LDA 3,UFTFN,2 ; GET BACK IN RIGHT ORDER AND 1,3,SNR ; HOW MANY DIGIT # JMP CON1 ; ONLY 1 DIGIT LDA 1,C60 ; STRIP OFF ASCII SUBZ 1,3 MOVZL 0,2 MOVZL 2,2 ; MOST SIGNF *4 ADDZL 2,0 ; *10 ADD 3,0 ; PUT IT ALL TOGETHER CON1: LDA 1,D15 SUBCZ# 0,1,SNC ; LEGAL ? JMP MCE0 ; NO MOVS 0,1 ; PUT IN FORMAT FOR STATUS REG MOVZL 1,1 MOVZL 1,1 MOVZL 1,1 MOVZL 1,1 LDA 3,CSP LDA 2,OAC2,3 ; GET UFT BACK STA 1,MCDEV,2 ; PUT IN UFT LDA 3,UFTDC,2 ; GET DEVICE CODE LDA 3,DCTCD,3 ; GOT IT LDA 1,fD16 ; SECOND DEVICE ? SUBZ# 1,3,SNC ; NOTE 2ND DEVICE CODE > 16 SUBZ 1,1 ; FIRST DEVICE CODE 0 15 IN ; TABLE ADD 1,0 ; ADD OFSET STA 0,MCDBN,2 ; SAVE BINARY DEVICE # LDA 3,CSP ; GET OPEN/CLOSE TABLE LDA 3,TABL,3 ADD 0,3 LDA 1,0,3 ; GET SL:OT ENTRY  NEG# 1,1,SZR ; DEVICE ALLOCATED ? JMP MCE1 ; YEP STA 2,0,3 ; PUT UFT ADDRESS IN TABLE SUBZ 0,0 STA 0,MCINU,2 ; SHOW NOT IN USE LDA 3,CSP ISZ ORTN,3 ; GOOD RETURN RTRN .CMEX: JMP CMEX .MCRBL: MCRBL .MCTBL: MCTBL C60: 60 D15: 15. D16: 1;6. MSK: 177 MCE0: JSR @.RETR ; ILLEGAL DEVICE # ERDNM MCE1: JSR @.RETR ; DEVICE ALREADY ALLOCATED ERFIU GOOP: LDA 1,.MCTD ; DEVICE IN SYSTEM ? COM# 1,1,SNR JMP MCE0 ; NO JMP INLIN GOOS: LDA 1,.MCT1 ; DEVICE IN SYSTEM ? COM# 1,1,SNR JMP MCE0 +INLIN: LDA 1,.XDC ; DIC INSTRUCTION ADD 1,0 ; ADD DEVICE CODE STA 0,.+1 0 ; EXECUTE IT LDA 1,C17X ; MASK OUT REST ANDS 1,0 ISZ ORTN,3 ; GOOD RETURN LDA 3,@CC ; GET TCB STA 0,TAC1,3 ; RETURN UNIT # TO USER RTRN ; ALL THROUGH C6: 6 C46: 4+6 C17X: 17*400 .XDC: DIC 0,0 .MCTD: MCTDC .MCT1: MCT1D MTPOS: LDA 2,UFBUF,2 ; GET BUFFER ADDRESS COM# 2,2,SNR ; IS THERE ONE ? JMP ERGO ; NOPE LDA 3,@CC ; YES, GET TCB ADDRESS LDA 0,TAC0,3 ; USER'S AC0 MOV# 0,0,SZR ; ZERO ? JMP ERGO  ; NOPE LDA 0,TAC1,3 ; YES, GET AC1 MOV# 0,0,SZR ; ZERO ALSO ? JMP ERGO ; TOO BAD LDA 3,CSP LDA 3,OAC2,3 ;UFT ADDRESS LDA 2,UFBUF,3 ;GET BUFFER ADDRESS AGAIN LDA 0,UFTST,3 ;UFT STATUS MOVL# 0,0,SZC ;WRITING? JMP SPACIT ;NO RETRY: ISZ BQUSC,2 ; UP BUF U7SE COUNT SO ERROR WON'T LOSE IT LDA 0,UFTBK,3 ;YES, GET # OF BLOCKS LDA 1,UFTBC,3 ; & NUMBER OF BYTES ADD 0,1,SNR ;ANYTHING TO OUTPUT? JMP NODATA ;NOPE JSR @.OVLAY ;ONE-TWO BUCKLE YOUR SHOE WRITI JMP CXIT ;ERROR- CHECK IF EOT NODATA: JSR @.WTEOF: ;THREE-FOUR SHUT THE DOOR RTRN ;FOOT CAUGHT IN DOOR JSR @.WTEOF ;FIVE-SIX PICK UP SCHLITZ RTRN ;OUT OF SCHLITZ DSZ BQUSC,2 ; DID'T LOSE BUF ON ERROR SO CAN DOWN COUNT JSR @.SBRCD ;SEVEN-EIGHT NO DATA LATE AND 0,1,SZR JSR @.SBRCD ;NINE-TEN 0sGUESS AGAIN AND 0,1,SNR JMP POSER ; NOT EOF LDA 3,OAC2,3 ;AC3 <- UFT ADDRESS SPACIT: ADC 0,0 ;RESET LOGICAL POSITION STA 0,UFTCB,3 ; CURRENT BLOCK SUB 0,0 ; STA 0,UFTBN,3 ; REQUEST BLOCK STA 0,UFTBP,3 ; REQUEST BYTE POINTER LDA 3,UFTDR,3 ;PICnsK UP DEVICE DRIVER LDA 0,DCBCB,3 ;TEST FOR FILE ZERO OF MAG TAPE COM# 0,0,SNR ; ARE WE LOST ? JMP POSER ; NO-- SKIP IF FILE 0 MOV# 0,0,SZR JMP FBACK ; NO-- BACKSPACE A FILE JSR @.REWND ; YES-- REWIND JMP .CMEX FBACK: JSR @.SBFIL ; YES, SPACE BACK A FILE AND 0,1,SZR JSR @.SFRCD ; FORWARD OVER EOF MARK AND 0,1,SZR JMP .CMEX ; GOOD RETURN NOW POSER: JSR @RETE. ; RETURN FILE POSITION ERROR ERSCP RETE.: RETER .SBFIL: SBFIL .SBRCD: SBRCD .SFRCD: SFRCD .WTEOF: WTEOF .OVLAY: OVLAY .REWND: REWND CXIT: JSR @.TSTEQ ; SEE IF END OF TAPE ERSPC RTRN ; NO- BAG IT JMP RETRY ; YES- UFTBK,UFTBC WILL NOW = 0. .TSTEQ: TSTEQ ; CHECK CELL'S ERROR ENDOV .END SOV25.SRB & !I RTITLE SOV25 SV25 .ENT FINIT ;FULL INITIALIZATION CODE .ENT CRMAP ;CREATE A MAP & PUSH BLOCK .EXTN CSYPA,CSYSD .EXTN DVLOCK,DVUNLOCK .EXTN CRMPE .EXTN WDCBK .EXTN OVLAY,OVLY1,OICAL .EXTN RETER .EXTN NSEG .EXTN DIVD .EXTN FIDCB,ASBUF,RDNBK .jEXTN RELMB,SETMOD,RELZT .EXTN FLUSH,CLEAR .NREL ;********************************** ; NUMBER OF STACK TEMPORARIES ; MUST BE FIRST WORD OF OVERLAY .IFN BSW!MBSW LASTEMP-TMP+1 .ENDC ; ; FINIT - PERFORMS THAT SEGMENT OF THE INITIALIZATION PATH ; THAT IS UNIQUE TO FULL INITIALIZATION. CALLED BY DVINI. ; ; INPUTS: AC0,AC1 - PARTITION BASE, WITH THE SIGN BIT OF AC0 ; CONTAINING THE ALLOCATION FLAG: ; 0 DON'T ALLOCATE A SYS.DR FRAME, 1 DO. ; AC2 - SYS.DR DCB, WITH FA SET UP ; ; OUTPUTS: AC0,AC1 - OVERLAY BASE ADDRESS ; ; RETURNS: STANDARD ERROR RETURN & SUCCESSFUL RETURN ; ;TMP USED BY OVLY1 ALOC=TMP+1 FINIT: STA 0,ALOC,3 ;SAVE ALLOCATION SWITCH MOVL 0,0 ; AWAY FROM RETURN ACCUMULATOR TRAFFIC MOVZR 0,0 ; AND CLEAR BIT FROM ADDRESS LDTA 3,MAPOF ADDZ 3,1,SZC ;FIND ADDRESS OF MAP INC 0,0 LDA 3,SFLK,2 ;MAP DCB ADDRESS STA 0,DBFA1,3 ;SET FA OF MAP DCB FOR CRMAP STA 1,DCBFA,3 JSR @.DVLOCK ;MUST LOCK DEVICE (DUAL PROCESSOR WORLD) JMP LCKD ;LOCK SUCCESSFUL, CARRY ON JSR @.RETER ;IUNSUCCESSFUL - ERDIU ; RETURN DIRECTORY IN USE ERROR LCKD: LDA 3,DCBDCT,2 LDA 0,DCNB1,3 ; GET BLOCK COUNT FROM DCT LDA 1,DCNBK,3 ; CONTINUED JSR @.OICAL CRMAP ; CREATE A MAP & SET UP PUSH BLOCK JMP ERRU ; ERROR - GO UNLOCK LDA 3,DCBDC,2 ; uDCT ADDRESS LDA 3,DCTCH,3 ; CHARACTERISTICS MOVR 3,3 MOVR 3,3,SZC ; FLOPPY ?? JMP FLOP ; NO BOOTSYS.OL LDA 1,.NSEG ; NUMBER OF OVERLAYS JSR @.OVLAY WDCBK ; WITHDRAW OVERLAY SPACE JMP ERRU ; ERROR FLOP: LDA 3,CSP ; STACK POINTER STA 0,OAC0,3 ; OVERLAY BASE ADDRESS (HIGH ORDER) STA 1,OAC1,3 ; RETURN OVERLAY BASE ADDRESS LDA 0,.CSNP ; NO PRE-ALLOCATE LDA 1,ALOC,3 MOVL# 1,1,SZC ;ALLOCATION REQUESTED? LDA 0,.CSPA ; YES, PRE-ALLOCATION REQUIRED STA 0,TMP,3 ; SAVE ADDRESS ON STACK J6SR @.OVLY1 ; GO MAKE A SYS.DR JMP ERRU ; ERROR, MUST UNLOCK JSR @.OVLAY CRMPE ; CREATE A MAP.DR ENTRY JMP ERRU ; ERROR ISZ ORTN,3 ;GOOD RETURN NOW ERRU: JSR @.DVUNLOCK ;UNLOCK THE DEVICE (AC2=DCB) RTRN .DVLOCK: DVLOCK .DVUNLOCK: DVUNLOCKy .OICAL: OICAL .OVLY1: OVLY1 .CSNP: CSYSD .CSPA: CSYPA MAPOF: SCMAP .RETER: RETER .OVLAY: OVLAY .NSEG: NSEG .DIVD: DIVD PSHOF: SCPSH-SCMAP BPB: SCDBS*16. .SETMOD:SETMOD .RELZT: RELZT .CLEAR: CLEAR .RELMB: RELMB .FLUSH: FLUSH .ASBUF: ASBUF .FIDCB: FIDCB .RdDNBK: RDNBK FLAG4: -4 PPA: SCPPA DBKSZ: SCDBS ; ; ROUTINE TO CREATE AN ELEMENTAL MAP AND PUSH BLOCK ; ; INPUTS: AC0,AC1 - DOUBLE-WORD BLOCK COUNT ; AC2 - SYS.DR DCB ADDRESS ; SFMSZ - DIRECTORY FRAME SIZE ; FA OF MAP DCB MUST BE SET UP (ADDRESS OFP MAP.DR) ; ; RETURNS: CALL+1 - ERROR ; CALL+2 - GOOD RETURN ; CRMAP ASSUMES IT IS COVERED BY A LOCK IN DUAL PROCESSOR SYSTEM MPDCB=TMP TOTCT=MPDCB+1 CLRCT=TOTCT+1 NBITS=CLRCT+1 BITDSP=NBITS+1 BLKDSP=BITDSP+1 BLK=BLKDSP+1 LASTEMP=BLK CRMAP: LDA 2,SFLK,2 ;GET MAP DCB ADDRESS STA 2,MPDCB,3 ;REMEMBER IT LDA 0,DBFA1,2 ; MAP BASE ADDRESS HIGH ORDER LDA 1,DCBFA,2 ; LOW ORDER LDA 3,PSHOF ;DISPLACEMENT FROM MAP TO PUSH BLOCK ADDZ 3,1,SZC ;GET ADDR OF PUSH BLOCK INC 0,0 MOVL 3,3 ;IN CASE IT'S NEGATIVE, SUBCL 3,3 ; CAPTURE SIGN BIT OF DISPLACEMENT SUB 3,0 ;ADD HIGH ORDER OF DISPLACEMENT LDA 3,CSP STA 0,DBCA1,2 ; SET PUSH BLOCK ADDRESS IN MAP DCB STA 1,DCBCA,2 LDA 0,OAC0,3 ; BLOCK COUNT, HI LDA 1,OAC1,3 ; BLOCK COUNT, LO LDA 2,BPB ; BILTS PER BLOCK JSR @.DIVD ; GET BLOCKS & BITS LDA 2,MPDCB,3 ; MAP DCB MOV# 0,0,SZR ; ANY REMAINDER ? JMP CRMA1 ; YES CONTINUE NEG 1,1 ; NO, DECREMENT THE COUNT COM 1,1 LDA 0,BPB ; LAST BLOCK IS FULL CRMA1: STA 1,SFBK,2 ; SAVE LAST BLOCK NUMBER IN}( DCB INC 1,1 ;NUMBER OF BLOCKS IN MAP STA 1,TOTCT,3 ; SAVE IN STACK STA 1,CLRCT,3 ; AGAIN MOVZR 0,0 ; REMAINDER DIVIDED BY 2 MOVZR 0,0 ; " " 4 MOVZR 0,0 ; " " 8 MOVZR 0,0 ; " " 16 MOVZL 0,0 ; FULL WORD BYTE COUNT STA 0,SFBC,2 ; TO DCB ;MAKE% A PUSH BLOCK: JSR @.ASBUF ; ASSIGN A BUFFER FOR PUSH BLOCK MOV 1,2 ; INDEX ON THE BUFFER SUB 1,1 STA 1,BQST,2 ; CLEAR THE STATUS LDA 0,DBKSZ ;BLOCK SIZE JSR @.CLEAR ; CLEAR THE BLOCK LDA 1,FLAG4 ;FLAG AS REAL REV 4 FOR INIT2, STA 1,0,2 ;BUTn PUSH SPACES AREN'T CREATED YET LDA 1,.NSEG ;NUMBER OF SYSTEM OVERLAYS STA 1,SCNVW,2 ;TO OVERLAY WORD LDA 3,OAC2,3 ;SYS.DR DCB LDA 1,SFMSZ,3 ;DIRECTORY FRAME SIZE STA 1,SCFZW,2 ;SET IN FRAME SIZE WORD JSR @.SETMOD ;SET MODIFIED JSR @.RELZT ;RELEAStE NEW PUSH BLOCK ;SET UP LOOP VARIABLES TO ALLOCATE BAD BLOCK REMAP AREA: SUB 0,0 STA 0,NBITS,3 ;DEFAULT IS DON'T SET ANY BITS LDA 2,OAC2,3 ;SYS.DR DCB ADDRESS LDA 0,SFTYPE,2 MOV# 0,0,SZR ;2NDARY PARTITION? JMP NOALLO ;YES, NO REMAP AREA TO ALLOC 1ATE LDA 2,DCBDC,2 ;UNIT DCT LDA 2,DCTBL,2 ;BAD BLOCK TABLE ADDRESS LDA 0,BESIZE,2 ;SIZE OF REMAP AREA STA 0,NBITS,3 ; EQUALS NBR OF MAP BITS TO SET LDA 0,BESTART,2 ;DISK ADDRESS OF REMAP AREA LDA 1,BESTART+1,2 ;LOW ORDER, TOO SUB 2,2 LDA 3,PPA ;PRpIMARY PARTITION BASE ADDRESS SUBZ 3,1,SZC ;DOUBLE SUBTRACT SUB 2,0,SKP ; IN ORDER TO GET BIT # ADC 2,0 ; IN MAP LDA 2,BPB ;#BITS PER BLOCK JSR @.DIVD ;CONVERT ADDRESS TO MAP BLOCKS, BITS STA 1,BLKDSP,3 ;BLOCK DISPLACEMENT IN MAP STA 0,BITDSP,3 L;BIT DISPLACEMENT IN MAP BLOCK NOALLO: SUB 0,0 STA 0,BLK,3 ;LOOP STARTS AT MAP BLOCK #0 LDA 2,MPDCB,3 LDA 0,DBFA1,2 ;SET UP FIRST MAP ADDRESS LDA 1,DCBFA,2 STA 0,DBCA1,2 STA 1,DCBCA,2 ;INITIALIZE MAP CONTENTS: MAPLP: LDA 2,MPDCB,3 ;MAP DCB ADDRESS JSR @.ASBUF ;ASSIGN A BUFFER ISZ DCBCA,2 ;BUMP FOR NEXT ADDRESS JMP .+2 ;NO LOW ORDER OVERFLOW ISZ DBCA1,2 ;UP HIGH ORDER MOV 1,2 ;INDEX ON BUFFER SUB 1,1 STA 1,BQST,2 ;CLEAR STATUS LDA 0,DBKSZ ;BLOCK SIZE JSR @.CLEAR ;CLEAR THE BLOCK LDA 0,BLK,3 ;RELATIVE BLOCK # LDA 1,BLKDSP,3 ;BLK REMAP AREA STARTS USGE 0,1 ;AT POINT TO ALLOCATE REMAP AREA? JMP NOSET ;NOT YET LDA 0,BITDSP,3 ;YES, GET STARTING BIT DISPLACEMENT LDA 1,NBITS,3 ; AND # BITS TO SET JSR SETBITS ;SET 'EM STA 1,NBITS,F3 ;SAVE REMAINING # BITS TO SET SUB 0,0 ;IF WE CONTINUE TO ANOTHER BLOCK, STA 0,BITDSP,3 ; START AT BEGINNING OF IT NOSET: ISZ BLK,3 ;NEXT BLOCK # JSR @.SETMOD ;SET MODIFIED JSR @.RELZT ;ZERO TLA SO NOT TO GOBBLE ALL BUFFERS DSZ CLRCT,3 ; CLEARED BENUF ? JMP MAPLP ; NO ;GO BACK & ALLOCATE SYS.DR INDEX, PUSH BLOCK, & MAP ITSELF: LDA 2,MPDCB,3 ; MAP DCB LDA 1,OAC2,3 ; SYS.DR DCB ADDRESS JSR @.FIDCB JSR @.RDNBK ; READ FIRST MAP BLOCK RTRN ; ERROR MOV 1,2 ; INDEX ON THE BUFFER LDA 1,TOTCT},3 ; SIZE OF MAP LDA 0,MAPOF ;ALLOCATE BLOCKS PRECEDING ADD 0,1 ; THE MAP, TOO SUB 0,0 ;START AT BEGINNING OF BLOCK JSR SETBITS ;SET SOME MAP BITS JSR @.RELMB ; RELEASE MODIFIED JSR @.FLUSH ; LET THEM ALL GO ISZ ORTN,3 ; GOOD RETURN NOW RTRN[ ; ; ROUTINE TO SET A BUNCH OF BITS IN A BLOCK, ; ASSUMING THEY ARE ALREADY ZERO. ; ; INPUT: AC0 - STARTING BIT DISPLACEMENT ; AC1 - # OF BITS TO SET ; AC2 - WORD ADDRESS OF START OF BLOCK ; ; OUTPUTS: AC1 - REMAINING # BITS TO SET (NEXT BLOCK) ; BITCyNT=OAC1 WDCNT=TMP SETBITS:RSAVE 1 NEGL# 1,1,SNC ;# BITS <= 0? RTRN ;YES, NOTHING TO DO MOVZR 0,0 ;CHANGE STARTING MOVZR 0,0 ; BIT DISPLACEMENT MOVZR 0,0 ; INTO THE STARTING MOVZR 0,0 ; WORD DISPLACEMENT ADD 0,2 ;STARTING WORD ADDRESS LDA 1,DBKSZ SUB 0,1 ;# WORDS LEFT IN BLOCK STA 1,WDCNT,3 ;MAX # WORDS CAN TOUCH LDA 1,OAC0,3 ;STARTING BIT DISPLACEMENT, AGAIN LDA 0,LOW4 AND 1,0 ;BIT DISPLACEMENT IN STARTING WORD COM 0,0 ; -DISP-1 SUBZR 1,1,SKP ;ONE BIT MASK STSHL: MOVZR 1,1 ;SHIFT IT OVER INC 0,0,SZR ;POSITIONED FOR FIRST BIT? JMP STSHL ;NOT YET SETWLP: LDA 0,0,2 ;PICK UP WORD SETBLP: ADD 1,0 ;SET A BIT STA 0,0,2 ;IN CASE WE'RE DONE DSZ BITCNT,3 ;DONE? JMP .+2 ;NOT YET RTRN ;YES MOVZR 1,1,SNC ;NEXT BIT, & AT END$ OF WORD? JMP SETBLP ;NO SUBZR 1,1 ;YES, RESET MASK INC 2,2 ;NEXT WORD DSZ WDCNT,3 ;END OF BLOCK? JMP SETWLP ;NO RTRN ;YES, LET CALLER GET NEXT BLOCK LOW4: 17 ENDOV .END FSTAT.SRB xo RTITLE FSTAT FSTA .NREL .ENT STATUS .ENT CSTAT .ENT DEBLK .EXTN SRUFD .EXTN MVWD .EXTN OVLAY .EXTN RELPB,RELMB,RELDB .EXTN LNKRS .EXTN UNPEND .EXTN IPBQ .EXTN DIVD .EXTN BQ .EXTN BLKIN .EXTN WAIT .EXTN PEND .IFE BSW!MBSW .EXTN SETFLb,DIVI .ENDC ;***************************************** ; NUMBER OF STACK TEMPORARIES USED ; MUST BE THE FIRST WORD IN THE OVERLAY .IFN BSW!MBSW 3 .ENDC ;FILE STATUS/UPDATE STATUS ; ;AC0: UFD ADDR ;AC2: SYS.DR DCB ADDR ;+1 RTN: ERROR, ERROR CODE AIN AC2 ;+2 RTN: GOOD SBAD=TMP SESW=SBAD+1 EXTAT=SESW+1 CSTAT: SUB 1,1,SKP ; STATUS WITHOUT LINK RESOLUTION STATUS: SUBZL 1,1 ; STATUS WITH LINK RESOLUTION STA 1,SESW,3 ; SAVE ENTRY SWITCH LDA 1,SFLK,2 ; MAP DCB LINK COM 1,1,SZR ; IS THERE A MA2yP DCB ? JMP NOMTA ; YES NOMAP: ISZ ORTN,3 ; NO, GOOD RETURN LDA 0,OAC0,3 ; GET UFD ADDRESS IN AC0 LDA 3,DCBDC,2 ; DCT ADDRESS LDA 3,DCTCD,3 ; DCT LINK MOV 0,2 ; INDEX ON UFT ADDRESS STA 1,UFTBC,2 ; CLEAR BYTE COUNT STA 1,UFTBK,2 ; & BLOCK COUNT =STA 1,UFTAT,2 ; & ATTRIBUTES STA 3,UFTDL,2 ; SET DEVICE LINK RTRN ; UP, UP AND AWAY NOMTA: SUB 1,1 STA 1,EXTAT,3 ; CLEAR EXTRA ATTRIBUTES STA 2,OAC2,3 ; RETURN DCB ADDRESS JSR @.OVLAY SRUFD RTRN ; ERROR...... STA 2,SBAD,3 ; SAVE BUFFER ADDRESS MOV 1,2 ; ENTRY ADDRESS TO AC2 DSZ SESW,3 ; SHOULD LINKS BE RESOLVED ? JMP NOLNK ; NO LDA 0,UFTAT,2 ; GET ENTRY'S ATTRIBUTES LDA 1,LNKAT ; LINK ENTRY MASK AND# 0,1,SNR ; IS ENTRY A LINK ? JMP NOLNK ; NO LDA 1,SBAD,3 ; ENTRY'S BUFFER ADDRESS b- LDA 0,OAC2,3 ; CURRENT DCB JSR @.OVLAY LNKRS ; RESOLVE THE LINK RTRN ; ERROR STA 0,OAC2,3 ; RETURN RESOLVED DCB STA 1,SBAD,3 ; SAVE BUFFER ADDRESS LDA 0,UFTAT,2 ; GET ENTRY'S ATTRIBUTES LDA 1,UFTLK,2 ; & LINK ACCESS ATTRIBUTES .IFE BSW!MBSW JSR @.SETFL ; 'OR' IN ACCESS ATTRIBUTES .ENDC .IFN BSW!MBSW IOR 1,0 .ENDC LDA 1,RESAT ; SHOW UFT A RESOLUTION TYPE ADD 1,0 STA 0,EXTAT,3 ; SAVE NEW ATTRIBUTES IN STACK NOLNK: MOV 2,0 ; 'FROM' ADDRESS LDA 2,OAC0,3 ; 'TO' ADDRESS LDA 3,SBAD,3 ;  BUFFER ADDRESS LDA 1,BQCA,3 ; DEVICE ADDRESS OF THIS BLOCK LDA 3,BQCA1,3 ; DEVICE ADDRESS THIS BLOCK STA 3,UFEA1,2 ; SAVE FOR LATER STA 1,UFTEA,2 ; SAVE FOR LATER MOV 2,1 ; UFT ADDRESS TO AC1 LDA 2,ENTLG ; ENTRY LENGTH JSR @.MVWD ; MOVE THE ENTRY- TO UFD AREA LDA 2,SBAD,3 ;GET BUFFER ADDRESS JSR @.RELPB ; RELEASE IT LDA 2,OAC2,3 ;DCB ADDRESS LDA 1,SFLK,2 ;MAP.DR LINK COM 1,1,SNR ;IS THERE A MAP.DR? JMP NOMAP ;NO LDA 2,OAC0,3 ; UFT ADDRESS LDA 1,EXTAT,3 ; EXTRA ATTRIBUTES IF ANY MOV# 1,1p,SZR ; ANYTHING THERE ? STA 1,UFTAT,2 ; YES, SET INTO UFT ; ATTRIBUTES ISZ ORTN,3 ; GOOD RETURN RTRN .IFE BSW!MBSW .SETFL: SETFL .ENDC LNKAT: ATLNK RESAT: ATRES .OVLAY: OVLAY .MVWD: MVWD ENTLG: UFDEL .RELPB: RELPB .RELDB: RELDB ; ; DEPOSIT A ,"BLOCK ADDRESS ; ; AC0: BLOCK ADDRESS (HIGH ORDER) ; AC1: BLOCK ADDRESS (LOW ORDER) ; AC2: DCB ADDRESS OF FILE ; JSR DEBLK ; CA=TMP MAPDC=CA+1 WRDNO=MAPDC+1 MAPX=OAC1 MAPX1=OAC0 DEBLK: STA 2,MAPDC,3 ; SAVE DCB ADDRESS LDA 2,.BQ ; GET START OF BUFuFER CHAIN SRHLP: LDA 0,MAPX,3 ; GET ADDRESS TO BE RETURNED LDA 1,BQCA,2 ; ADDRESS OF THIS BUFFER SUB# 0,1,SZR ; A MATCH ? JMP NXBUF ; NO, TRY NEXT BUFFER LDA 0,MAPX1,3 ; TRY HIGH ORDER LDA 1,BQCA1,2 SUB# 0,1,SZR ; KEEP GOING JMP NXBUF ; TRY NEĐXT ONE LDA 3,MAPDC,3 ; GET DCB ADDRESS LDA 0,DCBUN,3 ; YES, GET UNIT NUMBER LDA 1,BQUN,2 ; FROM BUFFER TOO SUB# 0,1,SZR ; A MATCH ? JMP NXBUF ; NO LDA 0,DCBDC,3 ; GET DCT ADDRESS LDA 1,BQDCT,2 ; FROM BUFFER ALSO SUB 0,1,SZR ; IS THIS IT ? JMP NDVXBUF ; NO ISZ BQUSC,2 ; ITS OURS JSR @.WAIT ; YES, WAIT FOR IT RTRN ; TIME OUT ERROR RTRN ; DATA ERROR JSR @.RELDB ; RELEASE & DESTROY BUFFER JMP DPOZIT ; NOW DEPOSIT THE BLOCK NXBUF: LDA 3,CSP LDA 2,BQNXT,2 ; GET LINK TO NEXT BUFFER MOVL.# 2,2,SNC ; ANY MORE BUFFERS TO SEARCH ? JMP SRHLP ; YES, PLAY IT AGAIN, SAM DPOZIT: LDA 2,OAC2,3 ; RECOVER DCB ADDRESS ALSO LDA 2,DCBDR,2 ; SYS.DR DCB ADDRESS OF FILE LDA 2,SFLK,2 ; MAP.DR DCB ADDRESS STA 2,MAPDC,3 ; SAVE MAP.DR DCB ADDRESS LKLUP: MɮOV 2,1 ; MAP DCB IS PEND KEY INTDS ;KEEP IVT INTERRUPTS OUT IN CASE ; THIS IS A DUAL PROCESSOR SYSTEM LDA 0,MPLCK,2 ; GET MAP LOCK WORD MOV# 0,0,SNR ; IS MAP LOCKED ? JMP LKOK ; NO, LOCK O.K. LDA 0,LKTIM ;FINITE WAIT IN CASE OTHER SIDE ;GiGOES DOWN & IVT UNLOCKS JSR @.PEND ; YES, PEND WAITING FOR UNLOCK JMP LKLUP ; TIME OUT JMP LKLUP ; UNPENDED - TEST STATE LKOK: ADC 0,0 ; -1 STA 0,MPLCK,2 ; SET MAP LOCKED INTEN LDA 0,MAPX1,3 ; GET BLOCK TO DE-ALLOCATE LDA 1,MAPX,3 LDA 3,DBFA1,y2 ; GET START OF MAP.DR LDA 2,DCBFA,2 SUBZ 2,1,SNC ; BLOCK ADDR - MAP.DR ADDR INC 3,3 ; HAD TO BORROW, SO INCREASE MINUEND SUB 3,0 ; COMPLETE DOUBLE WORD SUBTRACT LDA 2,MAPOS ; NOW ALLOW FOR MAP.DR OFFSET ADDZ 2,1,SZC ; OVERFLOW ? INC 0,0 ; YES LDA 2,BLKSZ ; DIVIDE BY # OF BITS/BLOCK JSR @.DIVD ; GET BLOCK #, AND WORD # LDA 2,MAPDC,3 ; GET MAP DCB STA 1,DCBCB,2 ; SET CURRENT BLOCK STA 0,WRDNO,3 ; SAVE WORD # LDA 0,DCBFA,2 ; GET FIRST ADDRESS ADDZ 1,0 ; FOR ADDRESS OF BLOCK STA 0,DCBCA,2 ; SET AS CURRENT LDA 0,DBFA1,2 ; GET HIGH ORDER MOV# 0,0,SZC ; OVERFLOW ? INC 0,0 ; YESY STA 0,DBCA1,2 ; HIGH ORDER CURRENT JSR @.BLKIN ; READ CURENT RTRN ; ERROR STA 0,CA,3 ; SAVE BUFFER ADDRESS LDA 1,WRDNO,3 ; GET WORD OFSET .IFN BSW!MWBSW SNB 0,1 ; IS BLOCK ALLOCATED ? JMP DEBER ; YES BTZ 0,1 ; SET THE BIT TO ZERO .ENDC .IFE BSW!MBSW LDA 2,C16. ; GET INDEX POINTER JSR @.DVI ; INTEGER DIVIDE LDA 2,CA,3 ; BUFFER ADDRESS ADD 1,2 ; INDEX POINTER FINALLY SET UP MOV 0,1 SUBZ!R 0,0 ; MASK INIT'D TO BIT 0 NEG 1,1,SNR JMP MSKOK ; BIT COUNT = 0, MASK OK MOVZR 0,0 ; SHIFT MASK RIGHT ONE BIT INC 1,1,SZR ; TEST BIT COUNT JMP .-2 ; NOT ZERO, OH SHIFT! MSKOK: LDA 1,0,2 ; MASK OK - GET MAP WORD AND# 0,1,SNR ; IS THE BLOCK AWLLOCATED ? JMP DEBER ; NO COM 0,0 ; YES, INVERT THE MASK AND 1,0 ; RESET THE BIT STA 0,0,2 ; RETURN WORD TO MAP BLOCK .ENDC ISZ ORTN,3 ; GOOD RETURN NOW ERET: LDA 2,CA,3 ; RESTORE BUFFER ADDRESS JSR @.RELMB ; RELEASE MODIFIED LDA 2,MAPDC,3 ; MAP DCB ADDRESS SUB 0,0 STA 0,MPLCK,2 ; UNLOCK THE DCB MOV 2,0 ; DCB ADDRESS IS UNPEND KEY JSR @.UNPEND ; UNPEND DCB WAITERS LDA 0,C2 ; FREE BLOCK UNPEND KEY JSR @.UNPEND ; UNPEND WDBLK XLDA 1,= STLKW LDA 0,DCBST,2 AND# 1,0,SNR ; LOCK WAITING?l RTRN SUB 1,0 ; YES, CLEAR BIT STA 0,DCBST,2 LDA 0,.IPBQ ; YES, MUST WAKE IPB PROCESS JSR @.UNPEND RTRN .BQ: BQ .WAIT: WAIT MDEER: ERMDE DEBER: LDA 0,MDEER ; MAP.DR ERROR LDA 2,CC STA 0,CTMP2,2 ; RETURN ERROR CODE JMP ERET .IFE BSW!MBSW SC16.: 16. .DVI: DIVI .ENDC MAPOS: SCMAP .PEND: PEND .DIVD: DIVD .BLKIN: BLKIN .RELMB: RELMB .UNPEND:UNPEND .IPBQ: IPBQ BLKSZ: SCDBS*16. LKTIM: C2: 2 LPOOL ENDOV .END DVRLS.SRB 90 RTITLE DVRLS .ENT DVRLS .ENT RLSER .ENT RLSE .EXTN MDRLS,RPIPH .EXTN SRUFD,SYSNM .EXTN CFNAM,SDIRR .EXTN OVLAY,OICAL .EXTN DIRR MDCB .EXTN SYSFG .EXTN RELMB .EXTN RETER .EXTN MDCB .EXTN RMVBAD ; REMOVE BAD BLOCK TABLE .EXTN CLEAR .EXTN OVLY1 .EXTN TSTNE .NREL ;***************************************** ; NUMBER OF STACK TEMPORARIES USED ; MUST BE THE FIRST WORD IN THE OVERLAY .IFN BSW!MBSW 2 .ENDC ; DEVICE RELEASE ROUTINE ; ; INPUTS: TAC0 - POINTER TO NAME ; ; RETURNS: CALL+1 - RELEASE ERROR ; CALL+2 - RELEASE SUCCESSFUL ; DCB USER COUNT FLAGS ; 1B0=BACKGROUND ; 1B1=FOREGROUNG ; DEFINE SOME TEMPS IN THE CELL US=CTEMP ; OUR USE COUNT FLAG OTHER=CTMP3 ; THE OTHER GUYS FLAG ; DEFINE SOME STACK TEMPS ERRS=TMP ; ERRO'R FLAG SHARED=ERRS+1 ; SHARED DIRECTORY FLAG DVRLS: RLSE: SUB 1,1 STA 1,ERRS,3 ; SHOW NO ERRORS LDA 2,@CC ;TCB ADDRESS LDA 0,TAC0,2 ; USER'S AC0 LDA 2,CQ ; CURRENT QUEUE LDA 1,QSUFP,2 ; QUEUE UFT POINTER JSR @.OVLAY CFNAM ; CHECK & UNPACK FIL&ENAME JSR @.OVLAY SDIRR ; LOOK FOR SPECIFIER MATCH JMP DNER1 ; SPECIFIER NOT FOUND ; ERDSN CONFUSING - WILL SEND ; ERDNI INSTEAD STA 2,OAC2,3 ; SAVE DCB ADDRESS LDA 1,DCBST,2 ; GET STATUS MOVL# 1,1,SZC ; INITED ?? JMP DNIER ; NO GIVE ERROR LDA 0,SFLK,2 ; MAP LINK COM# 0,0,SNR ; A DISK ? JMP RELS1 ; NO GO SEE ABOUT A DEVICE LDA 3,CC ; FORM MASKS LDA 1,CPROG,3 ; FORGROUND-BACKGROUND FLAGS MOVZR 1,1,SZR ; WHAT GROUND ? JMP REBG ; BACK GROUND SUBZR 1,1 ; FORGROUND S7TA 1,OTHER,3 ; SAVE OTHERS MASK MOVZR 1,1 ; AND OUR MASK STA 1,US,3 JMP RECOM ; JOIN COMMON CODE REBG: SUBZR 1,1 ; STORE OUR MASK STA 1,US,3 ; SAVE OUR MASK MOVZR 1,1 ; OTHER GUY'S MASK LDA 0,@.SYSFG ; OTHER GROUND RUNNING ? MOV 0,0,SNR ; WELL ? SUBZ 1,1 ; NO IGNORE FORGROUND INIT BIT STA 1,OTHER,3 RECOM: LDA 3,CSP ; RESTORE STACK POINTER LDA 0,SFTYPE,2 ;SECRET TYPE WORD COM# 0,0,SNR ;SUB-DIRECTORY? JMP RELSE ;YES, JUST RELEASE IT JMP REPART ; NO GO RELEASE IT A PARTITION j ; AT A TIME ; ROUTINE TO RELEASE A DIRECTORY - DCB IN AC2 RELSE: LDA 3,CC ; CURRENT CELL LDA 3,CPTAD,3 ; PROGRAM TABLE ADDRESS LDA 0,PDDCB,3 ; DEFAULT DCB SUB# 0,2,SNR ; RELEASING THE DEFAULT ? LDA 0,@.MDCB ; YES, DIR TO MASTER STA 0,PDDCB,3 ; DEFAULT DCB TO PROGRAM TABLE LDA 3,CC ; CELL ADDRESS AGAIN LDA 0,DCBUC,2 ; USER COUNT LDA 1,UCMSK ; USER COUNT MASK AND# 1,0,SZR ; ANY FILES OPEN IN THIS DIRECTORY ? JMP DIUER ; YES - GIVE ERDIU LDA 1,US,3 ; TAKE OUR INIT BIT OUT COM 1,1 AND 1,0 STA 0,DCBUC,2 ; IN THE DCB LDA 1,OTHER,3 ; OTHER GROUNDS INIT BIT AND 1,0,SZR ;OTHER GROUND IN HERE? JMP DIRSH ; YES - GIVE EROPD STA 0,DCBUC,2 ; NO CLEAR USE COUNT WORD LDA 0,DCBST,2 ; GET STATUS LDA 1,RELED ; RELEASED MASK AND 1,0 ADC .1,0 ; SHOW AS RELEASED STA 0,DCBST,2 ; RETURN TO DCB LDA 0,.SYSNM ; SYS.DR'S NAME JSR @.OVLAY SRUFD RTRN ; ERROR MOV 1,3 DSZ UFTUC,3 JMP .+1 JSR @.RELMB ; RELEASE MODIFIED LDA 2,OAC2,3 ; RESTORE DCB ADDRESS JSR @.OVLAY ;REMOVE PERIPHERAL ENTRIES RPIPH RTRN RLSER: LDA 0,.SFLA ; OFSET TO LOGICAL NAME ADD 0,2 ; AC2 -> LOGICAL NAME LDA 0,LNWC ; WORD COUNT JSR @.CLEAR ; CLEAR LOGICAL NAME LDA 2,OAC2,3 ; DCB ADDRESS AGAIN LDA 0,SFKEY,2 ; MOVE KEY TO LOGICAL NAME STA 0,SFLNA,2 +VLDA 0,SFKY1,2 STA 0,SFLNA+1,2 ISZ ORTN,3 ;SUCCESSFUL RETURN RTRN RELS1: ADDL# 1,1,SZC ; OK TO RELEASE IT ? JMP IGCER ; NO - WOULD CAUSE JMP TO OBLIVION LDA 3,DCBDC,2 ; YES DCT ADDRESS LDA 1,DCTRS,3 ; RELEASE PROCESSOR LDA 3,CSP ; RESTORE STACK POINTER STA 1,TMP,3 ; SAVE ENTRY ADDRESS JSR @.OVLY1 ; GO TO IT RTRN ; ERROR RETRUN JMP RLSER ; GO JOIN COMMON CODE .OVLY1: OVLY1 .CLEAR: CLEAR LNWC: SCFNL-1 .SFLA: SFLNA .OICAL: OICAL .SYSNM: SYSNM .SYSFG: SYSFG UCMSK: 37777 RELED: 77777Y .OVLAY: OVLAY .MDCB: MDCB .RELMB: RELMB .RETER: RETER .SFEL: SFEL .DIRR: DIRR .TSTNE: TSTNE ; ADDRESS ROUTINE TO CHECK CONTENTS OF CTMP2 DIRSH: LDA 3,CC ; IF ERROR ALREADY RECORDED THEN LDA 3,CTMP2,3 ; THEN WE WILL NOT ENTER SHARED MOV# 3,3,SZR ; EzmRROR SINSE IT IS NOT AS IMPORTANT RTRN ; AS THE OTHER ERRORS. JSR @.RETER EROPD IGCER: JSR @.RETER ERICM DIVFG: JSR @.RETER ; FORGROUNG USING IT ERFGE DIUER: JSR @.RETER ERDIU DNIER: LDA 1,SFLK,2 ; GET MAP.DR LINK COM# 1,1,SNR ; IS THIS A{ DISK ? JMP DNISE ; NO, DEVICE NOT IN SYSTEM ERROR DNER1: JSR @.RETER ERDNI ;DIRECTORY NOT INIT'D DNISE: JSR @.RETER ERDNM ;NOT IN SYSTEM REPART: SUB 0,0 ; IN CASE WE ARE CALLED STA 0,ERRS,3 ; BY OURSELVES STA 0,SHARED,3 ; SAY HAVE FOUND NO SHARED DIRECTORIES LDA 2,@.DIRR ; START AT THE BEGINING PARR1: LDA 3,CSP ; DON'T FORGET STACK POINTER LDA 3,OAC2,3 ; DCB OF DIRECTORY WE ARE RELEASEING LDA 0,DCBST,2 ; STATUS OF THE ONE WE ARE LOOKING AT SUB# 2,3,SZR ; THIS THE ONE WERE RELEASEING  MOVL# 0,0,SZC ; OR NOT INITTED JMP PARNX ; YES TRY NEXT ONE LDA 0,SFLK,2 ; MAP OF THE ONE WE ARE LOOKING AT LDA 1,SFLK,3 ; MAP OF ONE WE ARE RELEASING SUB# 0,1,SNR ; THIS ONE BELONG TO US ?? JMP PASUB ; YES GO RELEASE IT LDA 0,SFTYPE,2 ; 0TYPE OF ONE WE ARE LOOKING AT LDA 1,SFTYPE,3 ; TYPE OF ONE WE ARE TRYING TO RELEASE MOV 1,1,SNR ; IS ONE WE ARE RELEASEING PRIMARY COM# 0,0,SNR ; AND THIS NOT A SUBDIRECTORY JMP PARNX ; NO OR NO TRY NEXT LDA 0,DCBDC,2 ; DEVICE OF ONE WE ARE LOOKhING AT LDA 1,DCBDC,3 ; DEVICE OF ONE WE ARE RELEASING SUB# 1,0,SZR ; BELONG TO US ? JMP PARNX ; NO - TRY NEXT LDA 1,@.MDCB ; IS THIS THE MASTER DIRECTORY ? SUB# 1,2,SNR ; WELL ? JMP PARNX ; YES SAVE IT FOR LATER JSR @.OICAL ; RELEASE PARTITISON REPART ; (CALL OURSELVES) JMP PASU0 ; GO SHOW WE HAD ERROR PARNX: LDA 2,SFNX,2 ; NEXT DCB LDA 0,SFLK,2 ; ITS MAP LINK COM# 2,2,SZR ; END OF DCBS COM# 0,0,SNR ; OR END OF DISK DCBS JMP PAREN ; YES - THATS IT FOR THIS PASS JMP PARR1 ; h NO - GOT ONE CONTINUE PAREN: LDA 3,CSP ; STACK POINTER AGAIN LDA 2,OAC2,3 ; DCB OF ONE WE ARE ATTEMPTING TO RELEASE LDA 1,SHARED,3 ; IF NO DIRECTOIRES RELEASED WERE SHARED MOV# 1,1,SNR ; THEN JUST GO CHECK FOR ERRORS IN JMP PARE1 ; THE RELEASE ELSE LDA 3,CC ; SET THAT THIS PARTITION IS LDA 3,OTHER,3 ; IS OWNED BY OTHER GROUND LDA 1,DCBUC,2 ; GET ORNERSHIP FLAGS AND# 3,1,SNR ; AND SET THAT OTHER GROUND ADD 3,1 ; IS USING IT AND STORE STA 1,DCBUC,2 ; BACK LDA 3,CSP ; CHECK FOR ERROR IN RELK\EASING PARE1: LDA 1,ERRS,3 ; ERROR FLAG MOV 1,1,SZR ; ANY ERRORS ?? RTRN ; YES JUST RETURN LDA 1,@.MDCB ; NO - GET MASTER DCB SUB# 1,2,SNR ; RELEASING THE MASTER ?? JMP MASTR ; YES SPECIAL CODE JSR @.OICAL ; NO - RELEASE IT RELSE RTV4RN ; AN ERROR OF SOME TYPE LDA 0,SFTYPE,2 ; TYPE WORD AGAIN MOV 0,0,SZR ; PRIMARY OR SECONDARY ?? JMP RPEX1 ; SECONDARY ALL DONE JSR @.OVLAY ; PRIMARY MUST RELEASE BAD BLOCK TABLE RMVBAD RTRN ; AN ERROR HERE IS REAL BAD RPEX1: ISZ ORTN,3 ; | GOOD RETURN NOW RTRN PASUB: JSR @.OICAL ; RELEASE THE SUBDIRECTORY RELSE MOV# 0,0,SKP ; SKIP IF ERROR IN RELEASING ELSE JMP PARNX ; CONTINUE ; HAD ERROR IN RELEASEING, CHECK IF ERROR IS CAUSE IT WAS SHARED PASU0: JSR @.TSTNE ; IF ERROR WAS DUE TOWz BEING EROPD ; SHARED THEN JMP PASU1 ; JUMP ELESE ; RECORD ERROR NOT DUE TO SHARED ISZ ERRS,3 JMP PARNX ; CONTINUE RELEASING ; ERROR DUE TO BEING SHARED, RECORD IT AS SUCH PASU1: ISZ SHARED,3 JMP PARNX ; CONTINUE RELEASING MASTR: LDA 3,CC ; CURRENT CELL LDA 3,CPTAD,3 ; PROGRAM TABLE ADDRESS LDA 0,PTSPN,3 ; GET PUSH NUMBER FROM TABLE MOVZR# 0,0,SZR ; CALLED FROM CLI ? JMP DIUER ; NO, CAN ONLY RELEASE MASTER ; FROM CLI LEVEL LDA 0,@.SYSFG ; YES, GET FOREGROUND FLAG MOVR# 0,0,SZC ; IS FOREGROUND RUNNING? JMP DIVFG ; YES, THAT'S AN ERROR JSR @.OVLAY ; NO, RELEASE THE MASTER DEVICE MDRLS RTRN ;ERROR ENDOV .END SOV26.SRB  RTITLE SOV26 SV26 .NREL .ENT MEMI .EXTN RETER .IFN MSW .EXTD BBLK1,FBLK1 .EXTD C31K .ENT STMAP .ENT WRPR .ENT WREBL .IFE MBSW .EXTD CMAP .ENDC .IFN MSW .EXTD MAPCC .ENDC .EXTN UITBL .EXTD GMBLK .EXTD RMBLK .ENDC ;*************************************** ; NUMBER OF STACK TEMPORARIES USED ; MUST BE FIRST WORD IN THE OVERLAY .IFN BSW!MBSW 4 .ENDC .IFN MSW ; WRITE PROTECT/ENABLE A USER AREA ; AC0= START, AC1= END WRPR: SUB 1,1,SKP ;FLAG PROTECT WREBL: SUBZL 1,1 ;ENABLE STA 1,TMP,3 JSR MAPCC ; SET TO ACCESS USER MAP LDA @2,CC ;TCB LDA 1,TAC1,2 ;END USGE 1,0 ;USER KNOW WHERE UP IS ? JMP WRPER ;DISCIPLINE LDA 2,USTP ;UST LDA 2,USTNM,2 ;NMAX USGT 2,1 ;IN BOUNDS JMP WRPER ;STROKE AND DISTANCE LDA 2,C31K ;76000 X ANDS 2,1 ANDS 2,0 ;GET BLOCK NUMBERS MOVZR 0,0 MOVR 0,0 MOVZR 1,1 MOVR 1,1 ;AC0,AC1 = BLOCK NUMB LDA 2,CC LDA 2,CPTAD,2 ;PTBL ADDR LDA 3,.PMAP ;OFFSET ADD 3,2 ADD 2,1 ;END ADDR STA 1,WEND ADD 0,2 ;START LDA 0,CWPBT ; - WRITE PROTECT BIT R LDA 3,CSP LDA 3,TMP,3 WRNXT: LDA 1,0,2 ;MAP WORD AND 0,1 MOV# 3,3,SNR ;SKIP IF ENABLE ADC 0,1 ;SET BIT STA 1,0,2 ;BACK .IFN MBSW SMBK 1 ;TO MAP .ENDC LDA 1,WEND ;DONE ? SUB# 2,1,SNR JMP WRDON INC 2,2 JMP WRNXT WRDON: .IFE MBSW SUB 0 ,0 STA 0,CMAP ;FORCE MAP .ENDC JSR MAPCC LDA 3,CSP ISZ ORTN,3 RTRN WRPER: JSR @.RET ERMPR WEND: 0 .PMAP: PMAP CWPBT: -MPAWP-1 .RET: RETER .ENDC .IFN MSW ;******************************* STMAP: JMP STMA ; OVER THE SEVEN BIT HILL ;***********F******************** .ENDC ; MEMORY INCREMENT ; INPUT: INCREMENT IN AC0 ; OUTPUT: NEW NMAX ( IF SUCCESSFUL) IN AC1 .IFN MSW NNMAX= TMP MEMI: JSR MAPCC ; FOR ALL INFOS FLAVORS LDA 3,USTP LDA 1,USTNM,3 ; NMAX LDA 2,@CC ; TCB LDA 0,TAC0,2 ; INCCREMENT ADD 0,1 ; NEW NMAX LDA 0,MAXCL ; HIGHEST POSSIBLE NMAX USLE 1,0 ; TRYING TO GET TOO MUCH ?? JMP MEMER ; PUNISH  LDA 2,CSP STA 1,NNMAX,2 ; SAVE NEW NMAX LDA 0,USTSS,3 ; START OF SYMBOL TABLE USLT 0,1 ; NEW LESS THAN SYMBOL TABLE ? JMP ME@MEX ; YES LEAVE ALONE NEG 1,1 ; SUBTRACT ONE TO GET COM 1,1 ; LAST USED ADDRESS LDA 2,C377L ; FORM BLOCK NUMBER FROM ADDRESS ANDS 2,1 MOVZR 1,1 MOVZR 1,1 INC 1,1 ; ADD FOR LOST BITS LDA 2,CC LDA 2,CPTAD,2 ; PTBL LDA 0,PMSZ,2 ADDZ 0,1,SNR  ; HAVE THE PROPER NUMBER ?? JMP MEMEX ; YES ALL DONE STA 1,MCNT ; SAVE COUNT OF BLOCKS TO ADD OR SUB MOVZL# 1,1,SZC ; GIVEING BACK ?? JMP MEMI1 ; YES NO TEST NEEDED LDA 2,CC LDA 2,CPROG,2 ; PTBL LDA 0,BBLK1 ; BACKGROUND BLOCKS AVAILABLE MOrnVZR# 2,2,SNR ; FORGROUND ? LDA 0,FBLK1 ; YES GET FORGROUND BLOCKS SUBZ 1,0,SNC ; ENOUGH AVAILABLE ? JMP MEMER MEMI1: LDA 2,CC LDA 2,CPTAD,2 ; PTBL LDA 0,PMSZ,2 ; NUMBER OF BLOCKS IN USE MOV 0,3 ; SAVE IT SUB 1,0 ; ADJUST STA 0,PMSZ,2 SUB 3, 2 LDA 0,PGMSK MOVZL# 1,1,SZC ; ADDING OR SUBTRACTING JMP MESUB ; SUBTRACTION OF COURSE MEADD: JSR GMBLK ;GET A BLOCK JMP MEMER ;GET A FREE LUNCH LDA 3,PMAP,2 ;CURRENT CONTENTS AND 0,3 ;DROP ILLEG ADD 3,1 ;ADD TO BLK STA 1,PMAP,2 INC 2,2 ;NEXT SLOT DSZ MCNT ;DONE ? JMP MEADD ; NOT YET MECOM: .IFE MBSW SUB 2,2 STA 2,CMAP ;FORCE A RE-MAP .ENDC MEMEX: .IFN MBSW ;RST-LMP ON BIRD. SUB 0,0 LDA 2,CC ;LMP THE WHOLE MAP. LDA 2,CPTAD,2 ADDI PMAP,2 ELEF 1,32. LMP .ENDC LDA R@@2,CC ;TCB LDA 3,CSP LDA 0,NNMAX,3 ;NEW NAMX STA 0,TAC1,2 ISZ ORTN,3 ;GOOD LDA 3,USTP STA 0,USTNM,3 ;YOU GOT IT BILLY RTRN MESUB: ADD 1,2 ; POINT TO FIRST BLOCK TO GIVE AWAY MESU1: LDA 1,PMAP,2 ; GET BLOCK TO TAKE BACK JSR RMBLK ; RETURN TO FREE BLOCKS AND 0,1 ; SAVE LOGICAL ADC 0,1 ; MAKE ILLEGAL STA 1,PMAP,2 ; RESTORE INC 2,2 ISZ MCNT ; DONE ? JMP MESU1 ; NO TAKE ANOTHER JMP MECOM ; YES JOIN COMMON CODE MCNT: 0 PGMSK: -(MPAPH!MPAWP)-1 C377L: 177400 C377: 377 .IFN N?MSW ; NOVA 840/830 LIMIT IS 31KW MAXCL: 76000 .ENDC J MAXCL: 100000 [J] .ENDC .IFE MSW MEMI: LDA 3,USTP LDA 2,CC LDA 2,CPTAD,2 ;PTBL LDA 1,PUFPT,2 ;HIADR IS PUFPT-1 LDA @2,CC ;TCB LDA 0,USTNM,3 ;NMAX LDA 2,TAC0,2 ;USER MEM INC ADD 2,0 ;NEW NMAX USGE 1:,0 JMP MEMER ; OVERWITE WILL OCCUR LDA @2,CC ;TCB STA 0,TAC1,2 ; OK, SET UP NEW NMAX STA 0,USTNM,3 LDA 3,CSP ISZ ORTN,3 ; BUMP THE RETURN RTRN ; SUCCESS .ENDC MEMER: JSR @.RETER ; RETER ERMEM .RETER: RETER .IFN MSW .UILTH: UILTH .ENDC  .IFN MSW ; STMAP - SETS UP THE DCH MAP FOR A USER ; CALLED WITH AC0=DEV CODE ; AC1=USER BUFFER ADDR ;STACK TEMPORARIES PTA=TMP TLP=PTA+1 CNT=TLP+1 OUT=CNT+1 STMA: LDA 2,.UITBL ST2: LDA 3,C377 LDA 1,0,2 ;WORD FROM UITBL COM# 1,1,SNR ;SKIP IF NOT END JMP IDER1 AND 1,3 ;MASK OFF DEV CODE SUB# 0,3,SNR ;IS IT THE ONE WE WANT? JMP ST1 ;YES LDA 1,.UILTH ;SIZE ADD 1,2 JMP ST2 ;NO - KEEP GOING IDER1: JSR @.RETER ;YES - ERROR ERDNM ST1: LDA 3,CC LDA 0,CPROG,3 MOVL# 1,1,SNC ;FG/BhCG BIT IN UITBL WORD MOVZR 0,0,SZR ;IS PROG BG? MOVZR# 0,0,SZR ;FG OR BG FELL THROUGH JMP IDER1 ;GOTCHA LDA 0,CPTAD,3 ;PT ADDR LDA 3,0,3 ;TCB ADDR LDA 1,TAC1,3 LDA 3,CSP STA 0,PTA,3 ;SAVE PROGRAM TABLE ADDR LDA 0,UIDCH,2 MOV# 0,0,SNR ;DCH DEFINED? JMP IDER1 ;NO-ERROR LDA 2,C377L ANDS 0,2 ;NUMBER OF DCH PAGES STA 2,CNT,3 ;SAVE IT LDA 2,C377 AND 2,0 ;FIRST PAGE IN DCH MAP STA 0,TLP,3 ;REMEMBER IT LDA 2,C37 ANDS 0,2 ;GET DCH PAGE NUMBER MOVZL 2,2 MOVZL 2,2 ;MOVE TO HIGH BITS L DA 0,C1777 AND 1,0 ;GET OFFSET FROM USER ADDR ADD 2,0 ;MAKE FAKE ADDRESS FOR DEVICE STA 0,OUT,3 ;AND SAVE FOR LATER LDA 0,C31K ANDS 1,0 ;LOGICAL PAGE NUM FROM USER MOVZR 0,0 MOVZR 0,0 ;TO LOW BITS LDA 2,PTA,3 ;PROGRAM TABLE ADDR ADD 0,2 ;POJ3INT TO CORRECT LOC IN MAP .DO BB?MSW ELEF 1,MPSTS!MPSDC ; SET TO ACCESS DCH MAP SMST 1 .ENDC ST3: LDA 0,PMAP,2 ;MAP ENTRY FROM PT COM# 0,0,SNR ;END OF TABLE? JMP ST4 ;YES LDA 1,PHYS AND 1,0 ;GET PAGE NUMBER (PHYSICAL) LDA 1,TLP,3 ;DCH ADDRESS MOVS 1,1 .DO MPALG==37B5 MOVZL 1,1 MOVZL 1,1 .ENDC ADD 1,0 ;FORM MAP COMMAND LDA 1,DCHI ; SET THE DATA CHANNEL IND ADD 1,0 SMBK 0 ISZ TLP,3 ;NEXT PAGE IN DCH MAP INC 2,2 ;NEXT ENTRY IN PT MAP DSZ CNT,3 ;ALL DONE? JMP ST3 ;NO ST4: LDA 1,OUT,3 ;ADDRESS TO RETURN ISZ ORTN,3 ;TAKE SKIP RETURN LDA @3,CC ;TCB STA 1,TAC1,3 ;RETURN IT RTRN ;AND GO AWAY C1777: 1777 C40: 40 C37: 37 .UITBL: UITBL DCHI: MPAMD PHYS: MPAPH!MPAWP .ENDC ENDOV .END SOV27.SRB   RTITLE SOV27 SV27 .ENT CCMN .ENT RETCE .ENT RETUR,ERTN .ENT RETFA .IFE MSW .ENT RDCER .ENDC .IFN MSW .EXTD MFSTB .EXTD C31K .EXTD CMAP .EXTD MBLK .EXTN OVLAY,OVCHN .EXTN CPEM .EXTD RMBLK .EXTN CPRTN,CPUSH .ENDC .EXTN PT1,PT2 .EXTN WRMSO .EXTN FTMSG .EXTN FSYSF,SYSFG .EXTN OVLAY .EXTN RSET .EXTN RDCI .EXTN PRISW .EXTN MDCB .EXTN RELDB .EXTN SYSE2 .NREL ;******************************************************* ; NUMBER OF STACK TEMPORARIES USED ; MUST BE FIRST WORD IN OVERLAY6 .IFN BSW!MBSW 10 .ENDC TDCB= TMP TFA= TDCB+1 TYPE= TFA+1 PTAD= TYPE+1 PASS= PTAD+1 WRBLK= PASS+1 TFA1= WRBLK+1 WRBL1= TFA1+1 ; AC0= UST ADDR, AC2= PTBL UST ASSOCIATED WITH CALL IN (MRDOS ONLY) ; THIS CODE IS CHAINED TO FROM SOV8 CCMN: .IFN MSW JSR MFSTB ;MAP FIRST BLK OF PTBL IN AC2 .ENDC MOV 0,2 ;UST ADDR LDA 1,PASS,3 ;AC2 FROM CALLER LDA 3,USTAC,2 ;FIRST TCB .IFN MSW LDA 0,C31K ADD 0,3 ;BUMP SO IT IS MAPPED .ENDC STA 1,TAC2,3 LDA 3,CC LDA 3,CTEMP,3 ;FG/BG MOVL 3,3 ;RESET CP IF SET MOVZR 3,3 STA 3,USTPC,2 ;FLAG FORR USER LDA 3,CSP LDA 1,TYPE,3 .IFN MSW MOVL# 1,1,SZC ;SKIP NOT EXBG JMP CMN9 .ENDC LDA 3,CC ;CELL LDA 3,CPTAD,3 ;PTBL OF CALLER MOVZL# 1,1,SZR ;SKIP IF NOT EXFG LDA 3,.PT1 ;READY PT1 LDA 1,PSTAT,3G ;STATUS LDA 0,CNPSW ;RESET ALL BUT ABORT&CP AND 0,1 STA 1,PSTAT,3 LDA 3,CSP ;THE OLD AC BLUES.... LDA 1,OAC1,3 ;RESTORE AC1 MOVR# 1,1,SNC ;DEB ? JMP CMNEX ;NO LDA 0,USTSA,2 LDA 1,USTDA,2 STA 0,USTDA,2 STA 1,USTSA,2 .IFN MSW NEG 1,0 ;DEC )ADDR COM 0,0 LDA 1,TYPE,3 ;SEE IF EXFG MOV# 1,1,SZR ;SKIP IF REG .EXEC JMP CDBMP ;.EXFG- USE TYPE AS MAP ; INDICATOR LDA 3,CC ;CELL LDA 3,CPROG,3 ;PRI SUB 1,1 ;FOR BG MOVZR# 3,3,SNR ;SKIP IF BG INC 1,1 ;IS FG CDBMP: JSR@ .MBLK ;MAP DEB nfBLK AS LAST JMP CMNEX ;NO BLK THERE- VERY STRANGE.... LDA 0,0,2 ;SEE IF INT OFF DEB COM# 0,0,SZR ;SKIP IF INT OFF DEB JMP CMNEX ;NO-EXIT ; INT OFF DEB- ENABLE USE OF TTO,TTI,LPT,CPU LDA 2,.PT2 ;ASSUME BG MOV# 1,1,SZR LDA 2,.PT1 ;FG .IFE MBSW N LDA 1,DDEV1 ;CODE FOR TTO,TTI,LPT STA 1,PDEV+1,2 LDA 1,DDEV2 ;CPU STA 1,PDEV+7,2 SUB 1,1 STA 1,CMAP ;FORCE REMAP .ENDC .IFN MBSW LDA 1,DDEV1 ;ENABLE USE OF TTY,LPT,CPU LDA 3,PDEV+1,2 AND 1,3 STA 3,PDEV+1,2 .DO B?MSW SMST 3 ;SET IN MAP  .ENDC LDA 1,PDEV+7,2 MOVR 1,1 MOVZL 1,1 STA 1,PDEV+7,2 .DO B?MSW SMST 1 ;SET IN MAP .ENDC .ENDC JMP CMNEX ;EXIT .IFN MSW CMN9: LDA 2,.PT2 SUB 1,1 ; RESET EO STA 1,PSTAT,2 ; CLEAR EO LDA 1,@.CPEM ; TELL 'EM JSR @.OVLAY WRMSO ; WAKE UPM YOU FOOL JMP .+1 ; GONE JMP CMNEX .ENDC .PT2: PT2 .IFE MBSW DDEV1: 40476 DDEV2: 43776 .ENDC .IFN MBSW DDEV1: 177476 .ENDC .MBLK: MBLK .CPEM: CPEM .ENDC CMNEX: .IFN MSW LDA 2,CC LDA 2,CPTAD,2 ; CALLER PTBL JSR MFSTB .ENDC RTRN .PT1: PT1 RCNPSW: PSBRK+PSCP RETFA: JMP SRTFA ; RETURN TO OVERLAYED SAVE FILE RETUR: ISZ ORTN,3 ;GOOD RETURN ERTN: LDA@ 2,CC ;TCB ADDRESS OF CALLER LDA 1,TAC2,2 ;USER AC2 LDA 3,CC ;PASS BAC STA 1,CTMP2,3 JSR@ .OVLAY RSET ;CLOSE ALL OPEN FILES JMP .+21 ; IGNORE ERROR RETCE: LDA 2,CC LDA 3,CPTAD,2 ;PTBL SUB 0,0 STA 0,PFLAG,3 LDA 0,CPROG,2 ;PROG PRI MOVZR# 0,0,SNR ;SKIP IF NOT FG .IFN MSW JMP RETFG .ENDC .IFE MSW JMP RETFA ;BAG IT .ENDC SUB 0,0 RET1: STA 0,CTEMP,2 ;BG DSZ PTSPN,3 ; REDUCkE PUSH LEVEL BY ONE JMP .+2 ;OK JMP PSHER ;YOU FOOL !!! LDA 0,PTPB1,3 ; BASE ADDR WD 1 LDA 1,PTPBA,3 ; PARTITION BASE ADDRESS LDA 3,.SCPSH ; PUSH DIR RELATIVE ADDR ADDZ 3,1,SZC ; ADD, CHK FOR OVERFLOW INC 0,0 ; OVERFLEW... LDA 2,@CQ ; DCB ADDRlESS STA 0,DBFA1,2 ; SET FA IN DCB STA 1,DCBFA,2 LDA@ 2,.MDCB ; MASTER DCB ADC 1,1 ; -1 = NO ERROR CHECKING JSR @.OVLAY RDCI JMP . ;SHOULD HAVE PANICED BEFORE THIS LDA 2,CC LDA 2,CPTAD,2 ;PTBL ADDR .IFN MSW LDA 1,PTSPN,2 ;PUSH LDA@ 0,.CPUSH ;~CP PUSH OR 0 SUB# 1,0,SNR JMP CPR ;CPOINT RTN .ENDC LDA 0,PSTAT,2 LDA 1,CMPSW AND 1,0 ;READY TO ROLL STA 0,PSTAT,2 LDA 2,USTP LDA 2,USTCT,2 ;CTCB-EXEC CALLER .IFN MSW LDA 0,C31K ADD 0,2  ;EL BUMP .ENDC STA 2,@CC ;TO CC SO RETURN CODE WILL > ; PROCESS OK RTRN SRTFA: LDA@ 1,.FTMSG ;MSG JSR@ .OVLAY WRMSO JMP .+1 ; **********ERROR*********** LDA 2,CC LDA 2,CPTAD,2 ;PTBL .IFN MSW LDA 1,MAXPN ;RESET PLVL STA 1,PTSPN,2 .ENDC SUBZR 1,1 ;SET STATUS TO QUIET STA 1,PSTAT,2 SUB 1,1 HSTA@ 1,.FSYSF STA@ 1,.PRISW ;INIT TO NO TIME SLICE STA@ 1,.SYSFG ;NO FG STA@ 1,CC ;NOBODY HOME LDA 3,PDDCB,2 ;DEFAULT DCB LDA 1,DCBUC,3 ;UNLOCK IT ADCZR 0,0 MOVOR 0,0 ;SET SOME BITS AND 0,1 STA 1,DCBUC,3 .IFE MSW RTRN .ENDC .IFN MSW RETF2: SqUB 1,1 ;CLEAR MAP SIZE STA 1,PMSZ,2 .IFE MBSW STA 1,CMAP ;FORCE TOTAL REMAP .ENDC RETF3: LDA 1,PMAP,2 ;RELEASE MAP SPACE LDA 0,C377 AND 0,1 SUB# 0,1,SNR ;SEE IF END OF REAL BLKS RTRN ;YES JSR RMBLK ;REL LDA 0,PMAP,2 LDA 1,PGMSK ;STORE ILLEG IN SLOT AND 1,0 ADC 1,0 STA 0,PMAP,2 INC 2,2 ;NEXT JMP RETF3 .DO ?MSW PGMSK: -(MPAPH!MPAWP)-1 .ENDC .ENDC PSHER: JSR@ .PNIC PNPSH .IFN MSW RETFG: LDA 1,PTSPN,3 ;FG AT TOP NOW ? LDA 0,MAXPN SUB# 1,0,SNR JMP RETFA ;YES-RELEASE RESOURCES SUBZL 0,0 JMP RET1 ;COMMON PATH .ENDC CMPSW: PSBRK+PSCP ;RESET ALL BUT ABORRT,CP C377: 377 .SYSFG: SYSFG .PRISW: PRISW .MDCB: MDCB .OVLAY: OVLAY MAXPN: SCPNM+SCBPB .FTMSG: FTMSG .FSYSF: FSYSF .IFN MSW .OVCHN: OVCHN .CPUSH: CPUSH CPR: JSR@ .OVCN|HN CPRTN ;FINISH IN SOV20 .ENDC .SCPSH: SCPSH .IFE MSW!MBSW ; THIS CODE IS CHAINED TO FROM SOV3 MBAD=TMP+6 BUFD1=TMP+4 RDCER: LDA 2,MBAD,3 ; RELEASE BUFFERS JSR @.RELDB LDA 2,BUFD1,3 JSR @.RELDB MOV 0,2 LDA 3,CC LDA 3,CPTAD,3 ; PTBL SUB O!0,0 STA 0,PSTAT,3 JSR @.SE2 .SE2: SYSE2 .RELDB: RELDB .ENDC ENDOV .END SOV28.SRB  { RTITLE SOV28,SV28 .NREL .ENT OVOPN .EXTN OVLAY .EXTN ROPN .IFN MSW .ENT MAPDF .ENT VMEM .EXTN RETER .EXTN RDB .EXTN MVWD .EXTD C31K .EXTD FBLK1,BBLK1 .EXTD GMBLK .ENDC ; TEMPS DIR= TMP MDCNT= TMP NCNT= TMP+1 NOVLY= TMP+1 NDMEM= TMP"#+2 MPPT= TMP+3 VOCNT= TMP+4 NBLKS= TMP+5 FILAD= TMP+6 MPSLT= TMP+7 VSIZE= TMP+7 .IFN BSW!MBSW 10 ; # TEMPS .ENDC .IFN MSW ; CALL TO CHECK MEMORY SIZE AVAILABLE ; AC0= # BLKS AVAIL ON RTN VMEM: LDA 2,CC LDA 0,CPROG,2 ; PRI LDA 3,BBLK1 MOVZR## 0,0,SNR LDA 3,FBLK1 ; CALLER IS FG VMEM1: LDA @2,CC STA 3,TAC0,2 VGRT: LDA 3,CSP ISZ ORTN,3 RTRN ; DEFINE A VIRTUAL DATA AREA ; AC0= # BLKS ; AC1= 32K SLOT START ; AC2= 32K WINDOW SIZE MAPDF: LDA 2,CC LDA 2,CPTAD,2 ; PTBL LDA 1,PEDCT,2 ; DEF ALRnEADY ? SEQZ 1 JMP VERRR ; YUP STA 0,PEDCT,2 ; NOW IT IS LDA 1,PEOCT,2 ; 0 OR OVLY SIZE ADD 1,0 ; = END ADDR STA 1,PEDMP,2 ; = DATA AREA SLOT LDA 1,CLSTS ; IN BALL PARK ? USGT 1,0 JMP MPER ; KID THINKS HE'S BABE RUTH... LDA @3,CC ; TCB LDA 1P,TAC1,3 ; WINDOW SNEZ 1 ; WINDOW CAN'T BE 0... JMP MPER LDA 0,TAC2,3 ; SIZE STA 0,PMWSZ,2 ; TO PTBL STA 1,PMWIN,2 ADD 0,1 ; = END LDA 3,PMSZ,2 ; MAP SIZE NEG 3,3 ; = LAST VALID WINDOW SLOT USLE 1,3 ; SKP IF IN BALL PARK JMP MPER ; YES-ERROR ] LDA 1,PEDCT,2 ; # SLOTS SUB 0,1 ; NEEDED BLKS JSR MEMTS ; FIT ? JMP MPER ; NO STA 1,MDCNT,3 ; CNT LDA 1,PEDMP,2 ; START ADD 1,2 ; ADD TO GET PTBL REL ADDR LDA 3,CC LDA 3,CPTAD,3 ; PTBL LDA 1,PMWIN,3 ; WINDOW START LDA 0,PMWSZ,3 ; SIZE STA c0,MTMP ADD 1,3 ; FROM ADDR LDA 0,C377 MPWMV: LDA 1,PMAP,3 ; ALLOC BLK AND 0,1 STA 1,PEMAP,2 INC 2,2 INC 3,3 DSZ MTMP ; ALL MOVED ? JMP MPWMV ; NO LDA 3,CSP ; RESTORE STACK POINTER LDA 3,MDCNT,3 ; GET # OF BLOCKS TO BE GOT SNEZ 3 ; IF GOT ALrL NEEDED JMP VGRT ; THEN EXIT ELSE MPDF2: JSR GMBLK ; GET BLK JMP . ; ??? STA 1,PEMAP,2 ; TO MAP INC 2,2 DSZ MDCNT,3 ; DONE ? JMP MPDF2 ; ANOTHER JMP VGRT ; EXIT MPER: SUB 1,1 STA 1,PMWIN,2 ; COVER TRACKS STA 1,PEDCT,2 JMP MERCM ; ERROR Rf+TN ; TEST MEM REQ TO SEE IF AVAIL ; AC1= BLKS NEEDED ; AC2= PTBL ON RTN MEMTS: STA 3,MTMP LDA 2,CC LDA 0,CPROG,2 ; PRIORITY LDA 2,CPTAD,2 ; PROG TABLE FOR CALLER LDA 3,BBLK1 ; # BG MOVZR# 0,0,SNR ; SKIP IF CALLER BG LDA 3,FBLK1 ; FG MEMT1: SUBZG# 1,3,SZC ; SKIP IF ERROR ISZ MTMP ; GOOD RTN LDA 3,CSP JMP @MTMP MEMER: LDA 2,CC LDA 2,CPTAD,2 SUB 1,1 STA 1,PVST,2 ; COVER TRACKS MERCM: JSR @.RETER ERMEM VERRR: JSR @.RETER ERIBS .RETER: RETER .PEMAP: PEMAP .PMAP: PMAP CLSTS: (MPAPH&377)-7 nOVSZ: 0 MTMP: 0 C377: 377 .ENDC ; OPEN AN OVERLAY FILE ; AC0= BP TO NAME OVOPN: SUB 1,1 JSR @.OVLAY ROPN ; OPEN FOR READING RTRN ; ERROR-TAKE HER DOWN...... .IFE MSW JMP OVGRT .ENDC .IFN MSW LDA 2,USTP ; UST+76000 LDA 2,USTOD,2 ; ADDR OVaLY DIR LDA 1,C31K ; OFSET TO PAGE 31 ADD 1,2 STA 2,DIR,3 ; SAVE IT LDA 1,OVNDS,2 ; # NODES STA 1,NCNT,3 ; SAVE IT SUB 0,0 ; =0 TO CLEAR STA 0,NDMEM,3 ; INIT BLKS NEEDED STA 0,VOCNT,3 ; AND # VNODES STA 0,VSIZE,3 ; INIT TOTAL SIZE TO 0 OVOP1: LfDA 1,OVNAD,2 ; NODE-IF 1B0 IT'S VIRTUAL MOVL# 1,1,SNC ; SKIP IF YES JMP OVEND ; ALL DONE LOOKING ISZ VOCNT,3 ; ONE MORE LDA 1,OVDIS,2 ; # OVLYS IN NODE+SIZE IN 256 ; BLKS LDA 0,C377 ; RIGHT BYTE MASK AND 1,0 ; DROP #OVLYS AND DIV BY 4 INCZR# 0,0 INCZR 0,0 ; = # 1024 WD BLKS PER OVLY LDA 3,C377L ; LEFT BYTE MASK ANDS 3,1 ; # OVLYS STA 1,MTMP ; LOOP CNT LDA 3,CSP LDA 1,VSIZE,3 ; RUNNING TOTAL LDA 3,NDMEM,3 ; REQ MEMORY(BLOCKS) OVSIZ: DSZ MTMP ; DONE-FIRST IS SKIPPED JMP .+2 ; NOT NDONE JMP OVSZ2 ; DONE ADD 0,1 ; ADD IN # 1024 WD BLOCKS ADD 0,3 ; 1 MORE OVLY SIZE TO TOTAL JMP OVSIZ OVSZ2: ADD 0,1 ; ONCE MORE FOR OVLY 0 MOV 3,0 LDA 3,CSP ; GET STACK PTR STA 0,NDMEM,3 ; RUNNING TOTAL(W/O OVLY 0) STA 1,VSIZE,3 ; NEW TOTAL l .IFE MBSW LDA 1,C4 ; BUMP DIR SIZE ADD 1,2 .ENDC .IFN MBSW ADDI 4,2 .ENDC DSZ NCNT,3 ; DONE WITH NODES ? JMP OVOP1 OVEND: LDA 1,VOCNT,3 ; # VNODES SNEZ 1 ; ARE THERE ANY? JMP OVGRT ; NONE-ALL DONE ; SEE IF ENUF MEMORY TO LOAD LDA 1,NDMEM,3 ; # BLKS NEEDED JSR MEMTS ; ENUF MEM ? JMP MEMER ; ERROR ; AC2= PTBL LDA 1,VSIZE,3 ; SIZE(INCLUDING OVLY 0) STA 1,PEOCT,2 ; OVLY CNT LDA 0,PEDCT,2 ; ANY VIRTUAL DATA AREA ? ADD 0,1 ; IS YES USE IT AS BASE STA 0,PEOMP,2 ; STARTING SLOT LDA 0,CLSTl= 256.? LDA 2,VBF1 ;YES, USE OTHER OVERLAY COUNT BUFFER MOVZL 0,0 ;MAKE IT < 256. MOVS 0,0 ;MAKE DISPLACEMENT IN BUFFER ADD 0,2 ;FIND THE COUNT ISZ 1,2 ;INC LOW ORDER JMP .+3 ISZ 0,2 ;DOUBLE INCREMENT JMP .+1 ;MODULO 2^32 VPLAIN:` MOVZR 0,0 LDA 2,TUOVV ;NOW FOR THE GENERAL OVERLAY COUNTS MOVZR 2,2 ;SET UP FOR 2 INC'S IN ONE MOVZR# 0,0,SZC ;SKIP IF ANY OLD REQUEST INC 2,2 ;PENDING REQUEST MOVL 2,2 ;RECOVER LOW ORDER BIT MOVL 2,2 ;SHIFT UP ADDZL 0,0 ;MOVE STACK BIT TO CARRY MOVR 2,2 ;PUT IT IN AC2'S 1B0 NOTOV: LDA 0,TCRSEG ;FIND OURSELVES ADD 0,2 ;FIND THE COUNT ISZ 1,2 ;INC LOW ORDER JMP .+3 ISZ 0,2 ;DOUBLE INCREMENT JMP .+1 ;MODULO 2^32 MOVL# 2,2,SNC ;ALWAYS RETURN IF WE DON'T HAVE A STACK DSZ WHEN ;IS THE TIME RIGHT?2 JMP 0,3 ;NO. LDA 0,AWHILE STA 0,WHEN ;NEXT RIGHT TIME RSAVE ;HAVE A STACK, USE IT TO SAVE RETURN LDA 2,TCRSEG JSR WRITE ;WRITE TUNING FILE TO THE DISK LDA 2,VBF0 JSR WRITE ;OVERLAY COUNTS, TOO LDA 2,VBF1 JSR WRITE RTRN WRITE: COM# 2,2,SNR EJMP 0,3 ;DON'T WRITE IF IT ISN'T THERE MOV 3,0 ;SAVE RETURN... JSR @.SETMOD JSR @.QUENT MOV 0,3 JMP 0,3 RLS: RSAVE COM# 2,2,SNR RTRN ;DON'T TRY TO RELEASE WHAT DOESN'T EXIST JSR @.RELMB ;RELEASE MODIFIED JSR @.WAIT ;MAKE SURE THERE WERE'NT ANY ǹERRORS MOVZR 0,0 ;WELL,... MOVZR 0,0 RTRN MXMK: -128.*4 TUOVV: TUOV WHEN: 1 AWHILE: 7000 .RELMB: RELMB .SETMOD:SETMOD .QUENT: QUENT .WAIT: WAIT .MDCB: MDCB .FNDCB: FNDCB .BLKIN: BLKIN .RETER: RETER TU: 'TU' .TUSW: TUSW .TOON: TOON-Z OUCH: JSR @.RETEQR ;TUNE FILE DELETED BEFORE TURNED OFF ERDLE ; ;TUNING TURN OFF (FROM SYSTEM CALL .TUOFF) ; TUOFF: LDA 2,@.TUSW ;RESIDENT SWITCH COM# 2,2,SNR ;TUNING ALREADY OFF? JMP GDRET ;YES - CALL IS NOP ADC 0,0 ;NO - TURN IT OFF STA 0,@.TUSW ;AC0 HAS ERROR EeFLAG: -1=NONE LDA 1,.TOON ;MAKE POINTER SUB 1,2 ; TO TOONER'S BUFFER STA 2,TUNR,3 ;SAVE LDA 2,.VBF0,2 JSR RLS ;RELEASE OVERLAY COUNT BLOCKS LDA 2,TUNR,3 LDA 2,.VBF1,2 JSR RLS LDA 2,TUNR,3 ADC 1,1 ;RESTORE INITIAL STATE STA 1,.VBF0,2 ; IN CASoE TOONER IS STILL IN STA 1,.VBF1,2 ; CORE WHEN TUNING IS TURNED ON STA 1,.TCRSEG,2 LDA 1,.TUFDS,2 ;DIRECTORY DISPLACEMENT STA 1,SVUFDS,3 ;REMEMBER THAT LDA 1,.TUFP,2 ;ENTRY BLOCK ADDRESS STA 1,SVUFP,3 ;REMEMBER THAT, TOO LDA 1,.TUF1,2 STA 1,SVUF1,3}" JSR RLS ;NOW RELEASE GENERAL COUNT BLK COM# 0,0,SZR ;ERRORS SO FAR? RTRN ;YES LDA 0,SVUFP,3 ;ADDRESS OF TUNE FILE'S LDA 1,SVUF1,3 ; DIRECTORY ENTRY, REMEMBER? LDA 2,@CQ ;GRAB A DCB STA 0,DCBFA,2 STA 1,DBFA1,2 LDA 1,@.MDCB JSR @.FNDCB JSR Y@.BLKIN ;READ DIRECTORY BLOCK RTRN ;ERROR MOV 0,2 ;INDEX LDA 3,SVUFDSP,3 ;DISPLACEMENT TO ENTRY,REMEMBER? ADD 2,3 LDA 0,UFTFN,3 ;FIRST OF FILE NAME MOV# 0,0,SNR ;IS THERE A FILE HERE? JMP OUCH ;WAWAWHAT??!? LDA 0,UFTEX,3 ;LOOK AT THE EXTENSIO%N LDA 1,TU SUB# 0,1,SZR ;IS IT 'TU'? JMP OUCH ;NO!?! - OOOOOH, DEEP TROUBLE! LDA 0,UFTUC,3 ;USE COUNT MOV# 0,0,SZR ;UNLESS IT'S ZERO, DSZ UFTUC,3 ; DECREMENT IT JMP .+1 JSR @.RELMB GDRET: ISZ ORTN,3 ;THAT'S ALL FOLKS RTRN ENDOV .END QTYOV.SRB ^ RTITLE QTYOV .NREL .IFN MBSW!BSW ; DEF TMPS 1 .ENDC ; OVERLAY 65 AT 32400 ; THE FOLLOWING ARE OFFSETS INTO THE UFT FOR ; STORAGE WORDS USED BY THIS PROGRAM ;**** NOTE: ANY CHANGE SHOULD BE MADE IN ;**** QTYDR,QTYMD,SOV19,QTYOV,SOV5,ALMDiB,ALM1D QTRXP=UFTFN ;RECEIVE BYTE POINTER ; 0 NO READ QTORG=UFTFN+1 ;INITIAL RECEIVE BYTE POINTER QTTXP=UFTFN+2 ;TRANSMIT BYTE POINTER ; 0 NO WRITE QTRXT=UFTFN+3 ;READ CALLER TCB ; 1B0 + ERROR CODE QTXON=UFTFN+4 ;XON/XOFF FOR TELETJYPE READER ; -1 DON'T PUT OUT ANYTHING QTTBL=UFTEX ;ADDR OF TABLE ENTRIES INTO QTYTB QTTXT=UFCA1 ;TRANSMIT TCB QTRXS=UFTBN ;READ SEQUENTIAL LIMIT ; 0 READ LINE QTTXS=UFTBP ;WRITE SEQUENTIAL LIMIT ; 0  WRITE LINE ;READ BUFFER h QRSRT= UFTCA ;START OF BUFFER QREND= UFTCB ;END OF BUFFER QRGET= UFEA1 ;GET DATA POINTER QRSND= UFTEA ;SEND DATA POINTER ;WRITE BUFFER QWSRT= UFNA1 ;START OF BUFFER QWEND= UFTNA ;END OF BUFFER QWGET= UFLA1 ;GET DATA POINTER QWSND= UFTLA ;SEND DATA POINTER ;HOLD WORDS QECHO= UFFA1 ;HOLD FOR ECHOING ;-1 NO ECHO ;1B0 INHIBITS RECEIVES ; ON EMPTY BUFFER, WAKES UFT ; FLAGS CLOSING CHANNEL QXPND= UFTFA ;HOLD FOR EXPANDING  ; -1 NO EXPANSION ; -2 DON'T GETX DATA (CLOSING) QWCOL= UFTCN ;COLUMN COUNTER FOR TABBING ; 1B0 INDICATES WRITER BUSY NLNS= 64. ;NUMBER OF LINES, ASSUMED 64. THROUGHOUT UFTTB= 0 ;UFT TABLE ; 0 INDICATES UNOPENED ; 1B0 INDICATES FOREGROUND CHANNEL ; -1 INDICATES, END OF TABLE ALMCH= NLNS+2+1 ;ALM LINE CHARACTERISTICS TABLE ; +2 FOR LINE 64 ; +1 FOR TERMINATOR .ENT QTRDS,QTRDL .ENT QTWRS,QTWRL .EXTN RETER, RETE2 .EXTN QTYTB, ALM?, DLMUX, MODSET .EXTN SQT64,QKICK,RGET,TSEND,TGET,WSEND,QTYNO .N~REL ; READ - WRITE PROCESSING ; AC0 = BYTE POINTER ; AC1 = BYTE COUNT ; AC2 = UFT ; TCB = @CC QTRDL: SUBO 1,1 ;READ LINE ENTRY JMP SYSRW ;CONTINUE QTRDS: MOVZ 1,1,SNR ;TEST FOR RDS OF ZERO JMP J.NRET ;JUST RETURN JMP SYSRW ; CONTINUE QTWRL:U SUBZ 1,1 ;WRITE LINE ENTRY JMP SYSRW ;CONTINUE QTWRS: MOVO 1,1,SNR ;WRITE SEQ. ENTRY JMP J.NRET ; ZERO COUNT, RETURN ;CARRY CLEAR FOR READ ;CHECK FOR ERRORS SYSRW: LDA 3,QTTBL,2 ;GET TABLE ENTRY LDA 2,UFTTB,3 ;MAKE UFT MASTER UFT FOR LINE MOV# 2,2,SNR ;SEE IF IT IS THERE JMP QTNOP ;OOPS INTDS ;THIS IS CRITICAL LDA 3,QTTXP,2 ;GET WRITE BYTE POINTER MOV# 3,3,SZC ;SKIP IF READING JMP QTW1 ; ELSE WRITING LDA 3,QTRXT,2 ;CHECK FOR PREVIOUS ERROR MOVL# 3,3,SNC JMP QTR1 ; NOPE ADDOR 3,3 ;CLEAR THE ERROR STA 3,QTRXT,2 MOV 3,2 ;AC2 <- ERROR CODE INTEN ;RELIEF JSR @.RET2E ;REPORT ERROR .RET2E: RETE2 QTR1: LDA 3,QTRXP,2 ;AC3 <- READ BYTE POINTER QTW1: MOV# 3,3,SZR ;SEE IF IO IN PROGRESS JMP QTBSY ;YES, TOO BAD STA 2,SVU&FT ;SAVE THE UFT LDA 3,UFTUN,2 ;LINE 64? MOVL# 3,3,SNC JMP CKDSR ; NO-- CHECK DSR MOV# 3,3,SNC ;SKIP IF WRITING JMP QTON ; ELSE READING, LINE IS ON ALWAYS LDA 3,CSP ;RESTORE AC1 LDA 1,OAC1,3 LDA 3,.QTYTB ;GET TABLE ENTRY LDA 2,C377 ; LINE NUM PACKED AND 0,2 ADD 2,3 SUBS 2,0,SZR ;GET CODE IN AC0, SKIP IF DEV. CHAR JMP SPEED? ; ELSE CHECK FOR SPEED ;SET DEVICE CHARACTERISTIC MASK FOR OPENED LINE LDA 3,UFTTB,3 ;SEE IF UFT SNEZ 3 JMP IRET ; NOPE LDA 2,UFTDC,3 ;GET DCT LDA 2ǿ,DCTCH,2 ;THEN DEV. CHAR. COM 1,1 ;MAKE IT A MASK AND 1,2 ; MASK IT STA 2,UFTCH,3 ;AND UPDATE JMP IRET ;RETURN SPEED?: ;SET LINE SPEED FOR ANY LINE ; AC0= CODE (0--DEV. CHAR. ; 1--LINE SPEED ; 2--MODEM CONTROL ; AC1= DATA ; AC2 = LINE NUMBER ; AC3= TABLE ENTRY DOA2= DOA 2,0 DOC0= DOC 0,0 DOB1= DOB 1,0 ALM? ; ONLY IF ALM JMP IRET MOVOL 2,2 ;SET LINE .GADD DLMUX,DOA2 MOVZR 0,0,SZR ;SKIP IF SPEED JMP MODEM? ; ELSE HANDLE MODEM LDA 0,ALMCH,3 ;PICK UP LINE CHARcACTERISTICS LDA 2,COM3B8 ;REMOVE OLD SPEED ANDL 2,0 LDA 2,C3 ; ADD IN NEW ANDS 2,1 ADDR 1,0 STA 0,ALMCH,3 ;UPDATE .GADD DLMUX,DOC0 ;SEND OUT PSPEED JMP IRET ;RETURN MODEM?: ;CHANGE MODEM STATE(AC3= LINE ENTRY) ; 1B15 SET DTR ELSE LOWER  ; 1B14 SET RTS ELSE LOWER MOVR# 0,0,SZR JMP IRET ;ILLEGAL CODE, JUST RETURN LDA 2,C3 ;MASK IT IN CASE AND 2,1 MOVZL 1,1 ;SET ALMCH BITS CORRESPONDINGLY MOVS 1,1 IF ALRTS+ALDTR NE 1B5+1B6, NON-PARAMETRIC ACCESS LDA 2,C.DTRRTS ; STRIP OUT OLD BITS LDA 0,ALMCH,3 AND 2,0 ADD 0,1 ; ADD IN NEW STA 1,ALMCH,3 ; AND UPDATE LDA 2,UFTTB,3 ;IF CURRENTLY WRITING CHARACTERS MOV# 2,2,SNR JMP MODS ; NOT EVEN OPEN-- SET MODEM LDA 0,QWCOL,2 MOVL# 0,0,SNC MODS: JSR @.MODSET ; NOPE-- SET THE MZODEM STATE ; AC1= NEW CHARACTERISTIC WORD JMP IRET ; YEP-- NOCHAR IN QTYDR WILL DO IT ;ERROR RETURNS QTNOP: JSR @.RETER  ;FILE NOT OPEN ERFOP QTBSY: INTEN ;REENABLE JSR @.RETER ;SIMILTANEOUS IN OR OUTPUT ERSIM QTOFF: INTEN ;REENABLE JSR @.RETER ;LINE NOT READY ERRDY .QTYTB: QTYTB C377: 377 .DCLOC: DCLOC J.NRET: JMP NRET .MODSET: MODSET C.DTRRTS: -1-ALDTR-ALRTS CKDSR: ALM? ;CHECK FOR ALM JMP QTON ; NOPE-- ASSUME LINE ON LDA 3,QTTBL,2 ;GET TABLE ENTRY LDA 3,ALMCH,3 ;AC3 <- LIjNE CHAR TABLE LDA 2,.ALDSR ;CHECK FOR DSR AND# 2,3,SZR JMP QTON ; YEP--ITS ON LDA 2,SVUFT ;RESTORE AC2 LDA 3,UFTCH,2 ;MASK DEVICE CHARACTERISTICS LDA 2,.DCLOC ;IF MODEM LINE AND# 2,3,SNR JMP QTOFF ; THEN ERROR THE POOR BEAST ;SET UP RDOS ENtVIR ;NOTE: AFTER HERE RETER DOESN'T WORK QTON: LDA 3,@CC ;GET CALLER TCB LDA 2,CC ;GET CELL LDA 2,CPTAD,2 ;PTBL ASSCO WITH REQ STA 2,TSYS,3 ;SAVE FOR LATER SUBC 2,2 ;ZERO BYTE COUNT IN CALLER STA 2,TAC1,3 ; STA 2,@CC ;WIPE OUT CELL TCB LDA 2,SVUFT ;RESTORE UFT MOV# 2,2,SZC ;SKIP IF READING JMP WR1 ; ELSE WRITING ;READING STA 3,QTRXT,2 ;SAVE TCB STA 2,@.QTYNO ;FLAG HANDLER THAT READING STA 0,QTRXP,2 ;SAVE IN UFT SLOT STA 0,QTORG,2 ;SAVE FOR POSSIBLE RESET STA 1,QTRXS,2 ;SAVE BYTE COUNT LDA 1,UFTUN,2 ;CHECK FOR LINE 64 MOVL# 1,1,SNC JMP RLOOP ; NOPE--PROCESS AS REGULAR READ ;GET WORD FROM SCAN BUFFER (FULLWORD) QGET: LDA 3,QRGET,2 ;AC3 <- BUFFER GET POINTER LDA 0,QREND,2 ;CHECK AGAINST THE END SUBZ# 0,3,SNC ; AND WRAPK AROUND IF NEED BE INC 3,3,SKP ; ELSE SIMPLY BUMP IT LDA 3,QRSRT,2 ; LDA 0,QRSND,2 ;CHECK FOR EMPTY BUFFER SUB# 0,3,SNR ; JMP ZRET ; YES IT IS. WAIT ON IT STA 3,QRGET,2 ;UPDATE BUFFER GET POINTER LDA 0,0,3 ;PICK UP WORD MOVL# 0,0,SNC ;CONSO)LE INTERRUPT (1B1) JMP SQT ; SQUAT LDA 1,LNMSK ;AC1 <- LINE NUMBER ANDS 0,1 LDA 3,.QTYTB ;AC1 <- UFT WORD FOR LINE ADD 1,3 LDA 1,UFTTB,3 MOV# 1,1,SZR ;IT HAD BETTER BE OUT OF USE JMP QGET ; IN USE BETTER DROP THE BEAST SQT: JSR @.SQT64 ;STORe6E THE CHAR AND RETURN ZRET: SUB 0,0 STA 0,@.QTYNO ;STUFF ZERO FOR FREE HANDLER IRET: INTEN NRET: LDA 3,CSP ISZ ORTN,3 RTRN ;GOOD RETURN SVUFT: .BLK 1 .RETER: RETER .SQT64: SQT64 .RGET: RGET .TSEND: TSEND .TGET: TGET .WSEND: WSEND .QKICK: QKICK .QTYNO: QTYNO LNMSK: 77B7 ;LINE MASK FOR LINE 64 READS C3: 3 COM3B8: -1-3B8 .ALDSR: ALDSR ;GET WORDS FROM READ BUFFER RLOOP: INTDS ;NO INTERRUPTS JSR @.RGET ;AC0 <- NEXT CHAR IN BUFFER JMP XON? ; BUFFER EMPTY, MUST WAIT FOR MORE ; BUT FIRST C0HECK DCXON JSR @.TSEND ;SEND CHAR TO TASK JMP ZRET ; TASK REQUEST SATISFIED, ALL DONE INTEN ;LET ANY INTERRUPTS COME THROUGH JMP RLOOP ;GO GET SOME MORE XON?: LDA 3,UFTCH,2 ;CHECK CHARACTERISTICS LDA 1,.DCXON AND# 1,3,SZR JMP ZRET ; NO XON-E- RETURN LDA 0,.XON ;STUFF AN XON FOR THE WRITER STA 0,QTXON,2 JSR @.QKICK ;KICK THE BEAST IF NEED BE JMP ZRET ;AND RETURN .DCXON: DCXON .XON: 21 ;WRITING WR1: STA 3,QTTXT,2 ;SAVE THE TCB STA 0,QTTXP,2 ;SAVE BP STA 1,QTTXS,2 ;SAVE BYTE COUNT k( LDA 0,QXPND,2 ;CHECK IF BACKED UP COM# 0,0,SZR ; JMP IRET ; YES--RETURN DSZ QXPND,2 ;SET QXPND TO -2 FOR HANDLER TRAP ;SEND WORDS TO WRITE BUFFER WLOOP: INTDS ;DISABLE INTERRUPTS JSR @.TGET ;GET NEXT CHARACTER (NOTE AT LEAST ONE) JMP LAST1&4 ; LAST ONE. LETS GO HOME AND GET SOME REST XLOOP: JSR @.WSEND ;SEND CHAR TO BUFFER JMP WRDONE ; BUFFER FULL HOLD THIS CHAR AND WAIT COM# 0,0,SZR ;SKIP IF NO MORE EXPANSION JMP XLOOP ; ELSE CONTINUE EXPANDING INTEN ;LET ANY INTERRUPTS TRHOUGH JMP WLOOP ;GET NEXT CHAR LAST1: JSR @.WSEND ;SEND THE LAST CHAR JMP WRDONE COM# 0,0,SZR JMP LAST1 WRDONE: STA 0,QXPND,2 ;SAVE THE EXPANSION CHAR JSR @.QKICK ;SURE IS KICK HIM (LAZY BUM) JMP IRET ;RETURN ENDOV ;END OF OVERLAY .END M0XDB.SRB 2.LCNS ;COPYRIGHT (C) DATA GENERAL CORPORATION,1972,1973,1974,1975,1976,1977 ;ALL RIGHTS RESERVED ;LICENSED MATERIAL-PROPERTY OF DATA GENERAL CORPORATION ; M0XDB.SR ; THIS MODULE CONTAINS THE DCBS AND DCT FOR ; THE FIRST MAG TAPE CONTROLLER. ; SYSGEN WILL PRODUCE A .LIMIT FOR THE ; SELECTED ONE IF ANY. RTITLE M0XDB .NREL .ENT MTADC .ENT MTAQ .ENT M07DB,M06DB,M05DB,M04DB .ENT M03DB,M02DB,M01DB,M00DB ; THE FOLLOWING ENTRY POINTS ARE USED FOR ; LIMITING THE LOAD OF THIS MODULE. .ENT M08DL .ENT jM07DL,M06DL,M05DL,M04DL .ENT M03DL,M02DL,M01DL,M00DL .EXTN MTAIS .EXTN MTADT ; DISPATCH TABLE .EXTN MTRCB .EXTN MTADS .EXTN MTAST .EXTN MTRLB .EXTN MTRNB .EXTN MTINT .EXTN MTRLS ; FIRST MAG TAPE CONTROLLER DCT MTADC: 1B0 ; DCH INDICATOR MKMTA ; MASK MTAIS ; INTERRUPT SERVICE DCIDI ; CCHARACTERISTICS MTA ; DEVICE CODE MTAEX ; COMMAND ENABLE MTADT ; DISPATCH TABLE MTAST ; DEVICE START MTADS ; MAG TAPE DEVICE SET UP ROUTINE -1 ; CURRENT REQUEST POINTER .BLK 1 ; DAT)A CHANNEL MAP FIRST SLOT 5 ; NUMBER OF BLOCKS TO MAP MTADC ; POINTER TO PARENT DCT MTRLB ; READ LAST BLOCK MTRCB ; READ CURRENT BLOCK MTRNB ; READ NEXT BLOCK MTINT ; DEVICE INIT MTRLS ; DEVICE RELEASE -1 ; NUMBER OF BLOCKS HIGH ORDER -1 ; NUMBER OF BLOCKS LOW ORDER ; FAKE BUFFER HEADER PART OF MAG-TAPE DCT .IFN .-MTADC-DCNBK-1 COM: ; MUST AGREE WITH DISPLACEMENT ; IN MTADR .ENDC .BLK 1 ; BQQLK = -11 DEVICE REQUEST QUEUE .BLK 1 ; BQDST = -10 .BLK 1 ; BQERC = -07 .BLK 1 ; BQST = -06 STATUS AND COMMAND WORD MTADC ; BQDCT = -05 DCT ADDRESS .BLK 1 ; BQUN = -04 UNIT NUMBER .BLK 1 ; BQCA1 = -03 CUR BLK DEV ADDR, HIGH 77777 ; BQCA = -02 CUR BLK DEV ADDR, LOW (WD CNT)  .BLK 1 ; BQNXT = -01 DATA ADDRESS, NOT USED .BLK 1 ; BQBF = 00 START OF DATA .IFE BSW!MBSW MTAEX: .BLK 1 ; PLACE TO EXECUTE IO LDA 2,@CSP ; RESTORE AC2 JMP @RLOC ; RETURN .ENDC J MTAEX= -1 ; NOT NEEDED ON BIRD [J] MTAQ: .BLK 2 1B0 ; NEEDS FREE STACK MTADC .BLK QLN-4 .NDDCB M00DB,MTADC,0,M01DB,MT0,M00DL ** .NOMAC 1 .NDDCB M01DB,MTADC,1,M02DB,MT1,M01DL .NDDCB M02DB,MTADC,2,M03DB,MT2,M02DL .NDDCB M03DB,MTADC,3,M04DB,MT3,M03DL .NDDCB M04DB,MTADC,4,M05DB,MT4,M04DL .NDDCB M05DB,MTADC,5,M06DB,MT 5,M05DL .NDDCB M06DB,MTADC,6,M07DB,MT6,M06DL .NDDCB M07DB,MTADC,7,-1,MT7,M07DL M08DL: .BLK 2 ; ENTRY POINT FOR LIMIT ; ; IN CASE ALL UNITS LOADED ** .NOMAC 0 .END M1XDB.SRB t 2/n ; M1XDB.SR ; THIS MODULE CONTAINS THE DCBS AND DCT FOR ; THE SECOND MAG TAPE CONTROLLER. ; SYSGEN WILL PRODUCE A .LIMIT FOR THE ; SELECTED ONE IF ANY. RTITLE M1XDB .NREL .ENT MTA1D .ENT MTA1Q .ENT M17DB,M16DB,M15DB,M14DB .ENT M13DB,M12DB,M11DB,My10DB ; THE FOLLOWING ENTRY POINTS ARE USED FOR ; LIMITING THE LOAD OF THIS MODULE. .ENT M18DL .ENT M17DL,M16DL,M15DL,M14DL .ENT M13DL,M12DL,M11DL,M10DL .EXTN MTAIS .EXTN MTADT ; DISPATCH TABLE .EXTN MTRCB .EXTN MTADS .EXTN MTAST .EXTN MTRLB .-EXTN MTRNB .EXTN MTINT .EXTN MTRLS ; SECOND MAG TAPE CONTROLLER DCT MTA1D: 1B0 ; DCH INDICATOR MKMTA ; MASK MTAIS ; INTERRUPT SERVICE DCIDI ; CCHARACTERISTICS MTA1 ; DEVICE CODE MTAEX ; COMMAND ENABLE MTADT ; DISPATCH TABLE MTAST | ; DEVICE START MTADS ; MAG TAPE DEVICE SET UP ROUTINE -1 ; CURRENT REQUEST POINTER .BLK 1 ; DATA CHANNEL MAP FIRST SLOT 5 ; NUMBER OF BLOCKS TO MAP MTA1D ; POINTER TO PARENT DCT MTRLB ; READ LAST BLOCK MTRCB ; READ CURRENT BLOCK MTRNB ; READ NEXT BLOCK MTINT ; DEVICE INIT MTRLS ; DEVICE RELEASE -1 ; NUMBER OF BLOCKS HIGH ORDER -1 ; NUMBER OF BLOCKS LOW ORDER ; FAKE BUFFER HEADER PART OF MAG-TAPE DCT .IFN .-MTA1D-DCNBK-1 COM: ; MUST AGREE WITH DISPLACEMENT ; IN MT!BADR .ENDC .BLK 1 ; BQQLK = -11 DEVICE REQUEST QUEUE .BLK 1 ; BQDST = -10 .BLK 1 ; BQERC = -07 .BLK 1 ; BQST = -06 STATUS AND COMMAND WORD MTA1D ; BQDCT = -05 DCT ADDRESS .BLK 1 ; BQUN = -04 UNIT NUMBER .BLK 1 ; QBQCA1 = -03 CUR BLK DEV ADDR, HIGH 77777 ; BQCA = -02 CUR BLK DEV ADDR, LOW (WD CNT) .BLK 1 ; BQNXT = -01 DATA ADDRESS, NOT USED .BLK 1 ; BQBF = 00 START OF DATA .IFE BSW!MBSW MTAEX: .BLK 1 ; PLACE TO EXECUTE IO LDA 2,@CSP ; RESTORE AC2 JMP @RLOC ; RETURN .ENDC J MTAEX= -1 ; NOT NEEDED ON BIRD [J] MTA1Q: .BLK 2 1B0 ; NEEDS FREE STACK MTA1D .BLK QLN-4 .NDDCB M10DB,MTA1D,0,M11DB,MT10,M10DL ** .NOMAC 1 .NDDCB M11DB,MTA1D,1,M12DB,MT11,M11DL .NDDCB M12DB,MTA1D,2,M13DB,MT12,M12DnL .NDDCB M13DB,MTA1D,3,M14DB,MT13,M13DL .NDDCB M14DB,MTA1D,4,M15DB,MT14,M14DL .NDDCB M15DB,MTA1D,5,M16DB,MT15,M15DL .NDDCB M16DB,MTA1D,6,M17DB,MT16,M16DL .NDDCB M17DB,MTA1D,7,-1,MT17,M17DL M18DL: .BLK 2 ; ENTRY POINT FOR LIMIT ; ; IN CASE ALL UNI"TS LOADED ** .NOMAC 0 .END C0XDB.SRB  ; C0XDB.SR ; THIS MODULE CONTAINS THE DCBS AND DCT FOR ; THE FIRST CASSETTE CONTROLLER. ; SYSGEN WILL PRODUCE A .LIMIT FOR THE ; SELECTED ONE IF ANY. RTITLE C0XDB .NREL .ENT CTADC .ENT CTAQ .ENT C07DB,C06DB,C05DB,C04DB .ENT C03DB,C02DB,C01DB,C00|DB ; THE FOLLOWING ENTRY POINTS ARE USED FOR ; LIMITING THE LOAD OF THIS MODULE. .ENT C08DL .ENT C07DL,C06DL,C05DL,C04DL .ENT C03DL,C02DL,C01DL,C00DL .EXTN MTAIS .EXTN MTADT ; DISPATCH TABLE .EXTN MTRCB .EXTN MTADS .EXTN MTAST .EXTN MTRLB .EX9TN MTRNB .EXTN MTINT .EXTN MTRLS ; FIRST CASSETTE CONTROLLER DCT CTADC: 1B0 ; DCH INDICATOR MKCAS ; MASK MTAIS ; INTERRUPT SERVICE DCIDI ; CCHARACTERISTICS CAS ; DEVICE CODE MTAEX ; COMMAND ENABLE MTADT ; DISPATCH TABLE MTAST ; xDEVICE START MTADS ; MAG TAPE DEVICE SET UP ROUTINE -1 ; CURRENT REQUEST POINTER .BLK 1 ; DATA CHANNEL MAP FIRST SLOT 5 ; NUMBER OF BLOCKS TO MAP CTADC ; POINTER TO PARENT DCT MTRLB ; READ LAST BLOCK MTRCB ; READ CURRENT BLOCK MTRNB 4; READ NEXT BLOCK MTINT ; DEVICE INIT MTRLS ; DEVICE RELEASE -1 ; NUMBER OF BLOCKS HIGH ORDER -1 ; NUMBER OF BLOCKS LOW ORDER .IFE BSW!MBSW MTAEX: .BLK 1 ; PLACE TO EXECUTE IO LDA 2,@CSP ; RESTORE AC2 JMP @RLOC ; RETURN .ENDC J MTAEX= -1 ; NOT NEEDED ON BIRD [J] CTAQ: .BLK 2 1B0 ; NEEDS FREE STACK CTADC .BLK QLN-4 .NDDCB C00DB,CTADC,0,C01DB,CT0,C00DL ** .NOMAC 1 .NDDCB C01DB,CTADC,1,C02DB,CT1,C01DL .NDDCB C02DB,CTADC,2,C03DB,CT2,C02DL .NDDCB C03DB,CTADC,3,C04DB,CT3,C03}DL .NDDCB C04DB,CTADC,4,C05DB,CT4,C04DL .NDDCB C05DB,CTADC,5,C06DB,CT5,C05DL .NDDCB C06DB,CTADC,6,C07DB,CT6,C06DL .NDDCB C07DB,CTADC,7,-1,CT7,C07DL C08DL: .BLK 2 ; ENTRY POINT FOR LIMIT ; ; IN CASE ALL UNITS LOADED ** .NOMAC 0 .END C1XDB.SRB F ; C1XDB.SR ; THIS MODULE CONTAINS THE DCBS AND DCT FOR ; THE SECOND CASSETTE CONTROLLER. ; SYSGEN WILL PRODUCE A .LIMIT FOR THE ; SELECTED ONE IF ANY. RTITLE C1XDB .NREL .ENT CTA1D .ENT CTA1Q .ENT C17DB,C16DB,C15DB,C14DB .ENT C13DB,C12DB,C11DB,CyT10DB ; THE FOLLOWING ENTRY POINTS ARE USED FOR ; LIMITING THE LOAD OF THIS MODULE. .ENT C18DL .ENT C17DL,C16DL,C15DL,C14DL .ENT C13DL,C12DL,C11DL,C10DL .EXTN MTAIS .EXTN MTADT ; DISPATCH TABLE .EXTN MTRCB .EXTN MTADS .EXTN MTAST .EXTN MTRLB .u^EXTN MTRNB .EXTN MTINT .EXTN MTRLS ; SECOND CASSETTE CONTROLLER DCT CTA1D: 1B0 ; DCH INDICATOR MKCAS ; MASK MTAIS ; INTERRUPT SERVICE DCIDI ; CCHARACTERISTICS CAS1 ; DEVICE CODE MTAEX ; COMMAND ENABLE MTADT ; DISPATCH TABLE MTAST r ; DEVICE START MTADS ; MAG TAPE DEVICE SET UP ROUTINE -1 ; CURRENT REQUEST POINTER .BLK 1 ; DATA CHANNEL MAP FIRST SLOT 5 ; NUMBER OF BLOCKS TO MAP CTA1D ; POINTER TO PARENT DCT MTRLB ; READ LAST BLOCK MTRCB ; READ CURRENT BLOCK MTRNB ; READ NEXT BLOCK MTINT ; DEVICE INIT MTRLS ; DEVICE RELEASE -1 ; NUMBER OF BLOCKS HIGH ORDER -1 ; NUMBER OF BLOCKS LOW ORDER .IFE BSW!MBSW MTAEX: .BLK 1 ; PLACE TO EXECUTE IO LDA 2,@CSP ; RESTORE AC2 JMP @RLOC ; RETURN .ENDC J MTA EX= -1 ; NOT NEEDED ON BIRD [J] CTA1Q: .BLK 2 1B0 ; NEEDS FREE STACK CTA1D .BLK QLN-4 .NDDCB C10DB,CTA1D,0,C11DB,CT10,C10DL ** .NOMAC 1 .NDDCB C11DB,CTA1D,1,C12DB,CT11,C11DL .NDDCB C12DB,CTA1D,2,C13DB,CT12,C12DL .NDDCB C13DB,CTA1D,3,C14DB,)CT13,C13DL .NDDCB C14DB,CTA1D,4,C15DB,CT14,C14DL .NDDCB C15DB,CTA1D,5,C16DB,CT15,C15DL .NDDCB C16DB,CTA1D,6,C17DB,CT16,C16DL .NDDCB C17DB,CTA1D,7,-1,CT17,C17DL C18DL: .BLK 2 ; ENTRY POINT FOR LIMIT ; ; IN CASE ALL UNITS LOADED ** .NOMAC 0 .END MTADR.SRB 4Y{ RTITLE MTADR ; ENTRY POINTS IN THIS MODULE AVAILABLE TO OTHER MODULES .ENT MTADS ; MAG-TAPE DEV SETUP ROUTINE .ENT MTADT ; MAG-TAPE DISPATCH TABLE .ENT MTAST ; MAG-TAPE STARTUP ROUTINE .ENT MTAIS ; MAG-TAPE INTERRUPT SERVICE .ENT RDRCD ;"G READ A RECORD .ENT WTRCD ; WRITE A RECORD .ENT REWND ; REWIND THE TAPE .ENT GSTAT ; GET THE TAPE STATUS .ENT SBRCD,SBFIL ; SPACE BACK ONE RECORD, FILE .ENT SFRCD,SFFIL ; SPACE FORWARD ONE RECORD, FILE .ENT WTEOF ; WRITE AN END-OF-FILE ; 4ENTRY POINTS IN OTHER MODULES NEEDED IN THIS ROUTINE .IFN MSW ; SET IF MAPPED SYSTEM .EXTN SWAMP ;DCH MAP ROUTINE ; AC0 IS FIRST PAGE OF MAP, AC1 IS # OF PAGES .ENDC .EXTN INTLV ; INTERRUPT LEVEL .EXTN RELDB ; RELEASE THE BUFFER .EXTN MTOPN ; OPEN .EXTN MTOPA ; OPEN FOR APPENDING .EXTN MTOPD ; OPEN FOR DIRECT I/O .EXTN UNPEND ; UNPEND THE REQUEST .EXTN PEND ; PEND FOR 'N' SECONDS .EXTN MTCLS ; CLOSE .EXTN DFRS,DFRL ; DISK FILE READ ROUTINES .EXTN DFWS,DFWL ; DISK FILE WReITE ROUTINES .EXTN QUENT ; QUEUE THE REQUEST .EXTN DISMIS ; INTERRUPT RETURN ADDRESS .EXTN RETE2,RETER ; SYSTEM ERROR RETURNS ; ALL I/O INSTRUCTIONS HAVE COMMAND IN AC0, AND HAVE SYSTEM- ; BUFFER IN AC2 .EXTN XOAS ; START THE REWIND .EXTN XNOC ; CLEAR THE DEVICE .EXTN XDOA ; SELECT THE UNIT .EXTN XDOBS ; LOAD ADDRESS REG AND START .EXTN XIAC ; GET DEV STATUS AND CLEAR .EXTN XDIB ; GET ADDRESS REGISTER .EXTN XDOC ; SET WORD COUNT .EXTN XDIA ; GET MTA STATUS .NREL ; MAG-TAPE COMMAND DISPATCH TABLE ; ENTRY FOR EVERY POSSIBLE RDOS I/O FUNCTION MTADT: MTOPN ; OPEN MTCLS ; CLOSE DFRS ; READ SEQUENTIAL DFRL ; READ LINE -1 ; READ RANDOM, NOT PERMETTED DFWS ; WRITE SEQUENTIAL DFWL ; WRITE LINE -1 ; WRITE RANDOM, Nx#OT PERMETTED MTOPA ; OPEN FOR APPENDING MTOPN ; READ-ONLY OPEN MTOPN ; EXCLUSIVE(?) OPEN MTOPD ; OPEN FOR DIRECT I/O .IFE BSW!MBSW MTADS: STA 3,RLOC ; NULL DEVICE SETUP ROUTINE LDA 3,CSP JMP @RLOC .ENDC MTAMM MTADS: PSH 3,3 LDA 3,CSP POP %J [MTAMM] ; DEFINE SPECIAL BUFFER DISPLACEMENTS BQWC= BQCA ; WORD/RECORD COUNT ; ALSO USED IN M0XDB , M1XDB ; DEFINE DEVICE STATUS BITS ER= 1B0 ; ERROR DL= 1B1 ; DATA LATE RW= 1B2 ; UNIT IS REWINDING IL= 1B3 ; ILLEGAL STATUS DN= 1W%B4 ; RECORDING DENSITY 1=HIGH,0=LOW PR= 1B5 ; PARITY ERROR ET= 1B6 ; END OF TAPE ENCOUNTERED EF= 1B7 ; END OF FILE LP= 1B8 ; LOAD POINT ( BOT ) UT= 1B9 ; UNIT TYPE 1= 9, 0= 7 TRACK BT= 1B10 ; BAD TAPE TT= 1B11 TT= 1B12 WP= 1B13 ; UNIT I4S WRITE PROTECTED OC= 1B14 ; ODD CHARACTER UR= 1B15 ; UNIT READY ; INSTRUCTION DEFINITIONS READ = 0 ; READ A RECORD REWIND = 1 ; REWIND TILL LOAD POINT SPFOR = 3 ; SPACE FORWARD ONE RECORD SPREV = 4 ; SPACE REVERSE ONE RECORD WRITE = 5 ; WRITE A :FILE WREOF = 6 ; WRITE AN END-OF-FILE ERASE = 7 ; ERASE NEXT (LAST) RECORD STATUS = 7 ; GET MAG-TAPE STATUS PARCM = 1B2 ; BIT FOR SETTING EVEN PARITY CMMSK = 7*1B5 ; MASK FOR COMMAND WORD IN BQST TRYCT = 2 ; NUMBER OF TIMES TO ATTEMPT RECOVERY ; BUFNFER STATUS WORD, BQST OF SYSTEM BUFFER HEADER ; BIT ; ; 00 BACKSPACE NEEDED, PRIORITY OVER ERASE ; ; 01 ERASE NEEDED, PRIORITY OVER COMMAND ; 02 PARITY, 0->ODD, EOF & 7-TRACK EVEN PARITY ; 03 * COMMAND <1B3-1B5> ; ; 04 * ; 05 * ; 06 ; ; 07 ; 08 ; 09 ; ; 1@0 INDIRECT MODE ; 11 ; 12 I/O IN PROGRESS ; ; 13 ; 14 ERROR DETECTED ; 15 BUFFER MODIFIED ; BUFFER STATUS FLAGS ; QTIND = 1B10 ; INDIRECT I/O, USER'S DIRECT I/O ESNEX = 1B1 ; ERASE NEXT BKNEX = 1B0 ; BACKSPACE NEXT ; STATE DEFINITIONS, CURRENT ON NEXT r3STATE NORMAL = 0 ; NOT IN BAD-TAPE RECOVERY BK1SP = 1 ; BAKSPACE BEFORE READ R1EAD = 2 ; READ THE RECORD, CHECK IF GOOD BK2SP = 3 ; BACKSPACE OVER BAD RECORD R2EAD = 4 ; READ THE GOOD RECORD CTMSK = 377 ; RETRY COUNT MASK ERS1 = 5 ; FIRST ERASE ERS2 = 6 ; SECOND ERASE ERS3 = 7 ; THIRD ERASE STMSK = 177*1B7 ; STATE MASK ERDUP = 1B0 ; SET IF ERROR HAS BEEN REPRODUCED RDCMD = READ*1B5 ; READ INDIRECT MODE ; MAG TAPE START ROUTINE ; ; AC2 - DCT ADDRESS ; CAN NOT USE TEMPS, BECAUSE MAY BE CALLED BY INTERRUPT MTAST: INTEN RSAVE 0 LDA 2,DCCRQ,2 ; CURRENT BUFFER IN QUEUE MST1: COM# 2,2,SNR RTRN ; NO CURRENT REQUEST XLDA @0,= INTLV ; GET THE INTERRUPT LEVEL .IFE BSW!MBSW ; INTVL IS NON-ZERO FOR INTERRUPT ON NOVA SYSTEM MOV 0,0,SZR ; ARE WE@k IN AN INTERRUPT? .ENDC MSTAB ; INTVL IS NOT (-1) FOR INTERRUPT ON ECLIPSE SYSTEM COM 0,0,SZR ; ARE WE IN AN INTERRUPT? [MSTAB] JMP ININT ; YES ; SELECT THE UNIT AND GET THE STATUS WORD LDA 0,BQUN,2 ; UNIT NUMBER XXJSR XDOA ; SELECT THE UNIT XXJS-R XDIA ; GET MTA STATUS WORD ; IF UNIT IS NOT READY THEN PEND THE REQUEST MOVR 0,0,SNC ; UNIT READY? JMP PENDIT ; NO ; CHECK FOR BACKSPACE RECOVERY COMMAND ININT: LDA 3,BQST,2 ; STATUS WORD ADC 0,0 ; -1 XLDA 1,= SPREV*1B12 ; BACKSPACE COMMAND MOVL## 3,3,SZC ; BACKSPACE NEEDED? JMP GO ; YES ; CHECK FOR ERASE RECOVERY COMMAND XLDA 1,= ERASE*1B12 ; ERASE COMMAND ADDL# 3,3,SZC ; ERASE NEEDED? JMP GO ; YES ; GET THE COMMAND + PARITY, CHECK IF STATUS MOV 1,0 XLDA 1,= CMMSK+PARCM ; (COMMAND + PARFPITY) MASK ANDS 3,1 ; ISOLATE COMMAND MOVZL 1,1 ; POSITION IT MOV 1,3 ; COMMAND + PARITY AND 0,3 ; EXTRACT COMMAND, NO PARITY SUB# 3,0,SNR ; STAT COMMAND? JMP EXST ; YES ; CHECK IF REWIND COMMAND XLDA 0,= REWIND*1B12 SUB# 3,0,SNR ; IS IT? JM"JP EXRWD ; YES ; MUST BE A WRITE OR READ COMMAND LDA 0,BQWC,2 ; WORD COUNT ; OUTPUT , GO: STA 0,BQDST,2 ; SAVE THRU SUBROUTINE LDA 0,BQUN,2 ; UNIT NUMBER ADD 1,0 ; FORM COMPLETE COMMAND XXJSR XDOA ; SELECT THE UNIT LDA 0, JBQDST,2 ; RECOVER THE WORD COUNT SUB 3,3 STA 3,BQDST,2 ; CLEAR STATUS IN CASE OF ABORT XXJSR XDOC ; SET THE WORD COUNT ; GET THE BUFFER ADDRESS AND OUTPUT IT TO THE MAG-TAPE ; UNMAPPED .IFE MSW ; UNMAPPED LDA 3,BQST,2 MOV 2,0 ; SAVE THE BUFFER ADDd[RESS XLDA 1,= QTIND ; 'RDOS' INDIRECT BIT AND 3,1,SZR ; INDIRECT MODE? LDA 0,BQNXT,2 ; YES, CORE ADDRESS IN LINK WORD MOVL 0,0 MOVZR 0,0 ; RESET 1B0 XXJSR XDOBS ; LOAD ADDR REG AND START .ENDC SWPMM ; MAPPED LDA 3,BQDCT,2 ; DCT ADDRESS LDA 0,DCqHMP,3 ; FIRST PAGE IN DCH MAP LDA 1,DCHNM,3 ; NUMBER OF PAGES XXJSR SWAMP ; SET UP THE MAP XXJSR XDOBS ; LOAD ADDR REG AND START [SWPMM] RTRN ; RETURN TO CALLER ; DO A REWIND COMMAND EXRWD: LDA 0,BQUN,2 ; UNIT NUMBER ADD 1,0 ; FORM COMMAND XXJ SR XOAS ; START THE REWIND EXST: STA 2,BQWC,2 ; FORCE A NON-ZERO WORD COUNT XJMP MTAS ; SIMULATE AN INTERRUPT ; PEND THE REQUEST IF THERE IS NO ABORT PENDIT: LDA 3,BQST,2 ; STATUS XLDA 0,= CMMSK ; COMMAND MASK AND 0,3 ; MASK BITS SUB# 0,3,SNR ; I]S IT A GSTAT JMP EXST ; YES - DON'T PEND ;CHECK TO SEE IF CONTROL-A/C DONE TO ABORT THIS SUB 0,0 ; SET AC0=0 IN CASE ABORTING LDA 3,CQ ; CURRENT TASK QUEUE LDA 3,QSTAT,3 ; BIT TSAB SET IF CTRL-A, ABORT XLDA 1,= TSAB ; CTRL-A BIT AND# 1,3,SZR ; SKIP IF NO XJMP NCON ; ABORT ; NO, WAIT A WHILE THEN CHECK FOR READY AGAIN XLDA 0,= 5 ; WAIT FOR 5 SECONDS SUB 1,1 ; ZERO IS KEY INTDS XXJSR PEND ; PEND THE REQUEST JMP MST1 JMP MST1 LPOOL ; ERROR RECOVERY FOR FALSE IFG (BAD-TAPE) ON BACKSPACE ; AC0 = CONTROLLER STATUS ; AC2 = RECOVERY BUFFER HEADER ;STATE COMMAND TABLE, WHERE TO GO IF JUST COMPLETED COMMAND PRTBL: . XBK1SP ; BACKSPACE OVER THE GOOD RECORD XR1EAD ; READ THE RECORD, CHECK IF GOOD XBK2SP ; BACKSPACE OVER THE BAD RECORD XR2EZAD ; READ AND CHECK FOR EXPECTED ERROR XERS1 ; FIRST ERASE XERS2 ; SECOND ERASE RECOV ; THIRD ERASE, RESTART WRITE ; BAD-TAPE ERROR, PUT FAKE SYS BUF HEADER IN QUEUE XBDTP: ADDOR 1,1 ; CLEAR BACKSPACE BIT STA 1,BQST,2 ; IN CURRENT REQUEST XLDA '3,= PARCM!QTIOP!QTDSU AND 3,1 STA 1,PARST ; SAVE PARITY & STATUS FOR ; READ RECOVERY LDA 1,BQUN,2 ; REMEMBER DRIVE # LDA 3,BQDCT,2 ; GET DCT ADDRESS XLDA 2,= DCNBK+1-BQQLK ADD 3,2 ; ADDR OF FAKE SYS BUF HEADER STA 1,BQUN,2 ; COPY DRIVE # LDA 1,DCCRQ,3 ; CURRENT REQUEST STA 1,BQQLK,2 ; DEVICE REQUEST QUEUE STA 2,DCCRQ,3 ; NEW CURRENT REQUEST ; GET COMMAND AND NEXT STATE XLDA 1,= TRYCT STA 1,BQERC,2 ; <-> ; BACKSPACE COMPLETE, BACKSPACE AGAIN RECORD XBK2SP: XLDA 0,= BK1SPT JMP BNEXT ; BACKSPACE COMPLETE, INITIATE READ XBK1SP: XLDA 1,= LP AND# 1,0,SZR JMP XREAB ; GO INITIATE THE ERASES XLDA 0,= R1EAD JMP RNEXT ; READ COMPLETE, CHECK IF ANY ERRORS XR1EAD: MOVL# 0,0,SNC ; STATUS WORD JMP XREAA ; NO ERROR ON READ ; ERROR ON READ, SO BACKSPACE UNLESS TIME TO QUIT TRYING DSZ BQERC,2 ; NOP LDA 1,BQERC,2 ; XLDA 3,= CTMSK AND 1,3,SNR ; RETRY COUNT LEFT JMP XFATAL ; FATAL BAD-TAPE ERROR JMP RDBAD ; NO ERRLOR ON READ, IF HERE BEFORE THE RETURN TO NORMAL XREAA: LDA 1,BQERC,2 ; MOVL# 1,1,SZC JMP XREAB ; RETURN TO NORMAL ; SET THE DUPLICATED ERROR BIT AND TRY AGAIN XLDA 0,= R2EAD+1B8 JMP RNEXT ; TRY READ AGAIN ; ERROR RECOVER\ED, DO SEVERAL ERASES XREAB: XLDA 0,= ERS1 JMP ENEXT ; ERASE NEXT ; READ OF BAD RECORD COMPLETE, CHECK IF ANY ERRORS XR2EAD: XLDA 1,= PR+BT AND# 0,1,SNR JMP XFATAL ; FATAL BAD-TAPE ERROR ; ERROR ON READ, GO BACKSPACE OVER THIS RECORD RDBAD: XLDA 0,= BK2SP JMP BNEXT ; FIRST ERASE FINISHED, GO DO NEXT ERASE XERS1: XLDA 0,= ERS2 JMP ENEXT ; SECOND ERASE FINISHED, GO DO NEXT ERASE XERS2: XLDA 0,= ERS3 JMP ENEXT LPOOL PARST: 0 ; HOLDER FOR PARITY & STATUS ; GO RETURN FATAL ; MUST GIVE UP-- RETURN ORIGINAL ERROR STATUS XFATAL: LDA 2,BQQLK,2 ; ORIGINAL REQUEST LDA 3,BQDCT,2 ; DCT STA 2,DCCRQ,3 ; RESTORE ORIGINAL XJMP FATAL ; GO TO FATAL ; XMTAP ; SETS UP SYSTEM BUFFER HEADER FOR NEXT COMMAND ; AND STARTS THE COMMAND. ; ; CALLING SEQUENCE ; ; AC2 = RECOVERY BUFFER HEADER ; AC1 = NEXT COMMAND (FOR BQST) ; AC0 = NEXT RECOVERY STATE + ERROR DUPLICATE BIT ; JMP XMTAP ; START NEXT COMMAND ; RETURNS TO CALLER OF MTAIS BNEXT: XLDA 1,= BKNEX JMP XMTAP RNEXT: SUB 1,1,SKP ENEXT: XLDA 1,= ESNEX ; SET UP *SYSTEM BUFFER FOR NEXT COMMAND XMTAP: LDA 3,PARST ; PARITY & STATUS ADD 3,1 ; FORM FULL COMMAND & STATUS STA 1,BQST,2 ; RETURN THE COMMAND XLDA 1,= CTMSK+ERDUP LDA 3,BQERC,2 ; ANDS 3,1 ; <-> ADDS8 0,1 ; STA 1,BQERC,2 ; RETURN THE ; START THE MAG-TAPE AND RETURN TO CALLER XJMP MST1 ; GO START THE NEXT COMMAND LPOOL ; DECIDE WHICH ROUTINE TO PROCESS THE COMPLETED OPERATION XSTART: LDA 3,BQERC,2 ; XLDA 1,= STMSK ; EXTRACT STATE ANDS 1,3 LDA 1,PRTBL ; VECTOR OFF PRTBL, ADD 1,3 ; INDEXED BY STATE. JMP @0,3 ; PASS AC0 = STATUS ; AC2 = RECOVERY BUFFER LPOOL ; MTA INTERRUPT SERVICE ROUTINE ; ; AC2 - DCT ADDRESSf ; NO TEMPS ALLOWED MTAIS: XLDA 3,= DISMIS ; INTERRUPT RETURN ADDRESS RSAVE 0 ; GET CURRENT REQUEST AND STATUS, CLEAR DEVICE LDA 2,DCCRQ,2 ; CURRENT REQUEST MTAS: XXJSR XIAC ; GET DEVICE STATUS AND CLEAR STA 0,BQDST,2 ; SAVE DEVICE STATUS ; IF FILE CCOMMAND, THEN CHECK IF END FILE ERROR LDA 1,BQWC,2 ; GET WORD/RECORD COUNT MOVL# 1,1,SNC ; FILE SPACE REQUEST ? JMP NOFSP ; NO XLDA 1,= IL+EF+ET+LP ; ERRORS TO STOP SPACE FILE AND# 1,0,SZR ; FATAL TYPE ERROR ? JMP NOFSB ; YES- THAT WILL DO XJMP MaST1 ; NO- RESTART ; IF CURRENT DEVICE IS MAG-TAPE THEN CHECK FOR BAD-TAPE NOFSP: LDA 3,BQDCT,2 ; DCT ADDRESS XLDA 1,= 37 LDA 3,DCTCD,3 ; DEVICE CODE AND 3,1 ; 40 BIT OFF XLDA 3,= 22 SUB# 3,1,SZR JMP NOFSB ; NOT A MAG TAPE DEVICE ; CHECK IF IN BA&D-TAPE RECOVERY MODE LDA 1,BQERC,2 ; XLDA 3,= STMSK AND# 3,1,SZR JMP XSTART ; GO CHECK WHICH ROUTINE TO RUN ; CHECK IF IN BACKSPACE MODE AND WRITE MODE LDA 1,BQST,2 ; STATUS AND COMMAND WORD XLDA 3,= BKNEX+CMMSK AND 3,T1 ; BACKSPACE+COMMAND XLDA 3,= WRITE*1B5+BKNEX SUB# 1,3,SZR JMP NOFSB ; NOT IN BACKSPACE AND WRITE MODE ; IN BACKSPACE MODE, CHECK IF BAD-TAPE, GO PROCESS LDA 1,BQST,2 ; STATUS AND COMMAND WORD XLDA 3,= BT AND# 3,0,SZR XJMP XBDTP ; BAD TAPE ROUTIoNE JMP ICON ; NOT A BAD-TAPE ERROR, CONTINUE ; NOT BAD-TAPE, CHECK IF THERE IS AN ERROR NOFSB: XLDA 3,= DL+IL+PR+ET+LP+BT+EF LDA 1,BQST,2 ; STATUS WORD AND# 0,3,SZR JMP DEVER ; YES - GO HANDLE IT ; IF FINISHED BACKSPACE RECOVERY MODE THEN GO CLEAR BK\SP BIT ICON: MOVL# 1,1,SZC ; IN BACKSPACE MODE? XJMP ERRMD ; GO CLEAR BKSP BIT ; IF FINISHED ERASE, THEN CLEAR ERASE AND BKSP BITS ADDL# 1,1,SZC ; IN ERASE MODE? XJMP ERAMD ; GO CLEAR ERASE AND BKSP BITS ; IF USER DIRECT MODE, THEN GET DEVICE WORD CzOUNT AND SET ; DONE IN USER STATUS, AND SET TO UNPEND FROM UNPEND BIT. XLDA 0,= QTIND ; 'RDOS' INDIRECT BIT ANDZ 1,0,SNR ; INDIRECT MODE ? JMP NOIN ; NO INDI: XXJSR XDIB ; YES - GET C(ADDR REGISTER) STA 0,BQARD,2 ; AND RETURN IN CELL LDA 1,BQST,2 ;, FIND THE STATUS, AGAIN ISZ BQUST,2 ; SET DONE IN USER STATUS LDA 0,BQUST,2 ; USER STATUS WORD ADDL 0,0 ; SET CARRY FROM 1B1 (UNPEND ; BIT) ; IF 'RDOS' DIRECT, OR USER DIRECT AND UNPEND BIT SET ; THEN UNPEND THE BUFFER NOIN: MOV 2,0,SNC ; BUFFER .ADDRESS IS UNPEND KEY XXJSR UNPEND ; UNPEND THIS REQUEST ; RESET THE I/O IN PROGRESS BIT XLDA 3,= -QTIOP-1 ; I/O IN PROGRESS BIT AND 1,3 ; RESET I/O PROGRESS BIT STA 3,BQST,2 ; UPDATE STATUS ; TAKE THE BUFFER OF THE QUEUE, AND START THE NEXT REQUEST z6RECOV: LDA 3,BQDCT,2 ; DCT ADDRESS LDA 2,BQQLK,2 ; NEXT BUFFER REQUEST STA 2,DCCRQ,3 ; SAVE NEXT BUF REQUEST IN DCT MTNXT: XJMP MST1 ; GO START DEVICE IF THERE IS MORE LPOOL ; INTERRUPT SERVIE ERROR RECOVERY ROUTINES ; ; AC0 - MTA STATUS ; ; AC1 - BUyFFER STATUS ; ; AC2 - BUFFER ADDRESS ; IF EOF, ILLEGAL, OR LOAD-POINT THEN FATAL, RT ERROR DEVER: XLDA 3,= EF+LP+IL ; EOF, ILLEGAL, & LOAD-POINT AND# 3,0,SZR JMP FATAL ; FATAL ERROR ; IF PARITY ERROR OR BAD-TAPE, FIRST TRY TO RECOVER XLDA 3,= BT+PR+DL ; PARITY+BAD-TAPE+DATA-LATE AND# 3,0,SZR JMP NONFTL ; GO ATTEMPT RETRY ; IF EOT AND WRITE THEN RT ERROR, IF EOT AND READ THEN OK XLDA 3,= ET ; END-OF-TAPE AND# 3,0,SNR JMP ICON ; MUST HAVE BEEN ODD-CHAR, NOT ERROR XLDA 3,= CMMSK ; MASK FOR COMMAN D WORD AND# 3,1,SNR JMP ICON ; READ AND EOT IS NOT AN ERROR ; IF RECOVERY, THEN DO NOT RETURN END-OF-TAPE ERROR MOVL# 1,1,SNC ; CHECK FOR BACKSPACE ADDZL# 1,1,SZC ; CHECK FOR ERASE JMP ICON ; ERASE MODE, RETURN NORMAL ; FATAL ERROR, CHECK IF EOT. 5; AC0, AC1 MAY BE GARBAGE (SEE XFATAL) FATAL: LDA 0,BQDST,2 ; DEVICE STATUS XLDA 3,= ET ;CHECK FOR EOT AND# 3,0,SNR ; JMP NCON ; NO--CONTINUE ; SET THE EOT BIT IN THE UNIT DCB LDA 3,BQDCB,2 ; DCB LDA 3,DCBDR,3 ; UNIT DCB IF DIRECT (TO SYS BUFFER) XLDA 0,= QTIND ; 'RDOS' INDIRECT BIT AND# 1,0,SZR LDA 3,BQNBK,2 ; UNIT DCB IF INDIRECT LDA 1,DCBST,3 ; GET THE DCB STATUS XLDA 0,= -1-STEOT ; EOT BIT FOR DCB STATUS AND 0,1 ; CLEAR THE EOT BIT ADC 0,1 ; SET THE EOT BIT STA 1,DCBST,3 ; ? LDA 0,BQDST,2 ; RESTORE DEVICE STATUS ; SET THE ERROR BIT IN THE BUFFER STATUS WORD NCON: LDA 1,BQST,2 XLDA 3,= QTER ; ERROR BIT FOR BUF STATUS ADDZ 3,1 ; SET ERROR BIT ; IF 'RDOS' DIRECT, UNPEND AND GET THE NEXT REQUEST XLDA 3,= QTIND ; 'RDOS' INDIRECT BIT dS AND# 1,3,SNR ; INDIRECT? JMP NOIN ; NO - UNPEND, GET NEXT REQUEST STA 1,BQST,2 ; SAVE STATUS .IFE IOSW ; NOT INFOS ; 'RDOS' INDIRECT, GO GET ADDR, AND SET DONE IN STATUS JMP INDI .ENDC IFSMM ; INFOS ; IF COMMAND WAS A READ THE CHECK THE EOF BIT XLoDA 3,= CMMSK ; COMMAND MASK AND# 1,3,SNR ; IS COMMAND A READ? JMP RD ; YES ; IF NOT EOT ERROR, THEN DO NOT SET ERROR BIT, OR DEQUEUE XLDA 3,= ET ; EOT ERROR BIT JMP DQCK ; YES-- DEQUE THE BEASTS ; IF NOT EOF ERROR, THEN DO NOT SET ERROR BIT, OR DEQUEUE RD: XLDA 3,= EF ; YES DQCK: AND# 3,0,SNR ; IS ERROR AN EOF? JMP INDI ; NO - DON'T DEQUE ; DEQUEUE IF DEQUEUE BIT SET AND EITHER EOF ON READ OR ; EOT ON WRITE LDA 0,BQUST,2 ; YES - GET USER STATUS XLDA 3,= 1B13 ; DEQUEUE BIT AND# 0,3,SNR ; IrS IT SET? JMP INDI ; NO - GET NEXT REQUEST ADDL 0,0 ; SET CARRY FROM UNPEND BIT MOV 2,0,SNC ; UNPEND? XXJSR UNPEND ; GO UNPEND THE BUFFER XLDA 3,= -QTIOP-1 ; I/O IN PROGRESS BIT AND 1,3 ; RESET IO IN PROGRESS STA 3,BQST,2 ; UPDATE STATUS XXJSR8> XDIB ; GET C(ADDRESS REGISTER) STA 0,BQARD,2 ; RETURN IN BUFFER HEADER ISZ BQUST,2 ; SET DONE IN USER STATUS LDA 3,BQNBK,2 ; GET MASTER DCB POINTER .IFN STER-1B15 :; STER HAS BEEN RE-DEFINED !! .ENDC XLDA 0,= DCBST*16.+15. ; STER = 1B15 BTO 3,0 j; SET ERROR BIT IN DCB LDA 0,BQUN,2 ; YES - MUST DQ ALL REQUESTS ; FOR THIS UNIT LDA 1,BQQLK,2 ;UNLINK THE FIRST ONE LDA 2,BQDCT,2 ; START AT HEAD OF Q NBUF: STA 1,DCCRQ,2 MOV 1,3 ; GET FIRST BUF ON Q COM# 3,3,SNR ; ANYONE THERE? RTRN ; NO - 4GO HOME LDA 1,BQUN,3 ; GET ITS UNIT NUMBER SUB# 0,1,SZR ; SAME AS ERROR BUF? JMP NOMAT ; NO - GET NEXT BUF LDA 1,BQQLK,3 ; YES - GET ITS LINK ISZ BQUST,3 ; SET DONE ... ISZ BQUST,3 ; .. AND I/O SUSPENDED ISZ BQUST,3 ; .. IN USER STATUS JMPO NBUF ; AND START AGAIN NOMAT: MOV 3,2 ; ADVANCE TO NEXT BUFFER LDA 3,BQQLK,2 ; GET ITS LINK NXBF: COM# 3,3,SNR ; END OF CHAIN? JMP MTNX1 ; YES LDA 1,BQUN,3 ; NO - GET UNIT NUMBER SUB# 0,1,SZR ; SAME AS ERROR BUF? JMP NOMAT ; NO - LOOK AT NEXT5 BUF ISZ BQUST,3 ; YES - SET 1B15 AND ISZ BQUST,3 ; 1B14 (USER DONE AND ISZ BQUST,3 ; I/O SUSP) IN USER STATUS LDA 3,BQQLK,3 ; LINK TO NEXT BUF STA 3,BQQLK,2 ; PUT IN CHAIN JMP NXBF ; GO AGAIN MTNX1: LDA 2,BQDCT,2 ; GET THE DCT ADDRESS LDA 2,DCCRQ,2 ; GET THE NEXT REQUEST JMP MTNXT ; GO CHECK IF ANY MORE BUFFERS [IFSMM] ; HERE ONLY IF BAD-TAPE, PARITY-ERROR, OR DATA-LATE NONFTL: MOVZL 1,1,SNC ; IN BACKSPACE MODE? MOVZL# 1,1,SZC ; IN ERASE MODE? JMP FTL ; SUCH AS BAD-TAPE ON BACKSPACE-READ XLDA 3,= CMMSK*2 ; GET COMMAND MASK ANDS 1,3,SNR ; GET COMMAND JMP CRD ; COMMAND WAS READ, RETRY ; IF GET STATUS COMMAND, THEN DO NOT RETRY, FATAL XLDA 0,= STATUS*1B12 ; GET STATUS CODE SUB# 3,0,SNR ; IS IT? JMP FTL ; YES - DON'T RETRY ; IF )BACKSPACE COMMAND, THEN DO NOT RETRY, FATAL ; ALSO SPACE FORWARD AND REWIND XLDA 0,= SPREV*1B12 ; BACKSPACE COMMAND SUBZ 3,0,SZC ; USGT, RETRY NECESSARY? JMP FTL ; NOT TODAY ; MUST HAVE BEEN WRITE OR WRITE-EOF COMMAND ; DECREMENT THE RETRY COUNT AND SET THE ERASE-COMMAND BIT DSZ BQERC,2 ; TRIED ENUF? ADDOR 1,1,SKP ; SET ERASE BIT JMP FTL ; NO HOPE ; SET THE BACKSPACE-COMMAND BIT, SAVE IT AND TRY TO RECOVER .QE: MOVOR 1,1 ; SET BACKSPACE BIT .EQ: STA 1,BQST,2 ; UPDATE THE STATUS XJMP MST1 ; RES }TART MAG-TAPE ; IT WAS A READ, CHECK IF ANY RETRYS LEFT CRD: DSZ BQERC,2 ; ANY LEFT? JMP .QE ; SET BACKSPACE BIT AND RESTART ; RESET THE BACKSPACE-COMMAND BIT FTL: MOVZR 1,1 ; RESET BIT POSITION STA 1,BQST,2 ; SAVE THE STATUS WORD JMP FATAL ; DID N2%OT RECOVER ; RESET THE BACKSPACE AND ERASE COMMAND BITS ERAMD: ADDL 1,1 ; SHIFT LEFT TWO PLACES MOVZR 1,1 ; CLEAR ERASE BIT MOVZR 1,1,SKP ; CLEAR BACKSPACE BIT ERRMD: ADDOR 1,1 ; CLEAR BACKSPACE BIT ; GO TRY TO RECOVER JMP .EQ LPOOL ; ALL ENTRIES ON THIS PAGE HANDLE DIRECT BUFFERS ONLY, ; IE., BQST(QTIND) = 0. ; ROUTINE TO EXECUTE A MNEMONIC TAPE COMMAND ; ; INPUT: AC2 - BUFFER ADDRESS ; READ/WRITE A RECORD, COUNT IS 257 (-401 BASE 8) ; ODD PARITY, 257 WORDS ; RETURN AC3 = CSP ; DESTROYS AC0, :cAC1 ; RET TO CALL +2 IF OK ; RET TO CALL +1, WITH ERROR CODE IN CELL, AND ; BUFFER USE COUNT DECREMENTED, IF ERROR RDRCD: SUB 1,1,SKP ; READ A RECORD WTRCD: XLDA 1,= WRITE*1B12 ; WRITE A RECORD XLDA 0,= -401&77777 ; -401 WITH 1B0 RESET `JMP EXCMD ; SPACE RECORD, CNT = -1 WITH 1B0 RESET ; RET TO CALL +1, WITH ; AC0 = DEVICE STATUS ; AC1 = EOF TEST BIT ; AC3 = CSP SFRCD: ADCZR 0,0,SKP ; SPACE FORWARD 1 RECORD ; SPACE FILE, CNT = 0 (INFINITE), WITH 1B0 SET SFFIL: SUBZR 0,0 ; SPACE FORWARID 1 FILE XLDA 1,= SPFOR*1B12 ; SPACE FORWARD COMMAND JMP EXCMD ; GO EXECUTE THE COMMAND ; REVERSE RECORD, CNT = -1 WITH 1B0 RESET ; SAME RULES AS SPACE FORWARD SBRCD: ADCZR 0,0,SKP ; SPACE BACKWARD 1 RECORD ; REVERSE FILE, CNT = 0 (INFINITE) WITH 1B0S SET SBFIL: SUBZR 0,0 ; SPACE BACKWARD 1 FILE XLDA 1,= SPREV*1B12 ; SPACE REVERSE COMMAND JMP EXCMD ; GO EXECUTE THE COMMAND ; WRITE AN END-OF-FILE ; RETURN AC3 = CSP ; OTHERS SAVED ; RET TO CALL +2 IF EOF ; RET TO CALL +1 WITH ERROR CODE IN CELL, BUFQFER USE ; COUNT DECREMENTED IF NOT EOF ; NOTE IF EOT, BUT OTHERWISE SUCCESSFUL, TAKES SUCCESS RETURN WTEOF: RSAVE 1 ; SAVE ROOM FOR A COUPLE OF TMPS ; GET THE STATUS JSR GSTAT ; CHECK IF 7 OR 9 TRACK TAPE, 1B9 = 1 FOR 9 TRACK MOVS 0,0 X.LDA 1,= WREOF*1B12 ; 9 TRACK EOF COMMAND ADDL 0,0,SNC ; 7 OR 9 TRACK UNIT XLDA 1,= WREOF*1B12+1B9 ; 7 TRACK, EVEN PARTY SUB 0,0 ; WORD COUNT OF ZERO JMP EXCM1 ; GO EXECUTE THE COMMAND ; RETURN THE STATUS ; RET TO CALL +1, AC0 = DEVICE STATUS ; a AC1 = DESTROYED ; AC3 = CSP GSTAT: XLDA 1,= STATUS*1B12 ; GET STATUS COMMAND (ERASE) JMP EXCMD ; GO EXECUTE THE COMMAND ; REWIND THE MAG-TAPE ; RET TO CALL +1 ; AC3 = CSP ; OTHERS SAVED REWND: RSAVE 1 ; SAVE ROOM FOR A COUOPLE OF TMPS XLDA 1,= REWIND*1B12 ; REWIND JMP EXCM1 ; GO EXECUTE THE COMMAND LPOOL ; DEFINE DISPLACEMENTS ON STACK FOR TEMP STORAGE ; ; AC0 = WORD COUNT ; ; AC1 = COMMAND ; ; AC2 = BUFFER HEADER ADDRESS RTPTR=TMP ; EXECUTE THE COMMAND EXCMD: RSAVE : 1 EXCM1: STA 0,BQWC,2 ; SAVE THE WORD COUNT LDA 0,BQST,2 ; STATUS WORD XLDA 3,= -1-CMMSK-PARCM-ESNEX-BKNEX ; CLEAR STATUS ANDS 3,0 ; CLEAR COMMAND BITS & SWAP MOVZR 1,1 ; ACCOMODATE PARITY BIT ADDS 1,0 ; ADD COMMAND & SWAP STA 0,BQST,2 ; UPDATE S!TATUS XXJSR QUENT ; QUEUE IT MOVZR 1,1 ; 2*COMMAND (MODULO 8) XLDA 0,= 17 ; PARITY BIT MASK AND 0,1 ; CLEAR PARITY BIT LDA 0,RTNTB ; RETURN TABLE POINTER ADD 0,1 ; FORM RETURN INDIRECT STA 1,RTPTR,3 ; SAVE RETURN TABLE PTR ON STACK WLP: INTDS  ; NO INTERRUPTS, PLEASE LDA 0,BQST,2 ; GET BUFFER STATUS XLDA 1,= QTIOP ; I/O IN PROGRESS BIT AND# 0,1,SNR ; IS I/O IN PROG? JMP WLP1 ; NO, DON'T PEND WLP0: MOV 2,1 ; BUFFER ADDRESS IS PEND KEY XLDA 0,= 5 ; 5 SECOND WAIT XXJSR PEND ; PEND REQUpEST FOR 5 SECONDS NOP ; IGNORE TIME OUT LDA 3,CQ ; GET CURRENT QUEUE LDA 3,QSTAT,3 ; GET QUEUE STATUS XLDA 0,= TSAB ; ABORT STATUS BIT AND 3,0,SNR ; IS BIT SET? JMP WLP ; NO, WE'RE DONE ; WAIT FIVE MORE SECONDS TO GIVE CHANCE FOR OP TO FINISH I>NTDS MOV 2,1 ; BUFFER ADDRESS IS PEND KEY XLDA 0,= 5 ; 5 SECOND WAIT XXJSR PEND ; PEND REQUEST FOR 5 SECONDS NOP ; IGNORE TIME OUT ; ABORT WAS SET, CLEAR DEVICE IF NECESSARY, AND ABORT INTDS LDA 3,BQDCT,2 ; GET DCT ADDR LDA 1,DCCRQ,3 ; CURRENT = 2? JMP NES ; NOPE STA 3,BFTP1,2 ; YES, SAVE THE COUNT LDA 3,MXLSZ ; LINE SIZE IN BYTES INIT: STA 3,SEGSZ,2 ; THAT'S THE SEGMENT SIZE LDA 1,BETSZ ADD 2,1 ; LINK WORD ADDRESS OF FIRST SEG STA 1,BYCT,2 ; INTO THE BET (TEMPORARY) SUB 0,0 ; UNARY ZERO STA 0,IOAQ,2 ; CLEAR THE QUEUES STA 0,IODQ,2 STA 0,ERFLG,2 ; CLEAR THE ERROR FLAG INTLP: MOV 1,3 LDA 1,C4 ADDZL 3,1 ; FIRST BYTE ADDRESS STA 1,FBA,3 STA 1,BP,3 ; BYTE POINTER LDA 0,SEGSZ,2 ; SEGMENT SIZE ADD 0,1 ; LIMIT OBYTE ADDRESS STA 1,LBA,3 ; INTO HEADER INCZR 1,1 ; WORD ADDRESS (ROUND UP) STA 1,LINK,3 ; SET THE LINK DSZ BFTP1,2 ; ANYMORE SEGMENTS? JMP INTLP ; YES SUB 1,1 ; NO STA 1,LINK,3 ; CLEAR THE LINK LDA 0,BFAC0,2 ; FILENAME BYTE POINTER LDA 1,CHRI[M,2 ; CHARACTERISTIC MASK LDA 3,CHNBR,2 ; CHANNEL # LDA 2,CHMSK ; CHANNEL # MASK AND 3,2 .SYSTM .OPEN CPU JMP NES+1 LDA 2,USP ; USP MAY NOT BE .SAC3 LDA 0,PRCHN,2 ; RECOVER PRIORITY LDA 1,PRIMK ANDS 1,0 ; RETAIN IN RIGHT BYTE LDA 3,CHNBR,2 ; FLAG WORD LDA 1,BYCT,2 ; FIRST QUEUE ENTRY ADDL# 3,3,SZC ; READ OR WRITE ? STA 1,IOAQ,2 ; WRITE, PUT ON PROGRESS Q ADDL# 3,3,SNC ; TEST READ OR WRITE ? STA 1,IODQ,2 ; READ, PUT ON DORMANT Q LDA 1,TASK ; FWA OF TASK JSR @T?ASK JMP NES+1 JMP @RTN91 DIVI: STA 3,BFTP0,2 SUB 3,3,SKP INC 3,3 SUBZ 1,0,SZC JMP .-2 ADD 1,0 JMP @BFTP0,2 T?ASK: T.ASK PRIMK: 177400 CHMSK: 77 SPERR: ERSPC BETSZ: BFTP1+1 C4: 4 TASK: .TSK .SAVX: .SAVE RTN1: .RTRN LPHSZ: SCLLG/2+HDRLT+1 MXLSZ: SCLLG+1 NES: LDA 2,SPERR 'ADC 1,1 .ERR: LDA 3,USP COM# 1,1,SNR STA 1,CHNBR,3 STA 2,BFAC2,3 DSZ PCCRY,3 DSZ PCCRY,3 JMP @RTN1 TRMTB: . 15 ; CARRIAGE RETURN 14 ; FORM FEED 0 ; NULL AND END OF TABLE ; BUFFER ACCESS ROUTINES BFACS: MOVL 3,3 ; PC+CARRY STA 3,PCCRY,2 2| LDA 3,CHNBR,2 MOVL# 3,3,SZC ; LINE OR SEQUENTIAL? LDA 1,MXLSZ ; LINE JSR @.SAVX LDA 0,BFAC0,2 STA 0,UBP,2 STA 1,BYCT,2 JMP BYTST ; GO CHECK FOR BYTE CNT=0 TRLP: LDA 3,IOAQ,2 ; IOAQ ENTRY MOV 3,3,SZR ; IS THERE A SEGMENT? JMP GO ; YES LDA 0T,SGAD0 ; NO ADD 2,0 ; FORM SIGNAL ADDRESS JSR @R?EC ; KICK THE TASK AND JMP TRLP  ; WAIT FOR FREE SEGMENT ; SEGMENT AVAILABLE FOR PROCESSING ON USER SIDE GO: LDA 3,BP,3 ; GET THE BYTE POINTER LDA 0,CHNBR,2 ; CHANNEL # ADDL# 0,0,SZC ; READ OR WR^ITE? LDA 3,UBP,2 ; WRITE, GET USER BYTE POINTER MOVR 3,3 ; ADDRESS + CARRY SWITCH LDA 0,0,3 ; SOURCE WORD LDA 1,BTMSK ; BYTE MASK ( RIGHT ) MOV# 0,0,SNC ; WHICH BYTE? MOVS 0,0 ; LEFT AND 1,0 ; ISOLATE THE BYTE (RIGHT JUSTIFIED) LDA 3,IOAQ,2 <; GET THE Q ENTRY LDA 1,CHNBR,2 ADDL# 1,1,SNC ; READ OR WRITE? ISZ BP,3 ; READ, BUMP SYSTEM POINTER ADDL# 1,1,SZC ; JUST CHECKING ISZ UBP,2 ; WRITE, BUMP USER POINTER STBYT: LDA 3,IOAQ,2 LDA 3,BP,3 ; GET THE BYTE POINTER ADDL# 1,1,SNC ; READ OlR WRITE LDA 3,UBP,2 ; READ, USER POINTER IS DESTINATION MOVR 3,3,SNC ;WORD PTR, CRY=BYTE INDIC MOVS 0,0 ;LOCATE NEW BYTE CORRECTLY LDA 1,0,3 ;GET WHAT'S THERE ALREADY STA 0,0,3 ;SAVE NEW BYTE THERE LDA 0,PRIMK ;RIGHT BYTE MASK MOV# 0,0,SNC ٘;IF NEW BYTE GOES INTO RIGHT MOVS 0,0 ; GET MASK TO SAVE LEFT AND 0,1 ;RETAIN BYTE NOT TO BE CHANGED LDA 0,0,3 ;RETRIEVE NEW BYTE ADD 0,1 ;COMBINE THEM STA 1,0,3 ;STORE THEM BOTH BACK LDA 3,IOAQ,2 LDA 1,CHNBR,2 ADDL# 1,1,SNC ; READ OR WRITEj? ISZ UBP,2 ; READ, BUMP USER POINTER ADDL# 1,1,SZC ISZ BP,3 ; WRITE, BUMP SYSTEM POINTER DSZ BYCT,2 ; DEC THE COUNT JMP .+1 ; NO CATASTROPHE LDA 1,CHNBR,2 MOVL# 1,1,SNC ; LINE OR SEQUENTIAL? JMP SEGTST ; SEQ, TEST SEGMENT LDA 3,TRMTB ; LINE=f, TEST FOR TERMINATOR TRMLP: INC 3,3 LDA 1,0,3 SUB# 1,0,SNR ; IS CHAR A TERMINATOR JMP TRMFD ; YES, KILL THE SEGMENT MOV# 1,1,SZR ; NO, END OF TABLE? JMP TRMLP ; NO, KEEP GOING JMP SEGTST TRMFD: LDA 3,IOAQ,2 LDA 0,BP,3 STA 0,LBA,3 ; SEGMENT I3+S DEAD SEGTST: LDA 3,IOAQ,2 LDA 0,BP,3 LDA 1,LBA,3 ADCZ# 0,1,SZC ; IS SEGMENT ALIVE? JMP BYTST ; YES, TEST THE COUNT LDA 1,LINK,3 ; NO MOVL# 1,1,SZC ; IS SEGMENT IN ERROR? JMP COMCT ; YES, COMPUTE THE BYTE COUNT LDA 1,IOAOF ; NO JSR DEQ ; REq3MOVE FROM ACTIVE Q LDA 1,ERFLG,2 ; GET ERROR FLAG MOV# 1,1,SZR ; ANY ERRORS? JMP NOQ ; YES, DROP SEGMENT ON FLOOR LDA 1,IODOF ; NO JSR ENQ ; PUT ON DORMANT Q LDA 0,SGAD1 ADD 2,0 ADC 1,1 JSR @X?MT LDA 2,USP ; ERROR RETURN IS A NO-NO NOQ: LDA p0,CHNBR,2 MOVL# 0,0,SNC ; LINE OR SEQ? JMP BYTST ; SEQ LDA 1,BFAC1,2 ; REQUESTED BYTE COUNT LDA 0,BYCT,2 ; CURRENT BYTE COUNT SUB 0,1 ; NUMBER OF BYTES TRANSFERRED STA 1,BFAC1,2 ; RETURN IN AC1 JMP .RTRN ; RETURN BYTST: LDA 0,BYCT,2 MOV# 0,0,SZR ; BYTE COUNTER SATISFIED? JMP TRLP ; NO LDA 0,CHNBR,2 ; YES, DONE LDA 3,IOAQ,2 MOVL# 0,0,SNC ; LINE OR SEQUENTIAL JMP COMCT ; SEQ, COMPUTE THE COUNT LDA 0,LINER ; LINE, GET LINE TOO LONG ERROR STA 0,LINK,3 ; FLAG SEGMENT IN ERROR COMCT: LDA 1,BFAC1,2 ; REQUESTED BYTE COUNT LDA 0,BYCT,2 ; CURRENT BYTE COUNT SUB 0,1 ; NUMBER OF BYTES TRANSFERRED STA 1,BFAC1,2 LDA 0,BP,3 LDA 1,LBA,3 SUBZ# 1,0,SNC ; END OF SEGMENT? JMP .RTRN ; NO LDA 0,LINK,3 ; YES, TEST FOR ERROR MOVL 0,0,SZC ; ANY ?TERRORS? JMP .RTNT ; YES JMP .RTRN ; NO SGAD0: BFTP0 BTMSK: 377 R?EC: R.EC X?MT: X.MT .RTNT: LDA 0,@IOAQ,2 MOVL 0,0 MOVZR 0,0 ; CLEAR BIT 0 STA 0,BFAC2,2 ; RETURN ERROR CODE DSZ PCCRY,2 ; RETURN ADDRESS & CARRY DSZ PCCRY,2 .RTRN: LDA 3,USP LDA- 3,PCCRY,3 ; GET RETURN ADDRESS MOVZR 3,3 ; RESTORE CARRY AND PC INC 3,3 ; POINT TO PROPER RETURN EN.SCHED ; SET SCHEDULER MODE IN MAPPED WORLD LDA 2,USP LDA 0,BFUSP,2 ; USP FROM BET STA 0,USP LDA 0,BFAC0,2 ; AC0 LDA 1,BFAC1,2 ; & AC1 LDA 2,BFAC2,2 ; & AC2 .TSAVE RE.SCHED SGAD1: BFTP1 IOAOF: IOAQ IODOF: IODQ LINER: 1B0+ERLLI ; ENQUEUE AN ENTRY ; ; AC0 - ADDRESS OF LINK WORD OF ENTRY ; ; AC1 - RELATIVE Q WORD ADDRESS ENQ: ADD 1,2 ; INDEX ON Q WORD LDA 1,0,2 ; GET CURRENT Q ENTRY MOV# 1,1,SNR ; IS Q EMPTY? JMP NOLNK ; YES MOV 1,2 ; NO, INDEX ON ENTRY ENQ1: LDA 1,LINK,2 ; GET LINK WORD MOV# 1,1,SNR ; IS THERE A LINK? JMP NOLNK ; NO MOVL# 1,1,SZC ; ERROR SEGMENT? JMP 0,3 ; YES, DON'T ENQUEUE MOV 1,2 ; INDEX ON LINK JMP ENQ1 ; GET NEXT ENTRY NOLNK: STA 0,LINK,2 ; PUT NEW ENTRY ON THE Q MOV 0,2 ; INDEX ON THE NEW ENTRY LDA 1,FBA,2 STA 1,BP,2 ; INIT THE BYTE POINTER SUB 0,0 LDA 1,LINK,2 ; GET LINK WORD MOVL# 1,1,SNC ; ERROR SEGMENT? STA 0,LINK,2 ; NO, CLEAR ITS LINK I0LDA 2,USP JMP 0,3 ; RETURN ; DEQUEUE AN ENTRY ; ; AC0 - ADDRESS OF ENTRY'S LINK WORD (RETURNED) ; ; AC1 - RELATIVE ADDRESS OF Q WORD DEQ: ADD 1,2 ; INDEX ON Q WORD MOV 2,1 LDA 2,0,2 ; GET CURRENT ENTRY MOV 2,0,SNR ; IS THERE AN ENTRY? JMP DEQRT } ; NO STA 1,BP,2 ; YES, SAVE Q WORD ADDRESS IN THE LDA 1,LINK,2 ; GET LINK WORD MOVL# 1,1,SZC ; SEGMENT IN ERROR? SUB 1,1 ; YES, CLEAR THIS Q LDA 2,BP,2 ; GET Q WORD ADDRESS STA 1,0,2 ; MAKE LINE THE CURRENT ENTRY DEQRT: LDA 2,USP JMP 0,3 ; I/:O PROCESSING TASK OF BUFFER PACKAGE .TSK: LDA 3,IODQ,2 ; DORMANT Q ENTRY MOV# 3,3,SZR ; ANY DORMANT SEGMENTS JMP SYSA ; YES LDA 0,SGAD1 ADD 2,0 ; SIGNAL WORD ADDRESS JSR @R?EC COM# 1,1,SZR ; -1 MEANS ANOTHER REQUEST JSR @K?ILL ; OTHERWISE CLOS.E FUNCTION JMP .TSK SYSA: STA 2,USP LDA 0,FBA,3 ; FIRST BYTE ADDRESS LDA 1,SEGSZ,2 ; SEGMENT SIZE LDA 3,CHNBR,2 LDA 2,.CMSK AND 3,2 ADDL# 3,3,SZC ; READ OR WRITE? JMP WRT ; WRITE MOVL# 3,3,SNC ; READ--LINE OR SEQ? JMP RDSQ .SYSTM ; LINE READ .RDL CPU JMP .TER0 JMP .TER0+1 RDSQ: .SYSTM ; SEQUENTIAL READ .RDS CPU .TER0: JSR ERGO LDA 2,USP JMP COMTK WRT: MOVL# 3,3,SNC ; LINE OR SEQ? JMP WRSQ .SYSTM ; LINE WRITE .WRL CPU JMP .TER1 JMP .TER1+1 WRSQ: .SYSTM ; SEQUENTIAL WRITE95 .WRS CPU .TER1: JSR ERGO LDA 2,USP LDA 1,SEGSZ,2 COMTK: LDA 3,IODQ,2 ADD 1,0 STA 0,LBA,3 ; INIT LIMIT BYTE ADDRESS LDA 1,IODOF JSR DEQ ; REMOVE FROM DORMANT Q LDA 1,IOAOF JSR ENQ ; PUT ON ACTIVE Q LDA 0,SGAD0 ; GET THE OFFSET ADD 2,0 ; FORLM THE ADDRESS ADC 1,1 JSR @X?MT ; SIGNAL THE PACKAGE LDA 2,USP ; ERROR RETURNS ARE A NO-NO JMP .TSK K?ILL: K.ILL ; BUFFER CLOSE FUNCTION PROCESSING BFCLS: MOVL 3,3 STA 3,PCCRY,2 JSR .SAVE LDA 0,CHNBR,2 COM# 0,0,SNR ; CHECK IF CHANNEL HAS BEENT OPENED JMP CHCL1 ; NO--JUST EXIT ADDL# 0,0,SNC ; READ OR WRITE? JMP CHCLS ; READ, JUST CLOSE THE CHANNEL SUB 0,0 ; CLEAR SIGNAL AREA STA 0,BFTP1,2 LDA 0,SGAD1 ; SIGNAL ADDRESS OFFSET ADD 2,0 ; SIGNAL WORD ADDRESS ADC 1,1 ; SIGNAL JSR @X?MTw@W LDA 2,USP ; VERY BAD LDA 3,IOAQ,2 ; NO LDA 1,LINK,3 MOVL 1,1,SZC ; ANY ERRORS JMP @RTN3 ; YES LDA 1,FBA,3 LDA 3,BP,3 SUB 1,3,SNR ; ACTIVE DATA COUNT JMP CHCLS ; NO DATA IN SEGMENT STA 3,SEGSZ,2 ; SAVE IN BET LDA 1,IOAOF JSR DEQ ; REMOVE CURRENT ENTRY LDA 1,IODOF JSR ENQ ; AND PUT ON DORMANT Q LDA 0,SGAD1 ADD 2,0 ADC 1,1 JSR @X?MTW LDA 2,USP ; CLOSE I/O CHANNEL--KILL I/O HANDLING TASK CHCLS: LDA 0,SGAD1 ADD 2,0 ; SETUP SIGNAL WORD ADDRESS SUBZL 1 1 ; SETUP TO KILL BUFFER TASpK JSR @X?MTW LDA 2,USP CHCL1: LDA 0,CHNBR,2 ADC 1,1 STA 1,CHNBR,2 LDA 2,.CMSK AND 0,2 ; CHANNEL NUMBER ONLY .SYSTM .CLOS CPU JMP @.ER1 JMP @RTN2 .CMSK: 77 .ER1: .ERR RTN2: .RTRN RTN3: .RTNT X?MTW: X.MTW ; ROUTINE TO SAVE STATUS OF CALLING TASKt IN BUFFER TABLE ;ON RETURN: ; AC0=0 ; AC1=ORIGINAL AC1 IN CALL ; AC2=ADDRESS OF FWA OF BUFFER TABLE .SAVE: STA 0,BFAC0,2 STA 1,BFAC1,2 STA 2,BFAC2,2 LDA 0,USP STA 0,BFUSP,2 STA 2,USP SUB 0,0 JMP 0,3 ;ERROR ROUTINE--SETS ERROR FLAG IN BUFFER TABLnE ERGO: MOVL 2,0 MOVOR 0,0 LDA 2,USP DSZ ERFLG,2 LDA 2,IODQ,2 STA 0,LINK,2 LDA 0,FBA,2 JMP 0,3 .END ; END OF BFPKG.SR IOPC.SR= 7h1.TITL IOPC .RB IOPC.RB .ENT .IOPC .EXTN I.OPC .ZREL .IOPC= JSR @. I.OPC .END ; END OF IOPC.SR OPCOM.SR=- 'k; THIS PROGRAM COMMUNICATES WITH THE OPERATOR AND EFFECTS CHANGES ; IN THE MULTI-TASKED ENVIRONMENT ; VALID MESSAGES ARE: ; *,FUNCTION,ARGUMENTS ; FUNCTIONS ARE: ; TST- TASK STATUS ; QUE- QUEUE A TASK TO RUN AT A TOD ; RUN- RUN A PROGRAM ONCE ; KIL- KILL A TASK ; PRI- CHANGE A TASK'S PRI ; SUS- SUSPEND A TASK ; RDY- READY A TASK ; DEQ- DEQUE A .QTSK REQ ; THE ARGUMENTS WILL BE A FUNCTION OF THE INDIVIDUAL CALL .TITL OPCOM .RB OPCOM.RB .ENT OPRD,I.OPC .EXTN STOC .EXTN I.DST,RDMSG,TSTBT .EXTN D./:QTSK .EXTN MBUF, T.IDS, T.IDP, T.IDK, T.IDR, Q.TSK .EXTN GBARG,GDARG .EXTN BINOC .EXTN T.WROP .EXTN EN.SCHED,.TSAVE .EXTN LPN.X .EXTD CTCB .NREL OPRD: LDA 3,.MBUF ; START OF FUNCTION ADDR LDA 2,.FTBL ; KNOWN FUNCTION TABLE OPNXT: LDA 0,CTLN ; LENGTH} OF FUNCTION ENTRY (NEGATIVE) SUB 0,2 ; POINT TO NEXT ONE LDA 0,0-FTBLN,2 ; GET 1ST WORD MOVL# 0,0,SZC ; END ? JMP @.INER ; ERROR LDA 1,1,3 ; TEXT SUB# 1,0,SZR ; SKIP IF MATCH JMP OPNXT ; MOVE ON LDA 0,1-FTBLN,2 ; SECOND WORD LDA 1,2,3 SUB#z 1,0,SZR ; SKIP IF MATCH JMP OPNXT LDA 0,C3 ; GET BP TO NEXT ARG ADDZL 3,0 ; SKIP OVER FIRST THREE WORDS JMP @2-FTBLN,2 ; GO TO ROUTINE FTBLN= 3 ; LENGTH OF EACH ENTRY .FTBL: .+1 .TXTM 1 .TXTN 1 .TXT /TST,/ STAT .TXT /QUE,/ TQUE .TXT /KIL,/ TKIL .TXT /PRI,/ TPRI .TXT /SUS,/ TSUS .TXT /RDY,/ TRDY .TXT /RUN,/ TRUN .TXT /DEQ,/ TDEQ ; TABLE TERMINATOR (1B0) AND ENTRY LENGTH CTLN: -FTBLN .TXTN 0 C3: 3 ; GET TASK STATUS ; FORMAT= TST,TID ; TID IS 1-377 OCTAL STAT: JSR @.GBARG ; CHECK TID JSR @I?DST ; GET STATUS LDA 3,C10 ; TID EXIST ? SUB# 3,0,SNR JMP TIDNF ; NO LDA 1,TPRST,2 ; GET PRI FOR BINOC LDA 2,CAB ADD 0,2 ; MAKE CHAR ASCII LDA 0,.SMSD ; ADDR OF SPACE FOR STATUS JSR @.STBT ; TO MSG LDA 0,.PRAD ; ADDR PRI FhIELD JSR @.BINOC ; CONVERT AND STORE LDA 0,.SMSG ; STATUS MSG CEXIT: ADC 1,1 ; FLAG AS NON-TASK MSG JSR @T?WROP ; WRITE OUT JMP FATAL JMP @.RDMSG ; ANOTHER INPUT C10: 10 .SMSG: SMSG*2 .SMSD: SMSG*2+5 .PRAD: SMSG*2+13 .BINOC: BINOC .RDMSG: RDMSG T?WROP: T.WROP T?IDK: T.IDK T?IDS: T.IDS T?IDR: T.IDR I?DST: I.DST FATAL: .SYSTM .ERTN JMP . ; KILL A TASK ; FORMAT: KIL,TID ; TID 1-377 TKIL: JSR @.GBARG ; CHECK TID JSR @T?IDK ; KILL IT JMP TIDNF ; NOT FOUND TOK: LDA 0,.TOKM JMP CEXIT .TOKM: TOKM*2 ; SUSPEND A TASK ; FORMAT: SUS,TID ; TID 1-377 TSUS: JSR @.GBARG ; CHECK TID JSR @T?IDS ; SUSPEND CALL JMP TIDNF JMP TOK ; READY A TASK ; FORMAT: RDY,TID ; TID= 1,377 TRDY: JSR @.GBARG ; CHECK TID JSR @T?IDR JMP TIDNF ; NOT FOUND JMP TOK TIDNF: LDA 0,.TNFM ; NOT FOUND MSG JMP CEXIT .MBUF: MBUF .TNFM: TNFM*2 .STBT: TSTBT .INER: INER CAB: "0 ; CHANGE A TASK'S PRI ; FORMAT: PRI,TID,NEW PRI ; TID= 1-377, NEW PRI = 0-377 TPRI: JSR @.GBARG ; CHECK TID STA 1,USP ; SAVE TID JSR @.GBARGۗ ; GET PRI-AC0= ADDR PRI LDA 3,C377 ; SEE IF TOO BIG SUBZ# 1,3,SNC JMP INER MOV 1,0 LDA 1,USP ; TID JSR @T?IDP ; CHANGE PRI JMP TIDNF ; TID ERROR JMP TOK ; EXIT ; QUEUE A TASK TO RUN EITHER AT ONCE OR AT A TOD ; FORMATS ARE: ; RUN,PROG#[,PR|I] ; QUE,PROG#,H,M,S,#TIMES TO RUN,INTERVAL[,PRI] ; H,M,S = STARTING TIME ; IF HOUR,MIN SEC NOT SPECIFIED, RUN NOW ; IF QNUM NOT SPECIFIED, RUN FOREVER... ; PRIORITY IS OPTIONAL ; ALL VALES ARE DECIMAL EXCEPT PRI TRUN: SUBZL 1,1,SKP ; FLAG TYPE TQUE: SUKB 1,1 STA 1,TYPE ; VALIDATE PROG# JSR @.GDARG ; GET NUMBER COM# 1,1,SNR ; IF NONE ERROR JMP INER STA 0,BPTMP ; BP TO NEXT ARGUEMENT LDA 2,PLIST ; LIST OF PROG MOV# 2,2,SZR ; SKIP IF UNDEFINED JMP PESR ; ENTER PROG SEARCH PFER: LDA 0,.PEMS JMP CEXIT .PEMS: PEMS*2 .GBARG: GBARG TYPE: 0 T?IDP: T.IDP PESR1: COM# 3,3,SNR ; END OF TABLE? JMP PFER ; YES, NO SUCH PROG # LDA 3,CPLEN ADD 3,2 ; ON TO NEXT ENTRY PESR: LDA 3,LPN,2 ; GET PROG # IN TABLE SUB# 1,3,SZR ; RIGHT ONE? JMP PESR1 ; NO4, CHECK IF DONE STA 2,USP ; SAVE ADDR PTBL ENTRY ; LOOK FOR A QUEUE AREA LDA 0,NQ ; - NUMB QUEUES LDA 2,QPOOL ; FIRST ONE ; QTLNK=0 FLAGS AN AREA AS FREE GQ1: LDA 1,QTLNK,2 MOV# 1,1,SNR ; SKIP, IF QUE AREA IS NOT FREE JMP GQ2 LDA 3,.QLN ADD 3,2 ^ INC 0,0,SZR ; END OF ROAD ? JMP GQ1 LDA 0,.QAMS ; NO AREA AVAIL CEXT1: JMP CEXIT GQ2: STA 2,QADDR ; SAVE ADDR LDA 3,USP ; PTBL ENTRY LDA 1,LPN?X ; PICK COUNT NEG 1,1,SNR ; SKIP IF EXTENDER EXISTS JMP TEXIT TLOOP: LDA 0,LPEX,3 ; TRANSFER A WOR:"D STA 0,QPEX,2 INC 3,3 ; INC TO NEXT INC 2,2 ; ENTRY INC 1,1,SZR ; COUNT LPN.X WORDS JMP TLOOP TEXIT: LDA 2,QADDR ; RESTORE THE ADDRESS LDA 3,USP LDA 1,LOV,3 ; OVERLAY NUM OR -1 STA 1,QTOV,2 ; TO QUEUE AREA LDA 1,LPC,3 ; PC STA 1,QPC,2 LDA 1,LCOND,3 STA 1,QCOND,2 ; CONDIONAL LOAD LDA 0,BPTMP ; RESTORE 0, BYTE POINTER TO ; NEXT ARGUMENT DSZ TYPE ; RUN ? JMP QUE1 ; NO-QUEUE ADC 1,1 STA 1,QSH,2 ; FLAG AS RUN NOW SUBZL 1,1 STA 1,QNUM,2 ; DO IT ONCE ; SEE IF PRI SPEC TQEX: JSR @ͳ.GBARG ; GET NEXT ARGUEMENT LDA 2,USP LDA 0,LTPR,2 ; CURRENT PRI COM# 1,1,SNR ; OP SPECIFY PRI ? JMP RUN1 ; NO LDA 3,C377L AND# 1,3,SZR JMP INER ; BAD PRI AND 3,0 ADD 1,0 ; ADD IN NEW PRI RUN1: LDA 2,QADDR ; ADDR QUEUE AREA STA 0,QPRI,2 ; TO AREA JSR @Q?TSK ; ENQUE JMP QER JTOK: JMP TOK QER: LDA 2,QADDR ; Q AREA SUB 0,0 STA 0,QTLNK,2 ; FREE IT LDA 0,.QEMS JMP CEXT1 .GDARG: GDARG .QEMS: QEMS*2 BPTMP: 0 QADDR: 0 .QAMS: QAMS*2 Q?TSK: Q.TSK INER: LDA 0,.IEMS JMP CEXT1 .IEMS: IEMS*2 uC377L: 177400 C377: 377 QUE1: JSR GQARG ; GET HOURS ; AC1= HOURS ; NOTE: NO HOURS SPECIFIED RETURNS A -1 STA 1,QSH,3 JSR GQARG ; GET MIN MOVZL 1,1 ; X 60 TO SEC MOVZL 1,1 MOVZL 1,2 MOVZL 2,2 MOVZL 2,2 MOVZL 2,2 SUB 1,2 ; =X60 STA 2,QSMS,3 ; S^AVE TMP JSR GQARG ; GET SEC LDA 2,QSMS,3 ADD 1,2 STA 2,QSMS,3 ; NOW = SEC IN HOUR TO START LDA 1,QSH,3 ; GET HOUR AGAIN ADD# 1,2,SZR ; TIME = 0? JMP QUE2 ; NO, LEAVE AS IS ADC 1,1 ; YES, SET RUN IMMEDIATE STA 1,QSH,3 QUE2: JSR GQARG ; GET NU/7M TIMES TO EXEC MOV# 1,1,SNR ; IF NO ARG STORE -1 ADC 1,1 STA 1,QNUM,3 JSR GQARG ; GET INTERVAL STA 1,QRR,3 JMP TQEX ; FINISH UP IN COMMON RUN CODE ; REQ TO DEQUE A QUE REQ ; FORMAT: DEQ,TID TDEQ: JSR @.GBARG ; GET TID JSR @D?QTSK ; DEQUE IT  JMP @.TIDNF ; TID ERR JMP JTOK .TIDNF: TIDNF PLIST: 0 D?QTSK: D.QTSK .LEN: LTLN CPLEN: LTLN ; STORED OVER BY .IOPC QPOOL: 0 LPN?X: LPN.X .QTLN: QTLN .QLN: QTLN ; STORE OVER BY .IOPC NQ: 0 ;INIT OP PROG RUNNING ; USER AC0= ADDR QUEUE AREA ; AC1= CHAQN FOR OVLYS+# QTBLS ; AC2= ADDR PROG TABLE ; PROG TABLE FORMAT: ; +0(LPN)- PROG NUMBER ; +1(LOV)- OVERLAY # OR -1 IF RESIDENT ; +2(LCOND)- COND/UNCOND OVLY LOAD ; +3(LTPR)- TID+PRI ; +4(LPC)- STARTING PC ; +5(LPEX) - START OF EXTENSION I.OPC: INC 3,3 ; A SSUME GOOD RETURN EN.SCHED .TSAVE STA 0,QPOOL ; SET QUEUE AREA BASE LDA 0,LPN?X ; DETERMINE QUEUE LENGTH LDA 3,.QTLN ADD 0,3 STA 3,.QLN LDA 3,.LEN ; AND PROGRAM TABLE SIZE ADD 0,3 STA 3,CPLEN LDA 3,C377 AND 1,3 ; GET NUMBER OF QUEUE FRAMEShp NEG 3,0,SNR ; SKIP IF >0, I.E., RUN, QUE/DEQ JMP @.STOC ; INIT TCB STA 0,NQ ; - # QUEUE FRAMES LDA 3,C377L ANDS 3,1 ; CHAN # TO 1 LDA 3,QPOOL ; BASE IQ02: SUB 2,2 ; INIT POOL STA 2,QTLNK,3 ; FLAG AS FREE STA 1,QOCH,3 ; SET CHANNEL LDA 2,.QLN ; BUMP ADD 2,3 INC 0,0,SZR JMP IQ02 LDA 3,CTCB LDA 2,TAC2,3 STA 2,PLIST ; SET BASE, VALIDATE RUN/QUE JMP @.STOC .STOC: STOC ; GET AN ARG FOR TOD QUEUE GQARG: STA 3,GQRT JSR @.GDARG ; GET DEC ARG COM# 1,1,SNR  ; MUST HAVE AN ARG JMP INER LD-6A 3,QADDR ; FOR ARG STORE-QUE AREA JMP @GQRT GQRT: 0 .NOLOC 1 SMSG: .TXT /STAT= ,PRI= / ; (3 DIGITS + 1 SPACE ; FROM BINOC) QAMS: .TXT /NO QUEUE AREA/ TOKM: .TXT /OK/ TNFM: .TXT /TID NOT ACTIVE/ IEMS: .TXT /INPUT ERROR/ QEMS: .TXT /ILLOGICAL QUEEUE/ PEMS: .TXT /PROG NOT FOUND/ .NOLOC 0 .END ; END OF OPCOM.SR TRDOP.SR= :o^.TITL TRDOP .RB TRDOP.RB .ENT .TRDOP .EXTN T.RDOP .ZREL .TRDOP= JSR @. T.RDOP .END ; END OF TRDOP.SR TWROP.SR= :o3.TITL TWROP .RB TWROP.RB .ENT .TWROP .EXTN T.WROP .ZREL .TWROP= JSR @. T.WROP .END ; END OF TWROP.SR OPMSG.SR=6 n .TITL OPMSG ; OPERATOR MESSAGE MANAGER .RB OPMSG.RB .ENT TSTBT,GDARG,GBARG .ENT BINOC,STOC,MBUF .ENT T.WROP,T.RDOP,RDMSG .EXTN SYST1,OPRD,USTAD,.SAC3,ID.SRCH .EXTN EN.SCHED,RE.SCHED,ER.SCHED,.TSAVE .EXTN INT.DS,INT.EN .EXTD CTCB .TXTM 1 .NREL ; ?WRITE AN OP MSG WITH OPTIONAL TASK ID PREFIX ; IF AC1=-1, AC0=BP TO MSG SENT AS IS ; IF AC1=<>-1, AC0=BP TO MSG WHOSE FIRST 4 CHARS GET ; OVERWRITTEN WITH TASK ID T.WROP: INC 3,3 ; ASSUME GOOD RETURN EN.SCHED .TSAVE COM# 1,1,SNR JMP TWR1 LDA 1,TID,3 JSR BINOC ; MOVE TO MSG ; NOTE: BINOC UPDATES AC0 BUT NOT TAC0 LDA 3,CTCB ; CALLER TWR1: LDA 1,TWR2 ; .WROP SYSTEM CALL JMP @.+1 SYST1 ; TO TCBMON TWR2: .WROP ; THE FOLLOWING ROUTINES ARE NOT RE-ENTRANT - USE WITH CARE!!! ;ROUTINE TO CONVERT 1ɴ BYTE BINARY TO ;ASCII DIGITS AND STORE ;AC1=NUMBER, AC0=BP TO STORE ;3 OCTAL DIGITS + 1 SPACE ARE STORED ;AND AC0 IS UPDATED BINOC: STA 3,BRTN LDA 3,C300 ANDZL 1,3 ; DROP ALL BUT 8,9 MOVZL 3,3 LDA 2,C60L ; 60*400 ADDS 3,2 ; =0,1,2,3 ASCII JSR ST,BT ; TO USER AREA LDA 3,C70 ; 2ND BYTE ANDZR 1,3 ; POSITION MOVZR 3,3 MOVZR 3,3 LDA 2,C60 ADD 3,2 ; GET ASCII JSR STBT ; TO USER MSG LDA 3,C7 ; LAST DIGIT AND 1,3 LDA 2,C60 ; GET ASCII ADD 3,2 JSR STBT LDA 2,C40 ; SP JSR STBT JMP @BRDTN C60L: "0*400 C300: 300 C70: 70 BRTN: 0 C40: 40 ;AC2=CHAR TO STORE, AC0=BP, AC1,0 PRESERVED ;AC0 IS INCED FOR RTN STBT: STA 3,STS3 STA 1,STS1 ; SAVE 1 STA 0,STS0 ; SAVE 0 LDA 1,C377 MOVZR 0,3,SZC ; LEFT OR RIGHT MOVS 1,1 ; RIGHT LDA 0,0,3 ;& CURRENT AND 1,0,SNC ; SAVE OTHER BYTE MOVS 2,2 ; FLIP TO POSITION ADD 2,0 ; MERGE STA 0,0,3 ; RETURN TO LOC LDA 1,STS1 ; RESTORE AC'S LDA 0,STS0 INC 0,0 JMP @STS3 C377: 377 STS1: 0 STS0: 0 STS3: 0 ; ROUTINE TO LOAD A BYTE ; AC0= BP AND IS I4NCED ON RTN ; AC2= CHAR ON RTN LDBT: STA 3,STS3 MOVZR 0,3 ; REAL ADDR LDA 2,0,3 ; CONTENTS LDA 3,C377 MOV# 3,3,SNC ; SKIP IF RIGHT BYTE MOVS 2,2 AND 3,2 ; DROP OTHER BYTE INC 0,0 ; NEXT ADDR JMP @STS3 ; BYE... TSTBT= STBT ;THIS ROUTINE ACCEPTS A READ OPERATOR ;REQUEST FROM A USER TASK ;THE USER TASK IS PENDED WITH TSRDOP ;AC0=MSG AREA FOR MSG (BP) ;ROUTINE WILL STRIP TID AND COMMA DELIMITER ;IF NO USER TASK HAS ISSUED A RDOP FOR ;THE TID, THE MSG WILL BE REJECTED AND THE OPERATOR NOTIFIED Υ T.RDOP: INC 3,3 ; ASSUME GOOD RETURN EN.SCHED .TSAVE LDA 2,FTIME ; FIRST TIME MOV# 2,2,SNR ; SKIP IF NO JSR FT01 ; SET UP READ TCB ; AC3 <= CTCB BY FT01 LDA 1,TPRST,3 ; PEND CALLER LDA 0,CRPND ; TSRDOP ADD 0,1 STA 1,TPRST,3 RE.SCHED CRPND: TSRDOP ;THIS CODE OPERATES AS A USER TASK THAT ;RESPONDS TO .RDOP MSGS ;WHEN AN INPUT IS RECEIVED, THE ROUTINE ;LOOKS FOR A MATCH ON TID AND UNPENDS MATCHING TASK ;IF FIRST 2 CHARS ARE "*,", MSG IS FOR OP COMM ROUTINE RDMSG: LDA 0,.MBUF .SYSTM .RDOP\ JMP RDOER ; BAG IT ADD 0,1 ; POINT PAST TERMINATOR STA 1,TEMP ; SAVE POINTER ;SEE IF OPCOM INPUT OR NUMERIC LDA 2,MBUF LDA 1,CASK ; *, SUB# 1,2,SNR JMP OPM ; OP COMM INPUT JSR @.GBARG ; GET TID IN AC1, STEP AC0 JSR RDMS1 ; PSUEDO-TASK CALL TO UNPEND CALLER JMP RDER2 ; COULDN'T FIND ONE JMP RDMSG ; WAIT AGAIN RDMS1: INC 3,3 ; ASSUME GOOD RETURN EN.SCHED .TSAVE ID.SRCH ; SEARCH FOR AC1=TID ER.SCHED ; NOT FOUND (ERROR CODE ; NOT NEEDED) LDA 1,TPRST,2 ; SEE IF RDOP LDA 3,CRPN>D ; TSRDOP AND# 3,1,SNR ; IS HE WAITNG FOR .TRDOP? ER.SCHED ; NOT WAITING ON .RDOP LDA 1,TEMP ; POINTER PAST TERMINATOR SUB 0,1 ; COUNT EXCLUDING TID AND ; COMMA STA 1,TAC1,2 ; PASS TO USER NEG 1,1 LDA 3,TAC0,2 ; BP STA 3,UBTMP ; SAVE ST A 2,TEMP ; SAVE TCB ADDR- ALL DONE WITH PTR ;AC0= MBUF NEXT BYTE NXTBT: JSR LDBT ; GET BYTE STA 0,BRTN ; SAVE INCED BP LDA 0,UBTMP JSR STBT ; TO USER STA 0,UBTMP ; SAVE LDA 0,BRTN ; SOURCE BP INC 1,1,SZR ; DONE? JMP NXTBT INT.DS ; (UNPENDING SOMEONE ELSE) LDA 2,TEMP ; TCB MSG SENT TO LDA 1,TPRST,2 ; UNPEND IT LDA 0,CRPND ; MASK SUB 0,1 ; CLEAR TSRDOP BIT STA 1,TPRST,2 ; YOUR MSG IS HERE INT.EN RE.SCHED .MBUF: MBUF*2 CASK: '*,' UBTMP: 0 TEMP: 0 .GBARG: GBARG OPM: JSR @.OPRD ; GO - RTN WILL BE TO RDMSG RDER2: LDA 0,.EMS2 ; UNLESS OPRD IS UNDEFINED JMP RDER RDER1: LDA 0,.EMS1 RDER: ADC 1,1 JSR @T?WROP ; WRITE MESSAGE JMP RDOER ; ?? JMP RDMSG ; .RDOP RDOER: .SYSTM .ERTN JMP . T?WROP: T.WROP FTIME: 0 .EMS1: EMS1*2 .EMS2: EMS2*2 .OPRD: OPRD C60: "0 C7: 7 MBUF=. ; THIS ROUTINE IS USED ONCE...IT WILL BE OVERWRITTEN AS PART OF BUF ;GET TCB AND ISSUE RDOP REQ FT01: STA 3,FTRTN LDA 2,@.FC COM# 2,2,SNR ; ANY TCB'S AVAILABLE? JMP TSKER ; NO - ERROR STA 2,FTIME ; SAVE LDAo 1,TLNK,2 ; REMOVE FROM LIST STA 1,@.FC ; UPDATE FREE CHAIN LDA 1,.RDPC ; INITIAL PC STA 1,TPC,2 SUB 0,0 ; PRI=0 STA 0,TPRST,2 STA 0,TID,2 ; TID=0 STA 0,TELN,2 ; NO EXTENDED SAVE/RESTORE STA 0,TKLAD,2 ; NO KILL PROCESSOR EITHER LDA 3,@.AC ; GkcET HEAD OF ACTIVE CHAIN STA 3,TLNK,2 ; PUT IT AFTER RDMSG TASK STA 2,@.AC ; PUT RDMSG AT HEAD OF CHAIN LDA 3,CTCB ; RESTORE FOR T.RDOP JMP @FTRTN ; CONTINUE TSKER: LDA 2,.TSKER ; NO MORE TCB'S ER.SCHED FTRTN: 0 .TSKER: ERNOT .RDPC: RDMSG*2 .FC: .GADD USTAD,USTFC .AC: .GADD USTAD,USTAC .BLK MBUF-.+(SCLLG/2)+1 ; RESERVE REST OF BUFFER EMS1: .TXT /INPUT ERROR/ EMS2: .TXT /TID NOT FOUND/ STOC: LDA 0,FTIME ; TCB SET UP YET MOV# 0,0,SNR ; SKIP IF YES JSR FT01 ; SET UP RE.SCHED ; GET AN ARG AND CONVERT FROM DEC OR OCT ASCII TO BIN ; AC0= BP ; ON RTN AC0 POINTS TO NEXT ARG, AC1= NUMBER GBARG: SUB 1,1,SKP ; FLAG AS OCT GDARG: SUBZL 1,1 ; FLAD AS DEC STA 1,GTYPE STA 3,GBRTN JSR @.LDBT ; GET BYTE LDA 3,CCR ; NO ARG ? SUB# 2,3,SNR JMP GNOAR ; NONE SUB 1,1 STA 1,NUMB ; INIT NUMBER GD1: LDA 3,CCR ; SEE IF END YET SUB# 2,3,SNR JMP ENDAR ; END OF INPUT LDA 3,COMMA SUB# 2,3,SNR JMP @GBRTN ; DONE LDA 3,GTYPE ; SEE IF OCT MOV# 3,3,SNR JMP GOCT ; YES LDA 3,C60 LDA 1,C71 ; SEE ѤIF DECIMAL CHAR ADCZ# 1,2,SNC ADCZ# 2,3,SZC JRER1: JMP RDER1 ; NOT DEC SUB 3,2 ; GET BITS LDA 1,NUMB ; CURRENT NUMBER MOVZL 1,3,SNC ; LOOK FOR OVERFLOW AND POSITION MOVZL 3,3,SZC JMP JRER1 ; OVERFLOW ADD 3,1,SNC ; MERGE MOVZL 1,1,SZC ; DEC 9NUMB JMP JRER1 ; TOO BIG GD2: ADD 2,1 ; NEW BITS IN STA 1,NUMB JSR @.LDBT ; NEXT JMP GD1 ; AGAIN SAM GOCT: LDA 3,C370 ; MASK AND 2,3 LDA 1,C60 SUB# 1,3,SZR ; SKIP IF OCTAL JMP JRER1 LDA 1,C7 AND 2,1 ; GET BITS LDA 2,NUMB ; CURRENT NUMBER MOVZL 2,2,SZC ; POSITION AND LOOK FORR OVERFLOW JMP JRER1 MOVZL 2,2,SNC MOVZL 2,2,SZC JMP JRER1 JMP GD2 ; JOIN COMMON CODE GNOAR: ADC 1,1 ; -1=NO ARG ENDAR: NEG 0,0 COM 0,0 ; BACK UP BP SO SEE CR AGAIN JMP @GBRTN ; RTN GBRTN: 0 NUMB: 0 GT^kYPE: 0 C71: "9 COMMA: ", C370: 370 CCR: 15 .STBT: STBT .LDBT: LDBT .END ; END OF OPMSG.SR TOVLD.SR= 9od.TITL TOVLD .RB TOVLD.RB .ENT .TOVLD .EXTN T.OVLD .ZREL .TOVLD= JSR @. T.OVLD .END ; END OF TOVLD.SR OVREL.SR= 8o`.TITL OVREL .RB OVREL.RB .ENT .OVREL .EXTN O.VREL .ZREL .OVREL= JSR @. O.VREL .END ; END OF OVREL.SR OVKIL.SR= 8oP.TITL OVKIL .RB OVKIL.RB .ENT .OVKIL .EXTN O.VKIL .ZREL .OVKIL= JSR @. O.VKIL .END ; END OF OVKIL.SR OVEX.SR= 8h.TITL OVEX .RB OVEX.RB .ENT .OVEX .EXTN O.VEX .ZREL .OVEX= JSR @. O.VEX .END ; END OF OVEX.SR TOVLY.SR=62 .TITLE TOVLY .RB TOVLY.RB .ENT T.OVLD,O.VREL,O.VKIL,O.VEX .EXTN K.ILL,.SAC3 .EXTN EN.SCHED,RE.SCHED,ER.SCHED,.TSAVE,SYST0 .EXTN INT.DS,INT.EN .EXTD CTCB .NREL ; ; MULTITASK OVERLAY MANAGEMENT MAINTAINING USE COUNTS ; ; TASK CALLS: .TOVLD - LOAD AN OVERLAY ; .OVREL - RELEASE AN OVERLAY ; .OVKIL - RELEASE AN OVERLAY AND KILL CALLER ; .OVEX - RELEASE AN OVERLAY AND TRANSFER CONTROL ; ; RANGES OF OVERLAY DOOHICKEYS: ; NODE NUMBERS: 0 TO 124. (32K - PAGE 0 - UST - BIG OVLAY DIR) ; OVERLAY NUMBERS: 0 TO 255. (SINGLE AND MULTITASK) ; OVERLAY SIZES: 1 TO 126. (32K - PAGE 0 - UST,ETC.) ; CONCURRENT USERS OF SINGLE OVERLAY: 0 TO 255. ; ; FORMAT OF APPLICABLE PORTIONS OF RESIDENT OVERLAY DIRECTORY: ; ; UST.USTOD --> OVNDS: NUMBER OF NODES ; ; FOR E>LACH NODE: ; OVRES = CURRENT OVERLAY // USE COUNT ; NODE FLAGGED EMPTY BY 377//0. NOTE THIS IS ; INDISTINGUISHABLE FROM FREE NODE CONTAINING OVERLAY ; NUMBER 377. THUS, CONDITIONAL LOADING OF OVERLAY 377 ; INTO A FREE NODE ALREADY CONTAINING OVERLAY 377 WILL ; BECOME AN UNCONDITIONAL LOAD. (AW, SHUCKS.) ; NODE IS EMPTY INITIALLY (RLDR SETS OVRES SO) AND ; AFTER ANY ERROR FROM .OVLOD (SYSTEM SETS OVRES SO). ; OVDIS, BIT 8 IS LOADING FLAG, SET DURING .OVLOD. ; IF NO ERROR ON .OVLOD, SYSTEM CLEARS LOAD B}IT. ; IF ERROR ON .OVLOD, SYSTEM MUST LEAVE BIT ON SO NO ; TASK GETS CONFUSED. CODE HERE CLEARS LOADING BIT. ; ; TASK NEEDING AN OVERLAY MAY BE PENDED/UNPENDED IN 2 WAYS: ; 1. IF CONDITIONAL LOAD FOR OVERLAY THAT'S BEING LOADED ; ALREADY, TASK "PENDED ONBR OVERLAY". KEY = 1B0+OVLY DESC. ; WHEN LOADING DONE, WAITER UNPENDED, GETS TO TRY AGAIN. ; 2. IF NODE IN USE AND TASK NEEDS TO LOAD ITS OWN OVERLAY ; (EITHER UNCONDTIONAL LOAD OR CONDITIONAL LOAD OF ; OVERLAY WHICH IS NOT CURRENT RESIDENT), TASK "PENDED z; ON NODE". KEY = 377 // NODE NUMBER. (NOTE: 177 IS ; IMPOSSIBLE NODE NUMBER, SO NO CONFLICT.) WHEN NODE ; FREED BY ALL USERS (OUC=0), WAITER GETS TO TRY AGAIN. ; ; PENDING IS WITH BIT TSXMT OF TPRST. PEND KEY STORED IN TSYS. ; OVERLAY PENDING DISTINGUISHED FROM .XMTW/.REC PENDING ; BY SETTING BIT 0 OF PEND KEY. ; ; ; .TOVLD - MULTITASK OVERLAY LOAD ; ; AC0 = OVERLAY DESCRIPTOR (NODE//NUMBER) ; AC1 = -1 FOR UNCONDITIONAL LOAD, OTHER (MANUAL SAYS 0) ; FOR CONDITIONAL LOAD (REQUIRES REENTRANT CODE) ; AC2 = OVERLAY CHANNEL NUMBER ; .TOVLD (OR GET TO "T.OVLD" WITH AC3=RET ADDR) ; <-- ERROR RETURN, ERROR CODE IN AC2 ; <-- NORMAL RETURN RETRY: MOVZR 3,3,SKP ;SET UP FOR REENTRY T.OVLD: INC 3,3 ; ASSUME GOOD RETURN EN.SCHED .TSAVE JSR OVND ;SETUP bm LDA 1,OVRES,2 ;CURRENT STATUS FOR LATER LDA 3,CTCB LDA 3,TAC1,3 COM# 3,3,SNR ;UNCONDITIONAL LOAD? JMP TOVL3 ; YES, DON'T CHECK LDA 3,C377L SUB# 1,3,SNR ;NODE LOOKS EMPTY? JMP TOVL3 ; YES, FORCE A LOAD ANDS 1,3 ;CURRENT RESIDENT SUB# 0,3,S ZR ;SAME AS WHAT WE WANT? JMP TOVL3 ; NO, NEED TO LOAD LDA 1,OVDIS,2 ;STILL LOADING OUR OVLAY? LDA 3,CNLD ; AND# 3,1,SZR ; JMP OPEND ; YES, PEND ON OVERLAY ISZ OVRES,2 ;INCREMENT USE COUNT RE.SCHED ;AND GO ; NEED TO LOAD (NEW) OVERLAY ; AC1 = OVRES,2 TOVL3: LDA 3,C377 ;NODE FREE? AND# 3,1,SZR ; JMP NPEND ; NO, PEND ON NODE MOVS 0,1 ;SET UP NEW OVRES INC 1,1 ;(1 USER) TO PLEASE STA 1,OVRES,2 ;POTENTIAL SHARERS OF NEW OVLAY LDA 1,OVDIS,2 ;SET LOADING FLAG LDA 3,CNLD ; ADD 3,1 ;(CAN'T BE HERE IF SET...) STA 1,OVDIS,2 LDA 3,CTCB ;SET UP FOR PARASITE .SYSTM LDA 2,TPC,3 ;SAVE REAL RETURN ADDR STA 2,TAC3,3 ; LDA 2,.OVLRT ;SET TO RETURN TO US JMP @.+1 SYST0 .OVLRT: OVLOD CNLD: 1B8 ; RETURN FROM .OVLOD SYSTEM CALL OVLOD: .OxVLOD CPU ;(CHAN # IN TAC2) MOVOR 3,3,SKP ;SET FOR REENTRY FLAGGING ERROR MOVZR 3,3 ;SET FOR GOOD REENTRY EN.SCHED ;REENTER SCHEDULER STATE .TSAVE ;(ERROR CODE IN TAC2) MOVL# 2,2,SZC ;ERROR ON .OVLOD? JMP OVLER ; YES ADDOR 0,0 ;SET 1B0 FבOR PEND KEY JSR OVSRH ;UNPEND WAITERS OF OVERLAY RE.SCHED ;RETURN ; ERROR ON .OVLOD, AC0=OVERLAY DESCRIPTOR OVLER: ADDOR 0,0 ;SET 1B0 FOR PEND KEY JSR OVSRH ;UNPEND WAITERS OF OVERLAY ADDOR 0,0  ;GET BACK OVLAY DESC JSR OVND ;NODE DIR ENTRY AND |OVLY # ; ***** THE FOLLOWING CODE DUPLICATES CODE NOW IN SYSTEM. ; IT MAY DISAPPEAR NEXT TIME AFTER REV 5.01 WE REV RDOS AND ; REQUIRE RE-LOADING OF SAVE FILES. LDA 3,C377L ;SET NODE TO FREE STA 3,OVRES,2 ; ; ***** LDA 1,OVDIS,2 ;RESET LOADING FLAG LD5A 3,CNLD ;(RDOS LEAVES LOADING BIT SUB 3,1 ; SET IF AN ERROR OCCURS SO STA 1,OVDIS,2 ; NO ONE IS FOOLED) JSR NPKEY ;GET NODE PEND KEY JSR OVSRH ;UNPEND WAITERS OF NODE LDA 3,CTCB LDA 2,TAC2,3 ;RETRIEVE ERROR CODE ER.SCHED ; PEND CALLER ON OVERLAY, KEY IS 1B0+OVLAY DESCRIPTOR OPEND: LDA 2,CTCB ;GET OVLAY DESC LDA 0,TAC0,2 ; OPND2: ADDOR 0,0,SKP ;SET 1B0, SKIP TO PEND ; PEND CALLER ON NODE, KEY IS 377//NODE NUMBER NPEND: JSR NPKEY ;GET NODE PEND KEY ; PEND CALLER, AC0=PEND KEY, AC2=CTCB PE ND: STA 0,TSYS,2 ;STASH PEND KEY IF PEND-OPND2 NE 2 CAN'T USE "SKP" LDA 1,TPRST,2 ;SET TSXMT BIT LDA 0,CXMTB ; ADD 0,1 ;(CAN'T BE SET ALREADY) STA 1,TPRST,2 ;(NO INT.DS NEEDED SINCE ;PENDING SELF) LDA 1,TPC,2 ;SAVE REAL PC AND CARRY STA 1,TmAC3,2 ; IN TAC3 SLOT LDA 1,.RETRY ;SET UP PC TO GO TO "RETRY:" STA 1,TPC,2 ; RE.SCHED .RETRY: RETRY*2 C377L: 377B7 C377: 377 CXMTB: TSXMT ; ROUTINE TO GET NODE PEND KEY IN AC0, CTCB IN AC2 NPKEY: LDA 2,CTCB ;CALLING TASK LDA 0,TAC0,2 ;OVLAY DESCxRIPTOR LDA 1,C377L ;MASK FOR NODE # PORTION ANDS 1,0 ;CREATE NODE PEND KEY: ADD 1,0 ;377//NODE NUMBER JMP 0,3 ;RETURN ; ROUTINE TO DO GENERAL SETUP WORK ; INPUT: AC0 = OVERLAY DESCRIPTOR ; CALL: JSR OVND ; OUTPUT: AC0 = OVERLAY NUMBER (RIGHT HALF OVLY DESC) ; AC1 DESTROYED (ALSO CARRY) ; AC2 -> OVLAY DIRECTORY ENTRY FOR NODE OVND: STA 3,OVNDX ; SAVE RETURN LDA 3,C377L ;ISOLATE NODE NUMBER ANDS 0,3 ; LDA 2,USTP ;GET OVLAY DIRECTORY ADDR LDA 2,USTOD,2 ; LDA 1,OVNDS,2 ; SEE IF IN BALLPARK3 ADCZ# 3,1,SNC JMP OVERR ; NO-MUST BE THE BABE CALLING ADDZL 3,3 ; TIMES 4 ADD 3,2 ;POINT AT NODE ENTRY LDA 3,C377 ;ISOLATE OVLY # FOR CALLER AND 3,0 ; JMP @OVNDX OVNDX: .BLK 1 ;OVND RET ADDR ; ROUTINE TO UNPEND WAITERS ON GIVEN PEND KEY ;- INPUT: AC0 = PEND KEY ; CALL: JSR OVSRH ; OUTPUT: AC0 UNCHANGED, ALL ELSE DESTROYED OVSRH: STA 3,OVSRX ;SAVE RETURN ADDR LDA 1,CXMTB ;BIT TSXMT LDA 2,USTP ;GET HEAD OF ACTIVE CHAIN LDA 2,USTAC,2 ; SRHLP: LDA 3,TSYS,2 ;GET KEY SUB# 0,3,SZR ;MATCHJ ? JMP NMTCH ;NO LDA 3,TPRST,2 ;STATUS WORD AND# 1,3,SNR ;PEND KEY MEANINGFUL? JMP NMTCH ; NO, IGNORE THIS TASK INT.DS ;(UNPENDING ANOTHER TASK) LDA 3,TPRST,2 ;STATUS AGAIN SUBC 1,3 ;CLEAR TSXMT BIT STA 3,TPRST,2 INT.EN NMTCH: LDA 2,TLNK,2V ;NEXT TCB COM# 2,2,SZR ;END OF CHAIN? JMP SRHLP ;MORE TO DO JMP @OVSRX ;DONE, RETURN OVSRX: .BLK 1 ; OVSRH RETURN ADDRESS ; .OVREL - RELEASE AN OVERLAY IN MULTITASK ENVIRONMENT ; ; AC0 = OVERLAY DESCRIPTOR ; .OVREL (OR GET TO "O.VREL" WITH AC3=RET ADDR) ; <-- ERROR RETURN, ERROR CODE IN AC2 ; <-- NORMAL RETURN O.VREL: INC 3,3 ; ASSUME GOOD RETURN EN.SCHED .TSAVE JSR OVAVL ; UNPEND ANY WAITERS FOR NODE RE.SCHED ; .OVKIL - RELEASE AN OVERLAY AND KILL THE CALLING TASK ; ; AC0 = OVERLAY DESCRIPTOR ; .OVKIL (OR GET TO "O.VKIL" WITH AC3=RET ADDR) ; <-- ERROR RETURN, ERROR CODE IN AC2 ; <-- NORMAL RETURN O.VKIL: INC 3,3 ; ASSUME GOOD RETURN EN.SCHED .TSAVE ; SAVE STATE IN CASE OF ERROR JSR OVAVL ; UNPEND ANY WAITERS FOR NODE JwSR @.+1 K.ILL ; KILL CALLER ; .OVEX - RELEASE AN OVERLAY AND TRANSFER CONTROL ; ; AC0 = OVERLAY DESCRIPTOR ; AC2 = PC TO RETURN TO ; .OVEX (OR GET TO "O.VEX" WITH AC3=RET ADDR) ; <-- ERROR RETURN, ERROR CODE IN AC2 ; <-- NORMAL RETURN O.VEX: INC27 3,3 ; ASSSUME GOOD RETURN EN.SCHED .TSAVE JSR OVAVL ;UNPEND ANY WAITERS FOR NODE LDA 3,CTCB ; NO ERROR- GO TO NEW PC LDA 2,TAC2,3 ; PC MOVL 2,2 STA 2,TPC,3 ; TO TCB RE.SCHED ; ROUTINE TO RELEASE AN OVERLAY AND MAKE THE NODE AVAILABLE ; IF THElH COUNT DROPS TO 0 (ALSO DOES ERROR CHECKING) OVAVL: STA 3,OVAVX ;SAVE RET ADDR JSR OVND ;SETUP LDA 1,OVRES,2 ;CURRENT NODE STATUS LDA 3,C377L ANDS 1,3 ;OVLY NUMBER SUB# 3,0,SZR ;RIGHT ONE ? JMP OVERR ; NO-ERROR LDA 3,C377 AND# 3,1,SNR ;ANY^V CURRENT USERS? JMP OVERR ; NONE, ERROR DSZ OVRES,2 ;DECREMENT USE COUNT (MAY SKIP) ANDZR# 3,1,SNR ;IS NODE NOW FREE? JMP NFREE ; NODE IS FREE JMP @OVAVX ;NOT YET, JUST RETURN ; NODE IS NOW FREE, UNPEND ANY WAITERS NFREE: JSR NPKEY ;GET NODE PEND KEY JSR OVSRH ;UNPEND WAITERS JMP @OVAVX ;NOW RETURN OVAVX: .BLK 1 ; OVAVL RETURN ADDRESS OVERR: LDA 2,OVNER ER.SCHED OVNER: EROVN ;INVALID OVERLAY DESCRIPTOR .END ; END OF TOVLY.SR OVERR: LDA 2,OVNER ER.SCHED OVNER: EROVN QTSK.SR= 8h.TITL QTSK .RB QTSK.RB .ENT .QTSK .EXTN Q.TSK .ZREL .QTSK= JSR @. Q.TSK .END ; END OF QTSK.SR DQTSK.SR= 7oS.TITL DQTSK .RB DQTSK.RB .ENT .DQTSK .EXTN D.QTSK .ZREL .DQTSK= JSR @. D.QTSK .END ; END OF DQTSK.SR TQTASK.SR== 1i.TITL TQTASK ; TASK QUEING LOGIC .RB TQTASK.RB .ENT Q.TCK,Q.TSK,D.QTSK .EXTN USTAD .EXTN EN.SCHED,RE.SCHED,ER.SCHED,.TSAVE,ID.SRCH .EXTN LQTSC,QTCNT .EXTN TSK.X .EXTN TLINK,ID.SRCH,SYST1 .EXTN K.ILL,T.OVLD .EXTD CTCB .NREL ; AC2= A(USER TABLE) (A.?K.A. QUEUE FRAME) ; TABLE FORMAT: ; +0- PC (QPC) ; +1- NUMB TIMES TO EXEC (QNUM) ; +2- OVERLAY ENTRY (QTOV) ; +3- START HOUR (QSH) ; +4- START MIN+SEC (QSMS) ; +5- TID+PRI (QPRI) ; +6- RERUN TIME INC (QRR) ; +7- LINK WORD (QTLNK) ; NOTE- OFFSETS FOR LINK A-ND PRI MUST CORRESPOND TO TCB ; +10- CHANNEL NUMBER, FOR LOADING OVERLAYS ; +11- TYPE LOAD (QCOND) ; +12- RESERVED ; +13- START OF EXTENSION (QPEX) Q.TSK: INC 3,3 ; ASSUME GOOD RETURN EN.SCHED .TSAVE LDA 2,TAC2,3 LDA 0,QNUM,2 ;NUMBER OF TIMES TO QUEU~E MOV# 0,0,SNR ;QNUM=0 IS ILLEGAL JMP TQERR ;ERROR EXIT LDA 0,QSH,2 ; START HOURS COM# 0,0,SNR ; SKIP UNLESS RUN IMMEDIATE JMP TQTS2 LDA 1,QSMS,2 ; GET SECOND FOR CHECKING LDA 3,SQSH ; CHECK AGAINST HOUR FOR TOMORROW SUBZ# 3,0,SNC JMP ADD24 3.; BEFORE--NEXT DAY ; QUEUE FOR TOMORROW SUB# 3,0,SZR ; SKIP IF EQUAL HOURS JMP SAMED ; ELSE SAME DAY, BUT LATER LDA 3,SQSMS ; CHECK AGAINST SECONDS SUBZ# 3,1,SZC JMP SAMED ; => SAME DAY ADD24: LDA 3,C24. ; MAKE IT NEXT DAY ADD 3,0 STA 0,QSH,2 ; STUFF HOURS SAMED: LDA 3,CMXMS ; MAX SECONDS ADCZ# 1,3,SNC JMP TQERR ; TOO BIG TQTS1: LDA 1,QPRI,2 ; VALIDATE TASK ID LDA 0,C377L ANDS 0,1 STA 2,TQRTN ; SAVE QUEUE FRAME POINTER ID.SRCH ; ACTIVE? JMP .+2 JMP TIDER ; YES-ERROR RTN JS>R @.QTISR ; LOOK THRU ACTIVE .QTSK REQ JMP .+2 ; NOT FND- OK JMP TIDER ; ACTIVE-BAG IT LDA 2,TQRTN ; RESTORE POINTER JSR TENQ ; ENQUEUE REQUEST LDA 0,FTFL ; FIRST TIME ? MOV# 0,0,SZR ; SKP IF YES RE.SCHED ISZ FTFL ; NOW IT'S NOT... LDA 1,CSECI ; SYSTM CALL LDA 3,CTCB JMP @.+1 SYST1 ; RUN IMMEDIATE TQTS2: LDA 0,SQSH ; SET TIME TO CURRENT TIME STA 0,QSH,2 LDA 0,SQSMS STA 0,QSMS,2 JMP TQTS1 ; VALIDATE TID TIDER: LDA 2,.ERTID ; TID ERROR ER.SCHED .ERTID: ERTID .QTISR: QTISR CSECI: .SECI FTFL: 0 ; ENQUEUE REQ INTO TOD CHAIN ; AC2= USER TOD AREA ADDR TENQ: STA 3,TQRTN LDA 3,QTNTB ; ON QUEUE CHAIN COM# 3,3,SNR ; SKIP IF NOT EMPTY JMP TQFR SUB 0,0 STA 0,LTCB ; INIT LAST TCB TQ1: LDA 0,QSH,2 ; QUEUED ENTRY START HOUR LDA 1R",QSH,3 ; CHAIN ENTRY STARTING HOUR SUBZ# 1,0,SNC ; SKP IF <= CHAIN ENTRY JMP TQINS ; >, INSERT HERE SUB# 1,0,SZR ; SAME HOUR JMP TQNXT ; NO -- GET NEXT QUEUED TASK LDA 0,QSMS,2 ; CHECK SECONDS LDA 1,QSMS,3 ; FOR ORDER SUBZ# 1,0,SNC ; JMP TQIϜNS ; IS LATER-- INSERT HERE TQNXT: STA 3,LTCB ; SAVE LAST LDA 3,QTLNK,3 ; MOVING ON... COM# 3,3,SZR ; SKIP IF END JMP TQ1 ; COMPARE ; INSERT AT PRESENT POINT TQINS: LDA 3,LTCB ; LAST IN CHAIN MOV# 3,3,SNR ; SKIP IF ONE JMP TQFR ; PUT AT HEAD? LDA 1,QTLNK,3 ; LINK INTO CHAIN STA 2,QTLNK,3 ; .-1 TO . STA 1,QTLNK,2 ; ,+1 TO . TQ3: ISZ @.QTCNT ; INC ON QUEUE COUNT JMP @TQRTN ; QUEUE FIRST TQFR: LDA 3,QTNTB ; CURRENT FIRST QTASKED STA 2,QTNTB ; NEW FIRST STA 3,QTLNK,2 ; LINK TO OLD FIRSKT JMP TQ3 TQERR: LDA 2,.ERQTS ; QUEUE ERROR ER.SCHED C24.: 24. .ERQTS: ERQTS QTNTB: -1 CMXMS: 3600. LTCB: 0 TQRTN: 0 C377L: 377B7 SQSH: -1 SQSMS: -1 .LQTSC: LQTSC ; IN TCBMON ; ROUTINE ENTERED FROM TCBMON IF TIME CHANGE ; AC0= HOURS,AC1= MIN+SEC Q.9TCK: STA 0,SQSH ; UPDATE CURRENT TIME STA 1,SQSMS STA 1,@.LQTSC ; UPDATE LAST SECOND LDA 3,QTNTB ; START OF CHAIN COM# 3,3,SNR ; TIME MAINTANENCE ENTRY ? RE.SCHED ; YESS-- CONTINUE ONWARDS ADD# 0,1,SZR ; SKIP IF MIDNIGHT JMP QTCK2 ; LDA 1,C24. SUB 0,0 T4LOOP: LDA 2,QSH,3 ; SUBTRACT 24 HOURS SUBZ 1,2,SZC JMP T4NEXT STA 0,QSMS,3 ; LIMIT TO MIDNIGHT MOV 0,2 T4NEXT: STA 2,QSH,3 LDA 3,QTLNK,3 ; NEXT ONE COM# 3,3,SZR ; JMP T4LOOP QTCK3: LDA 0,SQSH ; RESTORE ACS LDA 1,SQSMS LDA 3,Q!TNTB COM# 3,3,SNR ; SKIP IF ARROUND RE.SCHED ; ELSE ALL DONE QTCK2: LDA 2,QSH,3 ; START HOURS SUBZ# 2,0,SNC ; SKIP IF =< RE.SCHED ; ELSE CONTINUE ON SUB# 0,2,SZR ; SKIP IF EQUAL JMP QTCK4 ; FOUND THE NEEDLE LDA 2,QSMS,3 ; CHECK OUT THE SECONDS SUBZ# 2,1,SNC ; SKIP IF =< RE.SCHED ; FOUND A CANDIDATE TO RUN QTCK4: STA 3,LTCB ;QUEUE FRAME ADDRESS LDA 2,@.FC ; FREE CHAIN HEAD COM# 2,2,SNR ; SKIP IF A TCB IS THERE RE.SCHED ; WAIT FOR ONE LDA 1,TLNK,2 STA 1,@.FC ;NEW START-OF-FREELk-CHAIN POINTER SUB 1,1 STA 1,TELN,2 ;CLEAR EXTENSION ADDRESS STA 1,TKLAD,2 ; KILL ADDRESS ; SET PRIORITY AS SPECIFIED IN QUEUE FRAME LDA 0,QPRI,3 ; PRIORITY, AS DEFINED IN QUEUE LDA 1,C377 ; MASK: GET THE AND 1,0 ; PRIORITY OF THE TASK, AND STA 0,TPRST,2 ; STUFF IT INTO THE TCB ; SET UP TASK AC'S AND PC LDA 0,QTOV,3 ; OVERLAY NODE // NUMBER STA 0,TAC0,2 ; NEEDED BY THE OVERLAY LOADER LDA 0,QCOND,3 ; CONDITIONAL LOAD? STA 0,TAC1,2 ; IS ALSO USED BY OVERLAY LOADER LDA 0,QOCH,3 ; CHtANNEL # TO USE STA 0,TAC2,2 ; FOR LOADING THE OVERLAYS LDA 1,QPC,3 ;TASK'S STARTING PC MOVZL 1,1 ; TPC FORM STA 1,TPC,2 ; PUT IN TPC FOR NOW FOR ; USER TO SEE ; IS TID ALREADY ACTIVE? LDA 0,QPRI,3 ;ID // PRIORITY LDA 1,C377L ANDS 0,1 ; TID IN RIGHT HALF AC1 STA 2,TCBSV ; SAVE TCB ADDR ID.SRCH ; LOOK FOR THIS TID AMONG ACTIVE TCB'S JMP QTCK5 ; NOT FOUND, USE IT SUB 1,1 ; EXTANT, USE 0 QTCK5: LDA 2,TCBSV ;TCB ADDR. STA 1,TID,2 ;DEFINE THE TID LDA 1,LTCB ; QUEUE FRAME ADDRESS MOV 1,0 ;AC0,AC1 = QUEUE FRAME ADDR. JSR @TSK?X ; CALL TASK CREATION EXIT, ; AC2 = TCB ADDR. JMP T.ASE ; SOME KIND OF ERROR LDA 2,TCBSV ; TCB ADDRESS LDA 1,TPC,2 ; SAVE REAL PC FOR LATER STA 1,TTMP,2 LDA 1,.TQOVL ; PSEUDO-TASK PC, TO KEEP CO0;NTROL ; EVEN WHILST PRETENDING TO BE A ; MERE USER STA 1,TPC,2 ; STARTING PC ADDRESS LDA 3,LTCB ; QUEUE FRAME ADDRESS LDA 0,QNUM,3 ; IF QNUM = -1 COM# 0,0,SZR ; THEN RUN FOREVER DSZ QNUM,3 ; ELSE RUN UNTIL QNUM --> 0 JMP QTCKR ; RE-qQUEUE THIS TASK FOR YET ; ANOTHER TIME ; UNLINK QUEUE FRAME FROM THE TOD-QUEUE LDA 0,QTLNK,3 ; THE NEXT FRAME IS NOW STA 0,QTNTB ; THE TOP FRAME, AND SUB 0,0 ;  THIS FRAME IS FLAGGED AS STA 0,QTLNK,3 ; FREE, AND THERE IS DSZ W@.QTCNT ; ONE LESS FRAME ON ; THE QUEUE. JMP .+1 ; NOP THE DSZ ; RUN THE TASK, ELSE ALL THIS WORK HAS BEEN FOR NAUGHT QTCK6: LDA 2,TCBSV MOV 2,1 ;TCB ADDRESS LDA 0,TPRST,2 ; PRIORITY JSR @.TLNK ; LINK INTO THE ; ACTIVE TCB CHAIN JMP QTCK3 ; NOW SEE IF ANY OTHERS WANT TO ; RUN AT THIS TOD .FC: .GADD USTAD,USTFC ; FREE CHAIN POINTER C377: 377 TCBSV: 0 .QTCNT: QTCNT TSK?X: TSK.X ; DROP ANY ERRORS T.ASE: LDA 3,TCBSV ; GET NEW TCB ADDRESS LDA 1,@.FCoJ ; RELINK INTO FREE CHAIN STA 1,TLNK,3 STA 3,@.FC RE.SCHED ; RERUN SETUP QTCKR: LDA 1,QSMS,3 ; PRESENT MIN/SEC LDA 2,CMXMS ; MAX PER HOUR LDA 0,QRR,3 ; RERUN INC ADD 0,1 QTCR2: ADCZ# 1,2,SZC ; TOO BIG ? JMP QTCR1 ; NO SUB 2,1 ; REMOVE AN HOiUR'S WORTH ISZ QSH,3 ; BUMP THE HOURS JMP QTCR2 ; GO CHECK AGAIN QTCR1: STA 1,QSMS,3 ; MIN SEC START LDA 2,QTLNK,3 ; NEXT STA 2,QTNTB ; NEW START MOV 3,2 ; AREA ADDR DSZ @.QTCNT ; IT WILL BE ISZED IN TENQ JMP .+1 ; IGNORE DSZ TIME OUT JSR @.%TENQ ; LINK IN ;********>>>>>> ; LTCB HAS BEEN DESTROYED JMP QTCK6 ; GO RUN THE TASK. .EJECT ; ; THIS ROUTINE IS A 'PSEUDO-TASK' CREATED BY THE TQTASK LOGIC ; TO ALLOW SOME MAGIC TO HAPPEN. THIS ROUTINE GETS CONTROL ; PRIOR TO THE TRUE USER TASK. SINCE THIS ROUTINE IS EXECUTED ; AS THOUGH IT WERE A USER TASK, USER OVERLAY LOADS ARE EASY ; TO INITIATE FROM HERE. THUS, USER OVERLAYS (IF REQUIRED), ; ARE DONE FROM HERE, AND AT LONG LAST THE WEARY AND TIRED ; USER TASK IS ALLOWED TO RUN. ; ; ON ENTRY: AC0 = NODE // NUMBER ; AC1 = TYPE OF LOAD ; AC2 = CHANNEL # ; TTMP = ACTUAL TPC VALUE ; TQOVL: COM# 0,0,SNR ;SKIP IF OVERLAY LOAD REQUESTED JMP GLOAD ;CORE RESIDENT JSR @T?OVLD ;LOAD OVERLAY JMP TLDER ;OOPS, SORRY, ONLY ONE CHANCE GLOAD: LDA 3,CTCB ; WHERE'S MY TCB?? LDA 3,TTMP,3 ; TPC-TO-BE MOVZR 3,3 ;SET UP CARRY AND AC3 EN.SCHED ;EVENTUALLY, THIS WILL CAUSE .TSAVE ; THE REAL USER TASK LDA 0,K?ILL ;SO TASK KILLS ITSELF ON RETURN STA 0,TAC3,3 RE./~SCHED ; TO BEGIN ; ; T?OVLD: T.OVLD K?ILL: K.ILL TLDER: .SYSTM .ERTN JMP . .TLNK: TLINK .TQOVL: TQOVL*2 .TENQ: TENQ .EJECT ; DEQUE A PREVIOUSLY QUEUED REQ ; AC1= TID ; ERROR RTN IF TID= 0 OR NOT FOUND ; AC2= AREA BASE ON RTN D.QTSK: INC 3,3 ; ASSUME GOOD RETURN EN.SCHED .TSAVE JSR QTISR ; LOOK FOR TID JMP @.TQERR ; ERROR MOV 1,3 ; .-1 LDA 1,QTLNK,2 ; DEQUE STA 1,QTLNK,3 SUB 0,0 STA 0,QTLNK,2 ; SHOW AS FREE FOR OPCOM DSZ @.QTCNT ; ON Q CNT JMP .+1 LDA 3,CTCB STA 2,TAC2,3 ; FOR USER mDRE.SCHED ; SEARCH FOR A TID IN THE ACTIVE .QTSK AREAS ; INPUT: AC1= TID ; OUTPUT: AC2 = MATCH, QUEUE FRAME AREA BASE ADDR. ; AC1 = .-1 IN CHAIN QTISR: STA 3,QTISX LDA 2,DMQTB ; DUMMY START LDA 3,C1774 DQNXT: STA 2,LQSV ; SAVE .-1 LDA 2,QTLNK,2 ; ZNXT COM# 2,2,SNR ; SKIP IF NOT END JMP @QTISX ; BAD RTN LDA 0,QPRI,2 ; TID IN LB ANDS 3,0 SUB# 1,0,SZR ; SKIP IF MATCH JMP DQNXT LDA 1,LQSV ; .-1 ISZ QTISX ; GOOD RTN JMP @QTISX .TQERR: TIDER ;TASK ID ERROR DMQTB: QTNTB-QTLNK LQSV: 0 QTISX:,T 0 C1774: 377B7 .END ; END OF TQTASK.SR AKILL.SR= 7o.TITL AKILL .RB AKILL.RB .ENT .AKILL .EXTN A.KILL .ZREL .AKILL= JSR @. A.KILL .END ; END OF AKILL.SR ASUSP.SR= 7of.TITL ASUSP .RB ASUSP.RB .ENT .ASUSP .EXTN A.SUSP .ZREL .ASUSP= JSR @. A.SUSP .END ; END OF ASUSP.SR ARDY.SR= 7hc.TITL ARDY .RB ARDY.RB .ENT .ARDY .EXTN A.RDY .ZREL .ARDY= JSR @. A.RDY .END ; END OF ARDY.SR TACALL.SR= 0.TITL TACALL ; TASK PRIORITY CLASS CALLS .RB TACALL.RB .ENT A.KILL,A.SUSP,A.RDY .EXTN K.IL2,USTAD .EXTN EN.SCHED,RE.SCHED,INT.DS,.TSAVE,INT.EN .NREL ; KILL ALL TASKS OF PRI = AC0 A.KILL: EN.SCHED .TSAVE LDA 3,KMASK ; PICK UP KILL MASK JMP A1 v; JOIN COMMON CODE ; SUSPEND ALL TASKS OF PRI = AC0 A.SUSP: EN.SCHED .TSAVE LDA 3,SMASK ; PICK UP SUSP/RDY MASK MOVOS 0,1 ; PRI TO HIGH AC1, JMP A2 ; CARRY SIGNALS .ASUSP ; READY ALL TASKS OF PRI = AC0 A.RDY: EN.SCHED .TSAVE LDA 3,SMASK ; PIC#K UP SUSP/RDY MASK A1: MOVZS 0,1 ; PRI TO HIGH AC1, ; CARRY SIGNALS .ARDY ; NOTE: CARRY MUST BE PRESERVED FROM HERE TO END OF ROUTINE A2: STA 3,MASK ; SAVE MASK FOR LATER LDA 2,TDUML ; GET 0'TH TCB ADDR ALOOP: MOV 2,3 ; SAVE PREDECESSOR TCB LDA 2,TLNK,2 ; GET NEXT TCB COM# 2,2,SNR ; END OF CHAIN? RE.SCHED ; YES, NO ONE OF DESIRED PRI LDA 0,TPRST,2 ; GET THE PRI AND STAT MOVS 0,0 ; PRI TO HIGH HALF ADCZ# 0,1,SZC ; SKIP WHEN FIND FIRST CANDIDATE JMP ALOOP ; UNTIL THEN LOOP LDA 2,C377L /; LEFT BYTE MASK AND 2,0 ; CLEAR AWAY HIS STATUS BITS SUB# 0,1,SZR ; DOES HIS PRI MATCH? RE.SCHED ; IF NOT, NO ONE'S DOES, SO LEAVE ADC 2,1 ; BUMP REFERENCE PRI BY .776 OCTAL STA 3,LTCBS ; SAVE PREDECESSOR TCB INT.DS ; WILL BE PLAYING WITH TPRST LDA 2,LTCBS ; RETRIEVE PREDECESSOR TCB LDA 3,MASK ; RETRIEVE MASK TO USE MOVL# 3,3,SZC ; .AKILL OR .ASUSP/.ARDY ? JMP SRIN ; GO DO .ASUSP OR .ARDY JMP KIN ; GO DO .AKILL ; .ASUSP/.ARDY PROCESSING FOR ALL TASKS OF GIVEN PRIORITY ; AC3=MASK FOR TSSUSP, AC1=HIGHEST PRI/STAT TO MATCH ; CARRY=0 FOR .ARDY, =1 FOR .ASUSP ; ENTER AT "SRIN" SRLOOP: MOVS 0,0,SZC ; SWAP BACK, SKIP IF .ARDY ADC 3,0 ; SET TSSUSP IF .ASUSP STA 0,TPRST,2 ; PUT BACK IN TCB SRIN: LDA 2,TLNK,2 ; NEXT CANDIDATE COM# 2,2,SNSR ; END OF CHAIN? JMP OUT ; YES LDA 0,TPRST,2 ; HIS PRI AND STAT ANDS 3,0 ; CLEAR TSSUSP, PRI TO HIGH HALF SUBZ# 0,1,SZC ; SKIP WHEN PRI GOES OUT OF RANGE JMP SRLOOP ; UNTIL THEN KEEP GOING OUT: INT.EN ; INTS BACK ON RE.SCHED ; GO AWAY ; .AKILL PROCESSING FOR ALL TASKS OF GIVEN PRIORITY ; AC3=MASK OF BITS TO RETAIN ON KILL ; AC1=HIGHEST PRI/STAT TO MATCH ; ENTER AT "KIN" ; FOR EACH TASK OF CORRECT PRIORITY: ; SET HIS PRI TO 0 ; CLEAR ALL HIS STATUS BITS EXCEPT THOSE IN KMASK ; SET HIS TPC T͛O POINT AT K.ILL IN SCHEDULER ; DO ABOVE FOR ALL TASKS OF GIVEN PRI CLASS, THEN ; UNLINK WHOLE PRI CLASS AND RELINK AT HEAD OF ACTIVE CHAIN KLOOP: ANDS 3,0 ; CLEAR MOST STAT BITS, SET PRI=0 STA 0,TPRST,2 ; PUT BACK IN TCB LDA 0,K?IL2 ; SET UP TPC TO POINT AT STA 0,TPC,2 ; KILL CODE IN SCHEDULER KIN: STA 2,LTCB2 ; SAVE LOCAL PREDECESSOR TCB LDA 2,TLNK,2 ; GET NEXT TCB COM# 2,2,SNR ; END OF CHAIN? JMP KOUT ; IF YES LDA 0,TPRST,2 ; GET HIS STAT AND PRI MOVS 0,0 ; PRI TO HIGH HALF SUBZ# 0,1,SZC ; SKIP WHEN PRI GOES OUT OF RANGE JMP KLOOP ; UNTIL THEN LOOP KOUT: LDA 3,LTCBS ; GET TCB PRECEDING PRI CLASS LDA 0,TLNK,3 ; FIRST TCB IN CLASS STA 2,TLNK,3 ; UNLINK WHOLE PRI CLASS LDA 1,@UACHN ; CURRENT HEAD OF ACTIVE CHAIN LDA 3,LTCB2 ; LASTN TCB IN GIVEN CLASS STA 1,TLNK,3 ; LINK LAST TO PRIOR FIRST STA 0,@UACHN ; UPDATE ACTIVE CHAIN HEADER JMP OUT LTCBS: .BLK 1 ; SAVE FOR PREDECESSOR TCB LTCB2: ; SAVE FOR LOCAL PREDECESSOR TCB MASK: ; AC3 MASK FOR LOOP (ALSO ; DIFFERENTIATEwS .AKILL FROM OTHERS) .BLK 1 ; (LTCB2 AND MASK SHARE SAME LOC) SMASK: -1-TSSUSP ; SUSP BIT MASK FOR .ASUSP/.ARDY KMASK: TSSYS+TSABT+TSUSR/400&377 ; SWAPPED MASK OF BITS TO SAVE ; WHEN KILLING A TASK TDUML: .GADD USTAD,USTAC-TLNK; FAKE 0'TH TCB UACHN: .GADD USTAD,USTAC ; ACTIVE CHAIN POINTER C377L: 377B7 ; LEFT BYTE MASK K?IL2: K.IL2 ; KILL ADDR *2 FOR KILL PROCESSING .END ; END OF TACALL.SR XMT.SR= :ap.TITL XMT .RB XMT.RB .ENT .XMT .EXTN X.MT .ZREL .XMT= JSR @. X.MT .END ; END OF XMT.SR XMTW.SR=  :h.TITL XMTW .RB XMTW.RB .ENT .XMTW .EXTN X.MTW .ZREL .XMTW= JSR @. X.MTW .END ; END OF XMTW.SR REC.SR= 9a~.TITL REC .RB REC.RB .ENT .REC .EXTN R.EC .ZREL .REC= JSR @. R.EC .END ; END OF REC.SR IXMT.SR= 8h.TITL IXMT .RB IXMT.RB .ENT .IXMT .EXTN I.XMT .ZREL .IXMT= JSR @. I.XMT .END ; END OF IXMT.SR TXMT.SR=% 3.TITL TXMT ; TASK COMMUNICATIONS MODULE .RB TXMT.RB .ENT X.MT,X.MTW,R.EC,I.XMT .EXTN EN.SCHED,RE.SCHED,ER.SCHED,.TSAVE,INT.DS,INT.EN .EXTN USTAD .EXTD CTCB .NREL ; REQ TO XMIT DATA WORD TO ANOTHER TASK ; TWO CALLS: XMT, XMTW - NO WAIT AND WAIT FOR?R REC ; AC0=ADDR DATA WORD ; AC1=DATA TO XMIT ; .XMTW COMES HERE X.MTW: INC 3,3 ; ASSUME GOOD RETURN EN.SCHED .TSAVE ADC 3,3 ; FLAG WAIT WITH -1 JMP XMT1 ; JOIN COMMON CODE ; .XMT COMES HERE X.MT: INC 3,3 ; ASSUME GOOD RETURN EN.SCHED .TSAVE  ; AC3 (CTCB) GUARANTEED <> -1 XMT1: STA 3,XWAIT ; SET UP WAIT FLAG INT.DS ; SHUT OUT .IXMT MOV 0,2 ; KEY TO AC2 JSR XXSRH ; GO SEARCH FOR A RECEIVER JMP XMERR ; ERROR JMP XMT3 ; FOUND RECEIVER AND GAVE HIM DATA STA 1,0,2 ; NO REC YET, SAVE4 DATA ISZ XWAIT ; NEED TO PEND CALLER? JMP XMT3 ; NO, WAS .XMT LDA 3,CTCB ; YES, WAS .XMTW XMT2: STA 2,TSYS,3 ; FLAG HIM WAITING FOR KEY LDA 1,TPRST,3 ; SET HIS TSXMT BIT LDA 0,CXMT ; ADD 0,1 ; STA 1,TPRST,3 ; XMT3: INT.EN ; LET INTERRUPTS (.IXMT) IN RE.SCHED XMERR: INT.EN ER.SCHED XWAIT: .BLK 1 ; WAIT FLAG, -1 FOR .XMTW CXMT: TSXMT ; PEND BIT FOR .XMTW ; REQUEST TO RECEIVE DATA FROM A TASK ; AC0=KEY (DATA ADDR) ; AC1=DATA ON RETURN ; .REC COMES HERE R.EC: EN.SCHED .TSAVE INT.DS *U ; SHUT OUT .IXMT LDA 3,CTCB ; CALLER TCB LDA 2,TAC0,3 ; GET KEY LDA 1,0,2 ; GET DATA THERE CURRENTLY MOV# 1,1,SNR ; XMIT HAPPEN YET? JMP XMT2 ; NO, GO PEND CALLER ON KEY STA 1,TAC1,3 ; YES, RETURN DATA TO CALLER SUB 0,0 ; CLEAR KEY LOC STA 0,0,2 ; JSR XSRH ; GO UNPEND ANY .XMTW'ER JMP XMT3 ; FOUND ONE, LEAVE JMP XMT3 ; NOBODY OK TOO, LEAVE ; ROUTINE TO XMIT TO A TASK FROM THE INTERRUPT WORLD ; ENTERED WITH INTERRUPTS ON OR OFF, LEAVE SAME WAY ; ON ENTRY: AC0=KEY LOC, AC1=DATA ; RETURN4 TO +0 ON ERROR, CODE IN AC2 ; RETURN TO +1 ON SUCCESS (GAVE TASK HIS DATA OR DEPOSITED IT ; IN KEY LOC FOR SOME LATER RECEIVER) ; .IXMT COMES HERE I.XMT: SKPBN CPU ; SKIP IF INT ON ADDOR 3,3,SKP ; FLAG STATE IN RTN INTDS ; (MUST NOT BE INT.DS !) CSTA 3,IXRTN MOV 0,2 ; KEY ADDR TO AC2 JSR XXSRH ; GO SEARCH FOR RECEIVER JMP IXMER ; ERROR JMP IXEX ; FOUND SOMEONE AND GAVE HIM DATA STA 1,0,2 ; NO REC YET, SAVE DATA IXEX: ISZ IXRTN ; GOOD RETURN IXMER: LDA 3,IXRTN MOVL# 3,3,SNC ; SEE WHAT Ie)NT STATE WAS ON ENTRY INTEN ; (MUST NOT BE INT.EN !) JMP 0,3 ; RETURN TO CALLER IXRTN: .BLK 1 ; RET ADDR FOR I.XMT ; ROUTINES USED TO SEARCH ACTIVE CHAIN FOR KEY ; XSRH JUST DOES SEARCH, XXSRH FIRST CHECKS FOR XMIT ERRORS ; AC2=KEY, AC1=DATA (BOTH ENTRY AND EXIT, EXCEPT ON ERROR) ; CALLS: JSR XXSRH ; JSR XSRH ; <<- SAME> ; <<- SAME> XXSRH: LDA 0,0,2 ; KEY LOC CONTENTS MOV# 0,0,SZR ; BETTER BE 0 JMP XMER1 MOV# f1,1,SNR ; DATA BETTER NOT BE 0 JMP XMER2 INC 3,3 ; MAKE LOOK LIKE XSRH XSRH: STA 3,XRTN LDA 3,TDUML ; FAKE 0'TH TCB XLOOP: LDA 3,TLNK,3 ; GET NEXT TCB COM# 3,3,SNR ; NO MORE? JMP XNOM ; NO MATCH RETURN LDA 0,TSYS,3 ; GET TSYS VALUE SUB# 0,2,SZR ; MATCH? JMP XLOOP ; NO LDA 0,TPRST,3 ; MAKE SURE THIS TASK IS REALLY ADDZL 0,0 ; PENDED ON TSXMT MOVL 0,0,SNC ; (ASSUME TSXMT=1B2) JMP XLOOP ; IF NOT, GO TRY NEXT ; FOUND MATCH, UNPEND HIM AND GIVE HIM DATA MOVZR 0,0 ; CLEAR TSXMT MOVR 0,0h ; RESTORE REST OF STATUS MOVR 0,0 ; STA 0,TPRST,3 ; STA 1,TAC1,3 ; GIVE HIM THE DATA STA 3,TSYS,3 ; PUT IMPOSSIBLE KEY LOC AS TSYS JMP @XRTN XNOM: LDA 3,XRTN ; RETURN TO +1 JMP 1,3 XMER1: LDA 2,XMTER ; KEY LOC BUSY ERROR JMP 0,3 XMER2: LDA 2U,XMZER ; ZERO DATA ERROR JMP 0,3 XMTER: ERXMT XMZER: ERXMZ XRTN: .BLK 1 TDUML: .GADD USTAD,USTAC-TLNK; FAKE 0'TH TCB .END ; END OF TXMT.SR IDST.SR= 7hU.TITL IDST .RB IDST.RB .ENT .IDST .EXTN I.DST .ZREL .IDST= JSR @. I.DST .END ; END OF IDST.SR TIDS.SR= 9ha.TITL TIDS .RB TIDS.RB .ENT .TIDS .EXTN T.IDS .ZREL .TIDS= JSR @. T.IDS .END ; END OF TIDS.SR TIDR.SR= 9h\.TITL TIDR .RB TIDR.RB .ENT .TIDR .EXTN T.IDR .ZREL .TIDR= JSR @. T.IDR .END ; END OF TIDR.SR TIDK.SR= 9h9.TITL TIDK .RB TIDK.RB .ENT .TIDK .EXTN T.IDK .ZREL .TIDK= JSR @. T.IDK .END ; END OF TIDK.SR TIDP.SR= 9hR.TITL TIDP .RB TIDP.RB .ENT .TIDP .EXTN T.IDP .ZREL .TIDP= JSR @. T.IDP .END ; END OF TIDP.SR TIDC.SR=% :.TITL TIDC ; TASK ID FUNCTIONS .RB TIDC.RB .ENT I.DST,T.IDS,T.IDR,T.IDK,T.IDP .EXTN K.IL2,ID.SRCH,P.RI1,TUNLK,USTAD .EXTN EN.SCHED,RE.SCHED,ER.SCHED,.TSAVE,INT.DS,INT.EN .EXTD CTCB .NREL ;RETURN STATUS OF TASK ID = USER AC1 ; = 0 - READY ; = 1 - .S>YSTM OR .TRDOP ; = 2 - ANY SUSPEND (TSSUSP, TSABT, TSUPN) ; = 3 - WAITING FOR XMT/REC ; = 4 - WAITING FOR NODE - .TOVLD ; = 5 - ANY SUSPEND AND (.SYSTM OR .TRDOP) ; = 6 - ANY SUSPEND AND XMT/REC ; = 7 - ANY SUSPEND AND WAITING FOR NODE - .TOVLD ; = 10 - INACTIVE I.DST: EN.SCHED .TSAVE ID.SRCH ; LOOK FOR ID (AC1) JMP TIDS1 ; NOT ALIVE LDA 3,CTCB STA 2,TAC2,3 ; PASS BACK ID'S TCB SUB 0,0 ; INIT STATUS LDA 1,TPRST,2 LDA 3,RDY AND# 3,1,SNR ; IS TASK READY? JMP TIDEX ; YES LDA 3,XMT AND# 3,1,S&ZR ; TSXMT? JMP TIDS2 ; YES LDA 3,SUSB INC 0,0 ; MUST BE 1, 2, OR 5 NOW AND# 3,1,SNR ; TSSUSP, TSABT OR TSUPN? JMP TIDEX ; NO, MUST BE TSSYS OR TSRDOP INC 0,0 ; CAN ONLY BE 2 OR 5 LDA 3,SYS LDA 2,C3 AND# 3,1,SZR ; TSSYS OR TSRDOP? ADD 2,0 u ; YES, RETURN 5 TIDEX: LDA 3,CTCB STA 0,TAC0,3 ; RETURN STATUS IN CALLER'S AC0 RE.SCHED TIDS1: LDA 0,C10 ; NO SUCH TASK ID JMP TIDEX TIDS2: LDA 0,C3 ; TSXMT BASE IS 3 LDA 3,SUSB AND# 3,1,SZR ; TSSUSP, TSABT, OR TSUPN? ADD 0,0 ; YES, BASE IS 6  LDA 2,TSYS,2 ; GET THE XMT KEY MOVL# 2,2,SZC ; WAITING ON OVERLAY? INC 0,0 ; YES, RETURN 4 OR 7 JMP TIDEX RDY: TSSYS!TSSUSP!TSXMT!TSRDOP!TSABT!TSUPN!TSRSV XMT: TSXMT SUSB: TSSUSP!TSABT!TSUPN!TSRSV SYS: TSSYS!TSRDOP C3: 3 C10: 10 ; SUSPEND TASK WITHF ID = AC1 T.IDS: INC 3,3 ; ASSUME GOOD RETURN EN.SCHED .TSAVE MOVO 0,0 ; FLAG SUSPEND STIDX: ID.SRCH ; SEARCH FOR ID IN AC1 JMP TIDER ; NOT FOUND INT.DS ; PREVENT TSSYS & TSXMT UNPENDS  LDA 3,CTSUS LDA 0,TPRST,2 AND 3,0,SZC ; SKIP IF RESET (READY) ADC 3,0 STA 0,TPRST,2 INT.EN ; DON'T KEEP I/O WAITING RE.SCHED CTSUS: -1-TSSUSP ; AC1=TID OF TASK TO READY T.IDR: INC 3,3 ; ASSUME GOOD RETURN EN.SCHED .TSAVE MOVZ 0,0 ; FLAG READY JMP STIDX ; JOIN COMMON CODE TIDER: LDA 2,.ERTID 6ER.SCHED ; KILL TASK WITH ID = AC1 T.IDK: INC 3,3 ; ASSUME GOOD RETURN EN.SCHED .TSAVE ID.SRCH ; SEARCH FOR ID JMP TIDER ; NOT FOUND LDA 1,.AKRT ; PC = K.ILL STA 1,TPC,2 INT.DS ; PROTECT AGAINST TSSYS & TSXMT LDA 0,TPRST,2 ; STAT LDA 1,KBITS ; PRI = 0 AND 1,0 ; BUT LEAVE TSSYS, TSABT, & TSUSR STA 0,TPRST,2 ; TO TCB INT.EN JSR @.TUNLK ; DEQUE LDA 1,@.AC ; LINK AT HEAD OF CHAIN STA 1,TLNK,2 STA 2,@.AC RE.SCHED .AC: .GADD USTAD,USTAC .AKRT: K.IL2 .ERTID: ERTID .TUNLK: TUNLK KBITSc: TSSYS+TSABT+TSUSR ; CALL TO CHANGE PRI OF TASK = TID IN AC1 ; AC0= NEW PRI T.IDP: INC 3,3 ; ASSUME GOOD RETURN EN.SCHED .TSAVE ID.SRCH ; SEARCH FOR ID IN AC1 JMP TIDER ; NOT FOUND INT.DS MOVO 0,0 ; SET CARRY TO SHOW INT.DS JMP @.+1 ; ENTERLI .PRI WITH AC0 = NEW PRI P.RI1 ; AND AC2 = TCB .END ; END OF TIDC.SR PRI.SR= 8a3.TITL PRI .RB PRI.RB .ENT .PRI .EXTN P.RI .ZREL .PRI= JSR @. P.RI .END ; END OF PRI.SR TPRI.SR=%.TITL TPRI ; CHANGE TASK PRIORITY .RB TPRI.RB .ENT P.RI,P.RI1 .EXTN EN.SCHED,RE.SCHED,.TSAVE,TUNLK,TLINK,INT.EN .NREL P.RI: EN.SCHED ; CHANGE PRIORITY OF USER .TSAVE MOVZ 3,2 ; SHOW NO INT.DS ; COMMON CODE FOR .TIDP AND .PRI ; AC0 = NEW PRI ; A+nC2 = TCB ADDRESS ; CARRY = 1 => INT.DS WAS DONE P.RI1: LDA 1,STMSK ; LEFT BYTE MASK LDA 3,TPRST,2 ; CURRENT STATUS AND 1,3 ; DROP PRI MOVS 1,1 ; 377 AND 1,0 ; INSURE PRI <= 377 ADD 0,3 ; OLD STATUS + NEW PRI STA 3,TPRST,2 ; TO TCB MOV# 0,0,SZC(l ; INT.DS FROM .TIDP? INT.EN ; YES, THEN LET I/O IN JSR @.TUNLK ; REMOVE TCB FROM CHAIN MOV 2,1 JSR @.TLINK ; AND LINK IN BY NEW PRIORITY RE.SCHED STMSK: 377B7 .TUNLK: TUNLK .TLINK: TLINK .END ; END OF TPRI.SR DRSCH.SR= 7o.TITL DRSCH .RB DRSCH.RB .ENT .DRSCH .EXTN D.RSCH .ZREL .DRSCH= JSR @. D.RSCH .END ; END OF DRSCH.SR ERSCH.SR= 7o.TITL ERSCH .RB ERSCH.RB .ENT .ERSCH .EXTN E.RSCH .ZREL .ERSCH= JSR @. E.RSCH .END ; END OF ERSCH.SR TRSCH.SR= 4|i.TITL TRSCH ; ENABLE/DISABLE RESCHEDULING .RB TRSCH.RB .ENT E.RSCH,D.RSCH .EXTN EN.SCHED,RE.SCHED,.TSAVE,.SAC3 .NREL ; DISABLE TASK RESCHEDULING D.RSCH: EN.SCHED STA 3,DRSCX .SAC3 ; GET CORRECT AC3 JMP @DRSCX ; RETURN IMMEDIATELY ; ENABLE TAsZSK RESCHEDULING E.RSCH: EN.SCHED .TSAVE RE.SCHED DRSCX: 0 ; D.RSCH RETURN ADDRESS .END ; END OF TRSCH.SR ABORT.SR= 7o'.TITL ABORT .RB ABORT.RB .ENT .ABORT .EXTN A.BORT .ZREL .ABORT= JSR @. A.BORT .END ; END OF ABORT.SR TABT.SR=%.TITL TABT ; TASK ABORT PROCESSOR .RB TABT.RB .ENT A.BORT .EXTN EN.SCHED,RE.SCHED,ER.SCHED,.TSAVE,ID.SRCH .EXTN .SAC3,TUNLK,K.IL2,SYST0,INT.DS,INT.EN .EXTN USTAD .EXTD CTCB .NREL ; THIS ROUTINE ABORTS A TASKS CURRENT CALL AND KILLS IT ; AC1= TID TO KILL ; AC0 IS NOT PRESERVED IF .SYSTM/.ABTC IS ISSUED ; IF TASK HAS ISSUED A .RDOP, QTY I/O, OR IS CURRENTLY ; BEING ABORTED IT WILL NOT BE ABORTED AND AN ERROR RETURNED A.BORT: INC 3,3 ; ASSUME GOOD RETURN EN.SCHED .TSAVE ID.SRCH ; SEARCH FOR TID _IN AC1 JMP TIDER INT.DS LDA 0,TPRST,2 ; SEE WHAT TASK IS DOING MOVL# 0,0,SNC ; TSSYS SET? JMP AB01 ; NO, DON'T ABORT-GO KILL ; TASK MUST BE ABORTED- CALL RDOS LDA 1,CABT ; YES, TEST ABORT LOCK BIT AND# 0,1,SZR ; ABORT IN PROCESS? JMP ABER ; YES, RETURN ERROR ADD 0,1 ; NO, SET ABORT BIT STA 1,TPRST,2 ; (INT.EN OMITTED FOR EFFICIENCY) LDA 3,CTCB ; CALLER STA 2,TAC0,3 ; TCB TO ABORT LDA 2,TPC,3 ; REAL PC STA 2,TAC3,3 LDA 2,.ARTN ; PROC RTN JMP @.+1 SYST0 ; RETURN FROM SYSTEM CALL .oABTC - AC0 = ABORTED TCB ABRT: .ABTC ; SYSTEM ABORT CALL MOVO 0,0,SKP ; ERROR RETURN FROM SYSTEM MOVZ 0,0 ; FLAG GOOD RETURN EN.SCHED LDA 2,CTCB ; GET HIS TCB STA 3,TPC,2 ; RESTORE PC .SAC3 ; PICK UP RETURN CONTENTS STA 3,TAC3,2 INT.DS ;I BOTH PATHS NEED TO SHUT OUT ; INTERRUPTS MOV 0,2,SZC ; ERROR ? (MOVE TCB ADDR TO AC2) JMP ABER1 ; YES ; KILL TASK - ENTER HERE WITH AC2 = TCB TO ABORT AB01: LDA 1,.AKRT ; SET UP PC FOR KILLING STA 1,TPC,2 LDA 1,TPRST,2 ; CLEAR MOST BITS, LDAL 0,KBITS ; SET PRI = 0 AND 0,1 STA 1,TPRST,2 INT.EN ; INTERRUPTS OK NOW JSR @.TUNLK ; UNLINK TCB LDA 1,@.AC ; LINK AT HEAD OF CHAIN STA 1,TLNK,2 STA 2,@.AC RE.SCHED TIDER: LDA 2,.ERTID ER.SCHED ABER1: LDA 1,TPRST,2 LDA 0,CABT ; CLEAR ABOR`T BIT SUB 0,1 STA 1,TPRST,2 ABER: INT.EN ; LET INTERUPTS BACK IN LDA 2,.ERABT ER.SCHED .ARTN: ABRT CABT: TSABT .AKRT: K.IL2 ; KILL PROCESSOR .ERTID: ERTID .ERABT: ERABT .TUNLK: TUNLK .AC: .GADD USTAD,USTAC ; POINTER TO ACTIVE CHAIN KBITS: TSUSR 9; USER STATUS ONLY BIT TO SAVE .END ; END OF TABT.SR SUSP.SR= 9h.TITL SUSP .RB SUSP.RB .ENT .SUSP .EXTN S.USP .ZREL .SUSP= JSR @. S.USP .END ; END OF SUSP.SR TPEND.SR= M.TITL TPEND ; .SUSP LOGIC .RB TPEND.RB .ENT S.USP .EXTN EN.SCHED,.TSAVE,RE.SCHED .NREL S.USP: EN.SCHED .TSAVE LDA 1,TPRST,3 LDA 0,CPND ADD 0,1 STA 1,TPRST,3 RE.SCHED CPND: TSSUSP .END ; END OF TPEND.SR TUMOD.SR=% %.IFE MSW!BSW .TITL TUMOD .RB TUMOD.RB .ENDC .IFN BSW .TITL BTUMOD .RB BTUMOD.RB .ENDC .IFN MSW-MBSW .TITL MTUMOD .RB MTUMOD.RB .ENDC .IFN MBSW .TITL ATUMOD .RB ATUMOD.RB .ENDC .IFN MSW .ENT .REMAP .ENDC .ENT .UCEX,.UPEX,.UIEX,.SMSK .IFN MBSW .ENT .LEFE,.LmEFD,.LEFS .ENDC .ZREL S?MSK: S.MSK .IFN MSW R?EMAP: R.EMAP U?IEX: U.IEX U?PEX: U.PEX U?CEX: U.CEX .ENDC .IFN MBSW L?EFE: L.EFE L?EFD: L.EFD L?EFS: L.EFS .ENDC .SMSK= JSR @S?MSK .IFE MSW .UCEX= JMP 0,3 .UPEX= JMP 0,3 .UIEX= JSR 0,3 ; TO GET ADDR. FOR GRm}OUND DETERMINATION .ENDC .IFN MSW .REMAP= JSR @R?EMAP .UCEX= JSR @U?CEX .UPEX= JSR @U?PEX .UIEX= JSR @U?IEX .ENDC .IFN MBSW .LEFE= JSR @L?EFE .LEFD= JSR @L?EFD .LEFS= JSR @L?EFS .ENDC .NREL ; THIS ROUTINE OR'S IN AC1'S CONTENTS TO THE SYSTEM INTERRUPT ; ΗMASK S.MSK: .IFE MSW .IFE BSW LDA 2,CSP ; STATE SAVE AREA ON STK LDA 0,ICMSK,2 ; OLD STK COM 1,1 AND 1,0 ADC 1,0 .ENDC .IFN BSW LDA 0,@SP ; *** SUSPECT CODE *** IOR 1,0 .ENDC STA 0,CMSK MSKO 0 JMP 0,3 .ENDC .IFN MBSW LDA 0,C10 SCL ; SET MASK JMP 0,3 ; RTN .ENDC .IFN MSW-MBSW MOV 3,2 ; RTN ADDR LDA 0,C10 SCL NIOC MAP .ENDC .IFN MSW .IFE MBSW ; THE FOLLOWING ROUTINES ARE NEEDED IN MRDOS ONLY ; THEY TRAP INTO MRDOS WITH THE TRAP CODE IN AC0 U.CEX: LDA 0,C2 ; USER CLOCK SCL NIOC MAP U.PEX: LDA 0,C4 ; POWER FAIL ROUTINE RTN SCL NIOC MAP U.IEX: LDA 0,C3 ; INT SERVICE SCL NIOC MAP R.EMAP: MOV 2,0 ; # SLOTS MOV 3,2 ; RTN MOV 0,3 ; FOR COMMON PATH LDA 0,C11 ; REMAP CODE SCL NIOC MAP .ENDC .IFN MBSW U.CEX: LDA 0,C2 SVC ނ ; USER CLK RTN U.PEX: LDA 0,C4 SVC ; POWERFAIL ROUTINE RTN U.IEX: LDA 0,C3 SVC ; INT SERVICE RTN  R.EMAP: LDA 0,C11 ; REMAP CODE SCL JMP 0,3 ; BAD RTN JMP 1,3 ; GOOD RTN ; LEF MODE CONTROL CMDS ; NO PARAMETERS OR ERROR RTNS L.EFE: LDA 0,C12 ; SCL TO ENABLE SCL JMP 0,3 L.EFD: LDA 0,C13 ; SCL TO DISABLE SCL JMP 0,3 L.EFS: LDA 0,C14 ; SCL FOR STATE OF LEF SCL JMP 0,3 C12: 12 C13: 13 C14: 14 .ENDC C10: 10 C2: 2 C3: 3 C4: 4 C11: 11 .ENDC .END ; END OF TUMOD.SR TSVRS.SR=% E; GENERAL EXTENDED SAVE/RESTORE ROUTINE ; JSR'ED TO ON RESCHEDULE WHEN NEW TCB TO RUN <> OLD ONE ; CTCB -> TCB ABOUT TO RUN ; (ALSO, AC2 -> TCB THAT WAS JUST RUNNING, BUT THIS IS NOT ; USED BY THIS ROUTINE) ; ; TWO GROUPS OF PER-TASK DATA ARE HANDLED INDEPENDENTLY: ; 1) EXTENDED STATE (ESV.Z LOCS STARTING AT ESV.S) ; 2) FLOATING POINT STATE (ACS AND STATUS) ; ACTION FOR EACH GROUP DEPENDS ON CURRENT OWNER OF THE RESOURCE ; (AS IDENTIFIED BY LZSAV AND LFSAV, RESPECTIVELY) AND ; BY WHETHER NEW TCB TO RUN WILL] BECOME NEW OWNER. IF NEW TASK ; DOES NOT CARE ABOUT RESOURCE, NO SAVE/RESTORE IS DONE. ; (NOTE: THIS MEANS THAT TASKS NOT CRANKED UP WITH AN EXTENDED ; STATE OR FPU STATE BETTER NOT PLAY WITH THESE RESOURCES, OR ; OTHER TASKS USING THEM ACCORDING TO THE  RULES WILL GET ; SCREWED.) IF NEW TASK CARES ABOUT RESOURCE AND IS ALSO ; CURRENT OWNER, NO SAVE/RESTORE IS DONE. (NOTE: IF NEW ; TCB IS SAME AS OLD ONE, NO SAVE/RESTORE OF EITHER GROUP ; IS DONE (THIS ROUTINE IS NEVER CALLED). THIS MEANS THAT ; A TASK ˳MAY NOT DYNAMICALLY ACQUIRE EITHER AN EXTENDED STATE ; OR A FLOATING POINT STATE.) IF NEW TASK CARES BUT IS NOT ; CURRENT OWNER, CURRENT STATE IS SAVED IN CURRENT OWNER'S ; SAVE AREA (UNLESS CURRENT OWNER IS NULL [0], IN WHICH CASE ; SAVE IS SKIPPED), ANDg NEW TASK'S STATE IS RESTORED FROM HIS ; SAVE AREA. CURRENT OWNER IS NULL INITIALLY AND ANY TIME ; CURRENT OWNER GETS KILLED. .IFE MBSW!BSW .TITL TSVRS .RB TSVRS.RB .ENDC .IFN MBSW!BSW .TITL BTSVRS .RB BTSVRS.RB .ENDC .ENT ESV.X,ESV.A,ESV.K .EXTDU CTCB .EXTN ESV.S,ESV.Z .NREL ; ENTER HERE FROM RESCHEDULE CODE IN TCBMON VIA "JSR ESV.X", ; OR FROM USER ROUTINE ESV.X VIA "JSR ESV.A" ESV.A: ESV.X: STA 3,SRTN ; SAVE RETURN ADDRESS LDA 2,CTCB ; GET CURRENT TCB ; EXTENDED STATE SAVE/RESTORE ; LZS@AV -> CURRENT OWNER'S EXTENDED SAVE AREA (OR NULL) ; TELN,2 -> POTENTIAL NEW OWNER'S EXTENDED SAVE AREA Z.OFF= 1 ; OFFSET WITHIN TCB EXTENDER TO ; BEGINNING OF SAVE AREA LDA 2,TELN,2 ; GET EXTENDER ADDRESS ADDO# 2,2,SBN ; SKIP IF HAS ONE (.GT. 0#) JMP DOFPU ; ELSE JUST DO FPU .IFE MBSW!BSW ??NNZ: JMP FSTSR ; [BECOMES JMP ZOK IF ESV.Z=0, ; OR LDA 3,LZSAV OTHERWISE] SUB# 2,3,SNR ; LAST ADDR SAME AS NEW ONE? JMP ZOK ; IF YES SKIP SAVE/RESTORE STA 2,LZSAV ; ELSE UPDATE LAST ADDR LDA 1,SAV.Z ; PREPARE FOR SAVE LOOP LDA 2,SAV.S ; MOV# 3,3,SZR ; CHECK FOR NULL LAST ADDR JMP ZSIN ; ENTER LOOP JMP ZRSTR ; SKIP SAVE IF LZSAV NULL ZSLOOP: INC 2,2 ; BUMP POINTERS INC 3,3 ; ZSIN: LDA 0,0,2 ; MOVE A WORD STA 0,Z.OFF,3 ; INC 1,1,SZRz ; DONE? JMP ZSLOOP ; BACK FOR MORE ZRSTR: LDA 1,SAV.Z ; PREPARE FOR RESTORE LOOP LDA 2,SAV.S ; LDA 3,LZSAV ; SOURCE IS NEW GUY'S SAVE AREA JMP ZRIN ; ENTER LOOP ZRLOOP: INC 2,2 ; BUMP POINTERS INC 3,3 ; ZRIN: LDA 0,Z.OFF,3 ; MOVE A WORD STHA 0,0,2 ; INC 1,1,SZR ; DONE? JMP ZRLOOP ; NOT YET LDA 2,LZSAV ; NEW EXTENDER [MUST BE IN AC2] ZOK: LDA 2,0,2 ; GET FPU SAVE ADDRESS .ENDC .IFN MBSW!BSW LDA 3,LZSAV ; GET LAST EXT SAVE AREA ADDR INC 2,0 ; BUMP NEW ONE TO BLM-ING ADDR SUB# 0,S3,SNR ; ADDRS MATCH? JMP ZOK ; IF SO, NO NEED SAVE/RESTORE STA 0,LZSAV ; ELSE UPDATE LAST ADDR LDA 1,SAV.Z ; PREPARE FOR SAVE BLM LDA 2,SAV.S ; MOV# 3,3,SZR ; SKIP SAVE IF LZSAV NULL BLM ; MOVE THE BLOCK ZRSTR: LDA 1,SAV.Z ; PREPARE FOR RESTORE BLM MOV 0,2 ; LDA 3,SAV.S ; BLM ; MOVE THE BLOCK MOV 0,3 ; RESTORE AC3 TO LZSAV ZOK: LDA 2,-1,3 ; AC2 -> FPU SAVE AREA ADDR .ENDC ; FPU STATE SAVE/RESTORE ; LFSAV -> CURRENT OWNER'S FPU SAVE AREA (OR NULL) ; AC2 -> POTENTIAL NEW OWNER'S FPU SAVE AREA .IFE MBSW!BSW ; F.PAC= 0. ; FPAC ; F.TMP= 4. ; TEMP F.STAT= 8. ; STATUS F.LEN= 9. ; LENGTH OF SAVE BLOCK .ENDC .IFN MBSW!BSW ; F.STAT= 0. ; STATUS ; F.AC0= 2. ; FAC0 ; F.AC1= 6. ; FAC1 ; F.AC2= 10. ; FAC2 ; F.AC3= 14. ; FAC3 F.LEN={ 18. ; LENGTH OF SAVE BLOCK .ENDC DOFPU: LDA 3,LFSAV ; GET LAST AREA ADDR MOVZL 2,1,SZR ; IF THE NEW ONE IS 0 OR @0, SUB# 2,3,SNR ; OR IF NEW=OLD: JMP @SRTN ; THEN NO NEED SAVE/RESTORE FPU STA 2,LFSAV ; ELSE UPDATE LAST ADDR .IFE MBSW!BSW LDA 10,C4 ; AC0 <- FP PRECISION MOV# 3,3,SNR ; IF LFSAV IS NULL: JMP FRSTR ; THEN SKIP FPU SAVE SKPBZ FPU JMP .-1 DOBS 3,FPU2 ; STORE FPAC SKPBZ FPU JMP .-1 NIOC FPU2 ; MOVE TEMP TO FPAC ADD 0,3 ; BUMP POINTER SKPBZ FPU JMP .-1 DOBS 3,FPU2 ; !_STORE TEMP SKPBZ FPU JMP .-1 DIAC 1,FPU ; READ STATUS STA 1,F.STAT-4,3 ; SAVE IT IN SAVE AREA FRSTR: LDA 1,F.STAT,2 ; RESTORE STATUS FOR NEW TASK SKPBZ FPU JMP .-1 DOA 1,FPU ; ADD 2,0 ; BUMP POINTER SKPBZ FPU JMP .-1 DOBP 0,FPU2  ; LOAD VALUE FOR TEMP SKPBZ FPU JMP .-1 NIOP FPU2 ; MOVE FPAC TO TEMP SKPBZ FPU JMP .-1 DOBP 2,FPU2 ; LOAD FPAC .ENDC .IFN MBSW!BSW ; NOTE: MUST USE FPSH AND FPOP TO AVOID CAUSING TRAP ; MUST ALSO SUPPRESS STACK OVERFLOW AND UNDERFLOW ADC 0,0 ; AC0 <- -1ĺ ADDZ 0,3,SNC ; DECREMENT STACK POINTER-TO-BE JMP FRSTR ; SKIP FPU SAVE IF LFSAV NULL STA 3,SP ; SET UP STACK POINTER FOR PUSH STA 0,CSL ; SUPPRESS STACK OVERFLOW CHECK FPSH ; SAVE FPU STATE FRSTR: LDA 0,FOFST ; SET UP STACK POINTER FOR POP A*DDOR 0,1 ; (GUARANTEE THAT BIT 0 = 1 STA 1,SP ; TO SUPPRESS UNDERFLOW) FPOP ; RESTORE FPU STATE .ENDC JMP @SRTN ; RETURN TO CALLER (USUALLY ; SCHEDULER) .IFE MBSW!BSW ; (NOVA ONLY) ; COME HERE FIRST TIME SAVE/RESTORE HAPPENS ; NEGATE CONTENleTS OF SAV.Z, AND IF 0 SET UP CODE TO SKIP ; EXTENDED STATE SAVE/RESTORE FSTSR: LDA 0,..NZ0 ; SET UP REAL INSTRUCTION STA 0,??NNZ ; (LDA 3,LZSAV) LDA 0,SAV.Z ; GET EXT SAVE SIZE LDA 1,..NZ1 ; GET REPLACEMENT INSTRUCTION NEG 0,0,SNR ; NEGATE SIZE, tPSKIP IF NON-ZERO STA 1,??NNZ ; SET UP TO SKIP EXT SAVE/RESTORE STA 0,SAV.Z ; SET UP PROPER SIZE JMP ??NNZ ; RETURN TO MAINLINE ..NZ0: LDA 3,LZSAV-??NNZ,1 ; = LDA 3,LZSAV AT ??NNZ ..NZ1: JMP ZOK-??NNZ,1 ; TO BYPASS EXT SAVE/RSTR IF ; SIZE IS 0 .MENDC SRTN: .BLK 1 ; FOR RETURN ADDRESS SAV.S: ESV.S ; START OF EXTENDED SAVE AREA SAV.Z: ESV.Z ; LENGTH OF EXT SAVE AREA ; [FOR NOVA, MADE NEGATIVE BY ; FIRST-TIME CODE AT FSTSR] LZSAV: 0 ; LAST EXT SAVE ADDR ; [STORED AS +1 FOR ECLIPSE] LFSAV: 0 ; LAST FPU SAVE AREA ADDR .IFE MBSW!BSW C4: 4 ; NUMBER OF WORDS FOR FLOATING POINT REG .ENDC .IFN MBSW!BSW FOFST: (F.LEN-1)*2 ; OFFSET FROM FPU AREA PTR TO END OF AREA ; (SHIFTED LEFT ONE BIT) .ENDC ; ENTER HERE FROM TREL IN TCBMOiN WHEN KILLING A TASK ; MUST FORGET ABOUT THAT TASK'S EXTENDED STATE AND/OR FPU ; STATE SAVE AREAS, IF HE HAD EITHER OR BOTH ; (MAKE LZSAV OR LFSAV NULL TO FORGET ABOUT THEM) ; AC2 -> TCB GETTING KILLED (MUST BE PRESERVED) ESV.K: STA 3,SRTN ; SAVE RETURN ADDRESS SUBC 0,0 ; 0 FOR ZAPPING LDA 3,TELN,2 ; GET EXTENDER ADDR ADDO# 3,3,SBN ; SKIP IF HAS ONE JMP ESVK1 ; JUST LOOK FOR FPU SAVE AREA STA 0,LZSAV ; FORGET LAST OWNER OF EXT STATE LDA 3,0,3 ; PICK UP FPU SAVE AREA ADDR ESVK1: MOVZL# 3,3,SZR ; SKIP IF NO FPU SAVE AREA STA 0,LFSAV ; IF HAD ONE, FORGET IT JMP @SRTN ; RETURN TO SCHEDULER .END ; END OF TSVRS.SR SINGL.SR= 9o?.TITL SINGL .RB SINGL.RB .ENT .SINGL .EXTN S.INGL .ZREL .SINGL= JSR @. S.INGL .END ; END OF SINGL.SR MULTI.SR= 8o_.TITL MULTI .RB MULTI.RB .ENT .MULTI .EXTN M.ULTI .ZREL .MULTI= JSR @. M.ULTI .END ; END OF MULTI.SR SMTSK.SR= % $.TITL SMTSK ; SINGL/MULTI TASK .RB SMTSK.RB .ENT S.INGL ; ENTER SINGLE-TASK MODE .ENT M.ULTI ; ENTER MULTI-TASK MODE .EXTN EN.SCHED,RE.SCHED,.TSAVE,SM.SW .NREL S.INGL: EN.SCHED .TSAVE SUBZL 0,0 ; SINGLE-TASK STATE IS "1" STA 0,@SM?SW RE.SCHED M.ULTI: EN.SCHED .TSAVE SUB 0,0 ; MULTI-TASK STATE IS "0" STA 0,@SM?SW RE.SCHED SM?SW: SM.SW ; SINGLE/MULTI SWITCH .END ; END OF SMTSK.SR TASK.SR= 9h/.TITL TASK .RB TASK.RB .ENT .TASK .EXTN T.ASK .ZREL .TASK= JSR @. T.ASK .END ; END OF TASK.SR KILL.SR= 8h<.TITL KILL .RB KILL.RB .ENT .KILL .EXTN K.ILL .ZREL .KILL= JSR @. K.ILL .END ; END OF KILL.SR KILAD.SR= 8or.TITL KILAD .RB KILAD.RB .ENT .KILAD .EXTN K.ILAD .ZREL .KILAD= JSR @. K.ILAD .END ; END OF KILAD.SR TCBMON.SR=%: .IFN NSW!N3SW .TITL TCBMON .RB TCBMON.RB .ENDC .IFN MNSW!MN3SW .TITL MTCBMON .RB MTCBMON.RB .ENDC .IFN BSW .TITL BTCBMON .RB BTCBMON.RB .ENDC .IFN MBSW .TITL ATCBMON .RB ATCBMON.RB .ENDC ;.REV 6,00 .ENT EN.SCHED,RE.SCHED,ER.SCHED,.TSAVE .ENT INT".DS,INT.EN,ID.SRCH .ENT T.ASK,K.ILL,K.ILAD,K.IL2 .ENT TMAX, R.UTSK .ENT SYST0,SYST1 .ENT TUNLK,TLINK .ENT CTCB,SM.SW,LQTSC,QTCNT .ENT .RTASK .EXTN USTAD,Q.TCK,.SAC2 .EXTN TSK.X,TRL.X,ESV.X,ESV.K ;DOCUMENTATION ON THE MULTI-TASKING INTERFACE .DO 0 THE TMMULTI-TASKING INTERFACE HAS THE FOLLOWING PURPOSE: A. PROVIDE A STANDARD AND COMMON SET OF ENTRIES INTO THE MULTI- TASKING SCHEDULER. THESE ENTRIES PROVIDE THE ABILITY FOR A USER OR LANGUAGE TO PROVIDE SPECIAL-PURPOSE TASKING PRIMITIVES. B. PROVIDE NECESSARY EXITS FROM THE TASK SCHEDULER TO ALLOW USER/ LANGUAGE EXTENSIONS TO THE TASK CREATION AND DELETION PROCESSES. C. THE FOLLOWING DEFINITIONS ARE INCLUDED FOR CLARITY: INTERRUPT DISABLED STATE ------------------------ 1) GUARANTEED UNINTERRUPTABLE CODE PATH. 2) NO OTHER USER CAN ENTER CODE PATH UNTIL FIRST CALLER LEAVES THIS STATE, INCLUDING THE INTERRUPT WORLD. SCHEDULER STATE --------------- 1) CODE PATHS CAN BE INTERRUPTED, BUT CONTROL WILL ALWAYS RETURN TO POINT OF INTERRUPTION AFTER INTERmRUPT HAS BEEN DISMISSED. 2) GUARANTEES CODE PATH WILL NOT BE USED BY ANY OTHER USER EXCEPT INTERRUPT SERVICE ROUTINES. 3) USTPC IS INVALID IN UNMAPPED RDOS SYSTEMS. 4) LOCAL, NON TASK CONTEXT, STORAGE MAY BE USED. USER STATE ---------- 1) CODE PATH!QS MUST BE RE-ENTRANT UNLESS PROGRAM LOGIC PROHIBITS A PATH FROM BEING IN USE BY MORE THAN ONE TASK. 2) LOSS OF CONTROL WILL OCCUR WHENEVER AN INTERRUPT SERVICE ROUTINE READIES A HIGHER PRIORITY TASK. 4. IMPLEMENTATION -- -------------- THIS SECTIO9N DESCRIBES THE MULTI-TASKING INTERFACE. A. TASK CREATION EXIT - TSK.X -- -------------------------- THIS ROUTINE WILL BE CALLED IF IT EXISTS. IT IS ENTERED IN SCHEDULER STATE WITH THE TCB ALLOCATED AND UNLINKED FROM BOTH THE FREE AND ACTIVE CHAINS. USAGE IS AS FOLLOWS: INPUT: AC0 - TAC2 AC1 - QUEUE ARRAY ADDRESS OR -1 AC2 - TCB ADDRESS CALL: JSR "TSK.X" ; AC2 = ERROR CODE TSK.X NEED NOT PRESERVE AC'S OR CARRY. THIS ROUTINE IS CALLED FROM THE .TASK LOGIC WITH AC14 = -1 AND FROM THE QTASK CRANKING LOGIC WITH AC1 = ADDRESS OF QUE ARRAY. THIS ROUTINE ALLOWS THE USER TO SET UP A TCB EXTENDER, ETC. ON ERROR RETURN TO THE QTASK CRANKING LOGIC, THE TASK IS NOT PLACED ON THE ACTIVE CHAIN, THE TCB IS FREED, AND THE TASK WAITS TO BECOME ACTIVE AS IF THERE HAD BEEN NO TCB AVAILABLE. B. TASK DELETION EXIT - TRL.X -- -------------------------- THIS ROUTINE WILL BE CALLED IF IT EXISTS. IT IS ENTERED IN SCHEDULER STATE WITH THE TCB UNLINKED FROM BOTH THE ACTIVE AND FREE CHAINS. TRL.X ALLOWS THE USER TO FREE THOSE RESOURCES ALLOCATED BY TSK.X. USAGE IS AS FOLLOWS: INPUT: AC2 - TCB CALL: JSR "TRL.X" TRL.X DOES NOT NEED TO PRESERVE AC'S OR CARRY. C. ZREL CONSERVATION -- ----------------- TO ALLOW THOSE USERS THAT -ARE SHORT OF ZREL STORAGE THE ABILITY TO ACCESS THE MULTI-TASKING PRIMITIVES, TWO ENTRIES WILL BE PROVIDED FOR EACH PRIMITIVE. JSR THROUGH ZREL REFERENCES WILL BE BY THE CURRENTLY DEFINED NAMES SUCH AS .TASK, WHILE NREL REFERENCES WILL BE TO THE SAME NAME< WITH THE FIRST TWO CHARACTERS SWAPPED, E.G. T.ASK. THE ZREL ENTRY AND DEFINITION WILL BE IN A SEPARATE MODULE FROM THE NREL NODE, AND WILL PRECEDE IT IN THE LIBRARY. FOR EXAMPLE: 1ST MODULE ---------- .TITL .TASK .ENT .TASK .EXTN T.ASK .ZREL .TASK = JSR @. T.ASK .END 2ND MODULE ---------- .TITL T.ASK .ENT T.ASK .EXTN EN.SCHED,RE.SCHED .EXTN .TSAVE .NREL T.ASK: INC 3,3 EN.SCHED .TSAVE . . . RE.SCHED .END D. TPRST STATUS BITS -- ----------------- THERE WILL BE THE FOLLOBWING DEFINED STATUS BITS: NAME VALUE MEANING ---- ----- ------- TSSYS 1B0 PENDED BY SYSTEM CALL TSSUSP 1B1 PENDED BY .SUSP, .TIDS, ETC. TSXMT 1B2 PENDED ON XMT/REC TSRDOP 1B3 PENDED ON .TRDOP TSABT 1B4 ABORT LOCK BIT (PENDED) TSRSV 1B5 RESERVED (`PENDED) TSUPN 1B6 PENDED BY USER TSUSR 1B7 RESERVED FOR USER/LANGUAGE (STATUS ONLY) IF ANY BIT EXCEPT TSUSR IS SET TO ONE, THE TASK IS NOT READY TO RUN. TSRSV IS RESERVED FOR FUTURE USE. EACH BIT, BY ITSELF, WILL BE USED TO INDICATE THE SPECIFIC LrPEND CONDITION AS LISTED ABOVE. FOR INSTANCE, TSSYS ALWAYS MEANS THAT THE SYSTEM IS PROCESSING THIS TCB REGARDLESS OF THE SETTING OF TSXMT OR TSRDOP. THIS DIFFERS FROM PREVIOUS IMPLEMENTATION IN THAT TSSYS WAS SET ALONG WITH TSXMT OR TSRDOP WHEN A TASK WcAS PENDED ON A .XMTW, .REC, .TOVLD (NODE IN USE), AND .TRDOP (ANOTHER TASK DOES THE .SYSTM/.RDOP). E. EXTENDED SAVE/RESTORE -- --------------------- THE USER MUST FORCE LOADING OF THE EXTENDED SAVE/RESTORE LOGIC. BY DEFAULT, THERE WILL BE NO EXTENDED SAVE/RESTORE PERFORMED. TO FORCE LOADING, THE USER MUST PROVIDE AN EXTERNAL REFERENCE TO THE SYMBOL "ESV.X" OR "ESV.A". (SEE 4.G.7). IF BITS 1-15 OF TELN OF THE USERS TCB ARE NON-ZERO, THEN THE EXTENDED SAVE-RESTORE FUNCTION WILL BE PERFORMED. THE MULTI- TASKING EXTENDED SAVE-RESTORE WILL SAVE ANY OR ALL OF MEMORY, AND/OR THE FLOATING POINT PROCESSOR REGISTERS AND STATUS. 1B0 (SIGN BIT) OF TELN IS THE FPU-ONLY SAVE-RESTORE FLAG (1 = SAVE FPU-ONLY). THE CONTENTS OF TELN IS THE ADDRESS OF THE AREA INTO WHICH THE CURRENT TASK'S SAVE-RESTORE WILL BE MADE. --------------------------------------------- TELN: I 0 I SAVE-RESTORE ADDRESS I --------------------------------------------- ^ FPU-ONLY (1 = SAVE-RESTORE) THE FIRST WORD IN THE USElR'S SAVE-RESTORE AREA IS THE ADDRESS OF THE USER'S FPU SAVE-RESTORE AREA, OTHERWISE ZERO. IF THE SIGN BIT IS OFF, BUT THE FIRST WORD OF THE USER'S SAVE-RESTORE AREA IS NON-ZERO, THEN BOTH THE FPU AND MEMORY AREA WILL BE SAVED. IF THE SIGN BIT IS ON, THE sADDRESS CONTAINED IN THE REST OF THE USER'S TELN IS THE ADDRESS OF THE FPU SAVE-RESTORE AREA., AND NO MEMORY SAVE-RESTORE FUNCTION IS PERFORMED. TWO EXTERNAL SYMBOLS MUST BE DEFINED BY THE USER AT LOAD TIME IF THE MEMORY SAVE/RESTORE IS TO BE PERFORMED WHzEN BITS 1-15 OF TELN ARE NON-ZERO. DEFAULT VALUE OF ESV.Z IS ZERO (0) WHICH IMPLIES NO MEMORY SAVE IS TO BE DONE. ESV.S -> MEMORY ADDRESS OF START OF AREA TO BE SAVED ESV.Z -> SIZE OF CONTIGUOUS MEMORY TO BE SAVED (WORDS) OFFSET "TELN" MUST BE SETu UP USING THE TSK.X EXIT DEFINED ABOVE. THE SAVE-RESTORE FUNCTION IS INVOKED ONLY FOR THOSE TASKS WHOSE "TELN" OFFSET IS NON-ZERO, AND THEREFORE TASKS WHICH REQUIRE SAVING AND TASKS WHICH DO NOT REQUIRE SAVING MAY BE INTERMIXED. TELN ADDR1 FUNCTION ----; ----- -------- 0 OR @0 ..... NO MEMORY SAVE/RESTORE NO FPU SAVE SAVE/RESTORE ADDR1 0 OR @0 MEMORY SAVE/RESTORE AT ADDR1+1 NO FPU SAVE/RESTORE @ADDR1 ..... NO MEMORY SAVE/RESTORE FPU SAVE/STORE AT ADDR1 ADDR1 ADDR2 MEMORY SAVE/RESP8TORE AT ADDR1+1 FPU SAVE/RESTORE AT ADDR2 ------------- ---------- --------- I 0 I ADDR1 I -> I ADDR2 I -> I FPU I ------------- ---------- I SAVE I I MEMORY I I AREA I I SAVE I --------- I AREA I ---------- THE SHAPE OF THE FPU SAVE AREA IS SHOWN HERE: WORD NOVA ECLIPSE ---- ---- ------- 0 FPAC STATUS 1 " " 2 " FPAC0 3 " " 4 FTMP " 5 " " 6 " FPAC1 7 " " 8 STATUS " 9 " 10 FPAC2 11 " 12 " 13 " 14 FPAC3 15 " 16 " 17 " NOTE THAT THE ECLIPSE FORMAT FOLLOWmS THE FPSH/FPOP DISCIPLINE AS DEFINED IN THE ECLIPSE COMPUTER PROGRAMMERS REFERENCE MANUAL. F. OPCOM INTERFACE EXTENSIONS -- -------------------------- THE USER/LANGUAGE MAY DEFINE AN ENTRY LPN.X TO SPECIFY THE NUMBER OF EXTRA WORDS TO BE COPIED FROM TH;E END OF THE PROGRAM TABLE ENTRY TO THE END OF THE QUE ARRAY. THIS PROVIDES THE CAPABILITY TO PASS USER/LANGUAGE SPECIFIC INFORMATION TO A QUEUED TASK EVEN WHEN STARTED BY OPCOM. LPN.X HAS A DEFAULT VALUE OF ZERO. OPCOM WILL LENGTHEN THE AREA RESERVED FOtR BOTH PROGRAM AND QUE ENTRIES BY LPN.X. G. COMMON TASK SCHEDULER ENTRIES -- ----------------------------- THE FOLLOWING EXTERNALS ARE PROVIDED FOR INTERFACING TO THE TASK SCHEDULER. THEY ALLOW ENTRY AND EXIT FROM SCHEDULER, INTERRUPT DISABLED STATE. TiHEY PROVIDE A TASK ID SEARCH ROUTINE AND ENTRIES TO THE EXTENDED SAVE MANAGER. 1) ENTER SCHEDULER STATE - EN.SCHED -- -------------------------------- TO ENTER SCHEDULER MODE FROM A USER PROGRAM ISSUE THE FOLLOWING TWO EXTERNALS: INPUT: AC3 = ADDRESS TO RETURN TO AFTER LEAVING SCHEDULER STATE (AS SET UP BY THE JSR WHICH CALLED THE ROUTINE WHICH IS ENTERING SCHEDULER STATE) CALL: EN.SCHED .TSAVE ; AC0,AC1,CARRY INTACT ; AC2 WILL CONTAIN THE CONTENTS OF .SYS. ; (TO ENABLE ADDRESSING LOCAL TO THE CALL ; TO THE ROUTINE WHICH PUT ITSELF INTO ; SCHEDULER STATE, AS FOR A SYSTEM CALL). ; AC3 & CTCB WILL CONTAIN THE TCB ADDRESS NOTE THAT A PROGRAM IN SCHEDULER STATE CAN NOT DETERMINE FROM THE VALUE OF USTPC WHETHER IT IS EXECUTING INO THE BACKGROUND OR THE FOREGROUND. (THE PROGRAM MUST CHECK USTP FOR = OR <> 400.) 2) LEAVE SCHEDULER STATE NORMALLY - RE.SCHED -- ----------------------------------------- TO EXIT TO THE SCHEDULER A USER ROUTINE SHOULD DO: CALL: RE.SCHED 3) LEAVE SCHEDULER STATE ABNORMALLY - ER.SCHED -- ------------------------------------------- TO EXIT TO THE SCHEDULER AND INDICATE THAT RETURN SHOULD BE MADE TO THE ERROR RETURN FOR THE TASK CALL (THE LOCATION PRECEDING THE ONE SPECIFIED BY TPC), A USER ROUTINE SHOAULD DO: INPUT: AC2 - ERROR CODE CALL: ER.SCHED 4) DISABLE AND ENABLE INTERRUPTS - INT.DS, INT.EN -- ---------------------------------------------- TO ENTER INTERRUPT DISABLE MODE USE THE EXTERNAL-- INT.DS TO EXIT INTERRUPT DISABLED MODE USE THE EXTE[-RNAL-- INT.EN NOTE: AC0, AC1, AC2, AND CARRY ARE PRESERVED ACROSS THESE CALLS FOR ALL SYSTEMS. FOR THE MAPPED WORLD, THEY USE LOCAL STORAGE TO PRESERVE THE AC'S AND ARE THERFORE ONLY CALLABLE WHILE IN SCHEDULER STATE. 5) TASK ID SEARCH - ID.SR)CH -- ------------------------ TO SEARCH FOR A TASK WITH A GIVEN ID USE: INPUT: AC1 - TID TO SEARCH FOR (IN LOW BYTE, HIGH BYTE IGNORED) CALL: ID.SRCH ; ERROR CODE IN AC2 ; AC2 IS TCB ADDRESS FOR BOTH RETURNS, AC0 AND CARRY ARE PRES*+ERVED AND AC3 IS DESTROYED. THE RIGHT BYTE OF AC1 (THE TID) IS PRESERVED, THE LEFT BYTE IS ZEROED. 7) EXTENDED SAVE EXITS - ESV.X, ESV.A, ESV.K -- ----------------------------------------- THESE ROUTINE NAMES ARE KNOWN TO THE SCHEDULER AND ARE USED TeO IMPLEMENT THE EXTENDED SAVE/RESTORE FUNCTIONS IN THE FOLLOWING MANNER: ESV.X IS CALLED AT EACH TASK CONTEXT CHANGE. ESV.A IS AN ALIAS FOR ESV.X. THIS ALLOWS THE USER TO PROVIDE AN ENTRY POINT THAT DOES ADDITIONAL CONTEXT SWITCHING AND THEN TO CALL ESV.A TO DO THE NORMAL CONTEXT SWITCHING. ON ENTRY AT ESV.X OR ESV.A: AC2 - OLD TCB ADDRESS CTCB - NEW TCB ADDRESS AC3 - RETURN ADDRESS ESV.K IS CALLED FROM THE .KILL LOGIC. ITS FUNCTION IS TO ALLOW THE EXTENDED SAVE/RESTORE LOGIC TO RECOGNIZE THAT THE CURRENT TASK CONTEXT IS NO LONGER VALID. IF THE USER HAS PROVIDED HIS OWN ESV.X THAT CALLS ESV.A, THEN HE CAN DO THE EQUIVALENT OF ESV.K IN HIS TRL.X ROUTINE (SEE 4.B.). 8) SYSTEM CALLS - .SYSTM, SYST0, SYST1 -- ----------------------------------- THESE= THREE ENTRIES ALLOW THE PROGRAM TO CALL THE OPERATING SYSTEM TO PERFORM A SYSTEM FUNCTION. THE FIRST, .SYSTM, IS DEFINED AS A "JSR @17" AND IS USED TO EXECUTE A SYSTEM CALL FROM USER STATE. THE SECOND AND THIRD ENTRIES ARE .NREL ADDRESSES AND ARE USED ThO EXECUTE SYSTEM CALLS WHILE IN SCHEDULER STATE. THEY WILL BE EXPLAINED IN DETAIL HERE. SYST0 IS USED WHENEVER THE CALLER WISHES TO REGAIN CONTROL BEFORE GOING BACK TO HIS CALLER. SYST1 IS USED TO EXECUTE A SYSTEM CALL AND RETURN WITH THE CALLER HAVING qTO HANDLE ANY ERROR CONDITIONS HIMSELF. SYST0 ----- ON ENTRY AT SYST0, CALLER MUST BE IN SCHEDULER STATE. AC3 - CTCB AC2 - POINTS TO SYSTEM CALL WORD AN EXAMPLE OF NORMAL USAGE IS GIVEN BELOW: ... LDA 3,CTCB LDA 2,TPC,3 STA 2,TAC3,3 ; SAVE REAL REòTURN LDA 2,.RTN. ; POINT TO SYSTEM CALL JMP @.+1 SYST0 .RTN.: .+1 .OVLOD CPU ; AC0,AC1,AC2 FROM TAC0, ; TAC1,TAC2 ; AC3 = .SAC3 VALUE ; CARRY AS INPUT TO SYST0 MOVO 0,0,SKP ; FLAG ERROR RETURN MOVZ 0,0 ; FLAG GOOD RETURN EN.SCHED&k ; BACK TO SCHEDULER STATE ... ... ; DO CLEANUP, USE ERROR FLAG ... ; IF NEEDED ... LDA 2,CTCB STA 3,TPC,2 ; PC & CARRY FROM TAC3 .SAC3 ; REAL AC3 TO RETURN STA 3,TAC3,2 RE.SCHED ; GO TO REAL RETURN NOTE: FOR ANOTHER WAY TO USE SYST0, CO4NSULT TOVLY.SR SYST1 ----- CALLER ENTERS THIS ROUTINE IN SCHEDULER STATE. AC3 - CTCB AC1 - SYSTEM CALL WORD TPC - SETUP FOR CORRECT RETURN EXAMPLE OF NORMAL USAGE IS: EN.SCHED .TSAVE ... LDA 3,CTCB LDA 1,.CALL JMP @.+1 SYST1 .CALL: .WROP THE FOLLOWING TABLE DESCRIBES WHAT INITIAL VALUES RDOS GIVES TO WORDS IN A TCB AND WHEN THOSE VALUES MAY BE CHANGED DURING THE TASK'S LIFETIME.  'NAME' IS THE PARA- METER IN PARU.SR REPRESENTING THE OFFSET WITHIN THE TCB STRUCTURE. 'INITIAL CONTENTS' DESCRIBaES THE VALUE PUT THERE BY RDOS AND SEEN ON INPUT TO TSK.X. '.TASK?' MEANS "MAY BE SET OR CHANGED BY TSK.X IF TASK IS BEING INITIATED BY .TASK ?". '.QTSK?' MEANS "MAY BE SET OR CHANGED BY TSK.X IF TASK IS BEING INITIATED BY .QTSK ?". 'LATER?' MEANS "MAY BcBE SET OR CHANGED LATER IN THE TASK'S LIFE WHILE IN SCHEDULER STATE ?". WHERE TWO INITIAL CONTENTS DESCRIP- TIONS ARE GIVEN SEPARATED BY A '/', THE FIRST APPLIES FOR .TASK AND THE SECOND FOR .QTSK. A NUMBER IN BRACKETS REFERS YOU TO A NOTE FOLLOWING THE ATABLE. NAME INITIAL CONTENTS .TASK? .QTSK? LATER? ---- ------- -------- ------ ------ ------ TPC (START ADDR)*2+(CARRY UNDEFINED) YES YES YES TAC0 UNDEFINED/SYSTEM-MAINTAINED YES N DUMMY ZERO-ETH TCB TNXT: MOV 3,2 ; SAVE LAST TCB LDA 3,TLNK,2 ; BUMP TO NEXT TCB OR END INC 3,0,SZR ; IF LAST, MAKE TPRST=0 E LDA 0,TPRST,3 ; GET STATUS AND# 1,0,SZR ; SKIP IF READY TO RUN JMP TNXT ; TRY NEXT COM# 3,3,SNR ; END? JMP TEXIT ; YES, SYSTEM IDLE STA 2,LTCBS ; SAVE POINTER TO PREVIOUS TCB ; CHECK TO SEE IF NEED TO DO SAVE/RESTORE LDA 2,CTCB ; AC2 <- FORMER TCB SUB# 2,3,SNR ; SAME AS NEW ONE? JMP FND1 ; IF YES, SKIP SAVE/RESTORE ; SWAPPING TASKS: SAVE/RESTORE TASK RESOURCES STA 3,CTCB ; UPDATE CURRENT TCB MOV# 2,2,SNR ; IF PRIOR TCB NULL, JMP DOUSR ; SKIP USP/STACK SAVE LDA 0,USP ; SAVE OLD USP STA 0,TUSP,2 .IFN ANSW LDA 0,@REVWD ; NOVA 3? LDA 1,N3BIT AND# 1,0,SNR JMP NO3SV ; NO MFSP 0 ; SAVE STACK POINTER STA 0,TSP,2 MFFP 0 ; FRAME POINTER STA 0,TFP,2 LDA 0,CSL ; STACK LIMIT STA 0,TSL,2 LDA 0,TRPC ; INSTRUCTION TRAP PC STA 0,TSO,2 NO3SV: .ENDC .IFN ABSW LDA 0,SP ; SAVE STACK POINTER STA 0,TSP,2 LDA 0,CSP ; FRAME POINTER STA 0,TFP,2 LDA 0,CSL ; STACK LIMIT STA 0,TSL,2 LDA 0,CSO ; STACK OVERFLOW ROUTINE STA 0,TSO,2 .ENDC DOUSR: JSR @ESV?X ; CALL USER SAVE/RESTORE  ; AC2=OLD TCB, CTCB=NEW TCB LDA 3,CTCB ; NEW TCB AGAIN .IFN ANSW LDA 0,@REVWD ; NOVA 3? LDA 1,N3BIT AND# 1,0,SNR JMP NO3RS ; NO LDA 0,TSP,3 ; RESTORE STACK POINTER MTSP 0 LDA 0,TFP,3 ; FRAME POINTER MTFP 0 LDA 0,TSL,3 ; STACK LIMIT STA" 0,CSL LDA 0,TSO,3 ; INSTRUCTION TRAP PC STA 0,TRPC NO3RS: .ENDC .IFN ABSW LDA 0,TSP,3 ; RESTORE STACK POINTER STA 0,SP LDA 0,TFP,3 ; FRAME POINTER STA 0,CSP LDA 0,TSL,3 ; STACK LIMIT STA 0,CSL LDA 0,TSO,3 ; STACK OVERFLOW ROUTINE STA 0,CSO A.ENDC LDA 0,TUSP,3 ; RESTORE USP STA 0,USP ; SEE IF A PRI SHUFFLE NEEDED BEFORE GOING TO USER ; IF > 1 TASK SAME PRI MOVE CURRENT TASK TO END OF GROUP ; AC3, CTCB -> TCB TO RUN ;ENTRY POINT R.UTSK: ; AC2 CONTAINS THE ADDRESS OF THE TCB OF THE TASK TO R UN. FND1: LDA 2,TLNK,3 ; NEXT IN CHAIN COM# 2,2,SNR ; LAST IN CHAIN? JMP FND2 ; YES, NO SHUFFLE NEEDED LDA 1,TPRST,3 ; STAT/PRI FOR OUR GUY LDA 3,TPRST,2 ; STAT/PRI FOR NEXT IN CHAIN LDA 0,PRMSK AND 0,1 ; DROP STATUS BITS AND 3,0 SUB# 0,1,SZR kX; SAME PRIORITY? JMP FND2 ; NO, SKIP SHUFFLE LDA 3,LTCBS ; PREVIOUS STA 2,TLNK,3 ; REMOVE CTCB FROM CHAIN LDA 1,CTCB ; TCB TO LINK IN JSR LNKPR ; GO LINK IN FND2: LDA 2,CTCB ; CURRENT TCB R.UTSK: LDA 3,USTP ; UPDATE CURRENT TCB IN UST STA 2,USTCT,3 .IFN USW MOVS 3,3 MOVZR 3,3,SZR ; RESET USTPC TO 0=BG, 1=FG SUBZL 3,3 LDA 1,TPC,2 ; LOAD PC + CARRY MOVZR 1,1 ; RESTORE CARRY STA 1,ERTN LDA 0,TAC0,2 ; RESTORE AC0 .RTASK: LDA 1,TAC1,2 ; RESTORE AC1 INT.DS  ; PROTECT UNTIL OUT OF SCHEDULER( STA 3,@USTP ; LEAVE SCHEDULER STATE LDA 3,TAC3,2 ; RESTORE AC3 & AC2 LDA 2,TAC2,2 INT.EN JMP @ERTN ; GO TO USER ERTN: 0 .ENDC .IFN MSW LDA 0,C6 ; SCHEDULE EXIT .RTASK: LDA 1,TAC1,2 ; RESTORE AC1 .IFN MSW-MBSW SCL NIOC MAP .ENDC .IFN MBSW LDA (3,TAC3,2 LDA 2,TAC2,2 ; LOAD AC2,AC3 SCL ; SCHEDULE .ENDC C6: 6 .ENDC ; .RTASK - THIS ENTRY POINT IS NEVER REFERENCED BY THE ; SCHEDULER. IT IS HERE FOR DEBUGGING PURPOSES ONLY. ; AT .RTASK, AC2 IS THE TCB ADDRESS THAT IS TO BE RUN. ; THIS PROVIDES A POINT AT WHICH THE NEXT TASK TO BE RUN ; CAN BE MONITORED. ; ALL TASKS IDLE - EXIT TO SYSTEM TEXIT: LDA 1,QTCNT ; SEE IF QWAIT ACTIVE .IFN USW MOV 1,2,SZR SUBZL 2,2 ; YES-TELL RDOSY JMP SYSX ; EXIT .ENDC .IFN MSW MOV 1,0,SZR SUBZL 0,0 ADC 2,2M ; AC2 MUST BE -1 SO SYSTE KNOWS ; ITS TCBMON NOT TMIN... .IFE MBSW SCL NIOC MAP ; EXIT .ENDC .IFN MBSW SVC .ENDC .ENDC LQTSC: -1 ; LAST QTASK SECOND Q?TCK: Q.TCK ; EACH-SECOND QTASK CHECK ROUTINE ESV?X: ESV.X ; USER SAVE/RESTORE ROUTINE SBITS: TSSYS+TSSUSP+TSXMT+TSRDOP+TSABT+TSRSV+TSUPN; PEND BITS TDUML: .GADD USTAD,USTAC-TLNK; DUMMY ZERO-ETH TCB ADDRESS REVWD: .GADD USTAD,USTRV ; REVISION WORD IN UST N3BIT: ENUN3+ENMN3+ENUMN ; NOVA 3 + MICRO NOVA BITS ; SYSTEM CALL LOGIC SYST: EN.SCHEDy .TSAVE ; CAN ENTER HERE ALREADY IN SCHEDULER STATE WITH: ; AC2 -> SYSTEM CALL CONSTANT WORD ; AC3 = CTCB ; NOTE: CARRY IS PUT INTO TPC SYST0: LDA 1,0,2 ; LOAD SYST CONTROL WORD INC 2,2 INCL 2,2 ; ADD 2 FOR GOOD RTN STA 2,TPC,3 ; PUT BACK IN TCB ; CAN ENTER HERE ALREADY IN SCHEDULER STATE WITH: ; AC1 = SYSTEM CALL CONSTANT WORD ; AC3 = CTCB ; TPC,3 ALREADY SET UP FOR GOOD RETURN SYST1: STA 1,TSYS,3 ; SYSTEM REQ TO TCB LDA 1,TPRST,3 ; STATUS AND PRIORITY ADDOR 1,1 ; SET 1B0 (PEND) STA 1,TPRST,3 .IFE MSW MOV 3,2 ; PASS TCB IN AC2 SYSX: LDA 3,USTP MOVS 3,3 MOVZR 3,3,SZR ; RESET USTPC TO 0=BG, 1=FG SUBZL 3,3 INT.DS ; THIS IS ALWAYS "INTDS" STA 3,@USTP ; LEAVE SCHEDULER STATE SO SYSTEM JMP @2 ; WILL RETURN TO TMAX .ENDC .IFN MSW MOV 3,0 ; PASS TCB IN AC0 .IFE MBSW SCL NIOC MAP .ENDC .IFN MBSW SVC ; BIRD SUPERCALL .ENDC .ENDC TSV: 0 LTCBS: 0 QTCNT: 0 ; NUMBER OF GUYS ON QTASK CHAIN SM.SW: 0 ; SINGLE/MULTI-TASK SWITCH ; (0 => MULTITASK, 1 => SINGLETASK) ; LINK A TCB INTέO THE ACTIVE TCB CHAIN ; INPUT: AC0 = PRIORITY, AC1 = TCB ADDR ; ON EXIT: RH(AC0) AND CARRY PRESERVED ; TCB WILL BE LINKED IN AT END OF TCBS OF SAME OR HIGHER PRI ; (LNKPR IS SPECIAL ENTRY FOR USE BY RESCHED LOGIC) TLINK: LDA 2,TDUML ; DUMMY ZERO-ETH TCB% LNKPR: STA 1,TSV ; SAVE TCB LDA 1,PRMSK ; 377 AND 1,0 ; CLEAR OUT HIGH BYTE STA 3,TRTN ; SAVE INTERNAL RET TLNXT: STA 2,LTCBS ; SAVE LAST LDA 2,TLNK,2 ; NEXT COM# 2,2,SNR ; END ? JMP HERE ; YES LDA 3,TPRST,2 ; PRI AND 1,3 ; DROP STATUS ADoCZ# 0,3,SNC ; SKIP IF < , INSERT HERE JMP TLNXT ; TO NEXT HERE: LDA 3,TSV ; TCB TO INSERT LDA 2,LTCBS ; LINK IN POINT LDA 1,TLNK,2 ; FORWARD LINK AT INSERT POINT STA 1,TLNK,3 ; PUT IN INSERTED TCB STA 3,TLNK,2 ; LINK .-1 TO . JMP @TRTN ; ROUTINΙE TO UNLINK AN ENTRY FROM ACTIVE TCB CHAIN ; AC2 = TCB ; AC1 DESTROYED, AC0, AC2, & CARRY PRESERVED TUNLK: STA 3,TRTN LDA 3,TDUML ; DUMMY ZERO-ETH TCB TUNXT: COM 3,1,SZR ; SAVE LAST TCB (LOOP FOREVER ; IF NO MORE TCBS) LDA 3,TLNK,3 ; NEXT TCB IN pvCHAIN SUB# 2,3,SZR ; SKIP IF TCB FOUND JMP TUNXT COM 1,3 ; PREVIOUS TCB TO AC3 LDA 1,TLNK,2 STA 1,TLNK,3 ; LINK .-1 TO .+1 JMP @TRTN PRMSK: C377: 377 ; SAVE STATE OF A TASK IN ITS TCB ; CALL FROM SCHEDULER STATE WITH ".TSAVE" FOLLOWING EN.SCHEPD ; ON RETURN AC2=CALLER PC,AC3=TCB ADDR, AC0,AC1,CARRY PRESERVED ; NOTE: TSAVE DOES NOT SAVE USP, SO SCHEDULER STATE MAY NOT ; USE USP ; .TSAVE COMES HERE TSAVE: STA 3,TRTN ; SAVE RTN LDA 3,CTCB ; GET CURRENT TASK STA 0,TAC0,3 ; SAVE AC STA 1,TAC1̀,3 STA 2,TAC2,3 .SAC2 ; PICK UP AC3 CONTENTS STA 2,TAC3,3 .IFE MSW LDA 2,@USTP ; GET CALLER'S PC .ENDC .IFN MSW LDA 2,1 ; GET CALLER'S PC .ENDC MOVL 2,2 ; SHIFT WITH CARRY ADDED STA 2,TPC,3 ; STORE IN TCB MOVR 2,2 ; RESTORE CARRY JMP @TRTN  ; CREATE A NEW TASK - THIS IS ALSO DONE IN TQTASK.SR ; LH(AC0)=TID - IF NON-ZERO, ERROR IF ALREADY EXISTS ; RH(AC0)=PRIORITY - IF 0, PRIORITY SET = CALLING TASK'S ; AC1 = ADDR TO SET UP AS PC ; AC2 WILL BE PASSED TO THE NEW TASK ; .TASK COMES HERE T.ASK': INC 3,3 ; ASSUME GOOD RETURN EN.SCHED .TSAVE LDA 1,C377L ANDS 0,1,SZR ; SKIP IF NO ID SPECIFIED ID.SRCH  ; SEE IF IT ALREADY EXISTS JMP .+2 ; NO-OK TO CREATE JMP TIDER ; ONE TOO MANY LDA 2,@UFCHN COM# 2,2,SNR ; ALL GONE ? JMP TSKER ; IF YES LDA 3,TLNK,2 ; GET ONE STA 3,@UFCHN STA 1,TID,2 ; CHRISTEN THE LITTLE DEVIL LDA 3,CTCB ; CALLER LDA 1,TAC1,3 ; CALLER PC ADDR MOVL 1,1 ; SHIFT TO PC + CARRY STA 1,TPC,2 ; STORE IN NEW TCB LDA 1,ADKIL ; SET UP TAC3 AS KILL ADDRESS STA 1,TA"C3,2 SUB 1,1 STA 1,TELN,2 ; NO EXTENDED STUFF STA 1,TKLAD,2 ; AND NO KILAD LDA 1,PRMSK ; 377 AND# 1,0,SNR ; PRI SPECIFIED ? LDA 0,TPRST,3 ; IF NO USE CURRENT PRIORITY AND 1,0 ; CLEAR ANY STATUS BITS STA 0,TPRST,2 ; STORE PRI IN TCB LDA 0,TAC2,3 ; PASS AC2 TO TASK (AND TO STA 0,TAC2,2 ; TSK.X IN AC0) ADC 1,1 ; SIGNAL NOT QTASKING STA 2,TCBSV ; SAVE NEW TCB ADDRESS JSR @TSK?X ; CALL USER TASK CRANKER JMP T.ASE ; SOME KIND OF ERROR LDA 2,TCBSV ; GET NEW TCB ADDRESS LDA 0,TPRST,2 ; AND HIIS PRIORITY MOV 2,1 JSR TLINK ; PUT TCB INTO CHAIN BY PRIORITY RE.SCHED TCBSV: 0 TSK?X: TSK.X ; USER TASK CRANKING SUPPLEMENT ADKIL: K.ILL ; KILL ADDRESS AS RETURN ADDRESS T.ASE: LDA 3,TCBSV ; PUT TCB BACK ON FREE CHAIN LDA 1,@UFCHN STA 1,TLNRK,3 STA 3,@UFCHN ER.SCHED ; REPORT ERROR TO CALLER ; KILL A TASK CURRENTLY ACTIVE ; TCB IS IN CTCB JMP.1: JMP .+1 ; IN CASE KILLED TASK TAKES ; ERROR RET FROM .SYSTM ; .KILL COMES HERE K.ILL: ADC 3,3 ; ENSURE THAT WE WILL EN.SCHED ; GO INTO SCHEDULER STATE LDA 2,CTCB ; NO NEED TO DO A TSAVE JSR TUNLK ; UNLINK TASK FROM ACTIVE CHAIN LDA 3,TKLAD,2 ; ABORT ADDR SPECIFIED ? ADDO# 3,3,SEZ ; SKIP IF .LE. 0 JMP TKIL1 ; YES ; RELEASE TCB TO POOL JSR @ESV?K ; MAKE EXTENDED SAVE/RSTR (IF إ ; LOADED) FORGET ABOUT THIS GUY JSR @TRL?X ; LET USER DO HIS RELEASING LDA 2,CTCB ; RECOVER TCB ADDR LDA 1,@UFCHN ; LINK AT HEAD OF FREE CHAIN STA 1,TLNK,2 STA 2,@UFCHN SUB 0,0 ; FORGET GUY WHO GOT KILLED STA 0,CTCB STA 0,SM.SW ; REVERT T|O MULTITASK MODE LDA 1,@UACHN ; GET HEAD OF ACTIVE CHAIN COM# 1,1,SZR ; SKIP IF KILLED LAST GUY RE.SCHED ; ELSE GO RESCHEDULE ; SEE IF ALL IS REALLY QUIET AND RETURN IF YES LDA 1,QTCNT ; TOD QUEUED TASKS ? MOV# 1,1,SZR RE.SCHED ; SOMEBODY ON Q|UEUE-DON'T BAG IT ; YET.. LDA 1,.CRTN MOV 2,3 ; TCB JMP @.SYS1 ; *** THIS BETTER NOT ERROR .SYS1: SYST1 .CRTN: .RTN ; SYST CALL CONSTANT TRTN: 0 ESV?K: ESV.K ; EXT SAVE/RSTR KILL LOGIC TRL?X: TRL.X ; USER ROUTINE TO REL RESOURCES UFCHN: .GAbDD USTAD,USTFC ; FREE CHAIN HEADER UACHN: .GADD USTAD,USTAC ; ACTIVE CHAIN HEADER TDUM2: .GADD USTAD,USTAC-TLNK; DUMMY ZERO-ETH TCB ADDRESS ; ONLY GO TO THE ROUTINE ON THE FIRST CALL-B0 FLAGS NEXT TKIL1: MOVL 3,3 MOVOR 3,1 STA 1,TKLAD,2 ; BACK WITH 1Bmu0 STA 3,TPC,2 ; SHIFTED VALUE AS NEW PC LDA 1,C377L ; PRI=0 LDA 0,TPRST,2 ; (PRESERVE ANY USER BITS) AND 1,0 STA 0,TPRST,2 LDA 1,@UACHN ; PUT AT HEAD OF CHAIN STA 1,TLNK,2 STA 2,@UACHN RE.SCHED K.IL2= K.ILL*2 ; TPC FOR ROUTINES WHO SETUP KILLS ; DEFINE AN ADDR TO PROC KILLS ; AC0= ADDR TO SET ; .KILAD COMES HERE K.ILAD: EN.SCHED .TSAVE STA 0,TKLAD,3 ; SET ADDR RE.SCHED C377L: 377B7 TSKER: LDA 2,.ERNOT ; OUT OF TCBS ; ER.SCHED COMES HERE TERCM: LDA 3,CTCB ; TCB STA 2,TAC2,3 ; PAfSS TO TASK DSZ TPC,3 DSZ TPC,3 ; BAD RETURN RE.SCHED .ERNOT: ERNOT ; TASK ID SEARCH ; AC1= TASK ID TO SEARCH FOR ; ID.SRCH ; ; ; BOTH RETURNS PRESERVE AC0, RH(AC1), AND CARRY z; ID.SRCH COMES HERE I.DSRC: LDA 2,C377 ; MASK FOR LOW BTYE AND 2,1,SNR ; SKIP IF OK (NON-ZERO) JMP 0,3 ; ELSE RETURN AN ERROR STA 3,TRTN ; NOW SAVE RETURN LDA 2,TDUM2 ; GET TCB ACTIVE CHAIN HEADER TIDS1: LDA 2,TLNK,2 ; NEXT TCB COM# 2,2,SNR ; SKIP IF NOT END JMP @TRTN LDA 3,TID,2 ; LOOK AT NEXT ID SUB# 3,1,SZR ; SKIP ON MATCH JMP TIDS1 ; GO FOR NEXT LDA 3,TRTN ; GOOD RETURN JMP 1,3 TIDER: LDA 2,.ERTID JMP TERCM .ERTID: ERTID .IFN MSW ; ROUTINES TO DO INTDS AND INTEN IN MAPPED ENVIRONMENTS ; AC0, AC1, AC2, AND CARRY ARE PRESERVED UNIVERSALLY ; *** THESE ROUTINES MAY ONLY BE CALLED WHILE IN ; *** SCHEDULER STATE I.NTDS: STA 0,ISAV0 ; SAVE AC0 LDA 0,C5 ; GET INTDS CODE JMP ISKIP ; JOIN COMMON CODE I.NTEN: STA 0,ISAV0 ; SAVE EAC0 LDA 0,C7 ; GET INTEN CODE ISKIP: .IFE MBSW STA 2,ISAV2 ; SAVE AC2 STA 3,ISAV3 ; SAVE AC3 (RETURN ADDRESS) LDA 2,IRTN ; SET TO RETURN HERE SCL NIOC MAP IRTN: .+1 LDA 0,ISAV0 ; RESTORE AC0 LDA 2,ISAV2 ; RESTORE AC2 JMP @ISAV3 ; RETURN r).ENDC  .IFN MBSW SCL LDA 0,ISAV0 ; RESTORE AC0 JMP 0,3 .ENDC C5: 5 C7: 7 ISAV0: .BLK 1 ; ACCUMULATOR SAVE LOCATIONS .IFE MBSW ISAV2: .BLK 1 ISAV3: .BLK 1 ; (HOLDS RETURN ADDRESS) .ENDC .ENDC .END ; END OF TCBMON.SR DUMMY.SR= aI.TITL DUMMY ; DEFAULT FOR UNDEFINED TASK EXTN .RB DUMMY.RB .ENT T.OVLD,T.OVA,OPRD,Q.TCK,TRL.X,TSK.X,LPN.X .ENT ESV.X,ESV.K,ESV.S,ESV.Z .ENT SM.SW,R.UTSK .NREL SM.SW= -1 ;SINGLE/MULTI TASK SWITCH R.UTSK= -1 ;TCBMON ENTRY POINT LPN.X= 0 ; DEFAULT QUE EXTENSION SIZE ESV.S= -1 ; DEFAULT START OF EXTENDED SAVE AREA ESV.Z= 0 ; DEFAULT SIZE OF EXTENDED SAVE AREA TSK.X: JMP 1,3 ; NO TASK CREATION EXIT - GOOD RETURN ESV.X: ; NO EXTENDED SAVE/RESTORE ESV.K: ; NO ESV/RS KILL LOGIC OPRD: Ӱ ; NO OPCOM PACKAGE TRL.X: ; NO TASK KILL EXTENSION Q.TCK: JMP 0,3 ; NO TASK QUEUEING T.OVA: T.OVLD: LDA 2,ECODE ; NO TASKING OVERLAY LOADER .SYSTM .ERTN JMP . ECODE: ERQOV .END ; END OF DUMMY.SR NSAC3.SR= S * .TITLE NSAC3 .RB NSAC3.RB .ENT .SAC0,.SAC1,.SAC2,.SAC3 ; LOAD SYSTEM RETURN AC3 INTO REGISTER GIVEN. THIS ; MODULE DEFINES DEFAULT RETURN TO BE CONTENTS OF USP. .SAC0= LDA 0,USP .SAC1= LDA 1,USP .SAC2= LDA 2,USP .SAC3= LDA 3,USP .END N3SAC3.SR= S x .TITLE N3SAC3 .RB N3SAC3.RB .ENT .SAC0,.SAC1,.SAC2,.SAC3 ; LOAD SYSTEM AC3 RETURNED INTO REGISTER GIVEN .SAC0= MFFP 0 .SAC1= MFFP 1 .SAC2= MFFP 2 .SAC3= MFFP 3 .END DEB.SR  x.LCNS ;COPYRIGHT (C) DATA GENERAL CORPORATION,1972,1973,1975,1976,1977 ;ALL RIGHTS RESERVED ;LICENSED MATERIAL-PROPERTY OF DATA GENERAL CORPORATION ; DEB.SR ; RDOS INTERUPT ON DEBUG ; DEB= 1 ; SET DEBUG SWITCH ; ; THATS ALL THERE IS TO IT .EOT IDEB.SR W7ev; IDEB.SR ; RDOS INTERUPT OFF DEBUG ; DEB= 3 ; SET DEBUG SWITCH ; ; THATS ALL THERE IS TO IT .EOT NDEB1.SR %** ; TITLE MSW SSW IDEB SASW SYSW ** ; ----- --- --- ---- ---- ---- ** ; ** ; DEBUG 0 0 0 0 0 ** ; MDEBUG 1 0 0 0 0 ** ; IDEB 0 0 -1 0 0 ** ; MIDEB 1 0 -1 0 0 ** ; SADEB 0 1 -1 1 0 ** ; SAMDEB 1 1 -1 1 0 ;********************?************************; ; ; ; DDDDDDD EEEEEEEEE BBBBBBB ; ; DD DD EE BB BB ; ; DD DD EE BB BB ; ; DD DD EE BB BB ; ; DD DD EEEEEE ^ BBBBBBB ; ; DD DD EE BB BB ; ; DD DD EE BB BB ; ; DD DD EE BB BB  ; ; DDDDDDD EEEEEEEEE BBBBBBB ; ; ; ; ; ;***********************N/*********************; ; .REV 6,00 ** ; SWITCHES TO BUILD ALL THE NOVA DEBUGGERS IN THE WORLD ** .NOCON 1 ; DON'T LIST CONDITIONAL CODE ** ** .IFE DEB-1 ; DEBUG MSW=0 SSW=0 IDEB=0 SASW=0 SYSW=0 .TITL DEBUG .RB DEB.RB ** .ENDC ** ** .IFE D5EB-2 ; MDEBUG MSW=1 SSW=0 IDEB=0 SASW=0 SYSW=0 .TITL MDEBUG .RB MDEB.RB ** .ENDC ** ** .IFE DEB-3 ; IDEB MSW=0 SSW=0 IDEB=-1 SASW=0 SYSW=0 .TITL IDEB .RB IDEB.RB ** .ENDC ** ** .IFE DEB-4 ; MIDEB MSW=1 SSW=0 IDEB=-1 SASW=0 SYSW=0 .TITL MIDEB .RB MIDEB.RB ** .ENDC ** ** .IFE DEB-5 ; SADEB MSW=0 SSW=1 IDEB=-1 SASW=1 SYSW=0 .TITL SADEB .RB SADEB.RB ** .ENDC ** ** .IFE DEB-6 ; SAMDEB MSW=1 SSW=1 IDEB=-1 SASW=1 SYSW=0 .TITL SAMDEB .RB SAMDEB.RB ** .ENDC ** :** .NOLOC 1 .MACRO BKENT DSZ BPN1 TR$= . ; BREAKPOINT ENTRY HERE ** .DO IDEB==-1 SKPBN CPU DSZ INTFL INTDS ** .ENDC SKIP ** .DO MSW==1 ISZ 1 ** .ENDC ** .DO MSW==0 INTDS ** .ENDC **[SKIP] % .MACRO .SYM ^1^2^3^4^5 ** .SQ ^1 ^2 ^3 ^4 ^5 % .MACRO M.SYM1 ^1^2^3^4^5 0 ** .SQ ^1 ^2 ^3 ^4 ^5 % .MACRO .SYM2 ^1^2^3^4^5 0,0 ** .SQ ^1 ^2 ^3 ^4 ^5 % .MACRO .SQ F^4*50+F^5*40 F^1*50+F^2*50+F^3 ; ^1^2^3^4^5 % ** .NOLOC 0 .ENT DEBUG ** .DO IDEB==0 .EXTN SM.SW ;SINGLE/MULTI SWITCH .EXTN R.UTSK ;ENTRY tTO TCBMON, RUN CTCB ** .ENDC .ZREL BKP: .BLK 10 ; EIGHT BREAK POINTS IN PAGE ZERO .NREL ** .IFE SSW .USTS: USTSS ; OFFSET TO START OF SYMBOL TABLE .SYMP: SYMP ; SYMBOL TABLE POINTER IDEB ; TELLS SYSTM WHETHER DEBUG OR IDEB IS LOADED ** .ENDC 5KDEBUG: .DO SSW==0 LDA 3,USTP ; UST ADDRESS LDA 1,.DEBUG ; DEBUG ADDRESS LDA 0,USTSA,3 SUB# 1,0,SZR ; SA = DEBUG ADDRESS ? JMP TR$ ; NO - SKIP FIRST TIME CODE LDA 2,USTDA,3 ; YES - SWAP SA AND DA STA 0,USTDA,3 STA 2,USTSA,3 LDA 1,-1,2 ; SET UP SYS CALL ADDRESS STA 1,17 LDA 0,.USTS ; SET UP SYMP ADD 3,0 STA 0,@.SYMP ; SAVE IN ALT Y ** .DO IDEB==0 LDA 2,USTCT,3 ; CTCB LDA 0,TPC,2 ; GET PC MOVZR 0,0 ; ADJUST IT STA 0,@.ALOC ; PUT IT IN LOC LDA 0,TROP ; DEBUGERS REAL START ADDRESS STEWA 0,TPC,2 ; SAVE IT SO TMAX WILL START US JMP @USTSA,3 ; GO TO TMAX ** .ENDC SKIP STA 2,@.ALOC ;TMIN/TMAX JMP TR$ **[SKIP] TROP: TR$+TR$ ; PC TO RUN IN TCB FORMAT .ALOC: LOC ** .ENDC TR$= . ** .DO IDEB==-1 SKPBN CPU DSZ INTFL INTDS ** .ENDC SKIP  P** .DO MSW==0 INTDS ** .ENDC ** .DO MSW==1 ISZ 1 ** .ENDC **[SKIP] ** .DO 10 ** BKENT ** .ENDC .SAVE: STA 0,SAV0 ; SAVE AC'S STA 1,SAV1 STA 2,SAV2 STA 3,SAV3 SUBCR 3,3 STA 3,SAVC ; SAVE CARRY ** .DO IDEB==0 LDA 3,USTP ; UST LDA 1,USTSV,3 ;GET 7!HIS SV ADDRESS LDA 2,.MAGIC ; MAKE SURE WE IS NOT STILL MAGIC SEQ 1,2 ; IF WE IS NOT THEN SAVE USER STA 1,SVSV ;SAVE IT SUB 1,1 ;NOW ZAP IT STA 1,USTSV,3 LDA 2,MULSW ;SINGLE/MULTI SWITCH COM# 2,2,SNR JMP HELLO LDA 0,0,2 MOVL 0,0 ;SET THE BITS FOR MOVOR 0,0 ; SINGLE TASK MODE STA 0,0,2 ** .DO MSW==0 HELLO: INTEN ** .ENDC SKIP HELLO: SUB 1,1 STA 1,1 **[SKIP] ** .ENDC LDA 1,BPN1 ** .DO IDEB==-1 LDA 0,INTFL SUB 1,0 STA 0,INSET ** .ENDC STA 1,BPN LDA 0,X11 STA 0,INTFL STA 0,BPN1 TRP9: LsDA 3,CBTAB ; RESTORE THE BREAK POINTS. ADCZL 2,2 LDA 0,20,3 STA 0,@10,3 INC 3,3 ADDL 2,2,SZC JMP .-4 ADD 1,3 LDA 1,-2,3 STA 1,BADR ; SET BREAK ADDRESS. DSZ BPN JMP BENT ; A BREAK POINT ** .DO IDEB==-1 JSR SAVM ** .ENDC TRP10: SUBO 3,3 ; START VIA CARRIAGE. JMP @CREI ** .DO IDEB==0 MULSW: SM.SW ;SINGLE/MULTI SWITCH ** .ENDC INTFL: 11 BPN1: 11 ** .IFE SYSW .DEBUG: DEBUG ** .ENDC BENT: DSZ -12,3 ; TEST PROCEED COUNTER JMP NOBK ; NOT YET OV ISZ -12,3 ; DEFALT PROCEED=+1 ** .IFN SYSW L3DA 1,BADR LDA 2,.LDRT SUB# 1,2,SNR ; IS IT THE MAGIC OVLY ADDR ? JMP @.OVLK ; GO SEE IF TIME TO BREAK ** .ENDC ** .DO IDEB==-1 BENRT: JSR SAVM ** .ENDC LDA 2,BPN JSR PRBPT JSR .PAC ; PRINT ALL ACS. JMP TRP10 NOBK: LDA 3,CBTAB ; TTI/TTO FLAGS. ** .DO IDEB==-1 ISZ SAVC SUB 0,0 STA 0,TTIFL ADC 0,0 ; SAVE THE LINE PRINTER AND PUNCH STA 0,STATE ** .ENDC JMP ALTPX ; GO TO PROCEED LOGIC. .PAC: STA 3,.RET ; PRINT ALL ACS JSR @YCRLF ; CARRIAGE SUB 1,1 STA 1,ACN .PAC1: JSR @YPOCT ; PRINT OCtTAL. LDA 1,ACN LDA 3,CSAV ; POINT TO AC AREA. ADD 1,3 LDA 1,0,3 JSR @ZPOC ; PRINT C(AC) LDA 1,ACN ISZ ACN ADCZL 0,0 ADDZ# 0,1,SBN INC 1,1,SKP JMP @.RET JSR @PRBY ; PRINT SPACE JMP .PAC1 SAVC: 0 SAV0: 0 SAV1: 0 SAV2: 0 SAV3: 0 PRBPT: STA w$3,PRET ; PRINT BREAK ADDRESS. JSR @YCRLF ; CARRIAGE RETURN. LDA 0,PRBX ; C(1)=ADDRESS ADD 2,0 ; C(2)=#B JSR @YCR1 JSR @PRBY ; PRINT SPACE JSR @YVALS USYMS JMP @PRET PRET: 0 YCR1: CRLF+1 PRBX: 041057 PRBY: SPACE ** .DO IDEB==-1 SAVM: SKPBN TTI4 SKPBZ TTO JMP .-2 ; WAIT IF TTI OR TTO ARE BUSY ** .DO SASW==1 ; STAND ALONE ONLY SKPBN PTP ; WAIT FOR PAPER TAPE PUNCH ** .ENDC SKIP 401 **[SKIP] SKPBZ LPT JMP .-2 ; WAIT FOR PRINTER SKPDZ TTO ISZ SAVC ; SAVE TTO STATE SUBZ 2,2 ** .IFN SASW SKPDZ PTP MOVR 2,2 ** .ENDC SKPDZ LPT INC 2,2 ; IF LPT DONE, SET BIT 15 STA 2,STATE SKPDN TTI SUBZR 2,2,SKP DIA 2,TTI STA 2,TTIFL ; SAVE TTI STATE ** .ENDC Z1400: JMP 0,3 BPN: 0 CBTAB: BTAB CREI: CRE YCRLF: CRLF YVALS: VALSER YPOCT: POCT ACN: 0& ZPOC: ODPT .RET: 0 YDATA: DATA LOC: 1B0 CGRX: CGR ALTEM: 0 C60K: 60000 ** .IFN SYSW SYMB: 0 ; SPACE FOR SYMBOL TABLE POINTER 0 .LDRT: LDRTN .OVLK: OVLK ** .ENDC ** .DO IDEB==0 .MAGIC: MAGIC ** .ENDC ISEXT: SEXT C2K: 2000 C407: 400+RELAD-PINST INSET: 0z STATE= . SVSV: 0 ETE: ERR .M8: -10 C4K: 4000 CTRP0: TR001 X11: 11 BKINS: JMP @BKP ; JMP THROUGH BREAK POINT BKDIF: TR002-TR001 .BKP: BKP CSAV: SAV0 TTIFL: 0 BADR: 0 JFLAG: 0 ALTR: LDA 0,BPN ; GET BREAK POINT NUMBER MOV 0,0,SZR ; A BREAK POINT ENTR%Y ? MOV 3,3,SZR ; AND NO ARG TYPED ?? ADC 0,0,SKP ; NO ALL IS WELL JMP @ETE ; YES AN ERROR - SAVE THE FOOL STA 0,BPN LDA 0,LOC ; USE ADDRESS IN LOC MOV# 3,3,SZR ; WAS IT $R ? LDA 0,@YDATA ; YES, GET STA 0,@YDATA MOVL# 0,0,SZC JSR @ETE ; ERROR IF NEGATIVE ADDRESS. JSR @YCRLF LDA 0,@CGRX ; POINT TO A (JMP @DATA) STA 0,BADR ; STORE IN BREAK ADDRESS. ALTPY: LDA 2,BPN ; PROCEED LOGIC MOV 2,2,SNR JMP @ETE ; SAVE THE FOOL- NO BREAK POINT LDA 0,@YDATA MOV 3,3,SNR SUBZL 0,0 ; IF 0 ASSUME +1 LDA 3,CBTAB ; POINT TO BREAK DATA. ADD 3,2 STA 0,-1,2 ** .DO IDEB==-1 SKPBN TTO SKPBZ LPT JMP .-2 ; WAIT FOR ALL OUTPUT TO BE DONE ** .DO SASW==1 SKPBZ PTP JMP .-1 ** .ENDC ** .ENDC ALTPX: LDA 0,@BADR ; C(0)=PROCEED INST STA 0,PINST ALTP1: LDA 2,.M8 STA 2,ALTEM LDA 2,BKINS ; A (JMP @BKP) INSTRUCTION. LDA 1,@10,3 STA 1,20,3 ; PUT BREAK POINT INST STA 2,@10,3 ; BACK IN THE TABLE AND INC 2,2 ; JMP'S BACK IN THE INC 3,3 ; PROGRAM. ISZ ALTEM JMP ALTP1+3 LDA 1,BADR C ; C(0)=INSTRUCTION LDA 2,C60K LDA 3,Z1400 SUBZ# 2,0,SNC ANDS 0,3,SNR JMP ALTP4 ; NOT INDEX INSTRUCTION. LDA 2,CSAV ADD 3,2 MOVZR# 3,3,SZR LDA 1,0,2 ; C(1)=INDEX VALUE JSR @ISEXT ; SIGN EXTENSION. ADDL 0,1 ; (INDEX+DISPLACEMENT)*2 LDA 0,PINST LDA 3,C2K NEG 3,2 ; REMOVE ORIGIONAL ANDO 2,0 ; DISPLACEMENT. AND# 0,3,SNR ; INSERT A @BIT ADDZ 3,0 ; INTHE INSTRUCTION. MOVR 1,1 ; IF INST @, INSERT STA 1,RELAD ; @ IN THE ADDRESS. LDA 2,C407 ADDZ 2,0 ; WHEN MEM REFF STA 0,PINST ; IS lINDEXED, CHANGE IT. ALTP4: INLIN: LDA 2,C4K ; C(0)=INSTRUCTION LDA 1,BADR NEGZL 2,3 ANDZ 0,3,SZR JMP .+5 ; NOT JMP/JSR INSTRUCTION. INC 1,3 AND 0,2,SZR STA 3,@.SAV3 ; SET AC3 ON JSR SUBZ 2,0 ; C(0)=JMP INSTRUCTION SUBCL 3,3 ; =0 IF NOT JMP/JSnR STA 3,JFLAG STA 0,PINST ; PROCEED INSTRUCTION. INLI1: LDA 3,CTRP0 LDA 2,.BKP ; WHERE BREAKPOINTS ARE LDA 0,BKDIF LDA 1,M8 STA 3,0,2 ; PUT DEBUGGER INC 2,2 ; ENTRYS INTO LOCATIONS ADD 0,3 INC 1,1,SZR JMP .-4 RESTR: ** .DO IDEB==0 ; ONLY F(OR INT ON DEBS LDA 2,.MULS ; RESET SINGLE TASK MODE COM# 2,2,SNR ; MULTI TASKED GUY ? JMP EXIT ; NO - NO NEED TO RESET LDA 3,USTP ;UST ADDRESS LDA 0,.MAGIC ;MAGIC ROUTINE STA 0,USTSV,3 ; GETS CONTROL PRIOR TO TMAX LDA 0,0,2 MOVZL 0,0 MOVZR 0e,0 STA 0,0,2 EXIT: LDA 0,@.SAVC MOVL 0,0 ** .ENDC SKIP JSR DEVRS ; RESTORE DEV STAT **[SKIP] LDA 0,@.SAV0 ; RESTORE ACS LDA 1,@.SAV1 LDA 2,@.SAV2 LDA 3,@.SAV3 ** .DO IDEB==-1 DSZ JFLAG ;JMP OR JSR JMP PINST ;NO, LEAVE INTERRUPTS ALONE ISZ INSEST INTEN ** .ENDC PINST: 0 ; PROCEED INSTRUCTION. DSZ BADR ISZ BADR ISZ BADR ** .DO IDEB==-1 ISZ INSET INTEN ** .ENDC JMP @BADR RELAD: 0 ; ADDRESSED ON INDEX INST. ** .DO IDEB==0 .MULS: SM.SW ** .ENDC  ** .DO IDEB==-1 DEVRS: LDA 0,@.SAVC MOVZL} 0,0,SNR NIOC TTO ; RESTORE CARRY AND TTO STATE LDA 0,@S.TATE ** .IFN SASW MOVZL# 0,0,SNC NIOC PTP ** .ENDC MOVZR# 0,0,SNC NIOC LPT ; RESTORE LPT STATE LDA 0,TTIFL MOVL# 0,0,SZC NIOC TTI ; RESTORE TTI STATE JMP 0,3 ** .ENDC ALT: STA 3,TYFLG ; $TYPED LDA 3,@OP ; OPEN? MOV 3,3,SZR JSR @E ; ERROR IF OPEN. JSR @GETY ; GET A CHARACTER. JSR @SERHY ; SEARCH FOR DELIMIT. ALTD1 JMP ALT1 JSR @E ; ERROR, NO FIND. ALT1: LDA 3,TYFLG LDA 1,ALTD2-ALTD1,2 MOVL 1,1,SNC JMP @ALTD2-ALTD1,2 ; GO TO DELIMIT ROUTINE. MOV 3,3,SZR ; EXAMINE JSR @E ; ARG TYPED. MOVZR 1,2 JSR @.+2 JMP AAA ALT11: SPACE JMP1: JMP .+1 .BADR: BADR .SAVC: SAVC .SAV0: SAV0 .SAV1: SAV1 .SAV2: SAV2 .SAV3: SAV3 ** .DO IDEB==-1 S.TATE: STATE ** .ENDC E: ERR M8: -10 .PA: .PAC GETY: GET SERHY: SERH TYFLG: 0 CBT10: BTAB OP: OPEN M4: -4 ACTBP: 0 .Q: MOV 3,3,SZR ; $Q TYPED LDA 3,@ATA ; PRINT PROCEED COUNT. LDA 2,CBT10 LDA 0,M8 JMP A1 .A: LDA 2,CSAVR ; EXAMINE AC. $A MOV 3,3,SNR JMP .AA ; PRINT ALL AC'S LDA 0,M4 jLDA 3,@ATA A1: AND# 0,3,SZR JSR @E ; ARG > FIELD ADD 3,2 JSR @ALT11 AAA: STA 2,LPOINT LDA 1,0,2 STA 1,@ATA JSR ODPT ; PRINT NUMBERS. SUBZL 0,0 STA 0,LFLG STA 0,@OP JMP @.+1 EXP .AA: JSR @.PA ; PRINT AC'S JMP ALTAA ; GO TO CARRIAGE LOGIC. W+LPOINT: 0 LFLG: 0 DUMY: .+1 DUMMY: 0 CBTA: BTAB ATA: DATA CSAVR: SAV0 XY11: 10 FPTR: PRBPT ALTX: MOV# 3,3,SNR JSR @E LDA 3,@ATA JSR 0,3 SAVC CRE ALTB: LDA 2,@ATA ; BREAK LOGIC LDA 1,M8 MOV 3,3,SNR JMP ALTB1 ; PRINT BREAK POINTS. LDA 0,ACTBP i MOVL# 2,2,SZC JSR @E ; A NEGATIVE ADDRESS. ADDO# 0,1,SZC MOVZR# 2,2,SNR ; ADDRESS 0-1 OR JSR @E ; >8 BREAKS. LDA 3,CBTA STA 1,ATEM LDA 0,10,3 LDA 1,DUMY SUB# 0,2,SNR ; EXIT IF A BREAK EXIST. JMP CRF0 ; AT THIS ADDRESS. SUB# 0,1,SNR ; STOR˱E C(3) IF ITS STA 3,LPOINT ; OK TO BREAK THIS # INC 3,3 ISZ ATEM JMP .-10 ISZ ACTBP ; INC ACTIVE BREAK # LDA 3,LPOINT STA 2,10,3 ; STORE ADDRESS. SUBZL 0,0 ; SET PROCEED COUNT TO +1 STA 0,0,3 ; WHEN INSERTING BREAK. ALTAA: JMP CRF0 ; GO TO CA"RRIAGE LOGIC. ALTB1: LDA 0,XY11 ; PRINT THE LOCATION STA 0,ATEM ; OF ALL ACTIVE BREAK LDA 2,ATEM ; POINTS. LDA 3,CBTA ADD 2,3 LDA 1,7,3 ; C(1)=BREAK ADDRESS. LDA 0,DUMY SUB# 0,1,SZR ; DON'T PRINT IF DUMMY JSR @FPTR ; PRINT IT. DSZ ATEM JMPҗ ALTB1+2 JMP CRF0 ; GO TO CARRIAGE LOGIC. ATEM: 0 ALTD: LDA 3,CBTA ; $D TYPED LDA 2,DATA LDA 1,M8 LDA 0,TYFLG MOV 0,0,SNR JMP ALTD5 ; DELETE ALL ADDZ# 1,2,SZC JSR @E ; #>7 ADD 2,3 LDA 2,10,3 LDA 0,DUMY SUB# 0,2,SNR JSR @E ; ALLREADY DELEATED? DSZ ACTBP ; DECREMENT ACTIVE BREAKS. JMP .+1 ADC 1,1,SKP ALTD5: STA 0,ACTBP ; DELETE A BREAK. LDA 0,DUMY ; BY MOVING IT TO A STA 0,10,3 ; POINT IN THE DEBUGGER. INC 3,3 INC 1,1,SZR JMP .-3 CRF0: JMP @.+1 ; GO TO CARRIAGE LOGIC. CR ODPT: STA 3,ODR ; OCTAL/DECIMAL PRINTER. LDA 0,RADIX LDA 2,ODPT1 MOV 0,0,SZR LDA 2,ODPT2 JSR 0,2 JMP @ODR ODR: 0 ODPT1: POCT+1 ODPT2: SDEC RADIX: 0 JSWIT: ALTDM EQSIGN: SUB 0,0 ; = TYPED MOV 3,3,SZR STA 0,OPEN LDA 1,DATA JSR ODPT ; PRINT NUMBEVRS. JMP QEXP LFTARO: SUB 0,0 ; _ TYPED MOV 3,3,SZR STA 0,OPEN LDA 1,DATA JSR HALF ; HALF WORDS. JMP QEXP AMPER: SUB 0,0 MOV 3,3,SZR STA 0,OPEN LDA 1,DATA JSR BPOINT JMP QEXP ; DISPLAY DATA IN BYTE POINT FORMAT BPOINT: STA 3,BRTN ; SAVE 8RETURN STA 1,DTSV ; SAVE DATA LDA 3,.BPT1 ; SET UP RTN FOR MAIN DTSV PRINT MOVZR 1,1 ; DROP BYTE POINTER JMP ODPT ; GO DISPLAY MAIN DATA BPT1: LDA 1,DTSV LDA 0,CA0 ; "0 MOVZR 1,1,SZC ; SEE IF BYTE POINT = 1 MOVS 0,0 JSR @.TYPE ; GO TYPE 0 OR 1 JSR @.SPACE JMP @BRTN ; RETURN TO CALLER BRTN: BPT1 .BPT1: BPT1 .SPACE: SPACE .TYPE: TYPE CA0: '' DTSV: 0 USER: STA 3,ODR ; PRINT USER SYMBOL JSR @AVALS USYMS JSR @.SPACE JMP @ODR ASTKR: LDA 1,DATA MOVL 1,1 ; RESET 1B0 MOVZR 1,1,SKP LT;HEN: LDA 1,DATA SUB 0,0 ; : TYPED MOV 3,3,SZR STA 0,OPEN JSR USER ; PRINT USER SYMBOL QEXP: JMP @.+1 EXP QUOTE: LDA 2,XINP ; ADDR OF NON-SYSTM INST TABLE QUOT1: SUB 0,0 ; INSTRUCTION PRINTER MOV 3,3,SZR ; ;TYPED. STA 0,OPEN LDA 0,DATA JSR 0,B2 ; GO TO ROUTINE JMP QEXP QUEST: LDA 2,XINS ; SYSTM CALL PRINTER JMP QUOT1 HALF: STA 3,ODR ; PRINT HALF WORDS. LDA 0,L377 COM 0,2,SKP L377: 377 AND 1,0 ANDS 2,1 STA 0,CRLFR JSR @XPOCT LDA 1,CRLFR JSR @XPOCT JMP @ODR ALTPC: STA 2,JSWIT ; SET PRINT MODE JMP CR ANYP: LDA 2,JSWIT ; PRINTER CONTROL LDA 1,.+3 ; CENTER FOR / AND $S SUB 1,2  MOV 0,1,SKP ALTDM-. JMP @2,2 ANYPX: ODPT ; INSTRUCTIONS USER HALF XINP: INP CHARS BPOINT XINS: INPS PSIGN: SUBZL 0,0,SKP ; PLUS SIGN TYPED ].MSIGN: ADC 0,0 ; MINUS SIGN TYPED JMP EXP00 IV: VALUE ITY: ITYPE ER: ERR DATA: 0 C2000: 2000 M7: -7 OPEN: 0 ADR: 0 AVALS: VUSYM SPSP: 020040 XPOCT: POCT VAL.: VALUE DECER: 0 CRLF: LDA 0,LFCR ; PRINT A CARRIAGE+LINE. STA 3,CRLFR JSR @IT MOVS 0,0 oJSR @IT JSR @CRLFR LFCR: 005015 ILFLG: LFLG ILPOI: LPOINT IT: TYPE CRLFR: 0 UPAR: 0 SWITCH: 0 IGFLG: GFLG CGR: .+1 JMP @DATA ** .IFN MSW&SSW .MLDA: MLDA .MSTA: MSTA ** .ENDC ASIGN: LDA 3,@IV ; @ SIGN TYPED SUBZR 2,2 ; 100000 IF NOT INST,2000 IFE LDA 1,@ITY ; C(1)= C(ITYPE) ADCZL 0,0 MOV 1,1,SNR JMP .+4 ; NOT A INSTRUCTION. ADDOR# 0,1,SZR ; IF A WRONG TYPE INSTRUCTION JSR @ER ; ITS A ERROR. LDA 2,C2000 AS1: ADD 2,3 STA 3,@IV ; C(VALUE)=C(3) STA 3,DATA JMP EXP0 NLSIGN: LDA 2,@ITY ;D # (NO LOAD SYMBOL) SUBZL 0,0 ; FOR USE IN ALC SUB# 0,2,SZR ; GROUP ONLY. JSR @ER ; ERROR. ADDL 2,2 MOVL 2,2 ; C(2)=10 LDA 3,@IV JMP AS1 DIGFL: DFLG UPARO: ADCZL 0,0 ; UP ARROW STA 0,UPAR LF: SUBZ 3,3,SKP ; LINE FEED. CR: SUBO 3,3 ; CARRIAG E. LDA 0,DATA LDA 1,OPEN LDA 2,@ILPOI DSZ @ILFLG LDA 2,ADR STA 3,@ILFLG MOV 1,1,SNR ; IF REGISTER NOT OPEN JMP CRE ** .IFN MSW&SSW MOVZR# 1,1,SNR ; IF = 1 IS DEB REG OPENED JMP UNMP ; NO MAP LOAD JSR @.MSTA ; SEE IF MAPPED STRE NEEDED SUBC A3,3,SKP ; SO LEO'S KLUDGE HANGS TOGETHER ** .ENDC UNMP: STA 0,0,2 ; UPDATE C(MEMORY) CRE: STA 3,OPEN ; CLEAR OPENED REG. JSR CRLF ; ECHO. LDA 2,ADR INC 2,1,SNC JMP EXP ; CARRIAGE EXIT LDA 0,UPAR ; IF UP ARROW -2 ADD 0,1 SUB 0,0 STA 0,UPAR S;TA 1,DATA ; LINE FEED. JSR @AVALS ; GO TO VALSER TO USYMS ; PRINT USER SYMBOLS. LDA 0,SPSP JSR CRLF+1 LDA 0,SWITCH MOVL 0,0,SNC ADCZ 0,0,SKP ; TYPED. ADCO 0,0 ; EXCLAMATION TYPED. COMN: STA 0,OPEN ; OPEN THE REGISTER. STA 0,@ILFLG LDA 2,DATA ** .IFE SSW ** .DO MSW==1 LDA 3,USTP LDA 3,USTNM,3 SUBZ# 2,3,SNC ; IS THIS A LEGAL ADDRESS? JMP @ER ; NO!!!!! ** .ENDC ** .ENDC STA 2,ADR ; INITIALIZE A ADDRESS. ** .IFN SSW&MSW JSR @.MLDA ; SEE IF MAPPED LOAD NEEDED ** .ENDC SKIP LDA 0,0,52 **[SKIP] STA 0,DATA ; PRINT CONTENTS. MOVR 0,0 STA 0,SWITCH MOVL 0,0,SNC JSR ANYP ; SLASH PRINTER. EXP: SUB 0,0 ; EVALUATE THE TYPED STA 0,@IGFLG STA @0,VAL. ; STATEMENT. STA 0,IFLG STA 0,FIELD STA 0,ITYPE EXP0: SUB 0,0 STA 0,V0 EXP00: STA 0,COMB ; ENTRY FOR SIGN DELIMIT SUB 0,0  STA 0,CHCTR ; CHARACTER COUNTER STA 0,NUMB ; NUMBER STA 0,DNUMB STA 0,DECER STA 0,OCTER STA 0,@DIGFL ; DIGITS FLAG STA 0,@X50 ; RADIX 50 SYMBOL STA 0,@X51 EXP1: JSR GET ; GET KEYBOARD CHARACTER JSR  SERH ; DELIMIT SEARCH DELM1 JMP @EVALX ; DELIMITER FOUND. JMP @.+1 ; LOOK FOR DECIMAL PAT1 PAT1R: LDA 2,M12 ADD 0,1 LDA 0,@X50 MOV 0,0,SNR ; IF FIRST CHARACTER ADDZ# 1,2,SEZ ; AND CURRENT A DIGIT MOV# 2,2,SKP ; ASSEMBLE DIGITS. JMP ASSDIG ; OTHERWISE CHARACTER LDA 2,M7 LDA 3,C13 ; ASSEMBLY. SUBZ# 3,1,SZC ADD 2,1 ; LETTERS. ADC 1,2,SNR LDA 1,C45 ; "." LDA 3,CSQUI ; POINT TO SQUISH TABLE NEG 1,1 ISZ CHCTR LDA 2,CHCTR ADD 2,3 LDA 0,C5 ADCZ# 0,2,SZC ; TEST FOR MORE JMP EXP(U1 ; THEN 5 LETTERS. SUB 0,0 ; PUT CHARACTER IN SYMBOL LDA 3,-1,3 ; C(3)=1,50,50*50 ADD 3,0 INC 1,1,SZR ; GET IT IN JMP .-2 ; POSITION. MOVZR 2,1 MOVZR 1,1 LDA 3,X50 ADD 3,2 ADD 1,3 ; C(3)=WORD 1 OR 2 OF SYMBOL LDA 1,0,3 ; CHARACTER GOES  ADD 1,0 ; INTO PARTIALLY STA 0,0,3 ; FORMED SYMBOL. LDA 0,IFLG LDA 1,FIELD ADD# 0,1,SZR ; IF TUEHS THE FIRST FIELD JMP EXP1 ; AND PERHAPS A INSTRUCTION JSR @1,2 ; GO TO CHARACTER ROUTINES. EXP3: JSR @INSS ; 3 RD CHARACTER ISYMS ; SEARCHT INSTRUCTION SYMBOLS. JMP EXP51 ; NO FIND,NOT A INSTRUCTION. STA 0,NUMB ; PERHAPS INSTRUCTION, STORE JSR @ICLX ; VALUE. WHAT KIND OF INST? STA 2,ITYPE ; STORE INSTRUCTION TYPE. JMP EXP1 ; GET ANOTHER CHARACTER. EXP4: LDA 1,ARGT4 ; 4 TH CHARACTER MOV 0,0,SKP EXP5: LDA 1,ARGT5 ; 5 TH CHARACTER LDA 2,ITYPE ADD 1,2 LDA 2,0,2 LDA 0,CHAR ; THE CHARACTER STA 2,.+2 ; CHARACTER TABLES 4-5 JSR SERH ; SEARCH 0 JMP EXP41 ; A FIND EXP51: SUB 0,0 ; THE SYMBOL IS NOT A STA 0,ITYPE ; INSTRU%CTION. STA 0,NUMB ISZ IFLG JMP EXP1 EXP41: LDA 0,NUMB ; 4TH OR 5TH LETTER LDA 1,ARGVAL-ALC0,2 AND# 0,1,SZR JMP EXP51 ; NOT A INSTRUCTION. ADD 1,0 ; PUT IN VALUE STA 0,NUMB ; ITS STILL A INSTRUCTION. JMP EXP1 ASSDIG: LDA 0,NUMB ; ASSEMBLE DIGITS MOVZL 0,0,SZC JSR ERR MOVZL 0,0,SNC MOVZL 0,0,SZC JSR ERR ; NUMBER IS TO BIG!! NEG 1,1 STA 1,DFLG ; SET DIGIT FLAG. ADC 1,0 STA 0,NUMB JMP @.+1 PAT2 ** .DO IDEB==0 GET: STA 3,.S3 .SYSTM .GCHAR JMP ERR ** .ENDC SKIP GET: NIOC TTI SKPDN TTI ; GET A CHARACTER JMP .-1 DIA 0,TTI LDA 1,C177 AND 1,0 ; MASK OUT PARITY BIT **[SKIP] LDA 1,C175 ; AND CONVERT THEM LDA 2,C33 ; TO "$" SUBOR# 1,0,SZR SUB# 0,2,SNR LDA 0,C44 SUBZ# 0,2,SNC ; DON'T ECHO IF < 33 ** .DO IDEB==0 JSR @TP LD jA 3,.S3 ** .ENDC SKIP DOAS 0,TTO **[SKIP] STA 0,CHAR ; EXIT WITH 7 BIT JMP 0,3 ** .DO IDEB==0 .S3: 0 ** .ENDC SERH: LDA 2,0,3 ; SEARCH A TABLE LDA 1,0,2 ; FOR VALUE IN C(0) MOVL# 1,1,SZC JMP 2,3 ; NO FIND EXIT. SUB 0,1,SNR JMP 1,3 ; A FIND.  INC 2,2 ; C(2) POINTS TO ENTRY. JMP .-6 EVALX: EVAL IFLG: 0 FIELD: 0 ITYPE: 0 VALUE: 0 V0: 0 COMB: 0 CHCTR: 0 NUMB: 0 DNUMB: 0 M12: -12 OCTER: 0 X50: EX50 X51: EX50+1 C45: 45 CSQUI: SQUISH C5: 5 INSS: INSSER ARGT4: ARG4-1 ARGT5: ARG5-1 CHAR: 0 DFLG: 0 ܁EC177: 177 C175: 175 C33: 33 C44: 44 C13: 13 UDEF: LDA 0,ERR0 ; UNDEFINED SYMBOL SUBC 2,2,SKP ERR: LDA 0,ERR1 JSR @TP ; PRINT U OR ? SUBO 3,3 JMP @.+1 CRE ERR0: " ERR1: " TP: TYPE ICLX: ICLASS DAT: DATA .EOT NDEB2.SR 3 EVAL: STA 2,DLMPT ; DELIMITER TYPED LDA 0,OCTER ; WAS THERE AN OCTAL INPUT ERROR MOV 0,0,SZR JSR ERR ; YES LDA 0,NUMB ; C(0)=VALUE IF DIGITS LDA 1,@X50 LDA 3,DFLG ADD# 1,3,SNR ; EXIT IF NOTHING TYPED. JMP EVXX ; NOTHING TYPED ADDZ# 1,3,SZ,MC ; ERROR IF BOTH DIGITS JSR ERR ; AND SYMBOL. MOV 1,1,SNR ; DONT SEARCH IF JMP EV0 ; NO SYMBOL TYPED. LDA 1,ITYPE LDA 2,FIELD ADD# 1,2,SZR JMP EVAL0 JSR @INSS ; WHEN ITS FIELD 0 AND ISYMS ; NOT A INSTRUCTION CHECK JMP EVAL0+2 ; FOR A "MSKO" TYPE INST. STA 0,NUMB ; STORE ITS PROPERTIES. LDA 1,@X50 LDA 2,C1635 SUB 1,2,SZR JSR ICLASS STA 2,ITYPE LDA 0,NUMB JMP EV0 EVXX: LDA 3,COMB ; THE NOTHING TYPED EXIT MOV 3,3,SZR ; BUT ITS ERROR IF (+,-) JSR ERR ; FLAG SET. JMP @DELM2-DE)LM1,2 C1635: 163500 UDEF0: LDA 2,DLMPT ; UNDEFINED SYMBOL LDA 1,DELM2-DELM1,2 ; BUT IF DELIMITER % MOVL# 1,1,SNC ; GO TO TITLE LOGIC. JSR UDEF ; ERROR JMP @DELM2-DELM1,2 EVAL0: MOV 2,2,SNR ; IF ITS FIELD 0 AND A JMP .+4 ; INSTRUCTION DON'T SEARCH. JSR @.SYMS ; SEARCH USER SYMBOLS ASYMS ; IF NO FIND ITS JSR UDEF0 ; A ERROR. EV0: LDA 1,V0 ; C(0)=SYMBOL VALUE LDA 2,COMB MOVL# 2,2,SZC ; IF THIS SYMBOL IS NEG 0,0 ; CONNECTED TO A MOV 2,2,SZR ; PREVIOUS SYM VIA ADD 1,0 ; (+,-) COMB sIND THE TWO. STA 0,V0 STA 0,@DAT LDA 1,CDELM ; IF THIS SYMBOL IS LDA 2,DLMPT ; (+,-) EIT TO SIGN. SUBOR# 1,2,SNR JMP @DELM2-DELM1,2 EVAL1: LDA 0,V0 ; PUT THE VALUE IN LDA 2,CIBIT ; THE PROPER FIELD. LDA 1,ITYPE ; C(2) POINTS TO BIT MASK ADD 1,2 LDA 2,0,2 LDA 3,FIELD ADD 3,2 LDA 2,0,2 ; C(2)=FIELD MASK. MOV 2,1,SNR ; AVAILIABLE FIELDS JSR ERR ; EXCEEDED. MOV 3,3,SZR ; NO SHIFT IF FIELD 0 MOVZR 1,1,SZC JMP .+3 MOVZL 0,0 ; SHIFT DATA LEFT JMP .-3 ISZ FIELD LDA 1,VALUE MOV 3,3,SZR COM 2,3 ANDO 0,3,SZR ; DATA WONT FIT JMP EVAL4 ; IN THE FIELD. EVAL3: STA 3,V0 ADD 0,1 ; COMBIND THE DATA STA 1,VALUE ; IN THE FIELD. STA 1,@DAT MOV 0,0,SNC JMP EVAL1 LDA 2,DLMPT ; EXIT TO DELIMITER ADC 3,3 JMP @DELM2-DELM1,2 DLMPT: 0r .SYMS: SYMSER EVAL4: COMS 2,3 ; DATA WON'T FIT THE FIELD SUB# 2,3,SZR ; IF DISPLACEMENT, TRY HARDER JSR ERR ; NOT A DISPLACEMENT. ERROR... COMOR 3,3 MOVL# 0,0,SNC JMP EVAL5 ; A POSITIVE NUMBER. COM 0,1 ANDO 1,3,SZR ; NEGATIVE DISPLACEMENT JғSR ERR ; IS TO BIG. EVAL6: AND 2,0 LDA @1,VALU. JMP EVAL3 VALU.: VALUE EVAL5: LDA 1,@AD ; TRY TO MAKE IT SUBZ 1,0,SNC ; RELATIVE TO "." COM 0,1,SKP ; C(0)=SYMBOL-(.) MOV 0,1 AND# 1,3,SZR JSR ERR ; OUT OF RANGE SUBZL 3,3 ; FOR BITS 6-7 (01) \JMP EVAL6 ; INDEX. ICLASS: SUBZL 2,2 ; C(0)=DATA. ON EXIT MOVL 0,0,SZC ; C(2)=INSTRUCTION TYPE. JMP 0,3 INC 2,2 MOVL 0,0,SZC JMP .+4 MOVL 0,0,SZC INC 2,2 ; #3=MEM-REFF + AC JMP 0,3 ; #2=MEM-REFF NO AC MOVL 0,0,SNC JMP .-3 INC 2,2 INC 2,2 a LDA 1,C34K AND 1,0,SNR INC 2,2,SKP ; #6=NIO SUB# 1,0,SNR INC 2,2 ; #5=I/O SKIP JMP 0,3 ; #4=DIA/DOA CDELM: DELM1 CIBIT: .IBIT AD: ADR C34K: 34000 VUSYM: MOV 1,1,SZR JMP .+4 INC 3,3,SKP ; IF = 0 PRINT +0 SOCT JMP @.-1 VALSER: SUB 0,0 ; VAsLUE SEARCH STA 0,@EX5 ; CLEAR C(EX50) SYMSER: ADC 0,0,SKP ; SYMBOLS SEARCH INSSER: SUB 0,0 ; INSTRUCTIONS SEARCH STA 0,ISW STA 3,GSRET LDA 3,@GSRET ISZ GSRET STA 3,SYM ; START SEARCH SUBZR 3,3 STA 3,DIFF LDA 3,M14 ; =177744 STA 3,GOBAL ; NO LOCAL BIT STA 1,SVAL LDA 0,@EADR ; C(ADR) LDA 1,@EX5 LDA 2,C. ; "."*50*50 SUB# 1,2,SNR JMP GS12+2 ; EXIT PERIOD TYPED. GS0: LDA 2,SYM LDA 0,-1,2 ; C(0)=SYMBOL FLAGS MOVZR 0,0,SNC ; UNRESOLVED? JMP GS00 ; NO MOVZR 0,0 MOVZR 0,0 ; GET BITt 13 INTO CARRY SUBCL 1,1,SKP ; SET AC1 TO VALUE OF CARRY GS0CH: LDA 2,SYM ; PROCESS A CHAIN LDA 0,-2,2 INCZL# 0,0,SBN ; END OF CHAIN? JMP GS0ND  ; YES DSZ SYM ; NO, BUMP POINTER JMP GS0CH ; AND TRY AGAIN GS0ND: MOV# 1,1,SNR ; ANY (MORE) NODES? E JMP GSDEC ; NO, ALL DONE DSZ SYM ; YES LDA 1,-3,2 ; GET NODE WORD MOVL# 1,1,SNC ; ANY MORE NODES? SUB 1,1 ; NO, CLEAR AC1 DSZ SYM JMP GS0CH ; NOW PROCESS THIS CHAIN GS00: LDA 3,M3 MOVR# 0,0,SZC ; NAMED COMMON ? DSZ SYM ; YES - IGNORE IT.b MOVR 0,0,SZC JMP GSDEC MOVR 0,0,SZC STA 3,GOBAL ; A TITLE STATEMENT. LDA 1,GOBAL ANDR# 1,0,SZC JMP GSDEC MOVR 0,0 MOVR 0,0,SZC ; IF BIT 11 SET JMP GS11 ; SYMBOL KILLED FOR OUTPUT. LDA 3,DIFF ; CHECK FOR NUMERIC LDA 1,-2,2 ; DIFFIRENCE ANjD SAVE LDA 0,SVAL ; IF SMALLER THAN SUB 1,0 ; PREVIOUS DIFF. SUBZ# 3,0,SNC STA 2,SYMPT SUBZ# 3,0,SNC STA 0,DIFF GS11: LDA 0,0,2 ; CHECK FOR SYMBOL LDA 1,-1,2 LDA 3,GOBAL AND 3,1 ; MASK FLAGS LDA 2,@EX5 ; C(2),C(3)=LETTERS LDA 3,@EX51 ; TO RSEARCH FOR. MOV 0,0,SNR JMP GSNULL ; NULL SYMBOL SUB# 0,2,SNR SUB# 1,3,SZR JMP GSDEC ; NO FIND GS12: LDA 2,SYM ; SYMBOL SEARCH A LDA 0,-2,2 ; SUCCESSFUL VENTURE. ISZ GSRET ; C(0)=VALUE, RETURN JMP @GSRET ; TO CALL+3 GSNULL: LDA 0,@EX51 ; N5ULL SYMBOL LDA 1,C4 LDA 3,M3 AND 0,1,SZR JMP .+10 ; TITLE SEARCH LDA 0,TITLE MOV 0,0,SZR ; IF INSTRUCTION SEARCH ISZ ISW ; OR NO USER SYMBOLS JMP GSEND ; THIS IS END OF SEARCH. MOVZL# 0,0,SNR STA 3,GOBAL ; IF GOBAL SYMBOLS ONLY MOVZL# 0,0,SNR ; POINT TO START VIA C(44) LDA @0,SYMP ; AND SET GOBAL. STA 0,SYM ; IF TITLE POINT TO IT. JMP Z.K. SYMP: UST+USTSS GSDEC: DSZ SYM ; DECREMENT TO ADVANCE DSZ SYM ; TO THE NEXT SYMBOL. DSZ SYM Z.K.: LDA 2,SYMP ; IF SYMBOLS EXIST LDA 2,1,2 v; C(2)=END OF SYMBOLS. LDA 0,SYM LDA 3,C4 ; IF IN TITLE SEARCH OR LDA 1,@EX51 ; USER SYMBOLS AND 3,1,SNR ; PRESENT THEN CHECK LDA 1,TITLE ; FOR END OF SYMBOLS. MOV 1,1,SZR SUBZ 0,2,SZR JMP GS0 ; GET ANOTHER SYMBOL. GSEND: LDA 0,@EX5 ; IF IN e]SYMBOLS SEARCH MOV 0,0,SZR ; EXIT WITHOUT A FIND. JMP @GSRET ; IF VALUE SEARCH, PRINT LDA 3,DIFF LDA 0,SYMVL ; IF A SYMBOL WITH ADCZ# 0,3,SNC ; A VALUE LESS THAN JMP P50 ; 2000 OCTAL WAS FOUND LDA 1,SVAL ; VALUE WAS NOT FOUND, JSR POCT ; PRINT IN OCTAL AND JMP @GSRET ; FORGET ABOUT SYMBOL. EADR: ADR EX5: EX50 ISW: 0 GSRET: 0 SYM: 0 DIFF: 0 M14: 177744 GOBAL: 0 SVAL: 0 C.: F.*50*50 ; RADIX 50 . M3: 177755 SYMPT: 0 EX51: EX50+1 C4: 4 TITLE: 1B0 SYMVL: 2000 C60: 60 M40: -40 C72: 72 C6: 6 DE)CTAB: DECBLK C55: 55 OCTRET: 0 RDXT: 0 RDXRET: 0 P50: LDA 1,SYMPT ; PRINT RADIX 50 STUF.  STA 1,PSDEC LDA 1,@PSDEC ; GET 3 LETTERS. DSZ PSDEC JSR RDXPT SQUISH LDA 3,C60 SUB# 0,3,SNR JMP P52 ; EXIT ON NULL MOVZR# 2,2,SZR JMP .+4 LDA 1,@PSDEC ; ҢSECOND WORD LDA 3,M40 AND 3,1 ; MASK FLAGS LDA 3,C72 SUBZ# 0,3,SZC ; CONVERT BACK TO ADC 2,2,SKP ; ASCII CODE. LDA 2,C6 ADD 2,0 LDA 2,C133 SUB# 2,0,SNR LDA 0,C56 JMP RDX1-1 ; GO TO PRINTER. P52: LDA 1,DIFF ; IF DIFFIRENCE NOT 0 MOV 1,1,SZR ; PRINT SIGNED OCTAL. JSR SOCT JMP @GSRET C56: 56 C133: 133 SOCT: LDA 2,OCTAB ; PRINT SIGNED OCTAL MOV 0,0,SKP SDEC: LDA 2,DECTAB ; PRINT SIGNED DECIMAL STA 2,PSDEC LDA 0,C55 ; CHECK ON THE SIGN. ADCZL 2,2 MOVL# 1,1,SNC ADDO 2,0,SKP NEGZ 1,4l1 STA 3,OCTRET JSR TYPE ; PRINT (+,-) JSR RDXPT PSDEC: 0 JMP TYPE ; OUTPUT THE DIGITS. JMP @OCTRET ; EXIT RDXPT: STA 3,RDXRET ; RADIX PRINTER LDA 0,@RDXRET ; JSR RDXPT STA 0,RDXT ; TABLE ISZ RDXRET ; OUTPUT ROUTINE SUBCR 3,3,SKP ; FINAL EXIT JSR TYPE RDX1: LDA 2,@RDXT ISZ RDXT LDA 0,C60 JMP .+4 SUB 2,1 INC 0,0 ; FORM DIGIT INC 3,3 SUBZ# 2,1,SZC JMP .-4 MOVZR# 2,2,SZR MOV 3,3,SZR JSR @RDXRET ; DIGIT OUTPUT. MOVZR 2,2,SZR JMP RDX1 LDA 0,@RDXT JSR TYPE ; PRINT . OR SPACE. ISuZ RDXRET ; PRIOR TO EXIT. JMP @RDXRET POCT: MOVZ 0,0,SKP ; ZERO SUPPRESSION OCTAL MOVO 0,0 ; NO SUPPRESSION OCTAL STA 3,OCTRET JSR RDXPT OCTAB: OCTBLK JMP TYPE JMP @OCTRET SPACE: LDA 0,C40 ; TYPE SPACE .DO IDEB==0 TYPE: STA 3,..S3 .SYSTM .PCHAR JMP @OER LDA 3,..S3 JMP 0,3 ..S3: 0 OER: ERR ** .ENDC SKIP TYPE: JMP .+2 ; PRINT SWITCH - JMP .+1 IF LPT JMP PRINT SKPBZ TTO JMP .-1 DOAS 0,TTO ; TYPE C(AC0) JMP 0,3 **[SKIP] OCTBLK: 100000 ; OCTAL 10000 1000 100 10 1 C40: 40 .RDX 10 DECBLK: 10000 ; DECIMAL 1000 100 10 1 ". .RDX 8 SQUISH: 50*50 ; RADIX 50 50 1 50*40 40 .DO IDEB==-1 PRINT: SKPBZ LPT JMP .-1 DOAS 0,LPT JMP 0,3 ** .ENDC INP: STA 3,INPRET ; C(0)=DATA STA 0,INPDAT ; INSTRUCTION PRINTER. JSR @ICLȭ LDA 0,XIBIT ADD 0,2 STA 2,INPT1 LDA 2,0,2 STA 2,INPT2 LDA 2,0,2 LDA 1,INPDAT AND 2,1 JSR @VALS ; PRINT 3 LETTER INST ISYM2 ; TABLE MINUS SYSTM CALLS LDA 2,INPT1 JMP @.INPB-.IBIT-1,2; GO TO INST TYPE. INPS: STA 3,INPRET ; C(0) = DATA STA ;0,INPDAT ; INST PRINTER LDA 1,CSYM ; MASK FOR SYST CALLS LDA 3,USYPT ; POINT TO INSTRUCTION SYMBOLS STA 3,USYPC INPS2: DSZ USYPC ; BUMP POINTER TO NEXT SYMBOL DSZ USYPC LDA 3,@USYPC ; GET AN EQUIV SUB# 3,0,SNR ; EQUAL ?? JMP IMATC ; YES GO PR\OCESS AS WHOLE WORD MOV 3,3,SNR ; END OF TABLE ?? JMP INPS1 ; YES GO TO NORMAL LOGIC DSZ USYPC ; NO TRY NEXT ENTRY JMP INPS2 IMATC: LDA 3,CSPC ; MASK IT OUT AND 0,1 SUB 1,3 STA 3,USYPC MOV 0,1,SKP ; MASK = WORD INPS1: AND 0,1 ; DROP CHANڧ LDA 2,.BM6 STA 2,INPT2 ; USE I/O INST FORMATTER JSR @VALS ISYMS LDA 3,USYPC ; ANY CHANNEL ? MOV 3,3,SNR JMP INP23 ; NO FORGET THIS STUFF JSR SPACE JSR INPF JSR POCT JMP INP23 SEXT: LDA 2,C377 ; EXTEND THE SIGN AND 2,0 ; OF C(0). INCZR  >2,2 ANDZL 0,2 SUB 2,0 JMP 0,3 .BM6: BM6 INPDAT: 0 ICL: ICLASS XIBIT: .IBIT INPT1: 0 INPT2: 0 CSYM: 177400 VALS: VALSER INPRET: 0 USYPT: ISYMS USYPC: ISYMS CSPC: 21000 INP1: JSR INPCL ; ALC GROUP ARGVAL ; ZOC 60 JSR INPCL ARGVAL ; LRS 300 JSR INPCL PNDSIG ; # 10 JSR SPACE JSR INPF JSR POCT ; SAC JSR INPF JSR POCT ; DAC JSR INPF MOV 1,1,SNR JMP @INPRET ; NO SKIP CONDITION. JSR @VALS ; SEARCH FOR ALC SKIP. ASYMS JMP INP23 INP3: JSR SPACE ; (LDA,STA) ENTRY JSR INPF ; RIGHT JUSTIFY AC JSR POCT ; PRINT AC MOV 0,0,SKP INP2: JSR SPACE JSR INPCL ; (ISZ,DSZ,JMP,JSR) ENTRY ATSIGN 2000 LDA 0,INPDAT ; LOGIC FOR DISPLACEMENT JSR SEXT ; BITS 8-15 OF MEM-REFF. LDA 1,C1400 LDA 2,INPDAT LDA 3,C377 ANDS 2,1,SNR AND 3,0,SKP0 MOVZR# 1,1,SNR ; CHECK IF PAGE 0 JMP INPC ; OR PC RELATIVE. STA 1,INPX MOV 0,1 JSR @OCTDIS ; PRINT OCTAL DISP IF LDA 1,INPX ; INDEXED ON 2-3. JSR @.POCT ; PRINT INDEX REGISTER JMP @INPRET ; EXIT INPC: MOV 1,1,SZR ; SKIP IF PAGE 0 LDA 1,@ADX ; VALUE OF POINT. ADD 0,1,SNR ; SEARCH FOR SYMBOLIC JMP INP23+2 JSR @VALS ; ADDRESS TAG. USYMS INP23: JSR @XXXSP JMP @INPRET JSR @.POCT JMP .-3 INP6: JSR INPCL ; NIO .IO 300 INP61: JSR @XXXSP JSR INPF ; DEVICE CODE JSR @VALS IOSYM JMkP INP23 INP5: JSR INPCL+1 ; I/O SKIP .IOS0 ; (B,D) 200 JSR INPCL+1 .IOS1 100 ; (Z,N) JMP INP61 INP4: JSR INPCL ; I/O WITH AC .IO ; TEST SCP 300 JSR @XXXSP JSR INPF JSR @.POCT ; PRINT AC FIELD JMP INP61 INPF: ISZ INPT2 ; RIGHT JUSTI$JFY LDA 2,@INPT2 ; RESULT IN C(1) LDA 1,INPDAT AND 2,1 MOVZR 2,2,SZC JMP 0,3 MOVZR 1,1 JMP .-4 INPCL: MOVO 0,0,SKP ; SEARCH FOR LETTER MOVZ 0,0 ; VALUE AND PRINT. LDA 1,0,3 STA 1,.+11 LDA 1,1,3 LDA 0,INPDAT AND 1,0,SZR JMP .+3 MOV 0,0,SZC b6 ; IF C(CARRY)=1 JMP 2,3 ; EXIT ON NULL STA 3,INPC0 JSR @SEAR 0 LDA 0,ALC0-ARGVAL,2 JSR @TYPER LDA 3,INPC0 JMP 2,3 XXXSP: SPACE C377: 377 C1400: 1400 INPX: 0 INPC0: 0 OCTDIS: SOCT SEAR: SERH TYPER: TYPE ADX: ADR .POCT: POCT DELM1: 53 ; + 55 > ; - 100 ; @ 43 ; # 75 ; = 12 ; LF 15 ; CR 54 ; , 40 ; SPACE 44 ; $ 41 ; ! 57 ; / "' ; ' "_ ; _ 136 ; ^ 177 ; RUB-OUT "< "% "; ": "& "? "* -57 DELM2: PSIGN ; + MSIGN ; - ASIGN ; @ NLSIGN ; # EQSIGN ; = LF ; LF CR ; CR EXP0 ; , EXP0 ; SPACE ALT ; $ EXCLM ; ! SLASH ; / SQUOT ; ' LFTARO UPARO ERR GTHEN ; GREATER THEN @TIT ; TITLE QUOTE LTHEN AMPER ; AMPERSAND-BYTE POINTER OUTPUT QUEST ; .SYSTM CALL ASTKRx ; "*- DISPLAY WITH 0B0 -1 .IFN SASW XXXP: ALTPY ALTP: LDA 0,GFLG ; $P TYPED MOV 0,0,SNR JMP @XXXP ; ITS A PROCEED ADC 2,2,SKP ; PUNCH MEMORY ** .ENDC ALTS: .IFN SASW SUB 2,2 ** .ENDC SUB 0,0 MOV 3,3,SZR JMP ALTS0 LDA 3,USTP ;GET UST PTR  LDA 3,USTNM,3 ;GET NMAX(FOR TOP OF SEARCH) SKIP ALTS0: LDA 3,@D DSZ GFLG STA 0,STRT STA 3,END MOVL# 0,0,SNC ; NEGATIVE ADDRESS OR ADCZ# 3,0,SZC ; START > STOP ADDRESS. JMP @IE ; (ERR) ** .IFN SASW  MOV 2,2,SZR JMP @.PMEM ; PUNCH MEMORY ** .ENDl7C ** .IFE SSW ** .DO MSW==1 LDA 2,USTP LDA 2,USTNM,2 ; GET HIGHEST LEGAL ADDRESS SUBZ# 3,2,SNC ; LEGAL REFERENCE? JMP @IE ; NO!!!! ** .ENDC ** .ENDC LDA 0,STRT STA 0,@ALTADR ; UPDATE POINT"." ** .DO IDEB==-1 ALTS1: NIOC TTI JSR @ZCRLF LDA 1,HILOW MOVZR# 1,1,SNC ; OUTPUT TO LPT? JMP ALTS5 ; NO DSZ @STYPE ; SET PRINT SWITCH LDA 0,CFF JSR @STYPE ; START WITH A FORM FEED ** .ENDC ALTS5: ** .IFN SSW&MSW LDA 2,STRT ; ADDR JSR @..MLA ; SEE IF MAPPED LOAD ** .ENDC SKIP LDA @0,STRT **[SKIP]  LDA 2,WORD LDA 1,MASK AND 0,1 SUB# 1,2,SZR JMP ALTS2 ; NOT A FIND. ** .DO IDEB==0 JSR @ZCRLF ** .ENDC LDA 1,STRT JSR @ZVALS ; (VALSER) USYMS ; PRINT ADDRESSS. JSR @XXXSP .DO IDEB==-1 ** .IFN SSW&MSW LDA 2,STRT ; ADDR JSR @..MLA ; SEE IF MAPPED LOAD ** .ENDC SKIP LDA @0,STRT **[SKIP] LDA 1,HILOW MOVZR# 1,1,SZC JSR @.ALLPR ** .ENDC SKIP LDA 0,@STRT **[SKIP] JSR @ZINP ; PRINT DATA ** .DO IDEB==-1 ARTN: JSR @ZCRLF ** .ENDC ALTS2: LDA 0,END ** .DO IDEB==-1 SKPDZ TTI ; HAS USER STOPPED SEARCH JMP ALTS4 ; YES ** .ENDC LDA 1,STRT LDA 3,BUMP ; INC ADD 3,1 STA 1,STRT ; NEW LOC STA 1,@ALTAD ADCZ# 1,0,SZC ; SKIP IF DONE JMP ALTS5 ** .DO IDEB==0 ALTS4: JSR @ZCRLF ** .ENDC SKIP ALTS4: LDA 1,HILOW MOVZR# 1,1,SZC ISZ @STYPE **[SKIP]C JMP @ALTS3 ALTS3: EXP BUMP: 1 ** .IFN SASW .PMEM: PMEM ** .ENDC GTHEN: MOV 3,3,SZR ; $< TYPED LDA 3,@D STA 3,STRT SUBZL 3,3 STA 3,GFLG SUB 0,0 JMP @.+1 EXP+2 ZINP: ANYP ZVALS: VUSYM IE: ERR ZCRLF: CRLF GFLG: 0 WORD: 0 MASK: 0 D: DATA ALTAD: ADR STYPE: TYPE ** .DO IDEB==-1 CFF: 14 .ALLPR: ALLPR HILOW: 0 ** .ENDC STRT: .BLK 1 END: .BLK 1 ** .IFN SSW&MSW ..MLA: MLDA ** .ENDC KILL: LDA 2,@ADIG ; $K KILL ALL SYMBOLS NEGZ 3,3,SZR ; 0$K KILL LOCAL SYMBOLS MOV 2,2,SZR ; A$K KILL SYMBOL A JM;P AK2 LDA 2,@ASY LDA 1,CISYMS ADCZ# 1,2,SNC ; TRYING TO KILL A PERM JSR @IE ; SYMBOL IS A ERR. LDA 3,C7757 ; INSERT A BIT 11 LDA 0,-1,2 ; IN THE SYMBOLS FLAGS AND 3,0 ; TO PREVENT OUTPUT. ADC 3,0 STA 0,-1,2 KRET: JSR @ZCRLF JMP @ALTS3 ASY: SۖYM ADIG: DFLG CISYMS: ISYMS C7757: 177757 TITLE AK2: SUBR 0,0 STA 0,@.-2 JMP KRET ** .IFN SASW ; ONLY FOR STAND ALONE WORLD ALTV: LDA 3,USP ; GET BREAK ADDRESS LDA 2,USTBR,3 COM# 2,2,SNR ; ENABLED ?? JMP @ALTVE ; NO GIVE ERROR JMP -1,2 ; YE'=START ? JMP E.XIT ; NO, THATS ALL ADDL# 0,1,SZC COM 1,0 ; <16 WORDS STA 0,WDCNT ; SAVE -(WORD COUNT) SUB 0,2 STA 2,TEND ; LAST + 1 JSR PNCH ; PUNCH WORD COUNT ADD 2,0 JSR PNCH ; PUNCH START. ADDRESS MOV 0,2 LDA 3,WDCNT ADD 3,0 LDA 1,0,2 ; GET DATA WORD INC 2,2 ADD 1,0 ; ADD TO FORM CHECKSUM INC 3,3,SZtR JMP .-4 ; LOOP THROUGH DATA NEG 0,0 ; CHECKSUM JSR PNCH LDA 1,WDCNT ; NOW PUNCH DATA ADD 1,2 LDA 0,0,2 ; DATA WORD JSR PNCH ; PUNCH IT INC 2,2 LDA 0,TEND SUB 2,0,SZR ; TEST FOR END OF BLOCK JMP .-5 JSR PNCH ; YES PUNCH 2 NULLS JMP PME{M1 ; PUNCH NEXT BLOCK ALTE: MOV 3,3,SNR SUBZR 2,2,SKP LDA 2,@.D. JSR TDEV1 ; TEST FOR OUTPUT DEVICE SUBZL 0,0 JSR PNCH ; PUNCH 00001 MOV 2,0 ; AC2CONTAINS ADDRESS JSR PNCH COM 0,0 ; NEG (AC2+1) JSR PNCH ; IS CHECKSUM SUB 3,3 ; PUNCH LEADER ALTF: LDA 2,X12 MOV 3,3,SZR LDA 2,@.D. MOVZL 2,1 ; *10 TO OBTAIN INCHES ADD 2,1 NEGZL 1,2 JSR TDEV1 ; TEST FOR OUTPUT DEVICE SUB 0,0 JSR PNCH INC 2,2,SZR JMP .-2 E.XIT: LDA 1,@EHILO MOVZL# 1,1,SNC HALT ; TURN OFF PUNCH MOVZ 1,1 JSR @Z.CRLF JMP @EX.P ; TEST OUTPUT DEVICE CODE TDEV1: LDA 1,@EHILO MOVZL# 1,1,SNC HALT MOVO 1,1 JMP 0,3 X12: 12 EHILO: HILOW E.END: END S.TRT: STRT .D.: DATA Z.CRL: CRLF EX.P: EXP .EJECT ** .ENDC ** .IFN SSW&MSW ; ROUTINES TO LOAD/STORE INTO MAP SPACE ; REG UBLK = PHYS BLK OR 0 ; CALLERS AC2= ADDR ; AC0= CONTENTS ON RTN ; AC1,AND CARRY NOT CHANGED (LEO SOMETIMES KEEPS CARRY FOR 20 ROUTINES...) ; THIS ROUTINE WILL USE THE LAST MAP BLOCK IN THE 8021 ; THE LAST BLOCK WILL BE RESTORED IN ALL CASES MSTA: STA 3,MPRT STA 0,WDSV ; SAVE DATA TO STORE LDA 3,CON1 ; =1 JMP MLDA1 MLDA: STA 3,MPRT SUBC 3,3 MLDA1: STA 3,MPSW ; LDA/STA FLAG LDA 3,UBLK ; SEE IF MAP NEEDED MOV# 3,3,SNR JMP NOMAP ; NO LDA 3,LBLK ; SEE LAST BLK CONTENTS DOA 3,MAP DIC 3,MAP 5LDA 0,CRBT ; 377 AND 0,3 LDA 0,CLBK ; DOA RESTORE VALUE ADD 0,3 STA 3,LBRST ; SAVE FOR EXIT LDA 3,UBLK ** .IFN SYSW LDA 0,ML177 SUBZ# 3,0,SNC ; BLOCK # OR MAP TABLE ?? JMP MPTBL ; A MAP TABLE GO TO IT MPTRT: LDA 0,CLBK ; RESTORE DOA VALUE ** .ENDC ADD 3,0 DOA 0,MAP ; SET TO UBLK BLK# LDA 3,C1777 ; MAKE USER ADDR INTO MOD 76000 ADDR AND 2,3 ; LOW BITS LDA 0,C31K ; 76000 ADD 0,3 DSZ MPSW ; LDA OR STA ? JMP .+4 ; LOAD LDA 0,WDSV ; DATA STA 0,0,3 JMP .+2 LDA 0,0,3 ; GET DATA > LDA 3,LBRST ; RESTORE LAST BLK DOA 3,MAP JMP @MPRT NOMAP: DSZ MPSW ; LDA OR STA ? JMP .+4 ; LDA LDA 0,WDSV STA 0,0,2 JMP @MPRT LDA 0,0,2 JMP @MPRT ** .IFN SYSW ; ONLY FOR SYSTEM DEBUGGERS MPTBL: MOV 2,0 ; EXTRACT BLOCK # FROM ADDRESS STA 1,MLTMP ; FREE UP AN AC LDA 1,C31K ; CLEAR OUT NOISE BITS ANDS 1,0 MOVR 1,1 ; SAVE CARRY MOVZR 0,0 MOVZR 0,0 MOVZL 1,1 ; RESTORE CARRY LDA 1,ML177 ; MASK TO 7 BITS ADD 0,3 ; POINT TO PROPER BLOCK IN TABLE LDA 3,0,3 ; GET ACTUAL BLOCK NUMBER #AND 1,3 ; 7 BITS AGAIN SUB# 1,3,SNR ; VALID BLOCK NUMBER ? JMP @OVLER ; NO BAG IT LDA 1,MLTMP ; RESTORE AC1 JMP MPTRT ; JOIN COMMON CODE ML177: 177 MLTMP: 0 ** .ENDC CON1: 1 UBLK: 0 MPRT: 0 WDSV: 0 MPSW: 0 C31K: 76000 C1777: 1777 LBRST: 0 CRBT:&# 377 LBLK: 117400 CLBK: 17400 .EJECT ** .ENDC ** .IFN SSW-SASW ; SEE IF BREAK POINT SET AT LDRTN IS OURS ; IF OVRG NOT = 0, LOOK FOR RIGHT OVLY IN OVLK: LDA 2,OVRG COM# 2,2,SNR JMP @.BENRT ; NOT LOOKING LDA 0,.OVTAB ; TABLE BASE ADD 2,0 ; = CRSEGo VALUE LDA 2,CRSEG ; JUST LOADED SUB 2,0,SZR ; SKIP IF RIGHT OVLY JMP @.NOBK ; CONTINUE ADC 0,0 STA 0,OVRG ; CLEAR REG LDA 2,0,2 ; BUFFER ISZ BQUSC,2 ; LOCK IN DSZ @OVACT ; REMOVE BREAK POINT JMP .+1 LDA 0,OVDUM ; THE HARD WAY STA 0,-2,30 JMP @.BENRT OVSET: MOV 3,3,SNR ; ARG TYPED ?? JMP @OVLER ; NO BAG IT LDA 3,@OVDAT ; OVERLAY # LDA 0,OVNSE ; HIGHEST OVERLAY IN SYSTEM SUBZ# 3,0,SNC ; LEGAL NUMBER ?? JMP @OVLER ; NO GIVE EM HELL STA 3,OVRG ; YES SAVE IT LDA 3,OVLDR ; FAKE OUT BREAK POINT LOGIC STA 3,@OVDAT ; TO PUT BREAK POINT AT LDRTN JMP @OVALB ; GO TO BREAK LOGIC OVACT: ACTBP OVDUM: DUMMY OVLER: ERR OVDAT: DATA OVLDR: LDRTN OVALB: ALTB OVNSE: NSEG .NOBK: NOBK .OVTAB: OVTAB OVRG: -1 .BENRT: BENRT .EJECT ** .ENDC *W* ** .IFE SSW FPOUT: MOV 3,3,SZR ; ALLOR ONE ? JMP FSPEC ; ONLY ONE JSR @CR.LF LDA 0,ASCP ; TYPE ALL JSR @.TYP. JSR @.SP. JSR AFI ; GET FLOATING POINT REGISTER JSR LOCTP ; PRINT IT IN HEX JSR @.SP. LDA 0,ASCT JSR @.TYP. JSR @.SP. JSR ATI LDA 2,TBLK JSR LOCTP ; PRINT IT JSR @.SP. LDA 0,ASCS JSR @.TYP. JSR @.SP. JSR ASI LDA 2,TBLK JSR LLOCT FOUT: JMP @.+1 CR CR.LF: CRLF AFI: STA 3,ARTN. LDA 2,FBLK SKPBZ FPU JMP .-1 DOBS 2,FPU2 JMP @ARTN. ; RESTORE FPAC AFO: STA 3,ARTN. LDA k2,FBLK SKPBZ FPU JMP .-1 DOBP 2,FPU2 JMP @ARTN. ATI: STA 3,TRT.N JSR AFI LDA 2,TBLK SKPBZ FPU JMP .-1 NIOC FPU2 SKPBZ FPU JMP .-1 DOBS 2,FPU2 JSR AFO JMP @TRT.N ASI: STA 3,SRTN SKPBZ FPU JMP .-1 DIAC 0,FPU LDA 2,TBLK STA 0,0,2 JMP @SRTN ASCP: " ASCT: " FSPEC: LDA 0,@DAT.A ; FIND WHICH ONE MOV# 0,0,SZR JMP FNXT JSR @CR.LF LDA 0,ASCP JSR @.TYP. JSR @.SP. JSR AFI JSR LOCTP JMP FOUT FNXT: MOVZR 0,0,SZR JMP FLAST JSR @CR.LF LDA 0,ASCT JSR @.TYP. JSR @.SP. JSR ATI LDA 2,kTBLK JSR LOCTP JMP FOUT FLAST: MOV# 0,0,SZC JMP @.FER MOVZR 0,0,SZR JMP @.FER JSR @CR.LF LDA 0,ASCS JSR @.TYP. JSR @.SP. JSR ASI LDA 2,TBLK JSR LLOCT JMP FOUT .TYP.: TYPE .SP.: SPACE ASCS: " TBLK: .+1 .BLK 4 ARTN.: 0 FBLK: .+1 .BLK 4 .EJECT ** LLOCT: STA 3,LORTN LDA 0,C.2 STA 0,LCNT SUBZL 1,1 STA 1,.WDCT JMP LLP.-1 LOCTP: STA 3,LORTN LDA 0,C.2 STA 0,LCNT LDA 0,C.4 STA 0,.WDCT MOVZL 2,2 ; MAKE BYTE POINTER LLP.: STA 2,LADRP ; SAVE ADDRESS JSR LDBYTE STA 0,HTMP MOVZR 0,0 MDOVZR 0,0 MOVZR 0,0 MOVZR 0,0 LDA 1,HMSK AND 1,0 LDA 2,HXTAB ADD 0,2 LDA 0,0,2 JSR @.TYP. LDA 0,HTMP LDA 1,HMSK AND 1,0 LDA 2,HXTAB ADD 0,2 LDA 0,0,2 JSR @.TYP. LDA 2,LADRP INC 2,2 DSZ LCNT JMP LLP. JSR @.SP. LDA 0,C.2 STA 0,LCNT DSZ#Q .WDCT JMP LLP. JMP @LORTN LDBYTE: LDA 1,C.377 MOVZR 2,2 LDA 0,0,2 MOV# 0,0,SNC MOVS 0,0 AND 1,0 JMP 0,3 LCNT: 0 HMSK: 17 HTMP: 0 C.2: 2 .WDCT: 0 TRT.N: 0 SRTN: 0 .E.XP: EXP DAT.A: DATA .FER: ERR LORTN: 0 LADRP: 0 C.377: 377 C.4: 4 HXTAB: .+1 60 61 62 63 64 65 66 67 70 71 101 102 103 104 105 106 .EJECT ** .ENDC ** ARG4: ALC0 ; 4TH CHARACTER TABLE. NOARG NOARG IO IOS0 IO ** .DO 5 NOARG ** .ENDC ARG5: ALC1 ; 5TH CHARACTER TABLE. NOARG NOARG NOARG IOS1 ** .DO 6 NOARG ** .ENDC .IBIT: BM0 ; POINT TO BIT MASK. BM1 BM2 BM3 BM4 BM5 BM6 .INPB: INP1 ; OUTPUT PRINTER POINTERS. INP2 INP3 INP4 INP5 INP6 INP23 EX50: 0 ; THE RADIX 50 0 ; TYPED IN SYMBOL EXP1 ; POINT TO INPUT EXP1 ; CHARACTER ROUTINEkyS EXP3 EXP4 EXP5 ALC0: 132 ; Z 117 ; O 103 ; C ALC1: 114 ; L 122 ; R 123 ; S -1 IO: 123 ; S 103 ; C 120 ; P -1 IOS0: 102 ; B 104 ; D -1 IOS1: 132 ; Z 116 ; N NOARG: -1 43 ; # -1 100 ; @ -1 ARGVAL: 20 ; Z 40 ; O 60 ; C 100 ; L 200 ; R 300 ; S -1 .IO: 100 ; S 200 ; C 300 ; P -1 .IOS0: 0 ; B 200 ; D -1 .IOS1: 100 ; Z 0 ; N -1 PNDSIG: 10 ; # -1 ATSIGN: 2000 ; @ -1 BM0: -1 ; NOT A INSTRUCTION 0 BM1: 103400 ; ALCg 060000 014000 000007 0 BM2: 014000 ; MEM-REFF, NO AC 000377 001400 0 BM3: 060000 ; MEM-REFF WITH AC 014000 000377 001400 0 BM4: 063400 ; I/O WITH AC 014000 000077 0 BM5: 063400 ; I/O SKIP 000077 0 BM6: 063400 ; NIO 000077 0 ** .NOMAC 1 0 ; INPUT/OUTPUT SYMBOLS 0 ; NULL TERMINATOR. 0 .SYM C P U .SYM M T A .SYM D S K .SYM D K P .SYM L P T .SYM T T I 1 .SYM T T O 1 .SYM R T C .SYM T T O .SYM T T I IOSYM= .-1 .SYM S Z R .SYM S Z C .SYM S N R .SYM S N C .SYM S K P .SYM S E ZSC .SYM S B N ASYMS= .-1 0 ; INSTRUCTION SYMBOLS. 0 USYMS: 0 .SYM2 A N D .SYM2 A D D .SYM2 S U B .SYM2 A D C .SYM2 I N C .SYM2 M O V .SYM2 C O M .SYM2 N E G ;SKP (I/O TYPE) SKPBN 0 .SQ S K P .SYM2 D O C .SYM H A L T .SYM I O R S T .SYM2 D I C .SYM1 M S K O .SYM2 D O B .SYM1 I N T A .SYM2 D I B .SYM2 D O A .SYM1 R E A D S .SYM2 D I A .SYM1 N I O .SYM I N T D S .SYM I N T E N .SYM2 S T A .SYM2 L D A .SYM1 D S Z .SYM1 I S Z .SYM1 J S R .SYM1 J M P ISYM2= .-1 .SYM . C R E A T .SYM . D E L E T .SYM . R E Ne A M .SYM . M E M .SYM . B R E A K .SYM . R L S E .SYM . D I R .SYM . E X E C .SYM . I N I T .SYM . R T N .SYM . R E S E T .SYM . E R T N .SYM . C R A N D .SYM . G C H A R .SYM . P C H A R .SYM . D E L A Y .SYM . M E M I .SYM . C C O N .SYM . E X F G .SYM . E X B G .SYM1 . R O P E N .SYM1 . M T O P D .SYM1 . O V O P N .SYM1 . C H A T R .SYM1 . G T A T R .SYM1 . R D B .SYM1 . W R B .SYM1 . A P P E N D .SYM1 . O P E N .SYM1 . C L O S E .SYM1 . R D S .SYM1 . R D L .SYM1 . R D R .SYM1 . W R S .SYM1 . W R L .SYMLC1 . W R R .SYM1 . O V L O D .SYM1 . M T D I O .SYM1 . S P O S .SYM1 . G P O S .SYM1 . E O P E N .SYM1 . C H L A T .SYM1 . C H S T S .SYM1 . U P D A T .SYM . G H R Z .SYM . D U C L K .SYM . R U C L K .SYM . G T O D .SYM . S T O D .SYM . S D A Y .SYM . G D ApR Y .SYM . I D E F .SYM . I R M V .SYM . S P K L .SYM . S P D A .SYM . S P E A .SYM . C P A R T .SYM . C D I R .SYM . L I N K .SYM . E Q I V .SYM . G D I R S .SYM . S Y S I .SYM . W C H A R .SYM . I C M N .SYM . W R C M N .SYM . R D C M N .SYM . O D I S .SYWM . O E B L .SYM . D E B L .SYM . D D I S .SYM . R D O P R .SYM . W R O P R .SYM . S T M A P .SYM . G C I N .SYM . G C O U T .SYM . S T A T .SYM . E C L R .SYM . F G N D .SYM . G M E M .SYM . S M E M .SYM . B O O T .SYM . M D I R .SYM . G C H N .SYM . U L ON K .SYM . W R P R .SYM . W R E B L .SYM . G S Y S .SYM . O V R P .SYM . A B T C .SYM . G M C A .SYM . S E C I .SYM . H S T R U .SYM . H S T S T .SYM . R D S W .SYM . V M E M .SYM . M A P D F .SYM . T U O F F .SYM . T U O N .SYM . I N T A D ISYMS=.-1 ; ;( RADIX FIFTY CHARACTER TRANSLATIONS ; .DUSR F=0 .DUSR F0=1 .DUSR F1=2 .DUSR F2=3 .DUSR F3=4 .DUSR F4=5 .DUSR F5=6 .DUSR F6=7 .DUSR F7=10 .DUSR F8=11 .DUSR F9=12 .DUSR FA="-66 .DUSR FB="-66 .DUSR FC="-66 .DUSR FD="-66 .DUSR FE="-66 .DUSR FF="-66 .DUSR% FG="-66 .DUSR FH="-66 .DUSR FI="-66 .DUSR FJ="-66 .DUSR FK="-66 .DUSR FL="-66 .DUSR FM="-66 .DUSR FN="-66 .DUSR FO="-66 .DUSR FP="-66 .DUSR FQ="-66 .DUSR FR="-66 .DUSR FS="-66 .DUSR FT="-66 .DUSR FU="-66 .DUSR FV="-66 .DUSR FW="-66 .DUSR  FX="-66 .DUSR FY="-66 .DUSR FZ="-66 .DUSR F.="-11 ** .DO IDEB==0 .EJECT MAGIC: STA 0,M0 ;SAVE AC'S STA 1,M1 STA 2,M2 STA 3,M03 LDA 3,USTP LDA 1,USTDA,3 ;DEBUG START ADDRESS LDA 2,USTCT,3 LDA 2,TPC,2 ;GET USER'S PC MOVZR 2,2 ; AND ADJUST IT ;IS PC >= (USTDA) ? ADCZ# 2,1,SZC ;SKIP IF MAYBE IN DEBUG JMP MAGC0 ;OUTSIDE DEBUG LDA 0,DEBLN ;LENGTH ;IS PC < DEBUGGER END ? ADCZ# 2,0,SNC ;SKIP IF INSIDE DEBUG JMP MAGC0 ;OUTSIDE LDA 2,USTCT,3 ;CURR. TCB JMP @RTASK ;RUN THIS TASK MAGC0: L1DA 0,@..SVSV ;USER' USTSV MOV 0,1,SNR ;SKIP IF VALID LDA 1,USTSA,3 ;ELSE USE SCHED STA 1,EXAD ;EXIT ADDRESS STA 0,USTSV,3 ;RESTORE USER'S USTSV LDA 0,M0 ;RESTORE AC'S LDA 1,M1 LDA 2,M2 LDA 3,M03 JMP @EXAD ;GO RTASK: R.UTSK ;TCBMON ENTRY, RUN CURR TCB ..SVSV: SVSV ;USER'S USTSV M0: 0 M1: 0 M2: 0 M03: 0 EXAD: 0 ;DEBLN MUST BE AT THE END OF EXECUTABLE CODE DEBLN: .+0 ;DEBUGGER END .EJECT ** .ENDC .TXTM 1 COPYR: .TXT /COPYRIGHT(C)DGC,1972,1973,1974,1975,1977 ALL RIGHTS RESERVED/ .END DSKDEFS.SRII & ; ; ***************************************** ; * HARDWARE DISK INTERFACE DEFINITIONS * ; ***************************************** ; .TITL DKDEF ; ; .......... NAMING CONVENTIONS ........... ; ; ; THE FIRST LETTER OF A NAME DESIGNATES THE REGISTERf CLASS: ; ; U - ERROR/STATUS (DIA, DIB STATUS BITS) ; V - COMMAND (DOA, DOB 1B0'S) ; W - COMMAND ARGUMENTS (DOC, DIC) ; ; THE SECOND LETTER DESIGNATES THE DISK INTERFACE TYPE: ; ; O - OLD STYLE MOVING HEAD (DIABLO, 111, 114) ; T - TOP LOADER, FLOPPY ; 3 - 3330 ; V - UNIVERSAL (NON-ZEBRA) MOVING HEAD ; Z - ZEBRA ; B - DIB STATUS BITS (ZEBRA & 3330) ; F - MICRONOVA FLOPPY ; N - NOVADISK ; P - PAGING DISK ; ; FOR NAMES REFERRING TO BITS (OR COMMANDS) THE 3RD, 4TH, & 5TH ; CHARACTERS ARE ALPHABETIC. FOR NAM,ES REFERRING TO FIELDS, THE ; 4TH & 5TH CHARACTERS ARE ALPHABETIC, WHILE THE 3RD CHARACTER ; DESIGNATES THE ATTRIBUTE THE NAME REFERS TO AS FOLLOWS: ; ; . - FIELD LOCATION (BIT # OF LOW ORDER BIT) ; 1 - FIELD SIZE IN BITS ; ? - FIELD VALUE ; ; NAMES REFERR*ING TO FIELD ATTRIBUTES HAVE AN INTEGER VALUE; ; NAMES REFERRING TO A BIT HAVE A VALUE OF THE FORM 1BX. ; ; ; NAMES FOR PAGING PACKET WORDS ARE OF THE FORM PPXXX, ; WHERE XXX ARE ALPHABETIC. ; ; MOVING HEAD DEFINITIONS ARE FIRST; MICROFLOPPY, NOVADISK, >& ; PAGING DISK DEFINITIONS ARE NEAR THE END. ; ; .......... DOA DEFINITIONS .......... ; ; UNIVERSAL MOVING HEAD .DUSR VVATRW = 1B0 ;READ/WRITE ATTENTION CLEAR .DUSR VVAT0 = 1B1 ;DRIVE 0 ATTENTION CLEAR .DUSR VVAT1 = 1B2 ;DRIVE 1 ATTENTION CLEAR .DUSR VVAT2 = 1B3 .DUSR VVAT3 = 1B4  .DUSR VVATD = VVAT0!VVAT1!VVAT2!VVAT3 ;DRIVE ATTN CLR BITS .DUSR VVATS = VVATD!VVATRW ;ALL ATTENTION CLR BITS .DUSR VV?RD = 0 ;READ COMMAND FIELD VALUE .DUSR VV?WR = 1 ;WRITE .DUSR VV?SK = 2 ;SEEK .DUSR VV?RC = 3 ;RECAL *.DUSR VVRECAL = 7B7 ;UNIVERSAL RECAL COMMAND .DUSR VV.CYL = 15. ;CYLINDER IS AT BOTTOM OF WORD .DUSR VV1CMD = 2. ;COMMAND FIELD IS 2 BITS WIDE ; OLD STYLE MOVING HEAD .DUSR VO1CYL = 8. ;CYLINDER TAKES UP A BYTE .DUSR VO.CMD = 7. ;COMMAND FIELD IS AT BIT 7 .DUSR VOREAD = (VV?RD)B(VO.CMD) ;DEFINE COMMAND WORDS .DUSR VOWRITE = (VV?WR)B(VO.CMD) .DUSR VOSEEK = (VV?SK)B(VO.CMD) .DUSR VORECAL = (VV?RC)B(VO.CMD) ; TOP LOADER ;EVERYTHING IS THE SAME AS OLD STYLE, EXCEPT: .DUSR VTXCYL = 1B5 ;EXTRA CYLINDER BIPlT ; 3330 .DUSR V31CYL = 9. ;CYLINDER FIELD SIZE .DUSR V3.CMD = 6. ;COMMAND FIELD BASE .DUSR V3READ = (VV?RD)B(V3.CMD) ;COMMAND WORDS .DUSR V3WRITE = (VV?WR)B(V3.CMD) .DUSR V3SEEK = (VV?SK)B(V3.CMD) .DUSR V3RECAL = (VV?RC)B(V3.CMD) ; DOB STUFF .DUSR V3FMT = 1B0 ;3330 FORMAT BIT ;NOTE: OLD-STYLE & TOP LOADER FORMAT BIT IS IN DOC ; ZEBRA DOA DEFINITIONS ;ATTENTION BITS ARE SAME AS UNIVERSAL MOVING HEAD .DUSR VZ.CMD = 8. ;COMMAND FIELD .DUSR VZ1CMD = 4. .DUSR VZ.UNIT = 10. ;UNIT (DRIVE) FIELD .DUSR VZ1UNIT = 2. .DUSR VZ.XMEM = 15. ;EXTENDED MEM FIELD IS AT BOTTOM OF WORD .DUSR VZ1XMEM = 5. ;DEFINE COMMAND FIELD VALUES .DUSR VZ?RD = 0. ;READ .DUSR VZ?RC = 1. ;RECALIBRATE .DUSR VZ?SK = 2. ;SEEK .DUSR VZ?ST = 3. ;STOP DISK .DUSR VZ?OF = 4. ;OFFSEsT FORWARD .DUSR VZ?OR = 5. ;OFFSET REVERSE .DUSR VZ?WD = 6. ;WRITE DISABLE .DUSR VZ?RL = 7. ;RELEASE DRIVE .DUSR VZ?TR = 8. ;TRESPASS .DUSR VZ?A1 = 9. ;SET ALTERNATE MODE #1 .DUSR VZ?A2 = 10. ;SET ALTERNATE MODE #2 .DUSR VZ?NO = 11. ;NO-OP .DUSR VZ?VF = 12P. ;VERIFY .DUSR VZ?RB = 13. ;READ BUFFERS .DUSR VZ?WR = 14. ;WRITE .DUSR VZ?FM = 15. ;FORMAT ;DEFINE COMMAND WORDS .DUSR VZREAD = (VZ?RD)B(VZ.CMD) .DUSR VZRECAL = (VZ?RC)B(VZ.CMD) .DUSR VZSEEK = (VZ?SK)B(VZ.CMD) .DUSR VZSTOP = (VZ?ST)B(VZ.CMD) .DUSR VZOFWD = (VZ?OF)B(VZ.CMD) .DUSR VZORVR = (VZ?OR)B(VZ.CMD) .DUSR VZWDIS = (VZ?WD)B(VZ.CMD) .DUSR VZRELS = (VZ?RL)B(VZ.CMD) .DUSR VZTRESP = (VZ?TR)B(VZ.CMD) .DUSR VZAL1 = (VZ?A1)B(VZ.CMD) .DUSR VZAL2 = (VZ?A2)B(VZ.CMD) .DUSR VZNOP = (VZ?NO)B(VZ.CMD) .DUSR VZVF/fY = (VZ?VF)B(VZ.CMD) .DUSR VZRDBUF = (VZ?RB)B(VZ.CMD) .DUSR VZWRITE = (VZ?WR)B(VZ.CMD) .DUSR VZFMAT = (VZ?FM)B(VZ.CMD) ; ; ......... DIA DEFINITIONS ......... ; ; UNIVERSAL MOVING HEAD .DUSR UVATRW = 1B0 ;READ/WRITE ATTENTION .DUSR UVAT0 = 1B1 ;DRIVE 0 ATTENTION .DUSR UVAT1 = 1B2 .DUSR UVAT2 = 1B3 .DUSR UVAT3 = 1B4 .DUSR UV.ATN = 4. ;MIGHT AS WELL ALSO DEFINE AS FIELD .DUSR UV1ATN = 4. ;LENGTH .DUSR UVATD = UVAT0!UVAT1!UVAT2!UVAT3 ;DRIVE ATTN BITS .DUSR UVATS = UVATD!UVATRW ;ALL ATTENTION BITS .DUSR UVRDY = 1B9 ;DISK READY .DUSR UVSEK = 1B10 ;SEEK ERROR .DUSR UVEND = 1B11 ;END ERROR .DUSR UVCHK = 1B13 ;CHECKSUM ERROR .DUSR UVLAT = 1B14 ;DATA LATE ERROR .DUSR UVERR = 1B15 ;ANY ERROR ; OLD STYLE MOVING HEAD .DUSR UOSK0 = 1B5 ; DRIVE SEEKING BITS .D5USR UOSK1 = 1B6 .DUSR UOSK2 = 1B7 .DUSR UOSK3 = 1B8 .DUSR UOUSA = 1B12 ;UNSAFE OR ADDRESS ERROR .DUSR UOEMK = 1B9-1B14 ;ERROR MASK: BITS 10 THRU 14 ; TOP LOADER .DUSR UTFPY = 1B5 ;FLOPPY BIT .DUSR UTUNS = 1B8 ;DRIVE UNSAFE .DUSR UTADR = 1B12 ;ADDRESS  ERROR .DUSR UTEMK = 1B8+1B9-1B14 ;ERROR MASK: BITS 8, 10 THRU 14 ; 3330 .DUSR U3DUP = 1B5 ;DUAL PROCESSORS .DUSR U3SEC = 1B6 ;SECTOR ERROR INDICATOR .DUSR U3HED = 1B7 ;HEAD ERROR INDICATOR .DUSR U3ADR = 1B8 ;ADDRESS ERROR .DUSR U3UNS = 1B12 ;DRIVE UNSAF|E .DUSR U3EMK = 1B5-1B14-1B9 ;ERROR MASK: BITS 6-8, 10-14 .DUSR UBBSE = 1B0 ;BAD SECTOR BIT OF DIB .DUSR UB3EMK = 1B0 ;ERROR MASK ; ZEBRA DIA .DUSR UZFUL = 1B0 ;CONTROLLER FULL .DUSR UZATRW = 1B1 ;READ/WRITE ATTENTION .DUSR UZAT0 = 1B2 ;DRIVE 0 ATTE=@NTION .DUSR UZAT1 = 1B3 .DUSR UZAT2 = 1B4 .DUSR UZAT3 = 1B5 ;DRIVE 3 ATTENTION .DUSR UZ.ATN = 5. ;MIGHT AS WELL ALSO DEFINE AS FIELD .DUSR UZ1ATN = 4. .DUSR UZATD = UZAT0!UZAT1!UZAT2!UZAT3 ;DRIVE ATTN BITS .DUSR UZATS = UZATD!UZATRW ;ALL ATTENTION BITS .DUSR UZPAR = 1B6 ;PARITY ERROR .DUSR UZISE = 1B7 ;ILLEGAL SECTOR ERROR .DUSR UZECC = 1B8 ;ECC ERROR .DUSR UZBSE = 1B9 ;BAD SECTOR ERROR .DUSR UZCAE = 1B10 ;CYLINDER ADDRESS ERROR .DUSR UZSAE = 1B11 ;SURFACE OR SECTOR ADDRESS ERROR .DUSR UZVFE = 1B12 ;VERIcFY ERROR .DUSR UZTIM = 1B13 ;HARDWARE R/W TIME OUT .DUSR UZLAT = 1B14 ;DATA LATE ERROR .DUSR UZERR = 1B15 ;ANY ERROR .DUSR UZEMK = 1B5-1B14 ;ERROR MASK: BITS 6 THRU 14 ; DIB BITS .DUSR UBINV = 1B0 ;INVALID STATUS .DUSR UBRSV = 1B1 ;DRIVE RESERVED .DUSƗR UBTRS = 1B2 ;TRESPASSED .DUSR UBRDY = 1B3 ;DRIVE READY .DUSR UBBSY = 1B4 ;DRIVE BUSY .DUSR UBOFF = 1B5 ;OFFSET MODE .DUSR UBWDS = 1B6 ;WRITE DISABLED ;1B7 UNUSED .DUSR UBICS = 1B8 ;ILLEGAL CYLINDER OR SURFACE .DUSR UBICD = 1B9 ;ILLEGAL COMMAND .DUSR UBPWR = 1B10 ;DC VOLTAGE FAULT .DUSR UBUNS = 1B11 ;DRIVE UNSAFE .DUSR UBPOS = 1B12 ;POSITIONER FAULT .DUSR UBSCL = 1B13 ;SERVO CLOCK FAULT .DUSR UBWRF = 1B14 ;WRITE FAULT .DUSR UBERR = 1B15 ;ANY ERROR IN THIS WORD .DUSR UBZEMK = 1B7-1B14 ;ERROR MASK: BITS 8 THRU 14 ; ; ........ DOC/DIC DEFINITIONS ........ ; ; UNIVERSAL MOVING HEADS .DUSR WV.SCNT = 15. ;SECTOR COUNT FIELD .DUSR WV1SCNT = 4. .DUSR WV.SECT = 11. ;SECTOR FIELD BASE .DUSR WV1SURF = 5. ;SURFACE FIELD LENGTH .DUSR WV.UNIT = 1. ;UNIT (DRIVE) bFIELD .DUSR WV1UNIT = 2. .DUSR WVSCM = (1B(15.-WV1SCNT)-1)B(WV.SCNT) ;SECTOR CNT MASK ; OLD STYLE & TOP LOADERS .DUSR WO1SECT = 4. ;SECTOR FIELD LENGTH .DUSR WO.SURF = 7. ;SURFACE FIELD BASE .DUSR WOFMT = 1B2 ;FORMAT MODE ; TOP LOADERS .DUSR WT1SURTF = 1. ;SORT OF: EACH DISK HAS ONLY 2 SIDES .DUSR WT?FH = 2 ;HEAD BIT TO PICK FIXED DISK .DUSR WTFHD = (WT?FH)B(WO.SURF) .DUSR WTFMT = 1B2 ;FORMAT MODE ; 3330 .DUSR W31SECT = 5. ;SECTOR FIELD LENGTH .DUSR W3.SURF = 6. ;SURFACE FIELD BASE ;NOTE: 3330 F]ORMAT BIT IS IN DOB ; ZEBRA .DUSR WZ.SCNT = 15. ;SECTOR COUNT FIELD .DUSR WZ1SCNT = 5. .DUSR WZ.SECT = 10. ;SECTOR FIELD .DUSR WZ1SECT = 5. .DUSR WZ.SURF = 5. ;SURFACE (HEAD) FIELD .DUSR WZ1SURF = 5. .DUSR WZMAP = 1B0 ;MAPPING SWITCH .DUSR WZSCM = (1B.(15.-WZ1SCNT)-1)B(WZ.SCNT) ;SECTOR CNT MASK ; ; ...... MICRONOVA FLOPPY DEFINITIONS ...... ; ; DOA STUFF .DUSR VF.UNIT = 0. ;UNIT FIELD .DUSR VF1UNIT = 1. ; 1 BIT WIDE .DUSR VFINR = 1B1 ;INNER CYLINDER (DENSITY COMPENSATION) .DUSR VF.SECT = 7. ;SECTOR F IELD .DUSR VF1SECT = 3. .DUSR VF.CMD = 15. ;COMMAND FIELD .DUSR VF1CMD = 8. .DUSR VFINB = 43. ;BOUNDARY: SET VFINR IF CYL > VFINB .DUSR VFNCYL = 77. ;# CYLINDERS PER DISK .DUSR VF?SE = 000 ;SETTLE COMMAND FIELD VALUE .DUSR VF?SO = 001 ;STEP OUT (TOWARDS a0) .DUSR VF?SI = 002 ;STEP IN (AWAY FROM 0) .DUSR VF?RA = 010 ;READ ADDRESS .DUSR VF?RD = 020 ;READ BLOCK .DUSR VF?WR = 040 ;WRITE BLOCK .DUSR VF?F0 = 240 ;FORMAT SECTOR 0 .DUSR VF?FM = 241 ;FORMAT NEXT SECTOR .DUSR VFSETTL = (VF?SE)B(VF.CMD) ;COMMAND WOR5DS .DUSR VFSTOUT = (VF?SO)B(VF.CMD) .DUSR VFSTIN = (VF?SI)B(VF.CMD) .DUSR VFRADDR = (VF?RA)B(VF.CMD) .DUSR VFREAD = (VF?RD)B(VF.CMD) .DUSR VFWRITE = (VF?WR)B(VF.CMD) .DUSR VFFM0 = (VF?F0)B(VF.CMD) .DUSR VFFMT = (VF?FM)B(VF.CMD) ; DIA STUFF .DUSR UFNRDY = 1B0 ;NOT READY .DUSR UFHOME = 1B1 ;HOME (ON CYLINDER 0) .DUSR UFLOAD = 1B2 ;HEAD IS LOADED .DUSR UFWDS = 1B6 ;WRITE DISABLED .DUSR UF.UNIT = 7. ;UNIT FIELD .DUSR UF1UNIT = 1. .DUSR UFDIP = 1B8 ;SPEED HAS DROPPED (DOOR OPENED) .DUSR UFICD = 1B10 ;ILLEGAL COMMAND .DUSR UFNOS = 1B11 ;NOT ON SPECIFIED SECTOR .DUSR UFCHK = 1B12 ;CHECKSUM .DUSR UFLAT = 1B13 ;DATA LATE .DUSR UFWRF = 1B14 ;WRITE FAULT .DUSR UFERR = 1B15 ;ANY ERROR (INCLUDING NO DATA RECEIVED ; ERROR, WHICH DOESN'T HAVE ITS OWN BIT) .DUSR UFEMK = 1B9-1B14 ;ERROR MASK: BITS 10 THRU 14 ; DIC STUFF (AFTER READ ADDRESS COMMAND) .DUSR WF.SECT = 13. ;SECTOR FIELD .DUSR WF1SECT = 3. .DUSR WF.CYL = 7. ;CYLINDER (TRACK) FIELD .DUSR WF1CYL = 7. ; ; ........ NOVADISK DEFINITIONS ........ ; ; DIA ERROR3 BITS .DUSR UNERR = 1B15 ;ANY ERROR .DUSR UNCHK = 1B14 ;CHECKSUM ERROR .DUSR UNNST = 1B13 ;NO SUCH TRACK .DUSR UNLAT = 1B12 ;DATA LATE .DUSR UNWLK = 1B11 ;WRITE LOCKED .DUSR UNEMK = 1B10-1B14 ;ERROR MASK: BITS 11 THRU 14 ; DOB DIAGNOSTIC BIT .DUSR VN>DAG = 1B0 ;SET DIAGNOSTIC MODE ; ; ......... PAGING DISK DEFINITIONS ......... ; ; PACKET FORMAT .DUSR PPBLK = 0 ;DISK BLOCK & UNIT .DUSR PPCMD = 1 ;COMMAND WORD .DUSR PPBUF = 2 ;MEMORY ADDRESS .DUSR PPSTAT = 3 ;RETURNED STATUS WORD .DUSR PPLNK = 4 ;SOFTWARE LINK .DUSR PPLEN = 5 ; DOC ALTERNATE MODE BITS .DUSR WPAL1 = 1B15 ;SET ALTERNATE MODE #1 .DUSR WPAL2 = 1B14 ;SET ALTERNATE MODE #2 .DUSR WPAL3 = 1B13 ;SET ALTERNATE MODE #3 ; PPBLK PACKET WORD: DISK ADDRESS .DUSR WP.UNIT = 3. ;UNIT (DRIVE) FIELD .DUSR WP1UNIT = 2. .DUSR WP.BLK = 15. ;DISK BLOCK # FIELD .DUSR WP1BLK = 12. .DUSR WP.SECT = 15. ;ALSO BREAK TO SUBFIELDS - SECTOR .DUSR WP1SECT = 5. .DUSR WP.TRK = 10. ; AND TRACK .DUSR WP1TRK = 7. ; PPCMD PACKET WORD: COMMAND .DUSR VP.XMEM = 4.U ;EXTENDED MEMORY FIELD .DUSR VP1XMEM = 5. .DUSR VP.CMD = 7. ;COMMAND FIELD .DUSR VP1CMD = 3. .DUSR VPMAP = 1B8 ;MAPPING SWITCH .DUSR VPHALT = 1B9 ;HALT ON END OF TRANSFER .DUSR VPHOE = 1B10 ;HALT ON ERROR .DUSR VP?RD = 0 ;READ COMMAND .DUSR VP?WT = 1 ;WR1wITE .DUSR VP?VF = 2 ;VERIFY .DUSR VP?JM = 3 ;JUMP .DUSR VP?ID = 4 ;IDLE .DUSR VPREAD = (VP?RD)B(VP.CMD) ;COMMAND WORDS .DUSR VPWRITE = (VP?WT)B(VP.CMD) .DUSR VPVFY = (VP?VF)B(VP.CMD) .DUSR VPJMP = (VP?JM)B(VP.CMD) .DUSR VPIDLE = (VP?ID)B(VP.CMD) ; PPSTAT PACKET WORD: STATUS .DUSR UPERR = 1B0 ;ANY ERROR .DUSR UPBEN = 1B3 ;BUS ENABLE (DUAL PROCESSORS) .DUSR UPIDN = 1B6 ;IDLE DONE .DUSR UPPAR = 1B7 ;PARITY ERROR .DUSR UPCDE = 1B8 ;DATA CHANNEL DATA ERROR .DUSR UPTIM = 1B9 ;HARDWARE R/W TIME OUT .DUSR UPRDY ˊ= 1B10 ;DRIVE READY .DUSR UPUNS = 1B11 ;DRIVE UNSAFE .DUSR UPLAT = 1B12 ;DATA LATE ERROR .DUSR UPECC = 1B13 ;DATA (ECC) ERROR .DUSR UPVFE = 1B14 ;VERIFY ERROR .DUSR UPDON = 1B15 ;PAGE DONE .DUSR UPEMK = 1B6-1B14-1B10 ;ERROR MASK: BITS 7-9, 11-14 BOOT.SR;  .LCNS ;COPYRIGHT (C) DATA GENERAL CORPORATION,1973,1974,1975,1976,1977 ;ALL RIGHTS RESERVED ;LICENSED MATERIAL-PROPERTY OF DATA GENERAL CORPORATION ; ; ; ;;;; ;;;;; ;;;; ;;;; ;;;;;;; ; ; ; ; ; ; ; ; ; ; ;  ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;;;;; ; ;;;; ;;;;; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;  ; ; ; ; ; ;  ; ; ; ; ; ; ; ; ; ; ; ;;;;; ;;;; ;;;; ; ; SUPER SOPHISTICATED (I.E. 'HIP') BOOTSTRAP ; PROGRAMMER: VINCENT LA ROCK ; ASSEMBLE WITH PARU, PARS, NSKID, AND DSKDEFS ; LOAD WITH RLDR/C ; DO NOT RUN COSMETIC PROGRAMS ON THIS SOURCE - THE SPACING, ; TABULATION, ETC HAVE BEEN DONE BY HAND... .TITL BOOT .RB BOOT.RB .REV 6,20. .TXTM 1 ; PACK LEFT TO RIGHT .NOCON 1 ;*************************************************************+A ; NOTICE - IF ANYTHING IN THE TWO-BLOCK ROOT CHANGES, ITS ; INTERNAL REV NUMBER MUST BE CHANGED (SEE ROOT'S PAGE ZERO). ;************************************************************* ;----------------------- ;OVERVIEW OF BOOT PATHS: ;----------------------- ;FROM .BOOT SYSTEM CALL: SOV22 READS DISK BLOCK 0 (=ROOT'S FIRST ; BLOCK), AND ENTERS AS IN PROGRAM LOAD. ; ;FROM PROGRAM LOAD (SWITCHES) - ENTER FIRST BLOCK OF ROOT, ; WHICH READS ITS SECOND BLOCK, MOVES ITSELF TO HIGH CORE, ; READS THE FIRST: BLOCK OF BOOT.SV AND JUMPS TO BRDSYS, WHICH ; READS BOOT (LESS PAGES 0 & 1) AND JUMPS TO START (IN ROOT), ; WHICH READS THE REST AND ENTERS AT HIPPI (DEFINED BY BOOSA), ; WHICH IN TURN FINDS THE FILE TO BE BOOTED AND JUMPS TO RDSYS, ; WHICH READS ALL koBUT PAGES 0 & 1 AND JUMPS TO START (IN ROOT), ; WHICH READS PAGES 0 & 1 AND EITHER HALTS OR STARTS THE LOADED ; PROGRAM (ENTRY DEFINED BY SCPSA). ; ;WHEN BOOT IS ITSELF BOOTED TO, ENTRY IS AT INSTL (DEFINED BY ; SCPSA, OR SCINS OR SCINT). THE INSTALLERd (INVOKED BY A 'Y' ; ANSWER TO THE QUERY 'INSTALL BOOSTRAP?') USES COMMON ROUTINES ; TO WRITE THE ROOT ONTO BLOCKS 0 & 1 OF THE SPECIFIED DISK(S). ; A 'N' ANSWER TRIGGERS THE IN-CORE BOOT PATH, WHICH MOVES ROOT ; TO THE END OF CORE AND JUMPS TO HIPPI. } ;--------------------------------------- ;DETAIL OF INTERACTIONS BETWEEN MODULES: ;--------------------------------------- ;SOV22 READS ROOT'S FIRST PAGE INTO PAGE ZERO, AND PASSES ; UNIT (PHYSICAL UNIT NUMBER) VIA PARU BOOTSTRAP CONSTANT SCUN, ; PASSES ASCUN (ASCII UNIT NUMBER) THROUGH SCAUN, AND JUMPS ; TO SCGO IF THERE IS A FILENAME (BYTE POINTER PASSED IN AC0, ; WHICH SCGO STORES IN BYPY), ELSE TO SCNGO (ASK FROM CONSOLE). ; ;FROM ROOT TO BRDSYS - ROOT FINDS BRDSYS BY AN ABSOLUTE JUMP: ; I.E., ITHE LOCATION OF BRDSYS IS FIXED. ON ENTRY, AC3 CONTAINS ; A POINTER TO INDEX (THE DISK ROUTINE IN ROOT); OTHERWISE ; INTERACTION IS SAME AS FROM BOOT TO RDSYS (BELOW). ; ;FROM BRDSYS TO START - BRDSYS FINDS START BY JUMPING TO A FIXED ; LOCATION PRECEEDING INDEX, WHICH IS ASSUMED TO CONTAIN A JUMP ; TO START. BRDSYS REFERENCES RLBKN THE SAME WAY: ABSOLUTE ; DISPLACEMENT FROM THE POINTER TO INDEX. NOTE THAT AT THIS ; POINT BOOT & ROOT CAN BE OF DIFFERENT REVISION LEVELS. ; OTHERWISE SAME AS RDSYS TO START (BELOW). ; ;BETWEEN START & BOOT - START STORES IN SCBAS A POINTER TO ITS ; 2ND BLOCK, AND JUMPS @BOOSA. START IDENTIFIES BOOT BY THE ; START MODE (SAME AS SQUASH MODE IN THIS CASE) OF -2. BOOT ; COMPARES ROOT'S REV NUMBER WITH ITS OWN; IF UNEYQUAL, JUMPS TO ; REVIN, WHICH PICKS UP ASKEY, ASCUN, BYPY FROM ROOT (THESE ARE ; ASSUMED TO BE IN FIXED LOCATIONS), DOES AN AUTO-INSTALL, AND ; ENTERS BOOT AGAIN. USING SCBAS, BOOT MANUFACTURES POINTERS TO ; NUMEROUS POINTS OF INTEREST IN ROOT (SEE ROO_PO & FRIENDS IN ; PAGE ZERO; BOOT CAN DO THIS SINCE BOOT & ROOT ARE NOW OF THE ; SAME INTERNAL REVISION LEVEL) AND PICKS UP ASKEY,ASCUN,&BYPY. ; BOOT AND ROOT SHARE THE FOLLOWING PAGE ZERO LOCATIONS: ; IDXBF, ENTBF, CPBA. ; ;FROM BOOT TO RDSYS - CPBA MUST POINT TO FIRST INDEX BLOCK OF ; THE FILE TO BE READ, SQMOD SET TO ITS SQUASH MODE (SCZMX), ; & ABSMD NONZERO IF LOAD IS ABSOLUTE (/A). FOR SQUASHED FILE, ; LCLID SHOULD POINT TO END OF CLI, SYSST TO START OF SYSTEM. ; FOR A SYSTEM BOOT, THE FOLLOWq ING ARE STORED IN ROOT IN HIGH ; CORE: DEVICE SPECIFIERS (SEE DVNAM & FRIENDS IN PAGE ZERO); ; PARTITION LEVEL, PARTITION BASE ADDRESS, & OVERLAY BASE ADDR. ; ;FROM RDSYS TO START - AC2 CONTAINS THE START MODE, ; 1B0 - ABSOLUTE, 0 - STAND ALONE, -2 - BOOT, OTHER - SYSTEM. ; ;BETWEEN START & THE BOOTED PROGRAM - ON ABSOLUTE LOAD, THERE IS ; NO INTERACTION (START JUST HALTS). OTHERWISE, SCTBP CONTAINS ; EITHER 0 OR A BYTE POINTER TO A STRING WHICH IS PRINTED. ; FOR A STAND ALONE BOOT, JUMP INDIRECT THROUGH SCPSA. IF WE ; CAME FROM ROOT (START MODE -2), PASS BASE THROUGH SCBAS, JUMP ; INDIRECT THROUGH BOOSA. FOR A SYSTEM BOOT, PASS BASE THROUGH ; SCBAS (POINTS TO END OF DEVICE SPECIFIERS), PARTITION LEVEL ; THROUGH SCCPL, PARTITION BASE - SCPB1&SCP(hBA, OVERLAY BASE - ; SCOF1&SCOFA (HI & LO ORDER RESPECTIVELY), AND JUMP @SCPSA. ;GETAD 0,1 PUTS FIRST ADDR OF FILE IN ACS 0,1, ; ASSUMING AC2 POINTS TO THE DIRECTORY ENTRY... .MACRO GETAD LDA ^1,UFTDL,2 377*400 ;OR 177400, OR AND 3,3; OR NOP L*DA ^2,.-1 ;OR WHATEVER YOU PLEASE, SIR ANDS ^2,^1 ;HIGH ORDER BYTE LDA ^2,UFTAD,2 ;LOW ORDER 2 BYTES % ;DOUBLE SKIPS: .MACRO DSZR ** MOV ^1,^1,SNR ** MOV ^2,^2,SZR % .MACRO DSNR ** DSZR ^1,^2 ** JMP .+2 % ;ECLIPSE SURROGATES: .MACRO .XOR s MOV ^2,^3 ANDZL ^1,^3 ADD ^1,^2 SUB ^3,^2 % .MACRO .BLM LDA 0,0,2 STA 0,0,3 INC 2,2 INC 3,3 NEG 1,1 COM 1,1,SZR JMP .-6 % .MACRO .BAM JMP .+2 0 STA 1,.-1 LDA 1,0,2 ADD 0,1 STA 1,0,3 INC 2,2 INC 3,3 DSZ .-7 JMP .-6 % .MACRO NOT (-(^1)-1)% .DUSR NOP=401 .DISS SKPLT = USLT 0,0 ;EQUATE TO NEW PARS SKIP NAMES .DISS SKPLE = USLE 0,0 .DISS SKPGT = USGT 0,0 .DISS SKPGE = USGE 0,0 ;DEFINE LOWER PAGE ZERO: .LOC SCTBP HIPMS*2 ;HIPBOOT'S MESSAGE .LOC SCINS ;SWITCHED INIT, INSTL .LOC SCPSA ; OR PROGRAM START, INSTL .LOC SCINT ; OR TAPE INIT -- ; IT'S ALL THE SAME TO ME INSTL ;THE INSTALLATOR .LOC SCCLI BOOSA: HIPPI ;BOOTING STARTING ADDRESS .LOC SCZMX 0 ;WE STAND ALONE ;PAGE ZERO ~USED BY TWO BLOCK ROOT ROUTINES ;DON'T MOVE UNLESS YOU KNOW ALL ABOUT ROOT'S PAGE ZERO CPBA: .BLK 2 ;DISK POINTER TO FILE'S FIRST INDEX BLOCK IDXBF: BUF ;DISK BUFFER FOR INDEX BLOCKS ENTBF: BUF+SCDBS ;OTHER DISK BUFFER .DUSR USP=. ;STACK .LOC SCBVAS ROOBA: RBASE ;POINTER TO TWO BLOCK ROOT .LOC 50 ; GET AWAY FROM THE CRAP ALL THE ; BOOTERERS AND INITERERERS GET THEIR FINGERS INTO (FOR A VIVID ; DESCRIPTION READ "THE BOOTSTRAP CUNSTANTS" BY PARU.SR), ; AND LEAVE A BUNCH OF ELBOWROOM, BESIDES. ;****DO NOT CHANGE: THE LOCATION OF BRDSYS IS FIXED ; FOR ALL TIME - ROOTS OF DIFFERENT REV WILL EFFECTIVELY ; REFERENCE IT ABSOLUTELY.  ;RDSYS LOADS ALL OF THE CORE IMAGE EXCEPT PAGES ZERO AND ONE ;THE CORE IMAGE IS EXPANDED IF IT IS IN SQUASHED FORMAT BRDSYS: STA 3,.RINDEX ;BOOTING ENTRY POINT RDSYS: ADC 0,0 LDA 3,.RINDEX STA 0,RLBKN-RINDEX,3 ;RLBKN IS NO LONGER VALID, LDA 1,BLKSZ ; SINCE THE INDEX BUFFER STA 1,IDXBF ; IS NOW PAGE ONE LDA 0,NMAX LDA 2,CMAP ;SUBTRACT 2 FROM # BLOCKS TO READ SUB 2,0 ; SINCE WE DON'T READ PAGES 0 & 1 STA 0,NMAX NEGL# 0,0,SNC ; =0 OR NEGATIVE? JMP DONE ;YES, NOTHING TO DO MOVZL 1,1 ;START READING AT PAGE 2 RDLP: STA 1,CORAD LDA 0,CMAP ;PICK A RELATIVE BLOCK NUMBER ISZ CMAP MOV 1,2 ;PASS ADDRESS IN AC2, T6OO, IN CASE WANT TO CHANGE CALLING SEQUENCE IN FUTURE REV JSR @.RINDEX ;READ IT JMP DONE ;EOF ON INDEX FILE JMP RDZERO ;INDEX ENTRY ZERO - ZERO BLOCK RDLZ: LDA 1,CORAD ;PICK UP CORE ADDRESS LDA 0,BLKSZ ADD 0,1 ;NEW CORE ADDRESS LDA 2,SQMOD ;GET MODE WORD MOVZR# 2,2,SNR ;SQUASHED FILE ? JMP RDZ ;NO LDA 2,LCLID LDA 3,SYSST SKPGT 2,1 ;IF BEFORE END OF CLI, SKPGT 3,1 ; OR PAST BEG OF SYSTEM, JMP RDZ ; NO UNSQUASH SQLP: ADD 0,1 DSZ NMAX ;ONE LESS BLOCK TO READ JMP .+2 HALT ;SYSTEM #IS MORE THAN 1 BLOCK LONG ADCZ# 3,1,SNC ;FILL IN SQUASHED SPACE JMP SQLP SUB 0,1,SKP RDZ: DSZ NMAX ;TRIED ENOUGH SLOTS? JMP RDLP ;NOT YET ;YES, GO TO NEXT PAGE DONE: LDA 0,ABSMD ;ABSOLUTE MODE FLAG MOV# 0,0,SZR ;IS IT SET ? SUBZR 2,2,SKP l;YES, SET 1B0 FOR MODE LDA 2,SQMOD ;NO, GET SQUASH MODE WORD LDA 3,.RINDEX JMP JSTART-RINDEX,3 ;FINISH THE LOAD RDZERO: LDA 1,BLKSZ SUB 0,0 ;CLEAR A BLOCK ZLP: STA 0,0,2 INC 2,2 NEG 1,1 ;DECREMENT COUNT COM 1,1,SZR ; & DONE? JMP ZLP ;NO JMPU RDLZ ABSMD: 0 ;NONZERO MEANS ABSOLUTE (/A) BOOT SQMOD: -2 ;A SPECIAL MODE JUST FOR BOOT CMAP: 2 ;RDSYS STARTS WITH PAGE 2 CORAD: 0 LCLID: 0 ;END OF CLI SYSST: 0 ;START OF SYSTEM NMAX: (BOOEND-Z+377)/SCDBS+2 ;SIZE OF THIS BOOT.SV IN BLOCKS ;(SIZE OF NREL + PAGE ZERO & UST) BLKSZ: SCDBS ;POINTERS TO GOODIES IN THE TWO BLOCK ROOT ;WHEN BOOT IS ENTERED THROUGH THE ROOT, THESE ARE RELOCATED ;TO POINT TO THE REAL ROOT (I.E., THE ONE IN HIGH CORE). ROOCT: ROOEN-ROOPO ROOPO: .+1 .RINDEX:RINDEX .DOBLAD:DOBLbAD .RLBKN: RLBKN .WDPIB: WDPIB .DSRCH: DSRCH .FRMSZ: FRMSZ .RREAD: ROOREF[RREAD] ;IN ROOT'S DRIVER .RWRITE:ROOREF[RWRITE] .BADTBL:BADTBL .UNIT: UNIT .SECT: ROOREF[NSECT] ;IN ROOT'S DRIVER .HEAD: ROOREF[NHEAD] .ASKEY: ASKEY .ASCUN: ASCUN .BYPY: BYPY ROOEN=.-1 .PRMSG: PRMSG ;THESE DON'T NEED TO BE .PRM2: PRMS2 ; FROM THE REAL ROOT .TTYO: TTYO .BTCORE:BTCORE .BTFROM:BTFROM .BYE: BYE .REVN: REV ;THIS MUST NOT BE FROM THE REAL ROOT .RBASE: RBASE ; ALSO .ROOT: ROOT ; AND ANOTHER RRBASE: RBASE ;VARIABLE FOR RELOCATING ROOT POINTERS ;RESERVE SPACE FOR SYSTEM SPECIFIERS ;THE ORDERING IS KNOWN TO INIT1 PDKEY: .BLK 1 ;PRIMARY DEVICE KEY LIKE 'DK' OR 'DP' PDUNT: .BLK 1 ;PRIMARY DEVICE UNIT NUMBER IN ASCII SPN: .BLK SCFNL-1 ;SECONDARY PARTITION NAME (NO EXTENSION) OSN: .BLK SCFNL ;OPERATING SYSTEM NAME SPFLT: .-PDKEY ;LENGTH OF ABOVE PARLT: SCFNL-1 ;LENGTH OF PARTITION NAME FIELD DVNAM: PDKEY ;POINTERS PARNAM: SPN SYSNAM: OSN DVCHR: 0 ;CURRENT DEVICE CHARACTERISTICS WORD ARG: .BLK SCFNL-1 ;UNPACKEOD NAME SPACE EXT: .BLK 1 ;EXTENSION SPACE ARGWP: ARG ARGBP: ARG*2 EXTBP: EXT*2 SYSFA: .BLK 2 ;POINTER TO WHAT TO BOOT CPL: 0 ;CURRENT PARTITION LEVEL BSPA: .BLK 2 ;BOOTSTRAP PARTITION ADDRESS AUTO: 0 ;SAVED SWITCHES: -1 IF AUTO RESTART INSSW: -1 ;-1 IF NOT INSTALLING, ; 0 PLAIN INSTALLING, 1 AUTO-INSTALLING BYTPT: LNBUF*2 ;POINTER TO INPUT STRING LINPT: LNBUF*2 ;FIXED POINTER TO LINE BUFFER SV: SAV? RT: RET? .LDBYT: LDBYT .STBYT: STBYT .MVWD: MVWD .NUDEV: NUDEV .PARTS: PARTS .TSTUC: TSTUC .RDLl.IN: RDLIN .UNPAK: UNPAK .CHEXT: CHEXT .SRCH: SRCH .LOOKUP:LOOKUP .INDEX: INDEX .SAVARG:SAVARG .BAKARG:BAKARG .SIZIT: SIZIT .RECAL: RECAL .ZPRMS: ZPRMS .READ: READ .SKPNC: ISKPNC .SK1NC: ISK1NC .MINIL: MINILOADER .ETYNA: ETYNA .EPRIN: EPRIN .EHALT: EHALT !ERFIT: EHFIT ERNCONT:EHNCONT ERFNF: EHFNF EREXCU: EHEXCU ERLKDEP:EHLKDEP ERNPAR: EHNPAR ERDEV: EHDEV ERNTOP: EHNTOP EROFLIN:EHOFLIN ERHDWRF:EHHDWRF ERDFM: EHDFMT PPBA: SCPPA FNL: SCFNL ;FILENAME LENGTH ENTLT: UFDEL ;DIRECTORY ENTRY LENGTH MASK: 177 LOzBYT: 377 C2: 2 BELL: 7 LF: 12 ASCIZ: "Z ASCIA: "A ASCI9: "9 ASCI0: "0 DOLAR: "$ ;DELIMITER TABLE FOR RDLIN & UNPAK: DLIPT: .+1 BLANK: " DOT: ". SLASH: "/ COLON: ": COMMA: ", CR: 15 NULL: 0 .LOC 370 0 ;DEBUGGER'S BREAKPOINTS GO HERE .NREL F7;END OF PAGE ZERO Z=. ;RELOCATABLE ZERO ;DEFINE STACK PARAMETERS, UNCONDITIONALLY NOVA STYLE .DUSR SLGT=16 ;STACK FRAME SIZE .DUSR AC0=1 .DUSR AC1=2 .DUSR AC2=3 .DUSR TMP=4 .DUSR ORTN= -SLGT .DUSR OAC0=AC0-SLGT .DUSR OAC1=AC1-SLGT .DUSR OACM2=AC2-SLGT ; SUBROUTINE CALL LINKAGE .MACRO ENTER ;SUBROUTINE ENTRY ** STA 3,@USP ** JSR @SV % RETURN = JMP @RT ;SUBROUTINE EXIT SAV?: STA 3,LOC LDA 3,USP STA 0,AC0,3 STA 1,AC1,3 STA 2,AC2,3 LDA 0,.SLGT ADD 0,3 STA 3,USP LDA 0,OAC0,3 J?MP @LOC .SLGT: SLGT LOC: 0 RET?: LDA 3,USP LDA 0,.SLGT SUB 0,3 STA 3,USP LDA 0,AC0,3 LDA 1,AC1,3 LDA 2,AC2,3 JMP @0,3 ; ; DISK ID BLOCK (BLOCK 3) FORMAT: ; SDREV = 0 SDCHK = 1 SDHED = 2 SDSEC = 3 SDBL1 = 4 SDBLK = 5 SDFMZ = 6 SDCHR = $7 ; CHARACTERISTIC BITS IN SDCHR CHDOBL = 1B0 CHTOPL = 1B1 CH3330 = 1B15 CHBOOT = 1B14 CHNOVDSK = 1B13 ;DEVICE IS NOVADISK (USED INTERNALLY ONLY) CHZEBRA = 1B12 ;DEVICE IS ZEBRA (USED INTERNALLY ONLY) CHPAGING = 1B11 ;DEVICE IS PAGING DISK (USEPD INTERNALLY ONLY) ; ; MACROS TO SKIP IF CHARACTERISTIC BIT NOT SET ; ; SKPNC CHMUMBLE - LOOKS AT WORD IN DVCHR ; SK1NC CHMUMBLE - LOOKS AT AC1 ; .MACRO SKPNC ** JSR @.SKPNC ** ^1 % .MACRO SK1NC ** JSR @.SK1NC ** ^1 % ISKPNC: ENTER LDA 1,DyVCHR JMP SK1IN ISK1NC: ENTER SK1IN: LDA 2,ORTN,3 ISZ ORTN,3 ;SKIP OVER ARG LDA 0,0,2 ;PICK IT UP AND# 1,0,SNR ISZ ORTN,3 ;SKIP IF CLEAR RETURN .PUSH .NOMAC .NOMAC 1 ** .PUSH .NOLOC ** .NOLOC 1 HIPMS: .TXT /<15><12>BOOT REV 6.20<15><12>/ COPYR: .TXT /COPYRIGHT(C)DGC,1972,1973,1974,1975,1977 ALL RIGHTS RESERVED/ FILE?: .TXT /<15><12>FILENAME? / SYSV: .TXT /SYS.SV/ ** .NOLOC .POP ; ; EH ERRORNAME,COMMONHANDLER,TEXTSTRING - DEFINE ERROR HANDLER ; .MACRO EH EH^1: LDA 2,EM^1 JMP @.^2 EM^1: (.+1)>{*2 ** .PUSH .NOLOC ** .NOLOC 1 .TXT ^3 ^4 ^5 ^6 ^7 ^8 ^9 ^?0 ^?1 ^?2 ^?3 ^?4 ^?5 ^?6 ^?7 ** .NOLOC .POP % ** ?0=10. ** ?1=11. ** ?2=12. ** ?3=13. ** ?4=14. ** ?5=15. ** ?6=16. ** ?7=17. EH FIT,EPRIN,/<15><12>INSUFFICIENT MEMORY<15><12>/ EH NCONT,EPRIN,ӣ/<15><12>OVERLAY FILE MUST BE CONTIGUOUS<15><12>/ EH FNF,ETYNA,/<15><12>FILE NOT FOUND: / EH EXCU,ETYNA,/<15><12>FILE NOT EXECUTABLE: / EH LKDEP,ETYNA,/<15><12>LINK DEPTH EXCEEDED AT LINK / EH NPAR,ETYNA,/<15><12>NOT A PARTITION: / EH DEV,ETYNA,/<15><r12>UNKNOWN DEVICE SPECIFIER - / EH NTOP,ETYNA,/<15><12>DEVICE NOT A TOP LOADER: / EH OFLIN,ETYNA,/<15><12>DEVICE OFF LINE: / EH HDWR,EHALT,/<15><12>HARDWARE FAILURE<15><12>/ EH DFMT,EPRIN,/<15><12>INVALID DISK ID BLOCK<15><12>/ .NOMAC .POP ; ; COMMO]N HANDLER TO PRINT ERROR MESSAGE THEN RESTART: ; EPRIN: JSR @.PRM2 ;PRINT THE ERROR MESSAGE ESTART: LDA 0,INSSW ;LOOK AT INSTALLING SWITCH COM# 0,0,SNR ;INSTALLING? JMP @BOOSA ;NO, RESTART BOOT JMP @.+1 ;YES, RESTART INSTALL INSTL ; HANDLER TO PRINT MESSAGE & HALT: EHALT: JSR @.PRM2 ;SOMEBODY'S FILENAME GOT MUNGED HALT JMP .-1 ;HARDWARE FAILURE - NO RECOVERY ; ; COMMON ERROR HANDLER TO TYPE ERROR MESSAGE ; FOLLOWED BY A FILENAME, & RESTART. ; FILENAME IS ASSUMED TO BE IN THE ARG AREA. ;ʐ CNT=TMP CNT1=CNT+1 ETYNA: ENTER ;GET SOME TEMPS JSR @.PRM2 ;PRINT THE MESSAGE LDA 3,USP LDA 0,NAMLT STA 0,CNT,3 ;SAVE COUNT IN THE STACK LDA 0,C2 ;+2 STA 0,CNT1,3 ;INTO THE STACK LDA 2,ARGBP ;ARG BYTE POINTER PRLUP: MOVR 2,3 ;WORD POINTEWR & CARRY LDA 0,0,3 ;GET A WORD LDA 1,MASK ;& THE MASK INC 2,2,SNC ;BUMP POINTER - TEST CARRY MOVS 0,0 ;LEFT BYTE, SWAP AND 1,0,SZR ;MASK, TEST FOR NULL JSR @.TTYO ;NOT NULL, PRINT IT LDA 3,USP ;GET STACK POINTER DSZ CNT,3 ;DEC THE COUNT JMP PRLUP ;NOT DONE DSZ CNT1,3 ;DONE, BUT ARE YOU SURE ? JMP .+2 ;NOT QUITE JMP ESTART ;COMPLETELY DONE, START 'ER UP AGAIN LDA 0,C2 STA 0,CNT,3 ;NEW COUNT LDA 0,DOT ;ASCII '.' JSR @.TTYO JMP PRLUP NAMLT: (SCFNL-1)*2 ; ;ROUTINES TO LOAD & ST6ORE BYTES ; ; AC1 - BYTE POINTER ; AC0 - RETURNED BYTE OR BYTE TO STORE LDBYT: ENTER MOVZR 1,2 ;WORD POINTER + CARRY LDA 1,MASK ;GET MASK (177) LDA 0,0,2 ;GET WORD MOV# 0,0,SNC ;RIGHT OR LEFT BYTE ? MOVS 0,0 ;LEFT - SWAP THE WORD AND 1,0 ;MASK UN WANTED BYTE STA 0,OAC0,3 ;RETURN BYTE TO CALLER RETURN STBYT: ENTER MOVZR 1,2 ;WORD ADDRESS + CARRY LDA 1,MASK ;MASK LDA 3,0,2 ;GET THE WORD MOV# 0,0,SZC ;RIGHT OR LEFT BYTE ? MOVS 3,3 ;RIGHT - SAVE LEFT BYTE ANDS 1,3,SZC ;CLEAR BYTE - TaEST CARRY ADD 0,3,SKP ;ADD BYTE ADDS 0,3 ;ADD BYTE & SWAP STA 3,0,2 ;RESTORE WORD RETURN ; ;ROUTINE TO MOVE WORDS ; ; INPUTS: AC0 - FROM ADDRESS ; AC1 - TO ADDRESS ; AC2 - WORD COUNT MVWD: ENTER MOV 0,3 ;FROM POINTER NEG 2,0,SNR ;FORM NEGAT{IVE COUNT & TEST RETURN ;NOTHING TO DO MOV 1,2 ;TO POINTER MVLP: LDA 1,0,3 STA 1,0,2 INC 3,3 INC 2,2 INC 0,0,SZR JMP MVLP RETURN ;SUBROUTINE TO DETERMINE IF CHARACTER IN AC0 ; IS A VALID FILENAME CHARACTER ; ; JSR CHTST ; -- NOT A FILENAME CHWxAR ; (NORMAL RETURN) CHTST: ENTER LDA 1,DOLAR SUB# 0,1,SNR ;IS BYTE = $ ? JMP LEGAL ;YES LDA 1,ASCIZ ;ASCII Z SKPLE 0,1 ;BYTE <= Z ? JMP NTLGL ;NO, NOT LEGAL LDA 1,ASCIA ;ASCII A SKPGT 1,0 ;A <= BYTE ? JMP LEGAL ;YES, LEGAL CHARACTER LD9A 1,ASCI9 ;ASCII 9 SKPLE 0,1 ;BYTE <= 9 ? JMP NTLGL ;NO LDA 1,ASCI0 ;ASCII 0 SKPGT 1,0 ;0 <= BYTE ? JMP LEGAL ;YES JMP NTLGL LEGAL: ISZ ORTN,3 ;LEGAL CHAR, SKIP NTLGL: RETURN ;SUBROUTINE TO DETERMINE IF CHAR IN AC0 IS VALID DELIMITER ; VALCID DELIMITERS ARE LISTED IN THE TABLE IN PAGE ZERO. ; ; JSR DLIMTST ; -- NOT A DELIMITER ; (NORMAL RETURN) DLIMTST:ENTER ISZ ORTN,3 ;ASSUME VALID LDA 2,DLIPT ;DELIMITER LIST POINTER STA 2,TMP,3 ;INTO THE STACK TRLUP: LDA 1,@TMP,3 ;GET A CANDIDATE B ISZ TMP,3 ;BUMP THE POINTER SUB# 0,1,SNR ;A MATCH ? RETURN ;YES, RETURN MOV 1,1,SZR ;END OF LIST ? JMP TRLUP ;NO DSZ ORTN,3 ;YES, NOT KNOWN DELIMITER RETURN ;SUBROUTINE TO UNPACK A FILENAME INTO THE ARG AREA ; ; AC0 CONTAINS BYTE POINTER TOj FILENAME AND IS RETURNED ; POINTING TO THE BYTE AFTER THE TERMINATOR ; AC1, ON RETURN, WILL CONTAIN THE TERMINATION CHARACTER ; IF THE TERMINATOR WAS COLON OR SLASH, ELSE ZERO ; ; TERMINATORS ARE: COLON, SLASH, BLANK, NULL, CR, & COMMA ; LEADING BLANKS & NULLS ARE IGNORED ; ; CALLING SEQUENCE: ; JSR @.UNPAK ; -- NO CHARACTER SEEN ; (NORMAL RETURN, CHARACTER SEEN) BYPT=OAC0 CHRSN=TMP IGCHR=CHRSN+1 AGPT=IGCHR+1 BYTCT=AGPT+1 UNPAK: ENTER SUB 0,0 STA 0,CHRSN,3 ;RESET CHARACTER SEEN FLAG  STA 0,IGCHR,3 ;& IGNORE CHARACTER LDA 2,ARGBP ;ARG AREA BYTE POINTER STA 2,AGPT,3 ;INTO THE STACK MOVZR 2,2 ;WORD POINTER LDA 1,FNL ;FILENAME LENGTH STA 1,BYTCT,3 ;TO THE STACK UCL: STA 0,0,2 INC 2,2 DSZ BYTCT,3 ;CLEAR THE UNPACK AREA JMP UCL  SUBZL 2,2 ;+1 SUBOL 2,1 STA 1,BYTCT,3 ;MAX BYTE COUNT FOR FILE NAME LUP0: LDA 1,BYPT,3 ;SOURCE BYTE POINTER ISZ BYPT,3 ;BUMP IT JSR @.LDBYT ;GET THE BYTE JSR CHTST ;NOT NULL, TEST VALIDITY JMP TRYTERM ;NOT FILE CHARACTER, SEE IF TERMINATOR ;FVILE CHARACTER, STORE IT: ISZ CHRSN,3 ;SHOW CHARACTER SEEN LDA 1,IGCHR,3 ;IGNORE SWITCH MOV# 1,1,SZR ;SHOULD WE IGNORE ? JMP LUP0 ;YES LDA 1,AGPT,3 ;ARG AREA BYTE POINTER ISZ AGPT,3 ;BUMP THE POINTER JSR @.STBYT ;STORE THE BYTE DSZ BYTCT,3 ;D%EC THE BYTE COUNT JMP LUP0 ;MORE TO COME ISZ IGCHR,3 ;FULL, IGNORE ANY MORE JMP LUP0 TRYTERM:JSR DLIMTST ;SEE IF DELIMITER JSR @ERHDWRF ;EITHER RDLIN OR RDOS HAS CHECKED THE NAME STA 0,OAC1,3 ;RETURN POSSIBLE TERMINATOR LDA 1,COLON ;GET A COLON SUB# 0,1,SNR ;IS IT A ':' ? JMP UNDONE ;YES, TERMINATE LDA 1,SLASH ;NOT A COLON - TRY SLASH SUB# 0,1,SNR ;IS IT A MATCH ? JMP UNDONE ;YUP, DONE LDA 1,DOT SUB# 1,0,SZR ;DOT? JMP NOT. ;NO ;YES, SWITCH TO EXTENSION MODE: LDA 0,EXTBP ;EXTENSION BYTE POINTER STA 0,AGPT,3 ;IS NEW POINTER SUB 0,0 STA 0,IGCHR,3 ;ACCEPT MORE CHARACTERS, NOW LDA 0,C2 ;SQUARE ROOT OF DECIMAL 4 STA 0,BYTCT,3 ;IS NEW COUNT JMP LUP0 NOT.: LDA 1,BLANK SUB# 0,1,SNR ;BLANK ? JMP CONDT ;YES, SEE IF LEADING_ OR TERMINATING MOV# 0,0,SZR ;NULL? JMP TERM ;NO, IT'S TRUE TERMINATOR CONDT: LDA 0,CHRSN,3 ;CHAR SEEN FLAG MOV# 0,0,SNR ;ANY? JMP LUP0 ;NO, IGNORE LEADING BLANKS, NULLS TERM: SUB 0,0 ;YES - STA 0,OAC1,3 ;SIGNAL TRUE TERMINATOR UNDONE: LDA 0,CHRSN,3 MOV# 0,0,SZR ;DID WE DO ANYTHING? ISZ ORTN,3 ;GUESS SO RETURN ; ;ROUTINE TO READ A LINE FROM THE TTY INTO THE LINE BUFFER ; ; THE LINE IS TERMINATED BY A CARRIAGE RETURN ; ILLEGAL CHARACTERS ARE NOT ACCEPTED & ECHO A 'BELL' ; RUBOUTS DELETE THE P6REVIOUS CHARACTER ON A CRT, OR, ; ON A TTY, ECHO A BACKARROW FOLLOWED BY THE DELETED CHARACTER ; CHPT=TMP LNPT=CHPT+1 RDLIN: ENTER LDA 2,LINPT ;INIT THE WORKING BYTE POINTER STA 2,LNPT,3 ;FOR THIS ROUTINE GCHAR: LDA 3,USP ;GET STACK POINTER SKPDN TTI JMP .-1 DIAC 0,TTI ;GET A BYTE LDA 1,MASK AND 1,0 ;MASK OFF PARITY SUB# 1,0,SNR ;TEST FOR RUBOUT JMP RBOUT ;YES JSR CHTST ;NO, TEST FILENAME VALIDITY JMP RDDLIM ;NOT FILE CHAR, TRY FOR DELIMITER STORE: JSR @.TTYO ;ECHO IT LDA 3,USP 4#;GET THE POINTER LDA 1,LNPT,3 ;GET THE POINTER ISZ LNPT,3 ;NOW BUMP IT JSR @.STBYT ;STORE THE BYTE LDA 2,CR SUB# 2,0,SZR ;CR ? JMP GCHAR ;NO SUB 0,0 ;YES, FORM NULL INC 1,1 ;BUMP THE BYTE POINTER JSR @.STBYT ;STORE IT LDA 0,LF INC 1,1 ;BH6UMP POINTER AGAIN JSR @.STBYT ;STORE LF JSR @.TTYO ;OUTPUT LF RETURN RDDLIM: JSR DLIMTST ;SEE IF DELIMINATOR JMP RDBAD ;NOPE JMP STORE ;YUP, WE'LL TAKE IT RDBAD: LDA 0,BELL JSR @.TTYO ;DING-A-LING JMP GCHAR RBOUT: LDA 2,LNPT,3 ;GET CURRENUT POINTER LDA 0,LINPT ;& START OF LINE SUB# 0,2,SNR ;AT THE BEGINNING ? JMP RDBAD ;YEA, RING THE CHIMES DSZ LNPT,3 ;MOVE LINE POINTER BACK LDA 1,LNPT,3 ;NOW PICK IT UP JSR @.LDBYT ;NOW GET THE LAST BYTE MOV 0,1 ;MOVE BYTE TO AC1 LDA 0,OUTTC ;OUTPUT DEVICE TIME CONSTANT LDA 2,TTYTC ;TTY TIME CONSTANT SKPLT 0,2 ;TTY OUTPUT ? JMP TTYRB ;YES, PROCESS IT JSR @.PRMS ;TYPE UNIVERSAL CRT RUBOUT BACK*2 JMP GCHAR ;NOW GET NEXT CHARACTER TTYRB: LDA 0,BKARW ;BACK ARROW JSR @.TTYO ;PUT OUT ]BACK ARROW MOV 1,0 ;CHARACTER TO AC0 JSR @.TTYO ;OUTPUT DELETED CHARACTER JMP GCHAR ;NOW GET NEXT CHARACTER BKARW: "_ TTYTC: 10000. OUTTC: -1 ;UNIVERSAL (WELL, 3 MACHINES) CRT BACKSPACE-BLANK-BACKSPACE: ; WORKS ON THE INFOTRON, DG DISPLAY, AND LCD TERMINALS. ; TRASHES ABOUT BUT ESENCIALLY DOES BACKSPACE-SPACE-BACKSPACE. ** .PUSH .NOLOC ** .NOLOC 1 BACK: .TXT '<31><32><27><32><27><40><31><32><27><32><27>' ** .NOLOC .POP ; ; ZPRMS - LIKE PRMS (WITH BYTE POINTER FOLLOWING CALL), ; EXCEPT THIS GUY DRETERMINES IF DEVICE IS TTY OR CRT. ; ZPRMS: ENTER LDA 1,@ORTN,3 ;PICK UP BYTE POINTER JSR @.LDBYT ;GET 1ST BYTE OF MESSAGE SUB 1,1 ;INIT COUNTER TO 0 DOAS 0,TTO ;START FIRST CHAR INC 1,1 ;BUMP COUNTER SKPDN TTO ;WAIT FOR DONE JMP .-2 STA 1,OUTTC ;DONE - SAVE TIME CONSTANT LDA 2,@ORTN,3 ;BYTE POINTER AGAIN ISZ ORTN,3 ;SKIP OVER IT INC 2,2 ;SKIP FIRST CHARACTER JSR @.PRM2 ;PRINT REST OF MESSAGE RETURN ; ;INTERFACE ROUTINE TO READ A DISK BLOCK - ; IDENTICAL TO RREAD EXCEPT IT RETURNS yISTACK POINTER ; READ: ENTER JSR @.RREAD RETURN ; ; ROUTINE TO SEARCH THE CURRENT DIRECTORY FOR A FILE, ; RESOLVING LINKS. IDENTICAL TO SRCH EXCEPT RESOLVES LINKS ; ; IN - ARG CONTAINS NAME TO LOOK FOR ; OUT - AC2, ENTRY ADDRESS ; ; CALLING SEQUENCE: J+SR LOOKUP ; -- FILE NOT FOUND ; (NORMAL RETURN) LKDEP=TMP LOOKUP: ENTER LDA 0,MAXDP STA 0,LKDEP,3 ;INITIALIZE DEPTH COUNTER LOOKLP: JSR @.SRCH ;LOOK FOR IT RETURN ;NOT FOUND LDA 0,UFTAT,2 LDA 1,LNKAT AND# 1,0,SNR ;GOT A LINK? JMP FOUND ;NO, SUCCESSFULLY FOUND RESOLUTION DSZ LKDEP,3 ;TEST LINK DEPTH JMP .+2 ;STILL O.K. JSR @ERLKDEP ;YOUR IN OVER YOUR HEAD MOV 2,0 ;MUST SAVE THIS ENTRY LDA 1,SAVPT ;SAVE AREA POINTER LDA 2,ENTLT ;ENTRY LENGTH JSR @.MVWD ;MOVE IT MOV 1,2 ;NOW INDEX ON IT LDA 1,UFLAD,2 ;GET FIRST WORD OF ALTERNATE SPECIFIER MOV# 1,1,SNR ;IS THERE ONE ? JMP CHPBA ;NO, CHANGE TO PRIMARY LDA 0,ASPOF ;ALTERNATE SPECIFIER OFFSET ADD 2,0 ;ADDDRESS OF ALTERNATE SPECIFIER LDA 1,ARGWP ;DESTINATION IS ARG ARErA LDA 2,FNL ;WORDS TO MOVE JSR @.MVWD ; JSR @.NUDEV ;SEE IF ITS A DEVICE JMP NODEV ;NOT TODAY, VINCENT JMP CHPBA ;NOW CHANGE THE PARTITION BASE NODEV: JSR @.CHEXT ;PUT A '.DR' ON THE NAME 'DR' JSR @.SRCH ;LOOK FOR IT JSR @ERFNF ;NOT THERE GETAD 0,1 ;FOUND - GET FIRST ADDRESS JMP CHBCH ;CHANGE PARTITION BASE CHPBA: SUB 0,0 LDA 1,PPBA ;PRIMARY PARTITION BASE CHBCH: STA 0,CPBA ;BECOMES CURRENT PARTITION BASE STA 1,CPBA+1 ADC 0,0 STA 0,@.RLBKN ;RESET RELATIVE BLOCK NUMBER LDA 2,SAVPT ;LOOK AT ORIGINAL LINK ENTRY LDA 0,UFLAN,2 ;FIRST WORD OF ALIAS NAME MOV# 0,0,SNR ;IS ALIAS DEFINED ? JMP NOALS ;NO LDA 0,ALSOF ;YES, GET ALIAS OFFSET ADD 0,2 ;ADDRESS OF ALIAS NAME NOALS: MOV 2,0 ;'FROM' ADDRESS LDA 1,ARGWP ;'TO' ADDRESS  LDA 2,FNL ;WORD COUNT JSR @.MVWD ;MOVE THE ENTRY NAME TO ARG AREA JMP LOOKLP ;NOW LOOK SOME MORE FOUND: STA 2,OAC2,3 ;RETURN ENTRY ADDRESS ISZ ORTN,3 ;GOOD RETURN RETURN LNKAT: ATLNK MAXDP: SCMER ASPOF: UFLAD ALSOF: UFLAN SAVPT: .+1 .BLK UFDEL ; ; ROUTINE TO SEARCH FOR THE FILE WHOSE NAME IS IN THE ARG AREA ; WITHOUT RESOLVING LINKS ; SRCH: ENTER LDA 2,ARGWP ;FILENAME IS IN ARG AREA JSR @.DSRCH ;USE DSRCH IN ROOT RETURN ;NOT FOUND LDA 3,USP ;STACK POINTER NOT RETURNED STA 2,OAC2,3 ;RETURN ENTRY ADDRESS ISZ ORTN,3 ;GOOD RETURN RETURN ; ; ROUTINE TO READ NTH BLOCK OF RANDOM FILE, LIKE RINDEX EXCEPT ; AC0 - N, THE RELATIVE BLK # ; AC2 - CORE ADDRESS ; INDEX: ENTER MOV 2,1 ;PASS CORE ADDRESS JSR @.RINDEX JMP IND1 JMP INRD2 ISZ ORTN,3 IND2: ISZ ORTN,3 IND1: RETURN ; ; HIPBOOT'S MAIN PROGRAM ; STA 2,ROOBA ;ENTRY FROM IN-CORE BOOT HIPPI: LDA 3,.STK STA 3,USP ;SET THE STACK POINTER LDA 0,.HIPPI STA 0,BOOSA ;RESTART ADDRESS ADC 0,0 ;NOT INSTALLING STA 0,INSSW ; (rFOR ERROR RECOVERY) SUB 0,0 STA 0,CPL ;& CURRENT PARTITION LEVEL STA 0,ABSMD ;& ABSOLUTE MODE FLAG STA 0,CPBA ;& HIGH ORDER WORD STA 0,BSPA ; OF ADDRESSES LDA 0,PPBA ;PRIMARY PARTITION BASE ADDRESS STA 0,CPBA+1 ;IS CURRENT BASE ADDRESS STA 0,BwSPA+1 ;& BOOTSTRAP PARTITION ADDRESS LDA 2,ROOBA LDA 0,BLKSZ SUB 0,2 ;POINT TO BEGINNING OF 1ST BLOCK LDA 0,REV-ROOT,2 ;PICK UP REV FROM REAL ROOT LDA 1,@.REVNO ;& FROM ONE WE HAVE SUB# 0,1,SZR ;SAME? JMP @.REVIN ;NO - MAKE THEM THE SAME LDA 0,E!ROOBA ;WHERE THEY ARE LDA 1,RRBASE ;WHERE WE THINK THEY ARE STA 0,RRBASE ;NO RELOCATION NEXT TIME AROUND SUB 1,0 ;RELOCATION CONSTANT LDA 1,ROOCT ;HOW MANY LDA 3,ROOPO ;WHERE THEY GO MOV 3,2 ;WHERE THEY COME FROM .BAM ;GET POINTERS TO ROOT RO&aOTINES LDA 3,USP LDA 0,@.ASKEY ;PICK A DISK TYPE STA 0,PDKEY LDA 0,@.ASCUN ; AND A UNIT NUMBER STA 0,PDUNT LDA 1,@.BYPY ;POINTER TO INPUT STRING MOV 1,1,SZR ;(IF THERE IS ONE) STA 1,BYTPT SUB 0,0 STA 0,@.BYPY ;CAN USE IT ONLY ONCE ADC 0,0 STA 0,@.RLBKN ;RESET RELATIVE INDEX BLOCK NBR LDA 0,AUTO ;IF RECOVERING FROM ERROR COM# 0,0,SNR ; WHILE IN AUTO MODE, SUBZL 0,0 ; FLIP OUT OF AUTO MODE MOV# 0,0,SNR ;ONLY READ IF AUTO IS ZERO READS 0 ;READ THE SWITCHES STA 0,AUTO ;SAVE MOV 1,1,SZR ;DO WE HAVE A FILENAME BYTE POINTER ? JMP NXARG ;YES, IGNORE CONSOLE OPERATIONS COM# 0,0,SNR ;RESTART REQUESTED ? JMP NOTHR ;YES, USE SYS.SV/SYS.OL ;THIS IS WHERE WE ASK THE FAMOUS "FILENAME? " QUESTION JSR @.RECAL ;GIVE OTHER SIDE OF DUAL PRJ"OCESSOR SYSTEM ; A CHANCE TO BOOT UP JSR @.ZPRMS ;PRINT PROMPT MESSAGE, DETERMINING FILE?*2 ; IF IT'S TTY OR CRT JSR @.RDLIN ;READ THE RESPONSE LDA 0,LINPT ;THIS IS WHERE RDLIN PUT IT STA 0,BYTPT ;PARSE THE PATHNAME NXARG: LDA 0,BYTPT ;WOR{KING LINE BYTE POINTER JSR @.UNPAK ;UNPAK THE NEXT ARG (I.E., NAME) JMP NOTHR ;NO MORE ARGS STA 0,BYTPT ;SAVE BYTE POINTER LDA 2,COLON SUB# 2,1,SZR ;STOP ON COLON? JMP NOTDIR ;NO JSR @.NUDEV ;YES, DIRECTORY, CHANGE DEVICE JMP .+2 ;OH, ITS NOT A DEVICE JMP GOTDIR ;IT WAS PRIMARY NAME, CONTINUE JSR @.CHEXT ;MUST BE PARTITION OR SUBDIRECTORY 'DR' JSR @.SIZIT ;MAKE SURE CURRENT DEVICE IS SIZED JSR @.LOOKUP ;LOOK IT UP JSR @ERFNF ;NOT FOUND JSR @.PARTS ;PARTITION? JSR @ERNPAR ;NOY), CAN'T BOOT TO SUBDIRECTORY GOTDIR: JMP NXARG ;CONTINUE PATHNAME PARSE NOTDIR: LDA 2,SLASH SUB# 2,1,SZR ;STOP ON SLASH? JMP TRYSV ;NO, MUST BE ORDINARY TERMINATOR LDA 1,BYTPT ;YES, LOOK AT FOLLOWING CHAR JSR @.LDBYT LDA 1,ASCIA SUB# 1,0,SNR ;' "A"? ISZ ABSMD ;YES, REMEMBER ABSOLUTE MODE TRYSV: LDA 0,EXT MOV# 0,0,SZR ;GOT AN EXTENSION? JMP GOTSV ;YES, DON'T CHANGE JSR @.CHEXT ;NO, MAKE IT '.SV' 'SV' JMP GOTSV .STK: STKAD .HIPPI: HIPPI .REVIN: REVIN CONAT: ATCON EXMSK: ATRAN MAXN: SCDBS/2-2+1 ; 2 BLOCKS FOR ROOT, +1 TO UNDO PRE-DECREMENT SYSSV: SYSV*2 ;NO FILE SPECIFIED - USE SYS.SV/OL NOTHR: LDA 0,SYSSV ;BYTE POINTER TO SYS.SV JSR @.UNPAK ;UNPACK IT JSR @ERHDWRF ;YOU'RE UP TO YOUR ASS ;IN ALLIGATORS NOW ;LOOK FOR SAVE FIL4E GOTSV: JSR @.SIZIT ;MAKE SURE DISK IS SIZED & EXISTS... JSR @.LOOKUP ;LOOK FOR SAVE FILE, RESOLVING LINKS JSR @ERFNF ;FILE NOT FOUND LDA 0,UFTAT,2 ;ATTRIBUTES LDA 1,EXMSK ;EXECUTABLE MASK AND# 0,1,SNR ;IS FILE EXECUTABLE ? JSR @EREXCU ;NO GBETAD 0,1 ;YES, GET FIRST ADDRESS STA 0,SYSFA ;AND SAVE IT STA 1,SYSFA+1 ;SEE IF RESOLUTION PARTITION IS IN USE, & SAVE SYSTEM NAME FOR LATER LDA 0,AUTO ;READ THE SWITCHES COM# 0,0,SZR ;AUTO-RESTART ? JSR @.TSTUC ;NO, SEE IF PARTITION IN USE LD.A 0,ARGWP ;FROM ADDRESS LDA 2,FNL ;COUNT LDA 1,SYSNAM ;TO POINTER JSR @.MVWD ;MOVE THE NAME ;NOW LOOK FOR OVERLAYS JSR @.CHEXT ;PUT A '.OL' ON IT 'OL' SUB 0,0 ;ASSUME NO OVERLAYS SUB 1,1 JSR @.SRCH ;LOOK FOR THE OVERLAYS, NO LINKS JMP NOOVS ;NO OVERLAYS LDA 0,UFTAT,2 ;ATTRIBUTES LDA 1,CONAT ;CONTIGUOUS AND# 0,1,SNR ;IS OVERLAY FILE CONTIGUOUS ? JSR @ERNCONT ;NO THEY'RE NOT GETAD 0,1 ;YES, GET FIRST ADDRESS NOOVS: ;SAVE VITAL INFORMATION ON TOP OF ROOT'S 2ND PAGE LDA 2,ROOBA ;GET BASE OF TWO BLOCK ROOT STA 0,SCOF1,2 ;SAVE OVERLAY BASE, 0 IF NONE STA 1,SCOFA,2 LDA 0,CPL ;CURRENT PARTITION LEVEL STA 0,SCCPL,2 ;SAVE IN TOP OF MEMORY LDA 0,BSPA ;BASE OF BOOTSTRAP PARTITION STA 0,SCPB1,2 ;ALSO LDA 0,BSPA+1 STA 0,SCPBA,2 4LDA 0,SYSFA ;TURN OUR ATTENTION TO THE STA 0,CPBA ; FILE WE'RE GOING TO BOOT LDA 0,SYSFA+1 ; STA 0,CPBA+1 ; ADC 0,0 ; STA 0,@.RLBKN ; ;NOW MAKE SURE EVERYTHING FITS LDA 2,ENTBF LDA 0,MAXN ;START AT THE END SVSZLP: NEG 0,0 ; AND COME DOWN  COM 0,0 JSR @.INDEX ;FIND LAST NON-ZERO INDEX JMP SVSZLP ; (DEFINES LENGTH OF FILE JMP SVSZLP ; FOR ABSOLUTE PROGRAMS) INC 0,0 ;MAKE # OF BLOCKS SIZE STA 0,NMAX ;SAVE FOR RDSYS LDA 1,ABSMD ;GET ABSOLUTE MODE FLAG MOV# 1,1,SZR ;IS THIS AN'0 ABSOLUTE LOAD ? JMP ABSLD ;YES, GET ON WITH IT SUB 0,0 JSR @.INDEX ;READ PAGE ZERO JSR @EREXCU JSR @EREXCU LDA 0,SCZMX,2 ;SQUASH/UNSQUASH FLAG STA 0,SQMOD ;SAVE IT MOV# 0,0,SZR ;IS THIS THE SYSTEM RESIDENT ? JMP SYSLD ;YES, DO YOUR THING  ABSLD: LDA 0,NMAX ;NO, RANDOM INDEX TELLS SIZE MOVS 0,3 ;PSEUDO NMAX + 1 BLOCK LDA 0,ROOBA ;ROOBA POINTS A BLOCK PAST ROOT SKPLT 3,0 ;IS OVERWRITE INEVITABLE ? JSR @ERFIT ;YES, QUIT WHILE WE'RE AHEAD JMP RDSYS ;NO, TAKE THE PLUNGE SYSLD: LDA .Y3,ROOBA ;SYSTEM LOAD, GET ROOT BASE LDA 0,SCOF1,3 ;FIRST ADDRESS OF OVERLAY FILE LDA 1,SCOFA,3 DSNR 0,1 ;WERE THE OVERLAYS FOUND ? JSR @ERFNF ;NO, YOU'RE IN THE BAG LDA 0,SCCLI,2 ;YES, GET END OF CLI STA 0,LCLID ;& SAVE IT LDA 0,SCPSA,2 ;START OF SYSTEM STA 0,SYSST ;SAVE ALSO SUBZL 0,0 JSR @.INDEX ;READ PAGE ONE JSR @EREXCU ; (AC2 STILL HAS BUFFER ADDR) JSR @EREXCU LDA 0,USTNM,2 ;SYSTEM'S NMAX LDA 1,ROOBA ;BASE OF ROOT MODULE LDA 3,BLKSZ ;DISK BLOCK SIZE NEG 3,3 ;NEGATIVE BLOCK SIZE ADD 1,3 ;LAST LEGAL ADDRESS FOR I/O SKPLT 0,3 ;WILL IT FIT ? JSR @ERFIT ;NOPE LDA 2,LOBYT ;YES, FIGURE NMAX FOR RDSYS ADDS 2,0 ;ROUND UP AND 2,0 ;# BLOCKS TO READ STA 0,NMAX ;FOR RDSYS LDA 0,DVNAM ;YES, GET FROM ADDRESS LDA 2,SPFLT ;SdyPECIFIER STORAGE LENGTH SUB 2,1 ;STORE AT END OF ROOT'S 1ST PAGE JSR @.MVWD ;MOVE SPECIFIERS TO HIGH CORE JMP RDSYS ;GOODBYE CRUEL WORLD ; ;SUBROUTINE TO CHANGE EXTENSION ; THE DESIRED EXTENSION FOLLOWS THE CALL ; CHEXT: ENTER LDA 0,@ORTN,3 ;PI CK UP NEW EXTENSION ISZ ORTN,3 ;RETURN TO CALL+2 STA 0,EXT ;NEW ONE RETURN ;ROUTINE TO TEST AN ENTRY FOR PARTITIONESS ;IF A PARTITION THE DEFAULT DIRECTORY IS CHANGED ; ; INPUTS: AC2 - ENTRY ADDRESS ; ; RETURNS: CALL+1 - NOT A PARTITION ; CALL+2 - EPSNTRY HAD PARTITIONESS PARTS: ENTER LDA 0,UFTAT,2 ;GET ATTRIBUTES LDA 1,PARAT ;PATITION MASK AND# 0,1,SNR ;IS IT A PARTITION ? RETURN ;NO RETURN TO CALL+1 ISZ ORTN,3 ;YES, BUMP THE RETURN GETAD 0,1 ;GET FIRST ADDRESS STA 0,BSPA ;SAVE AS BOOTlSTRAP ADDRESS STA 1,BSPA+1 STA 0,CPBA ;SAVE AS CURRENT BASE ALSO STA 1,CPBA+1 LDA 2,PPBA ;BASE OF PRIMARY PARTITION MOV 0,0,SNR ;DON'T CHANGE LEVEL IF THIS SUB 2,1,SZR ; IS THE PRIMARY PARTITION SUBZL 1,1 ;+1 STA 1,CPL ;IS CURRENT PARITION LE|xVEL ADC 2,2 ;-1 (& SAVE ACS 0&1) STA 2,@.RLBKN ;RESET RELATIVE BLOCK NUMBER DSNR 0,1 ;PRIMARY PARTITION ? RETURN ;YES, RETURN TO CALL+2 LDA 0,ARGWP ;NO, GET ARG AREA WORD POINTER LDA 1,PARNAM ;DESTINATION LDA 2,PARLT ;PARTITION NAME LENGTH JSsrR @.MVWD ;MOVE THE WORDS RETURN ;& RETURN PARAT: ATPAR SYSDR: SYSD*2 UCMSK: 7777 ASCIC: "C ** .PUSH .NOLOC ** .NOLOC 1 INUSE: .TXT /<15><12>PARTITION IN USE - TYPE C TO CONTINUE<15><12>/ ONTINU: .TXT /ONTINUE<15><12>/ SYSD: .TXT /SYS.DR/ ** .NOLOC .u@POP ; ;ROUTINE TO SEE IF BOOTSTRAP PARTITION IS IN USE, ; AND IF SO, ASK USER BEFORE CONTINUING ; TSTUC: ENTER JSR @.SAVARG ;SAVE CURRENT ARG CONTENTS LDA 0,SYSDR ;BYTE POINTER TO SYS.DR JSR @.UNPAK ;UNPAK IT JSR @ERHDWRF ;MUST BE THERE, I BROUGHd%T ;IT WITH ME JSR XCHBA ;SWAP CURRENT BASE FOR BOOTSTRAP BASE JSR @.SRCH ;LOOK FOR SYS.DR JSR @ERFNF ;NOT THERE - GAK !!!!! STA 2,TMP,3 ;SAVE ENTRY ADDRESS JSR XCHBA ;SWAP CURRENT BACK IN JSR @.BAKARG ;RESTORE ARG LDA 2,TMP,3 ;ADDRESS OF SYS.DR ENTRY LDA 0,UFTUC,2 ;USER COUNT LDA 1,UCMSK ;USER COUNT MASK AND# 1,0,SNR ;ANY USERS ? RETURN ;NO JSR @.PRMS ;PRINT INTERROGATION MESSAGE INUSE*2 SKPDN TTI ;WAIT FOR RESPONSE JMP .-1 DIAC 0,TTI ;GET INPUT CHARACTER JSR @.TTYO ;OUTPlUT IT LDA 1,MASK ;PARITY MASK AND 1,0 ;MASK OFF PARITY LDA 1,ASCIC ;ASCII 'C' SUB# 0,1,SZR ;CONTINUE ? JMP @BOOSA ;NO, START ALL OVER JSR @.PRMS ;NOW PRINT REST OF WORD ONTINU*2 RETURN ;& JUMP IN UP TO YOUR EYEBALLS ; ROUTINE TO EXCHANGE BOOTSTRAP & CURRENT PARTITION BASES XCHBA: ENTER LDA 0,BSPA ;PICK UP BOOTSTRAP LDA 1,BSPA+1 ; PARTITION BASE ADDRESS LDA 2,CPBA ;AND CURRENT PARTITION BASE LDA 3,CPBA+1 STA 0,CPBA ;AND STORE BACK THE OTHER WAY STA 1,CPBA+1 STA 2,BSPA STA 3,BSPA+1 ADC 0,0 STA 0,@.RLBKN ;MUST INVALIDATE INDEX BUFFER RETURN ; ; SAVARG - ROUTINE TO SAVE ARG CONTENTS ; SAVARG: ENTER LDA 0,ARGWP ;FROM WORD POINTER LDA 1,ARGSV ;DESTINATION POINTER LDA 2,FNL ;LENGTH JSR @.MVWD RETURN ; ; BAKARG - RESTORE[ PREVIOUSLY SAVED ARG CONTENTS ; BAKARG: ENTER LDA 0,ARGSV ;FROM LDA 1,ARGWP ;TO LDA 2,FNL JSR @.MVWD RETURN ARGSV: .+1 .BLK SCFNL ;SPACE FOR UNPACKED NAME, INCL EXT ; ; SIZIT - ROUTINE TO SIZE CURRENT DEVICE (NAME IN PDKEY/PDUNT) ; SIZIT: EbNTER JSR @.SAVARG ;MUST SAVE CURRENT ARG LDA 0,PDKEY ;FIRST TWO CHARS OF DEVICE NAME STA 0,TKEY LDA 0,PDUNT ;OTHER TWO CHARS OF NAME STA 0,TUNIT LDA 0,TDVNAM ;BYTE POINTER TO TERMINATED STRING JSR @.UNPAK ;UNPACK DEVICE NAME TO ARG AREA JSR @ERDEV ; UH OH... JSR @.NUDEV ;SIZE IT JSR @ERDEV ;WON'T SIZE JSR @.BAKARG ;GET BACK ORIGINAL ARG RETURN TDVNAM: (.+1)*2 TKEY: 0 TUNIT: 0 0 ;NULL TO TERMINATE NAME ; ;SUBROUTINE TO CHANGE INPUT DEVICE ASSOCIATION ; ; DEVICE NAME IS ASSUMED TO B`>E IN ARG ; ; JSR @.NUDEV ; -- INVALID DEVICE NAME ; (NORMAL RETURN) ; TYPEN=TMP DEVEN=TYPEN+1 UNIEN=DEVEN+1 NUHED=UNIEN+1 NUSEC=NUHED+1 NUDEV: ENTER LDA 1,ARG ;GET FIRST TWO CHARS OF DEV NAME (KEY) LDA 2,TYTAB ;LOOK IT UP IN DISK TYPE TABLE TY`LP: LDA 0,TYKEY,2 ;TABLE KEY COM# 0,0,SNR ;END OF TABLE? RETURN ;YES, UNKNOWN SPECIFIER SUB# 1,0,SNR ;MATCH? JMP GOTTY ;YUP, FOUND THE TYPE LDA 0,.TYLEN ;TABLE ENTRY LENGTH ADD 0,2 ;NEXT ENTRY JMP TYLP GOTTY: STA 2,TYPEN,3 ;SAVE POINTER TO TYPE ENTRY LDA 2,TYDEVTB,2 ;DEVICE TABLE ADDRESS FOR OUR TYPE STA 2,DEVEN,3 ;REMEMBER LDA 0,ARG+2 ;3RD WORD (5TH & 6TH CHARS) OF NAME MOV# 0,0,SZR ;ALL DEVICE NAMES ARE 4 CHARS OR FEWER RETURN ;LONGER - CAN'T BE VALID DEVICE NAME LDA 1,ARG+1 ;UNITSL WORD (2ND & 3RD CHARS) DVLP: LDA 2,DEVEN,3 ;CURRENT DEVICE TABLE ENTRY ADDRESS LDA 2,DVUNITB,2 ;UNIT TABLE ADDRESS COM# 2,2,SNR ;END OF DEVICE TABLE? RETURN ;YES, UNIT NOT FOUND UNILP: LDA 0,0,2 ;NOW SEARCH UNIT TABLE COM# 0,0,SNR ;END OF UNITS FWOR CURRENT DEVICE? JMP NOTDV ;YES, TRY NEXT DEVICE ENTRY SUB# 1,0,SNR ;MATCH? JMP GOTUN ;YOU BET INC 2,2 ;NEXT ENTRY IN UNIT TABLE JMP UNILP NOTDV: LDA 2,DEVEN,3 ;CURRENT DEVICE TABLE ENTRY ADDRESS LDA 0,.DVLEN ;LENGTH OF ENTRY ADD 0,2 ;NEXT D`OEVICE ENTRY ADDRESS STA 2,DEVEN,3 JMP DVLP GOTUN: STA 2,UNIEN,3 ;SAVE POINTER TO UNIT ENTRY LDA 2,TYPEN,3 ;TYPE ENTRY ADDRESS LDA 0,TYCHR,2 ;PRELIM CHARACTERISTICS FROM NAME LDA 2,DEVEN,3 ;OUR DEVICE TABLE ENTRY ADDRESS LDA 1,DVCODE,2 ;GET DEVICE C! ODE FROM DEVICE ENTRY LDA 2,DVUNITB,2 ;PTR TO BEGINNING OF UNIT TABLE LDA 2,0,2 ;DEFAULT ASCII UNIT STA 2,@.DFASCUN ;SAVE FOR INSTALLER LDA 2,.SDVR ;WHERE TO LOAD IT JSR @.MINILOADER ;BUILD SIZER DISK ROUTINE SZRDVR MOV 0,1 ;PRELIM CHARACTERISTnICS LDA 0,@UNIEN,3 ;ASCII UNIT WORD (3RD & 4TH CHARS OF NAME) LDA 2,UNIMSK ANDS 2,0 ;PICK TWO BITS & PUT IN LOW ORDER MOVZR 0,0 ;PUT IT IN HARDWARE DOC FORMAT MOVR 0,0 ; FOR OLD MOVING HEADS MOVR 0,0 ; I.E., AT BIT 1 (HI 2 BITS) SK1NC CHPAGING ;nPAGING DISK? JMP .+2 JMP NPGING MOVZR 0,0 ;YES, PUT AT BIT 3 MOVZR 0,0 JMP NUSZIT NPGING: SK1NC CHZEBRA ;ZEBRA? JMP .+2 JMP NZEBR MOVZR 0,0 ;YES, PUT AT BIT 10 MOVS 0,0  JMP NUSZIT NZEBR: LDA 1,@UNIEN,3 ;OLD MOVING HEADS - LOOK AT NAME LDA 2,LOBYT ;GET 4TH CHAR - 'F' OR NULL AND 1,2,SZR ;ODD HEAD SET? LDA 2,ODD ;YES ADD 2,0 ;ADD HEAD BIT TO UNIT NUSZIT: LDA 1,@UNIEN,3 ;ASCII UNIT WORD LDA 2,TYPEN,3 ;DISK TYPE ENTRY ADDRESS AGAIN LDA 3,TYSZR,2 ;SIZER ROUTINE ADDRESS LDA 2,TYCHR,2 ;PASS PRELIM CHARACTERISTICS JSR 0,3 ;SIZE THE DEVICE STA 0,NUHED,3 ;SAVE HEADS & SECTORS (MUST STA 1,NUSEC,3 ; LOAD DRIVER FIRST) STA 2,DVCHR ;SAVE CHARACTERISTICS FOR SKPNC MOV 2,0 ;PASS IN AC0 TO MINILOADER LDA 2,ROOBA LDA 1,.RDVRD ;FIND DESTIeNATION ADDR (EITHER ADD 1,2 ; OUR ROOT OR ROOT IN HIGH CORE) LDA 3,DEVEN,3 LDA 1,DVCODE,3 ;DEVICE CODE AGAIN JSR @.MINILOADER ;SET UP DRIVER FOR NEW DEVICE ROODVR LDA 2,TYPEN,3 LDA 0,TYKEY,2 ;DEVICE TYPE (FIRST 2 CHARS OF NAME) STA 0,PDKEY ;STORE LDA 0,@UNIEN,3 ;ASCII UNIT (3RD & 4TH CHARS OF NAME) STA 0,PDUNT ADC 0,0 ;-1 STA 0,@.RLBKN ;INVALIDATE RELATIVE BLOCK NUMBER LDA 0,NUHED,3 STA 0,@.HEAD ;STORE #HEADS IN DRIVER LDA 0,NUSEC,3 STA 0,@.SECT ; ALSO #SECTORS SUBZL 0,0 LDA 1,.DXPB  ;DOUBLE INDICES PER BLOCK SKPNC CHDOBL ;DISK REQUIRES DOUBLE ADDRESSING? JMP GDBL ;YES SUB 0,0 ;FLAG SINGLE WORD INDEX BLOCKS LDA 1,.SXPB GDBL: STA 0,@.DOBLAD ;STORE IN ROOT FOR RINDEX STA 1,@.WDPIB LDA 2,@.BADTBL COM# 2,2,SNR ;GOT ONE? LDA*} 2,.TBADTB ;NO, USE OUR OWN BUFFER ADC 0,0 ;TURN OFF MAPPING, STA 0,@.BADTBL ; JUST TO BE REAL SURE SUB 0,0 LDA 1,.BAD ;BAD BLOCK TABLE DISK ADDRESS JSR @.READ ;GO GET IT STA 2,@.BADTBL ;NOW WE CAN USE IT ISZ ORTN,3 ;GOOD RETURN RETURN ;RETUaRN NOW .TYLEN: TYLEN .DVLEN: DVLEN .DFASCUN: DFASCUN ODD: 2B7 UNIMSK: 3*400 .TBADTB:TBADTB .BAD: SCBAD .SXPB: SCWPB .DXPB: SCWPB/2 .SDVR: SDVR .RDVRD: RDVR-RBASE ;TABLE OF DISK TYPES: TYKEY = 0 ;KEY (LIKE 'DK' OR 'DP') TYDEVTB = 1 ;ADDRESS OF DEV¿ICE TABLE FOR THIS TYPE TYCHR = 2 ;PRELIM CHARACTERISTICS TYSZR = 3 ;SIZER ROUTINE ADDRESS TYLEN = TYSZR-TYKEY+1 TYTAB: .+1 'DK' DKDEV CHNOVDSK DKSZR 'DP' DPDEV 0 DPSZR 'DZ' DZDEV CHZEBRA+CHDOBL DZSZR 'DS' DSDEV CHPAGING DSSZR -1b ;DEVICE TABLES - ; I.E., TABLES OF AVAILABLE CONTROLLERS FOR EACH DISK TYPE: DVUNITB = 0 ;ADDRESS OF UNIT TABLE DVCODE = 1 ;DEVICE CODE DVLEN = DVCODE-DVUNITB+1 DKDEV: DSKUNI DSK DSK1UNI DSK1 -1 DPDEV: DKPUNI DKP DKP1UNI DKP1 -1 DZDEV:L DZSUNI DZP DZS1UNI DZP1 -1 DSDEV: DZSUNI DSP DZS1UNI DSP1 -1 ;TABLES DESCRIBING UNITS AVALABLE ON EACH CONTROLLER: ; NOTE - THE FIRST ENTRY OF EACH TABLE IS THE BOOTSTRAP UNIT ;NOVADISK DSKUNI: '0' -1 DSK1UNI: '1' -1 ;NORMAL MOVING ܇HEADS DKPUNI: '0' '0F' '1' '1F' '2' '2F' '3' '3F' -1 DKP1UNI: '4' '4F' '5' '5F' '6' '6F' '7' '7F' -1 ;ZEBRA & PAGING DISK DZSUNI: '0' '1' '2' '3' -1 DZS1UNI: '4' '5' '6' '7' -1 ; ; MINILOADER DEFINITIONS ; ; DEFINE CONDITIyON BITS, ONE FOR EACH DISK TYPE CBNOVD = 0 ;NOVADISK CBOMOV = 1 ;OLD MOVING HEAD DISK (DIABLO,114,111) CBTOPL = 2 ;TOP-LOADER CB3330 = 3 ;THE BIG ONE CBZEBR = 4 ;NEW BIG ONE CBPAGI = 5 ;PAGING DISK .DUSR NCB = 6 ;NUMBER OF ABOVE .DUSR IFNOVD = 1B(CBNO$VD) .DUSR IFOMOV = 1B(CBOMOV) .DUSR IFTOPL = 1B(CBTOPL) .DUSR IF3330 = 1B(CB3330) .DUSR IFZEBR = 1B(CBZEBR) .DUSR IFPAGI = 1B(CBPAGI) .DUSR IFUMOV = IFOMOV!IFTOPL!IF3330 ;FORMER UNIVERSAL COMMAND DISKS .DUSR CMALL = -1B(NCB-1) ;MASK FOR ALL DISK BITS .DUSR CMIO = 1B15 ;MASK FOR I/O BIT .DUSR CMWART = 1B14 ;SPECIAL QUIRK MODE TO HANDLE MACROS IN SOURCE .DUSR CMSTOP = 0 ;NO BITS MEANS END OF LOAD ; MINILOADER MAKES NON-SYMBOLIC REFERENCE .MACRO IFNOT (CMALL-(^1))% ; ; BOOT'S MINILOADER, FOR GENERATING DISK DRIVERS ; ; AC0 - CHARACTERISTIC WORD ; AC1 - DEVICE CODE ; AC2 - DESTINATION ADDRESS ; JSR MINILOADER ; TABLEADDRESS ; (NORMAL RETURN) ; ; WHERE TABLEADDRESS IS THE FIRST ARGUMENT TO A CINIT CALL. ; THE TABLE THE MINILOADER WORKS FROM IS DEFiINED USING MACROS ; (INCLUDING CINIT) THAT ARE DEFINED ON SUCCEEDING PAGES. ; LDEV=OAC1  LCON=TMP OUT=LCON+1 LDCNT=OUT+1 MINILOADER: ENTER MOV 0,1 ;CHARACTERISTIC WORD FOR SK1NC SUB 0,0 ;INITIAL CONDITION WORD ; MAP CHARACTERISTIC BITS TO MINILOADER !CONDITION BITS LDA 2,.IFNOVD SK1NC CHNOVDSK ADD 2,0 LDA 2,.IFPAGING SK1NC CHPAGING ADD 2,0 LDA 2,.IF3330 SK1NC CH3330 ADD 2,0 LDA 2,.IFTOPL SK1NC CHTOPL ADD 2,0 LDA 2,.IFZEBR SK1NC CHZEBR ADD 2,0 LDA 2,.IFOMOV MOV# 0,0,SNR ;NONE OF ABOVE? ADD 2,0 ;YES, MUST BE OLD MOVING HEAD STA 0,LCON,3 ;STORE CONDITION WORD LDA 0,OAC2,3 STA 0,OUT,3 ;INITIALIZE OUTPUT ADDRESS LDA 2,ORTN,3 ;POINTER TO ARG ISZ ORTN,3 ;SKIP IT LDA 2,0,2 ;TABLE POINTER LDLP: LDA 0,0,2 MOV# 0,0,SNR RETURNa LDA 1,.CMWART AND# 1,0,SNR ;WART ENTRY? JMP LDNORM ;NO LDA 1,1,2 ;YES, PICK UP WORD COUNT STA 1,LDCNT,3 LDA 1,LCON,3 AND# 1,0,SZR ;DO IT? JMP LDWALP LDA 0,LDCNT,3 ;NO, SKIP OVER WORDS ADD 0,2 JMP LDNXT LDWALP: LDA 0,2,2 ;COPY DIRECTLY INC 2,2 STA 0,@OUT,3 ISZ OUT,3 DSZ LDCNT,3 JMP LDWALP JMP LDNXT LDNORM: LDA 1,LCON,3 AND# 1,0,SNR JMP LDNXT LDA 1,.CMIO AND# 1,0,SNR JMP LDNIO LDA 0,1,2 LDA 1,LDEV,3 ADD 1,0,SKP LDNIO: LDA 0,1,2 STA 0,@OUT,3 ISZ OUT,3 LDNXT: INC 2,2 INq7C 2,2 JMP LDLP .CMIO: CMIO .CMWART: CMWART .IFNOVD: IFNOVD .IFPAGING: IFPAGING .IF3330: IF3330 .IFTOPL: IFTOPL .IFZEBR: IFZEBR .IFOMOV: IFOMOV ; ; MACROS FOR GENERATING THE CODE TABLE THE MINI-LOADER DRIVES ; ;ALL REFS TO LABELS DEFINED IN TABLE MUMST BE THROUGH THE REF MACRO... ; USE OUR OWN STACK, SINCE STUFF LIKE .NOMAC CLUTTERS UP THE ; MAC STACK. (NOTE: CELSE REFERS DIRECTLY TO TOP OF STACK...) .MACRO CPUSH ** .DUSR CSP=CSP+1 ** .DUSR CS\CSP=^1 % .MACRO CPOP ** .DUSR ^1=CS\CSP ** .DUSR CSP=C:SP-1 % .DUSR CSP=0 ; CINIT