Trailing-Edge
-
PDP-10 Archives
-
cuspmar86binsrc_2of2_bb-fp63a-sb
-
10,7/twice/twice.mac
There are 6 other files named twice.mac in the archive. Click here to see a list.
TITLE TWICE - DRIVER FOR USER MODE ONCE ONLY V5(45)
SUBTTL D BLACK/JSL/EVS/TW 26-Aug-85
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1970,1979,1980,1982,1983,1986.
;ALL RIGHTS RESERVED.
;
;
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
VTWICE==5 ;VERSION NUMBER
VEDIT==45 ;EDIT NUMBER
VMINOR==0 ;MINOR VERSION NUMBER
VWHO==0 ;EDITED BY DEC
;SEARCH S AND F LIBRARIES
SEARCH F,S
SEARCH MACTEN,UUOSYM
$RELOC ; TWOSEG
JOBVER==137
$ABS
LOC JOBVER
BYTE (3)VWHO(9)VTWICE(6)VMINOR(18)VEDIT
$HIGH ; RELOC 400000
$LOW ; RELOC
SALL
COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1970,1986. ALL RIGHTS RESERVED.
\;END OF COPYRIGHT MACRO
;DECLARE EXTERNS SO CAN SEARCH MONITOR LIBRARY FILE IN LIBRARY SEARCH MODE
EXTERN ONCMOD,REFSTR,FILFND,FILIO,FILUUO
;MISC PARAMETERS
DSK==1 ;CHANNEL FOR DISK IO
LINSIZ==100 ;SIZE OF TTY LINE BUFFER
PDLEN==100 ;LENGTH OF PUSH DOWN LIST
MJOBN==:-^D64 ;MINUS MAX NUMBER OF JOBS (NOT REALLY NEEDED)
SPBACT==:11 ;LENGTH OF CORE FOR A SPOOLING BLOCK (NOT NEEDED)
PAVJSP==:0
PROTM::0
SCDSWP::0
BLKSPK==:3 ;SHIFT FOR BLOCKS PER K
MBKSPK==:-3 ;RIGHT SHIFT FOR BLOCKS PER K
PIOMOD==:0
DSKPIN==:0
DSKPIF==:0
PION==:0
PIOFF==:0
PIPROG==:0
INDPPN==:0
ICPFAC==:0
JOBMSK==:777
AUQ==:5
DAQ==:6
IFNDEF JIFSEC,<JIFSEC==:^D60>
JIFMIN==:JIFSEC*^D60
IFNDEF RETRYN,<RETRYN==^D360 ;NUMBER OF TIMES TO RETRY TO CREATE SCRATCH FILE>
IFNDEF BLKPUN,<BLKPUN==^D50 ;BLOCKS PER UNIT IN SCRATCH FILE>
;DUMMY INTERNS (700)
XP M.SWCT,1 ;NON-ZERO IF NOT IN HDW CONFIG FILE
XP M.XFFA,1 ;... DITTO
;THE FOLLOWING CODE IS HERE ONLY SO THAT ALL MODULES AGREE ON THE VALUE OF
; M.TLTL
IFNDEF M.TTDN,<M.TTDN==:0>
IFNDEF M.XTL,<M.XTL==:0>
XP M.TLTL,M.TLTL+M.TTDN ;REDEFINE FOR RSX-20F LINES
XP M.TLTL,M.TLTL+M.XTL ;REDEFINE FOR XTC LINES
IFN M.KS10,<
XP M.TLTL,M.TLTL+1 ;ADD ONE FOR KLINIK LINE
>
$HIGH ;RELOC ;GO TO HISEG
PJBSTS::POINT JWSIZ,JBTSTS,JWPOS ;JOB WAIT STATE (QUEUE) CODE
PKLNT2::POINT 36,[0],35
DEYISN::
DEYCPS::
DEYCPF::POINT 36,FOO,35
FOO: BLOCK 1
FSTTIM::BLOCK 1 ;NON-ZERO FOR CALL TO REDHOM
REVCCD::CORTAL::CNTPT3::NXDDB::FPDBT1::SCDMM::GIVMM::
ALLKON::HIGHXC::SWPINS::FLTST::CNTFIL::
DONE::THIS::PROT1::.PDACS::TTCCIS::SWPCHK::ERPTMX::
QQRUN1::SWPPIK::TT2CI2::DIAMTA::TYPSCD::TTCCOS::TT2CO1::MPOPJ::
CNFST2::FILMSG::.PDDIA::SWPHNG::.PDDFL::PDYFSP::%SIFDA::TRPSET::DEVSRG::
SENDSP::ESVIDX::DPXREG::FSXREG::PRTDDB::RPXREG::EPKIDX::SWPSCN::
MACTSL::ERPTBK::.IPCFD::.IPCFP::FHXREG::SCNCNT::FNDPDS::
PDVTIM::SETHNG::DECIN1::QMXTAB::QMLTAB::FDAJOB::SNDMDC::MDCJOB::
PIDTAB::RTZER1::PCRLF::MAXACS::.PDEPA::SQREQ::QADTAB::SCDCHK::
.CPDLK::INTODD::DIACSB::INTODS::CPUOFS::STORS7::UPMM::
.CPQUE::SETUF::.CPQPC::.CPQPS::JDAADR::STATES::
DOORBL::.CPAEF::BOOTCP::TKYCPU::INTRDD::INTRDS::PRVBIT::.CPQND::
DEVHNG::%SIOPR::DIEUNI::TTPOPJ::SWPAD::TRPSTU::DLYCOM::
NXTCH::GFWDUD::SEGPTR::CLKNEW::GFWDCD::ZERSWP::
.CPCPN::DIADSB::SPBMAX::CLKMIN::CHKCPI::LOKSPI::.CPSWP::ONCPUN::
SETCPN::K4SWAP::
ONCPUS::UNLSPT::UNLSPI::GGVMM::INTOUU::.CPSOF::.CPFBO::.CPFBI::
DEYPCL::T3POPJ::PSIDVB::.CPSK1::W2PLSH::STEUB::PSIJBI::GVFWDS::
.CPJOB::GTFWDU::GTFWDC::SSEUB::INTRUU::SLEEPF::DD%PHO::DD%ALT::
FNDSDL::JBTLIM::SDLUNI::ZRNGE::DIAGCS::DIANUI::TLPJOB::.PDSTM::M1POPJ::
RPXSTW::OUCHE::RH2ND::STONBF::CHKNB::CSDMP::DEYCPU::.PDOBI::
.CPTAP::.IPCSC::%SIMDA::JBTDAU::.CPSWD::RNXREG::.E0MP::
.PDOSL::FORCE::JBTUPM::IPCULK::ADVSWP::ADVBFI::ADVBFO::
CPUOK::PIERR::SEQTOP::GFWNZ2::GFWNZS::PCLCP0::DWNMC::MKADD::
INTLVL::UPMC::MCUSER::PCLDKY::CPFBIT::
JBTPRG::LOGTXT::
SGANAM::SGAMOD::.PDQSN::.PDLBS::%CNIPS::MONVFF::ONCMAP::RWRTCH::
ENQNDR::DMPFZR::REMMPA::STRMPA::XCHMPA::SCNOWN::NPJSTP::DETJCK::
RPXCFG::RPXALV::MT0DDB::PAGEIT::GETPHP::FNDIPC::IPCPAG::
.CPDRQ::.CPEPT::.CPNBI::.C0CDB::.CPCDB::.CPMAP::.CPSCC::.CPSCD::
ADRERR::DWNMM::MCFREE::MCWAIT::DPXALV::INTRDC::INTODC::
IFN M.RP20,<
RNXCCM==:CYLCM##
RNYDXN::RNVSMR::RNVNMR::RNXCSB::RNPUNB::
RNXRLD::RNXALV::RNXCFG::DX2COM::
>
IFN FTCIDSK,<
RAXINT::RAXCPY::RAXUNL::RAXPOS::MSCGBF::
RAXCFG::RAXERR::RAXCCM::MSCCOM::RAXECC::
RAXALV::RAXLTM::RAXWTF::RAXWTC::RAXWTS::
RAXKON::RAXWRT::RAXRDS::RAXSTP::RAXRDC::
RAXREG::RAXRED::RAXRCL::RAXSEC::RAXRDF::
MSCUON::APRCHK::.CPPCB::LOCSEC::CPUAPP::
RAXUPA::MOVEI T1,1
JRST CPOPJ1
>; END IFN FTCIDSK
QNDRCK==:CPOPJ1
BUFSSN==:CPOPJ1
UUOLVL::FRCCPY::
JRST CPOPJ1
SSLBLD::ASLBLD::SDLBLD::SPCS::WCHFIL::FJCONT::SW2LC::SRFRDA::SRFRAU::CHKCSH::
PAGIPQ::FNDIP0::FLSOPQ::REVFUL::PPDRHD::SAVR::
BLDSSL::BLDASL::BLDSDL::RNXMVR::RNXEDL::RNXSEC::DIESTR::.BTRP2::
SPCGDT::MSCCUS::SPRIPX::
POPJ P,
.CPBIT::1
.C0CPN::1
FPOPJ:: POP P,F
POPJ P,
$LOW ;RELOC ;GO BACK TO LOSEG
WPOPJ1::AOS -1(P)
WPOPJ:: POP P,W
POPJ P,
FFMD1:: 0
RELMD1::0
ONCCOM::0
.CPNPD::IOWD PDLEN,PDLIST
TKBUDB::CNFMTK::TKBKDB:: 0
TWICE: JFCL ;IN CASE OF CCL ENTRY
RESET
MOVE T1,.JBREL## ;CURRENT END OF CONTIGUOUS LOWSEG
AOS T1 ;POINT TO START OF FREE SPACE
MOVEM T1,.JBFF## ;FOR CORE ALLOCATION
SETOM OPTQIK## ;DONT ASK ABOUT OFF-LINE UNITS
MOVE P,.CPNPD ;SET UP STACK
SETZ T1, ;WRITE ENABLE HIGH SEGMENT
SETUWP T1,
JRST [OUTSTR [ASCIZ/? Cannot write enable high segment
/]
EXIT]
MOVE T1,[%CCTYP] ;FIND OUT WHAT WE'RE RUNNING ON
GETTAB T1,
JRST [OUTSTR [ASCIZ/? Cannot tell what kind of processor this is
/]
EXIT]
MOVEI T1,-.CCKLX(T1) ;KL WILL TURN OUT 0
MOVEM T1,KSFLAG ;OTHERS WILL BE NON-0
IFN FTXMON,<
JUMPN T1,NOSEC1 ;IF ON A KS, DON'T MAP SECTION 1
MOVE T1,[.PAGSC,,T2] ;UUO AC
MOVEI T2,1
MOVE T3,[PA.GMS!<0,,1>]
PAGE. T1, ;MAP SECTIONS 0 AND 1 TOGETHER
JRST [OUTSTR [ASCIZ /? CAN'T MAP SECTIONS 0 AND 1 TOGETHER/]
EXIT]
NOSEC1:>
IFN FTAUTC,<
PUSHJ P,SETDAT ;SET UP TWICE DATA BASE TO MATCH RUNNING MONITOR
>; END IFN FTAUTC
MOVE T1,.JBFF## ;FIRST FREE LOCATION
MOVEM T1,ONCEND
DATE T1, ;TODAY'S DATE
MOVEM T1,THSDAT
TIMER T1, ;TIME OF DAY
MOVEM T1,TIME
MOVE T1,[XWD 44,11]
GETTAB T1,
MOVEI T1,^D60
MOVEM T1,TICSEC
IMULI T1,^D60
MOVEM T1,TICMIN
MOVE T1,[%CNDTM]
GETTAB T1,
SETZ T1,
MOVEM T1,DATE
MOVE T1,[DOLBLK] ;SETUP .JBINT TO INTERCEPT DISK OFF LINE
MOVEM T1,.JBINT## ;ALSO INTERCEPT XJRSTs ON THE KS
MOVE T1,[PJRST USRDIO]
MOVEM T1,UUOPWQ## ;PATCH FILIO TO CALL OUR DISK I/O ROUTINE
SETOM .UONCE## ;NOTE USER MODE ONCE ONLY
MOVEI U,DIFUSY## ;PTR TO LIST OF UNITS IN OUR SYSTEM
MOVSI T1,UNPSAF## ;SINGLE ACCESS BIT TO CLEAR FOR EACH UNIT
JRST USTSCF ;CLEAR IMPORTANT FLAGS FOR EACH UNIT
USTSCL: SETZM UNISTS##(U) ;MAKE SURE STATUS WORD CLEAR
SETZM UNILOG##(U) ;MAKE SURE KEEP FLAG CLEAR TOO
ANDCAM T1,UNIDES##(U) ;AND CLEAR WRITABLE FLAG
MOVE T2,UNINAM##(U) ;NAME OF UNIT
MOVEM T2,CHRBUF ;STORE IN DSKCHR BUFFER
MOVE T2,[XWD .DCUID+1,CHRBUF] ;ARG PTR
DSKCHR T2, ;GET UNIT ID
TDZA T2,T2 ;NOT A DISK?
MOVE T2,CHRBUF+.DCUID ;UNIT ID
MOVEM T2,UNIHID##(U) ;PICK UP NOW SO CAN SPECIFY READ/WRITE UNITS
;WITH UNIT ID SO DONT NEED TO KNOW WHICH
;PHYSICAL UNIT THEY'RE MOUNTED ON
USTSCF: HLRZ U,UNISYS##(U) ;NEXT UNIT IN OUR SYSTEM
JUMPN U,USTSCL ;LOOP FOR ALL OUR UNITS
SETZM CURUNI
GETPPN T1, ;GET OUR PPN
JFCL ;IN CASE JACCT ON
MOVEM T1,OURPPN
SETZM DEBUGF ;MAKE SURE NOT IN DEBUG MODE
;HERE TO ASK IF SCRATCH FILE TO BE USED
SETOM FILFLG ;ASSUME SCRATCH FILE
MOVEI T1,[ASCIZ .
Scratch file? (Y or <CR>) .]
PUSHJ P,YESNO ;ASK AND YE SHALL RECEIVE
SETZM FILFLG ;DON'T USE SCRATCH FILE
;HERE TO FIND OUT WHICH UNITS TO USE
NOSCR: MOVEI T1,[ASCIZ .
Read units: .]
PUSHJ P,SVMOUT## ;ASK FOR UNITS TO READ
NXTRED: PUSHJ P,GETUNI## ;GET NEXT UNIT TO READ
JRST NOREAD ;NO MORE UNITS TO READ
JUMPE U,ALLRED ;JUMP IF ALL TYPED
PUSHJ P,KEEPRD ;JUST ONE, KEEP IT
JRST NXTRED ;LOOP FOR NEXT TYPED
ALLRED: MOVEI U,DIFUSY## ;ALL, PTR TO FIRST UNIT
SETOM OFFLOK## ;DON'T TYPE OFF-LINE UNITS
NXARED: HLRZ U,UNISYS##(U) ;NEXT UNIT IN OUR SYS
JUMPE U,LSTRED ;JUMP IF NO MORE
PUSHJ P,KEEPRD ;KEEP THIS UNIT
JRST NXARED ;LOOP FOR NEXT UNIT IN OUR SYSTEM
NOREAD:
LSTRED: MOVEI T1,[ASCIZ .
Write units: .]
PUSHJ P,SVMOUT## ;ASK FOR UNITS TO WRITE ON
NXTWRT: PUSHJ P,GETUNI## ;GET NEXT UNIT TO WRITE
JRST NOWRIT ;NO MORE
JUMPE U,ALLWRT ;JUMP IF ALL TYPED
PUSHJ P,KEEPWT ;KEEP THIS UNIT FOR WRITING
JRST NXTWRT ;LOOP FOR NEXT TYPED
ALLWRT: MOVEI U,DIFUSY## ;ALL, PTR TO FIRST UNIT
NXAWRT: HLRZ U,UNISYS##(U) ;GET NEXT UNIT IN SYSTEM
JUMPE U,LSTWRT ;JUMP IF NO MORE
PUSHJ P,KEEPWT ;KEEP THIS UNIT FOR WRITING
JRST NXAWRT ;LOOP FOR NEXT UNIT IN OUR SYSTEM
;HERE TO REMOVE UNWANTED UNITS FROM OUR LISTS
NOWRIT:
LSTWRT: PUSHJ P,SAVKON ;PATCH OUT SETKON SO STATUS OF OFF LINE
; AND DOWN UNITS IS PRESERVED
MOVEI U,DIFUSY## ;PTR TO FIRST UNIT IN OUR SYSTEM
NXTKEP: HLRZ U,UNISYS##(U) ;NEXT UNIT
JUMPE U,SHORTD ;JUMP IF NO MORE UNITS
SETZM UNIHID##(U) ;CLEAR UNIT ID (WILL GET FROM HOME BLOCK)
SKIPN UNILOG##(U) ;SKIP IF KEEPING THIS UNIT
PUSHJ P,FLGDW ;NO, FLAG IT AS DOWN
MOVSI T1,UNPSAF## ;GET SINGLE ACCESS BIT
MOVSI T2,UNPHWP## ;GET HARDWARE WRITE PROTECT BIT
TDNN T1,UNIDES##(U) ;IS UNIT WRITABLE?
IORM T2,UNIDES##(U) ;NO, MARK AS WRITE LOCKED
SETZM UNILOG##(U) ;CLEAR FLAG
JRST NXTKEP ;LOOP FOR ALL UNITS
;TYPING ESCAPE DURING ONCE WILL BRING YOU BACK HERE TO TRY AGAIN.
SHORTD::
SETZB P1,SHUTUP## ;CLEAR SHORT FLAG
MOVE T1,ONCEND ;GET FIRST FREE LOCATION FOLLOWING TWICE
ADDI T1,1 ;MAKE SYSSIZ START AFTER TWICE
MOVEM T1,SYSSIZ ;(TO MAKE SETDDO WORK PROPERLY)
SKIPGE DEBUGF
JRST QUICK
MOVEI T1,[ASCIZ/
Startup option: /]
PUSHJ P,ASKGET ;ASK QUESTION
JRST ONCHLP ;GIVE SOME HELP
PUSHJ P,CTEXT ;GET FIRST WORD
JUMPN T2,LNG1 ;JUMP IF WORD GIVEN
CAIN T3,"/" ;SEE IF /H
JRST LNGHLP ;YES--LONG HELP
JRST ONCHLP ;NO--SHORT HELP
LNG1: MOVE T1,[-OPTLEN,,OPTTAB]
PUSHJ P,FNDNAM ;LOOKUP NAME
JRST ONCHLP ;GIVE SOME HELP
XCT OPTXCT(T1) ;DO YOUR THING
JRST SHORTD
;DONE BY XCT ABOVE
OPTXCT: PUSHJ P,SHRTPM##
PUSHJ P,SHRTST##
JRST QUICK
PUSHJ P,FILOPT##
JRST PVQCK
PUSHJ P,SHRTRF##
PUSHJ P,SHRTID##
PVQCK::
SETOM OPTQIK##
JRST QUICK
;SHORT HELP
ONCHLP: MOVEI T1,[ASCIZ "
CHANGE,DESTROY,GO,LONG,QUICK,REFRESH,UNITID
/H for help
"]
JRST ONCHL1 ;TYPE THAT OUT
LNGMSG: ASCIZ "
CHANGE - Change disk parameters
DESTROY - Rebuild all disks. Deletes all files, sets all defaults.
GO - Start the system if all is OK.
LONG - Enters long dialogue
QUICK - Same as GO but do not ask about OFF-LINE devices.
REFRESH - Refresh selected structures
UNITID - Change unit ID's
"
LNGHLP: MOVEI T1,LNGMSG
ONCHL1: PUSHJ P,ICONM
PUSHJ P,OPOUT
JRST SHORTD
OPTTAB: SIXBIT /CHANGE/
SIXBIT /DESTRO/
SIXBIT /GO/
SIXBIT /LONG/
SIXBIT /QUICK/
SIXBIT /REFRES/
SIXBIT /UNITID/
OPTLEN==.-OPTTAB
;THE LONG DIALOGUE BEGINNETH HERE.....
LONGD: SETOM (P) ;SET "ALTMOD"-TYPED FLAG
PUSHJ P,FILOPT## ;GO THROUGH THE REFRESH DIALOGUE(S) [LEVEL C]
; TYPE STATE OF WHOLE DISK SYSTEM, THEN
; ACCEPT CHANGES TO UNITS AND STR'S & REFRESH [LEVEL D]
QUICK: PUSHJ P,RESKON ;RESTORE SETKON ROUTINE IN CASE TWICE
; IS RESTARTED
EXIT ;ALL DONE
;SUBROUTINE TO MARK UNIT DOWN WITHOUT REMOVING IT FROM LIST OF UNITS
; USED TO BE USED ONLY WHEN SCRATCH FILE IN USE SO UNITS ALWAYS IN SAME
; PLACE IN FILE, BUT SINCE HIGH AVAILABLITY (602), ALL UNITS REMAIN
; IN UNIT DATA BLOCK CHAIN, SO THIS ROUTINE USED ALL THE TIME.
FLGDW: MOVEI T1,UNVDWN## ;VALUE TO MARK UNIT DOWN
DPB T1,UNYUST## ;STORE IN UNIT STATE
MOVSI T1,UNPOFL## ;UNIT OFF LINE
IORM T1,UNIDES##(U) ;STORE
SETZB T1,UNILOG##(U) ;CLEAR UNILOG
DPB T1,UNYSIC## ;AND SATS IN CORE
SETOM UNISUN##(U) ;NOT IN ACTIVE SWAPPING LIST NOW
POPJ P,
;FNDNAM--ROUTINE TO SEARCH FOR ABBREV. NAME IN TABLE
;CALL MOVE T1,AOBJN POINTER TO LIST OF NAMES
; MOVE T2,SIXBIT ABBREVIATION
; PUSHJ P,FNDNAM
;NON-SKIP IF UNKNOWN (T1=0) OR DUPLICATE (T1 .NE. 0)
;SKIP RETURN IF FOUND WITH T1=INDEX IN TABLE
FNDNAM::PUSHJ P,SAVE3 ;SAVE P1,P2
SETZB P1,T4 ;CLEAR MATCH MASK AND POINTER
MOVSI P2,(77B5) ;START AT LEFT END
FNDNM1: TDNE T2,P2 ;SEE IF SPACE
IOR P1,P2 ;NO--IMPROVE MASK
LSH P2,-6 ;MOVE RIGHT ONE CHAR
JUMPN P2,FNDNM1 ;LOOP FOR SIX CHARS
SETOM P2 ;SET ABBREV COUNTER
MOVE P3,T1 ;SAVE POINTER
FNDNM2: MOVE T3,(T1) ;GET NEXT CANDIDATE
XOR T3,T2 ;COMPARE
JUMPE T3,FNDNMW ;WIN
AND T3,P1 ;MASK IT
JUMPN T3,FNDNM3 ;LOOSE
MOVE T4,T1 ;WIN--SAVE POINTER
AOS P2 ;COUNT SUCCESS
FNDNM3: AOBJN T1,FNDNM2 ;LOOP FOR ALL ENTRIES
MOVE T1,T4 ;RESTORE POSSIBLE WINNER
JUMPN P2,CPOPJ ;JUMP IF UNSUCCESSFUL
FNDNMW: SUB T1,P3 ;COMPUTE INDEX
TLZ T1,-1 ;REMOVE JUNK
JRST CPOPJ1 ;SKIP RETURN
;SUBROUTINE TO SEE IF SHOULD KEEP UNIT FOR READING OR WRITING
;FOR READING MUST BE 1,2 OR SINGLE ACCESS
;FOR WRITING MUST BE SINGLE ACCESS OR 1,2 AND NOT IN A FILE STRUCTURE
KEEPWT: SKIPE FILFLG ;SKIP UNLESS USING SCRATCH FILE
JRST KEEPW1 ;OK TO WRITE
MOVE T1,UNINAM##(U) ;NAME OF UNIT
MOVEM T1,CHRBUF ;STORE IN DSKCHR ARGUMENT BUFFER
MOVE T1,[XWD .DCSNM+1,CHRBUF]
DSKCHR T1, ;FIND OUT ABOUT UNIT
POPJ P, ;NOT A DISK?
TLNN T1,UNPSAF## ;SKIP IF SINGLE ACCESS - OK TO WRITE
SKIPN CHRBUF+.DCSNM ;NO, OK IF NOT IN AN STR
JRST KEEPW1 ;OK TO WRITE ON THIS UNIT
MOVEI T1,[ASCIZ .Can't write.]
PUSHJ P,UEMSG ;TELL USER CAN'T WRITE THAT UNIT
JRST KEEPRD ;BUT KEEP IF FOR READING IF POSSIBLE
KEEPW1: MOVSI T1,UNPSAF## ;OK TO WRITE, BORROW BIT AS WRITABLE FLAG
IORM T1,UNIDES##(U) ;SET WRITABLE FLAG IN OUR UNIT DATA BLOCK
KEEPRD: MOVE T1,(U) ;PHYSICAL UNIT NAME
CALLI T1,64 ;(DEVNAM UUO) IS IT A REAL UNIT?
POPJ P, ;NO, MUST BE 2ND PORT OF DUAL-PORTED DRIVE
SETOM UNILOG##(U) ;SET FLAG TO KEEP UNIT
MOVE T1,OURPPN ;GET OUR PPN
SKIPN FILFLG ;SKIP IF SCRATCH FILE - OK TO READ
CAMN T1,FFAPPN## ;OK IF WE HAVE PRIVILEGES
POPJ P, ;USER HAS PRIVILEGES TO ACCESS UNIT
MOVE T2,UNINAM##(U) ;GET NAME OF UNIT
MOVEI T1,T2 ;PTR TO DSKCHR ARGS
DSKCHR T1, ;GET CHARACTERISTICS
POPJ P, ;NOT A DISK?
TLNE T1,UNPSAF## ;SKIP IF NOT SINGLE ACCESS - CANT READ
POPJ P, ;OK, SINGLE ACCESS MEANS USER CAN READ THIS UNIT
MOVEI T1,[ASCIZ .Can't read.]
;FALL INTO UEMSG TO TELL USER CAN'T READ THAT UNIT
UEMSG: PUSH P,T1 ;SAVE TEXT POINTER
PUSHJ P,SVOSET## ;SET UP TO TYPE
POP P,T1 ;RESTORE TEXT POINTER
PUSHJ P,SCONMS## ;TYPE MESSAGE
MOVEI T3," " ;NEED A SPACE AFTER THE MESSAGE
PUSHJ P,ONCTYO ;...
PUSHJ P,SPUNAM## ;TYPE UNIT NAME
PJRST SCRLFO## ;TYPE CRLF, OUTPUT MESSAGE, AND RETURN
SUBTTL SET UP TWICE DATA BASE
;THIS ROUTINE BUILDS THE DATA STRUCTURES NEEDED BY THE ONCE CODE BASED
;ON THE CONFIGURATION OF THE RUNNING MONITOR. THIS CODE DEPENDS ON
;TWICE BEING ASSEMBLED WITH THE SUPPLIED CONFIGURATION FILE AND ALSO
;ON FTAUTC BEING TRUE.
IFN FTAUTC,<
SETDAT: HRRZS SYSKON## ;ZERO LINK TO FIRST KONTROLLER IN SYSTEM
HRRZS SYSUNI## ;ZERO LINK TO FIRST UNIT IN SYSTEM
SETZ P2, ;START WITH FIRST UNIT
SETDT1: SYSPHY P2, ;ASK FOR NEXT PHYSICAL UNIT
SETZ P2, ;ASSUME DONE IF ERROR
JUMPE P2,CPOPJ ;RETURN IF WE'VE HIT THE END
MOVEM P2,CHRBUF ;SAVE THE UNIT NAME
MOVE T1,[.DCMAX,,CHRBUF] ;POINT AT THE UNIT NAME
DSKCHR T1, ;ASK MONITOR ABOUT IT
JRST SETDT1 ;DUH?
MOVEM T1,CHRBTS ;SAVE CHARACTERISTICS BITS FOR LATER
PUSHJ P,BLDUDB ;BUILD A UDB (AND CHN/KDB) FOR THIS UNIT
JRST SETDT1 ;LOOP FOR OTHER UNITS
> ;END IFN FTAUTC
;ROUTINE TO BUILD A UDB (AND A CHN/KDB IF NEEDED) FOR A UNIT.
;CALL:
; P2/ SIXBIT UNIT NAME
; PUSHJ P,BLDUDB
;RETURN:
; CPOPJ ALWAYS
BLDUDB: HLLZ T1,P2 ;GET SIXBIT KONTROLLER NAME
PUSHJ P,FNDKDB ;FIND THE KONTROLLER DATA BLOCK
SKIPA ;NONE, MUST BUILD ONE
JRST BLDUD1 ;FOUND IT, GO BUILD UDB
PUSHJ P,BLDKDB ;BUILD THE KONTROLLER DATA BLOCK AND CHANNEL
; DATA BLOCK
POPJ P, ;CAN'T, CAN'T USE THIS UNIT
BLDUD1: MOVEI T2,RPULEN## ;GET LENGTH OF A UDB (ALL THE SAME LENGTH)
PUSHJ P,GETCOR ;GET THE CORE
POPJ P, ;CAN'T
MOVE U,T1 ;SAVE UDB ADDRESS
MOVEM P2,(U) ;SAVE UNIT NAME
LDB T4,[POINTR CHRBTS,DC.UNN] ;GET PHYSICAL UNIT NUMBER
DPB T4,UNYPUN## ;SAVE IN UDB
ADD T4,KONTBP##(J) ;POINT AT RIGHT KONTAB SLOT
MOVEM U,(T4) ;POINT KDB AT THIS UDB
HRRZ T1,J ;GO SEARCH FOR FIRST AND LAST UDBS IN SYSTEM
PUSHJ P,FSTLST ; ON THIS KDB
MOVEM J,UNIKON##(U) ;SET UP RH(UNIKON)
HRLM U,UNIKON##(T4) ;POINT PREVIOUS LAST AT THIS UDB
SKIPE T1 ;IF ANY UNITS ON THE KDB
HRRM T4,LASUNI## ;LINK UNISYS AT END OF CURRENT KDB'S UNITS
HLLM T4,UNIKON##(U) ;POINT THIS UDB AT FIRST
HRRO T1,P1 ;SEARCH FOR FIRST AND LAST UDBS IN SYSTEM
PUSHJ P,FSTLST ; ON THIS CHN
MOVEM P1,UNICHN##(U) ;SET UP RH(UNICHN)
HRLM U,UNICHN##(T4) ;POINT PREVIOUS LAST AT THIS UDB
HLLM T4,UNICHN##(U) ;POINT THIS UDB AT LAST
SKIPE T1,LASUNI## ;GET FORMER LAST UNIT
SKIPE UNI2ND##(T1) ;(2ND PORT ISN'T ON CHAIN)
MOVEI T1,SYSUNI##-UNISYS## ;GET OFFSET
MOVE T2,UNISYS##(T1) ;GET ITS LINK
HRLM U,UNISYS##(T1) ;POINT AT US
HLLM T2,UNISYS##(U) ;LINK US TO FORMER NEXT
MOVEM U,LASUNI## ;SAVE LAST UDB CREATED
MOVSI T1,777 ;SET UP RANDOM UDB LOCS
MOVEM T1,UNICCT##(U) ;...
MOVE T1,[LBNHOM##,,LB2HOM##] ;...
MOVEM T1,UNIHOM##(U) ;...
SETOM UNICYL##(U) ;...
HRRZ T1,CHRBTS ;GET THE DSKCHR UUO BITS
MOVEM T1,UNIDES##(U) ;SET UP AS RH OF UNIDES
SETOM UNIAJB##(U) ;...
POPJ P, ;RETURN
;ROUTINE TO FIND A KDB GIVEN A KONTROLLER NAME.
;CALL:
; T1/ SIXBIT NAME
; PUSHJ P,FNDKDB
;RETURN:
; CPOPJ IF NO MATCH
; CPOJ1 IF FOUND WITH:
; J/ KDB ADDRESS
; P1/ CHN ADDRESS
FNDKDB: MOVEI J,SYSKON##-KONNXT## ;GET DIFFERENCE
FNDKD1: HLRZ J,KONNXT##(J) ;GET NEXT KDB ADDRESS
JUMPE J,CPOPJ ;RETURN IF NO MORE (DIDN'T MATCH)
CAME T1,-1(J) ;DOES NAME MATCH VALUE WE STUFFED IN KDB?
JRST FNDKD1 ;NO, KEEP LOOKING
HRRZ P1,KONCHN##(J) ;YES, LOAD UP CHN ADDRESS
JRST CPOPJ1 ;SKIP RETURN
;ROUTINE TO CREATE A KDB AND CHN.
;CALL:
; T1/ SIXBIT NAME
; PUSHJ P,BLDKDB
;RETURN:
; CPOPJ IF COULDN'T BUILD
; CPOPJ1 IF BUILT WITH:
; J/ KDB ADDRESS
; P1/ CHN ADDRESS
BLDKDB: PUSHJ P,BLDCHN ;BUILD THE CHANNEL DATA BLOCK
POPJ P, ;NO CORE
LDB T1,[POINTR CHRBTS,DC.UNT] ;GET UNIT TYPE
LDB T2,[POINTR CHRBTS,DC.CNT] ;GET KONTROLLER TYPE
HRL T1,T2 ;COMBINE
MOVSI P4,-TYPTBL ;-VE LENGTH OF TYPE TABLE
CAME T1,TYPTAB(P4) ;LOOK FOR A MATCH
AOBJN P4,.-1 ;KEEP LOOKING
JUMPGE P4,CPOPJ ;RETURN IF NO MATCH
HLRZ T2,KDBTAB(P4) ;GET LENGTH OF KDB
PUSHJ P,GETCOR ;GET THE SPACE
POPJ P, ;NOT AVAILABLE
MOVE J,T1 ;COPY KDB ADDRESS
HRL T1,KDBTAB(P4) ;GET PROTOTYPE ADDRESS
BLT T1,-1(T2) ;COPY THE PROTOTYPE
ADDI J,-KONINT## ;SKIP THE INTERRUPT INSTRUCTIONS
HLLZM P2,-1(J) ;SAVE KONTROLLER NAME IN KDB
MOVEI T1,SYSKON##-KONNXT## ;GET DIFFERENCE
BLDKD1: HLRZ T2,KONNXT##(T1) ;LINK THIS KDB ON END OF SYSKON CHAIN
JUMPE T2,BLDKD2 ;
MOVE T1,T2 ;COPY ADDRESS
JRST BLDKD1 ;LOOK FOR END
BLDKD2: HRLM J,KONNXT##(T1) ;SET THE LINK
HRRM P1,KONCHN##(J) ;POINT KDB AT CHN
HRRZ T1,J ;GET KDB ADDRESS
ADDB T1,KONTBP##(J) ;INCLUDE KDB ADDRESS IN KONTBP
HRRM T1,KONPTR##(J) ;SET UP KONPTR
JRST CPOPJ1 ;ALL DONE
;ROUTINE TO BUILD A CHANNEL DATA BLOCK.
;CALL:
; PUSHJ P,BLDCHN
;RETURN:
; CPOPJ IF NO MEMORY AVAILABLE
; CPOPJ1 IF SUCCESS WITH:
; P1/ CHN ADDRESS
BLDCHN: MOVEI T2,LENCCB## ;LENGTH OF A CHANNEL DATA BLOCK
PUSHJ P,GETCOR ;GET THE SPACE
POPJ P, ;NONE AVAILABLE. CAN'T DO ANYTHING
MOVE P1,T1 ;P1 = CHAN ADDRESS
MOVEI T1,SYSCHN-.CHSYS##
CDB1: SKIPN T2,.CHSYS##(T1) ;LINK THIS CDB ONTO THE SYSCHN CHAIN (AT END)
JRST CDB2
HLRZ T1,T2
JRST CDB1
CDB2: HRLM P1,.CHSYS##(T1) ;SAVE CHAN ADDR
SETOM CHNBSY##(P1) ;INDICATE IDLE
AOS T1,CNFCHN ;ONE MORE CHANNEL
SUBI T1,1 ;MAKE ZERO-BASED
DPB T1,CHYSCN## ;STORE IN CHN
JRST CPOPJ1 ;SKIP RETURN
;ROUTINE TO FIND FIRST AND LAST UDBS OF A CERTAIN TYPE IN SYSTEM
;CALL T1=0,,KDB OR T1=-1,,CDB
;RETURNS T4=1ST,,LAST (COULD BE THE SAME. IF NONE YET RETURNS T4=UDB,,UDB)
;RETURNS T1=0 IF FIRST SUCH UDB
FSTLST: PUSHJ P,SAVE1
MOVE P1,T1 ;SAVE ARGUMENT
PUSHJ P,FSTMAT ;FIND A MATCH
JRST FSTLS2 ;FOUND IT
FSTLS1: MOVE T4,U ;NO MATCH. 1ST=LAST=US
HRL T4,U
POPJ P,
FSTLS2: HRL T4,T3 ;SAVE 1ST FOUND IN LH(T4)
FSTLS3: HRR T4,T3 ;SAVE THIS AS LAST
PUSHJ P,FSTMA3 ;NEXT UDB A MATCH?
JRST FSTLS3 ;YES, SAVE UDB ADDR
POPJ P, ;NO MORE MATCHES. DONE
;ROUTINE TO SEE IF WE HAVE A MATCH
;RETURNS CPOPJ IF YES, CPOPJ1 IF NO
FSTMAT: HLRZ T1,SYSKON## ;START AT FIRST KDB IN SYSTEM
FSTMA1: MOVE F,T1 ;SAVE LOC OF KDB
MOVE T1,KONTBP##(T1) ;AOBJN POINTER TO UNITS ON KDB
FSTMA2: SKIPN T3,(T1) ;UDB THERE?
FSTMA3: AOBJN T1,.-1 ;NO, TRY NEXT
JUMPE T3,FSTMA4 ;FIND A UDB? NOT IF 0
JUMPL P1,[HRRZ T2,UNICHN##(T3)
JRST .+2] ;LOOKING FOR UNICHN IF NEGATIVE
HRRZ T2,UNIKON##(T3) ;POSITIVE - LOOKING FOR UNIKON
CAIN T2,(P1) ;MATCH?
POPJ P, ;YES, RETURN
JUMPN T2,FSTMA4 ;NO. FOUND THIS UNIT?
AOBJN T1,FSTMA2 ;YES. KEEP GOING IF NOT UNIT 7
FSTMA4: HLRZ T1,KONNXT##(F) ;STEP TO NEXT KDB
JUMPN T1,FSTMA1 ;LOOK FOR UNIT MATCH IF IT EXISTS
JRST CPOPJ1 ;NO MATCH. SKIP
;ROUTINE TO OBTAIN CORE FOR A CHN/KDB/UDB.
;CALL:
; T2/ NUMBER OF WORDS DESIRED
; PUSHJ P,GETCOR
;RETURN:
; CPOPJ IF NOT AVAILABLE
; CPOPJ1 WITH:
; T1/ ADDRESS OF CORE OBTAINED
GETCOR: MOVE T1,.JBFF## ;GET CURRENT FIRST FREE
ADDB T2,.JBFF## ;ADVANCE ALLOCATION
SUBI T2,1 ;BACK OFF BY ONE
CAMGE T2,.JBREL## ;NEED TO EXPAND?
JRST CPOPJ1 ;NO, RETURN
CORE T2, ;ASK FOR IT
POPJ P, ;ERROR
MOVE T2,.JBFF## ;GET NEW END ADDRESS
JRST CPOPJ1 ;SUCCESS
;TABLE OF KONTROLLER,,UNIT TYPES RETURNED BY DSKCHR UUO.
;USED AS AN INDEX INTO KDBTAB.
TYPTAB::XWD .DCCRP, .DCUR4 ;RP04
XWD .DCCRP, .DCUR6 ;RP06
XWD .DCCRP, .DCUR3 ;RM03
XWD .DCCRP, .DCUR7 ;RP07
XWD .DCCRN, .DCUN0 ;RP20
IFN FTCIDSK,<
XWD .DCCRA, .DCU80 ;RA80
XWD .DCCRA, .DCU81 ;RA81
XWD .DCCRA, .DCU60 ;RA60
>; END IFN FTCIDSK
;TABLE OF PROTOTYPE KDB LENGTH,,ADDRESS INDEXED BY TYPTAB INDEX.
KDBTAB: RPKLEN##,, RPXKDB## ;RP04
RPKLEN##,, RPXKDB## ;RP06
RPKLEN##,, RPXKDB## ;RM03
RPKLEN##,, RPXKDB## ;RP07
RNKLEN##,, RNXKDB## ;RP20
IFN FTCIDSK,<
RAKLEN##,, RAXKDB## ;RA80
RAKLEN##,, RAXKDB## ;RA81
RAKLEN##,, RAXKDB## ;RA60
>; END IFN FTCIDSK
TYPTBL==.-TYPTAB ;LENGTH OF TABLE
SUBTTL TTY INPUT SUBROUTINES
YESNO:: PUSHJ P,ASKGET ;ASK QUESTION, GET ANSWER
POPJ P,0 ;JUST C-R
PUSHJ P,ONCTYI ;GET NEXT CHAR
TRZ T3,40 ;FIRST CHAR OF RESPONSE (U.C.)
CAIN T3,"Y" ;WAS IT A Y ?
AOS 0(P) ;YES. SKIP
POPJ P, ;NO, MAYBE IT WAS "N". SO DON'T SKIP
ASKGET: PUSHJ P,ICONM ;OUTPUT THE QUESTION
PUSHJ P,OPOUT
PJRST GETLIN ;GET ANSWER
;SUBROUTINE TO READ A LINE
; CALL: PUSHJ P,GETLIN
; JUST A CR TYPED IN
; NORMAL RETURN (NOT A BLANK LINE)
GETLIN::MOVE T1,LINEP ;BYTE POINTER TO LINE
MOVEM T1,ONCTIP
SETZ J,
GET1: INCHWL T3 ;READ NEXT CHAR
CAIN T3,177 ;SKIP IF NOT RUBOUT
JRST GET1 ;IGNORE RUBOUTS
CAIE T3,33 ;SKIP IF ALTMODE
CAIL T3,175 ;SKIP IF NOT ALTMODE
JRST GETLN1 ;JUMP IF ALTMODE
CAIL T3,140 ;SKIP IF NOT LOWER CASE
TRZ T3,40 ;CONVERT TO UPPER CASE
IDPB T3,T1 ;STORE IN LINE BUFFER
CAIE T3,15 ;SKIP IF CARRIAGE RETURN
AOJA J,GET1 ;NO, COUNT CHARS
INCHWL T3 ;READ LINE FEED FOLLOWING
GET2: IDPB T3,T1 ;STORE LINE FEED
SETZ T3, ;NULL FOR END OF LINE
IDPB T3,T1 ;STORE THE NULL
JUMPN J,CPOPJ1 ;JUMP IF NON-BLANK LINE
POPJ P, ;NO, EMPTY LINE
GETLN1: HRROS J ;NOTE PRESENCE OF ALTMODE
MOVEI T3,15 ;STORE CRLF
IDPB T3,T1 ;STORE CR
MOVEI T3,12 ;LF
JRST GET2 ;STORE THAT AND EXIT
; SUBROUTINE TO INPUT A [P,PN]
PPNERR: MOVEI T1,[ASCIZ \Bad [P,PN] typed try again: \]
GTPPN:: PUSHJ P,ASKGET ;ASK QUESTION, GET ANSWER
POPJ P,
PUSHJ P,ALTM## ;DID HE TYPE ESC
PUSHJ P,SKIPS ;EAT LEADING SPACES
JRST PPNERR ;ERROR
CAIE T3,"[" ;BEGINNING OF PPN
JRST PPNERR ;NO, TRY AGAIN
PUSHJ P,GETOCT ;GET THE FIRST OCTAL NUMBER
JUMPE T2,PPNERR ;NULL PROJECT NUMBER IS BAD
TLNN T2,777777 ;TOO BIG?
CAIE T3,"," ;OR A BAD P,PN SEPARATER
JRST PPNERR ;YEP
PUSH P,T2 ;SAVE IT
PUSHJ P,GETOCT ;GET THE PROGRAMMER NUMBER
POP P,T1 ;GET PROJECT NUMBER BACK
JUMPE T2,PPNERR ;NULL PROGRAMMER NUMBER IS BAD
CAIE T3,"]" ;CHECK FOR LEGAL TERMINATER
CAIN T3,0 ;CRLF IS OK TOO
TLNE T2,777777 ;TOO BIG?
JRST PPNERR ;YEP
HRL T1,T2 ;GET PROGRAMMER NUMBER
MOVSS T1 ;SET IT UP AS [PROJ,PROG]
AOS (P) ;GIVE A SKIP
POPJ P, ;AND RETURN
GETOCT: MOVEI T2,777777 ;ASSUME WILD
PUSHJ P,COMTYS ;GET FIRST CHARACTER
CAIE T3,"*" ;WILD?
TDZA T2,T2 ;NO - CLEAR RESULT
GETOC1: PUSHJ P,COMTYS ;NEXT CHAR
CAIL T3,"0" ;IN RANGE?
CAILE T3,"7"
POPJ P,
LSH T2,3 ;CLEAR NULL DIGIT
SUBI T3,"0" ;CONVERT TO BINARY
ADDI T2,(T3) ;ADD TO TOTAL
JRST GETOC1 ;LOOP UNTIL DONE
;ROUTINE TO INPUT DISK SET NUMBER(S)
IFN FTSETS,<
GETSE0: MOVEI T1,[ASCIZ |Bad response, try again
|]
GETSET::PUSHJ P,ASKGET ;ASK QUESTION, GET RESPONSE
POPJ P, ;<CR> TYPED
PUSHJ P,ALTM## ;ALLOW ALTMODE COP-OUT
MOVE P1,ONCTIP ;GET CURRENT BYTE POINTER
PUSHJ P,DECIN ;TRY TO READ A NUMBER
JRST GETSE1 ;BAD RESPONSE, MAYBE "ALL"
JRST GETSE1 ;DITTO
CAIL T2,^D1 ;IN LEGAL RANGE?
CAILE T2,^D36 ;...
JRST GETSE0 ;NO, COMPLAIN AND ASK AGAIN
MOVE T1,T2 ;GET RESPONSE IN T1
JRST CPOPJ1 ;SKIP RETURN
GETSE1: MOVEM P1,ONCTIP ;RESTORE PREVIOUS BYTE POINTER
PUSHJ P,CTEXT ;GET RESPONSE
MOVSS T2 ;SWAP HALVES
CAIE T2,'ALL' ;VALID RESPONSE?
JRST GETSE0 ;NO, COMPLAIN AND ASK AGAIN
SETZ T1, ;GET A ZERO
JRST CPOPJ1 ;SKIP RETURN
>; END IFN FTSETS
;ROUTINE TO RETURN NEXT ALPHANUMERIC STRING
; IN COMMAND LINE (SIXBIT)
;CALL: PUSHJ P, CTEXT
; SIXBIT STRING RETURN LEFT JUSTIFIED IN AC T2
CTEXT:: PUSHJ P,SKIPS ;CALL HERE IF AT START OF LINE
POPJ P, ;NOTHING THERE.
CTEXT1::PUSHJ P,SKIPS1 ;SKIP LEAD SPACES,TABS,NULLS AND CLEAR T2
POPJ P, ;NOTHING THERE.
SKIPA W,[POINT 6,T2]
CTEX0: PUSHJ P,COMTYS ;ROUTINE IN SCNSER TO PICK UP CHAR.
CTEX1: PUSHJ P, CTEX ;IS IT ALPHANUMERIC
POPJ P,0 ;NO
TRC T3,40 ;CONVERT TO SIXBIT
TLNE W,770000 ;SIX CHARS YET?
IDPB T3,W ;NO. BUILD WORD
JRST CTEX0 ;LOOP FOR MORE
;SCAN FOR ALPHANUMERIC CHAR IN T3
CTEX: CAILE T3,"Z"+40 ;GREATER THAN LC Z?
POPJ P,0 ;YES. NOT SIXBIT.
CAIL T3,"A"+40 ;LOWER CASE LETTER?
TRZ T3,40 ;YES. MAKE UPPER CASE.
CAIL T3, "0"
CAILE T3, "Z" ;LETTERS ARE LARGER THAN NOS.
POPJ P,0 ;NEITHER
CAILE T3, "9"
CAIL T3, "A"
JRST CPOPJ1 ;LETTER OR NUMBER RETURN
POPJ P,0 ;NOT-LETTER/NUMBER RETURN
CTXDEV::PUSHJ P,CTEXT1 ;GET A WORD
CAIN T3,":" ;AND IF TERM IS A COLON,
PUSHJ P,COMTYS ;DISCARD IT
POPJ P,0 ;RETURN FROM CTXDEV
;SUBROUTINE TO READ A DECIMAL NUMBER
;VALUES T2=DECIMAL NUMBER
DECIN:: PUSHJ P,SKIPS ;SKIP TO FIRST NON-BLANK CHAR
POPJ P,
MOVEI P4,12 ;DECIMAL RADIX
JRST ANYRIN
;SUBROUTINE TO READ AN OCTAL NUMBER
;VALUES T2=OCTAL NUMBER
OCTIN:: PUSHJ P,SKIPS
POPJ P,
PUSHJ P,ANYR1
POPJ P,
JRST .+2
POPJ P,
MOVEI P4,10
ANYRIN: PUSHJ P,SKIPS1
POPJ P,
OCT0: CAIL T3,"0" ;SKIP IF NOT A LEGAL DIGIT
CAIL T3,"0"(P4) ;SKIP IF LEGAL DIGIT
JRST ANYR1
IMUL T2,P4 ;BUILD NUMBER
ADDI T2,-"0"(T3)
PUSHJ P,ONCTYI ;READ NEXT CHAR
JRST OCT0 ;AND LOOP TILL ILLEGAL CHAR
ANYR1: CAILE T3,40 ;SKIP IF BREAK CHAR
CAIN T3,","
JRST CPOPJ2
CAIE T3,"["
CAIN T3,"]"
JRST CPOPJ2
CAIN T3,"-"
JRST CPOPJ2
JRST CPOPJ1
;SUBROUTINE TO GET THE NEXT NON-BLANK CHAR
;CALL: PUSHJ P,SKIPS
; NON-SKIP RETURN IF BREAK CHAR
; SKIP RETURN IF NOT BREAK CHAR
SKIPS:: PUSHJ P,ONCTYI ;GET NEXT CHAR
SKIPS1::SETZ T2,
MOVE T3,TTCMCH ;GET THIS CHAR
CAIE T3," " ;SKIP IF A TAB
CAIN T3," " ;NO SKIP IF SPACE
JRST SKIPS ;SKIP THIS CHAR
CAIL T3,40 ;SKIP IF A BREAK CHAR
CPOPJ1::AOS (P) ;SKIP RETURN IF NOT A BREAK CHAR
CPOPJ:: POPJ P,
CPOPJ2::AOS (P)
JRST CPOPJ1
CAMCPU::SETZ T4,
POPJ P,
;SUBROUTINE TO GET NEXT CHAR BUT CONVERT ; TO LF
;VALUES T3=NEXT CHAR
COMTYS: PUSHJ P,ONCTYI
CAIN T3,";" ;SKIP IF NOT ;
MOVEI T3,12
MOVEM T3,TTCMCH
POPJ P,
;SUBROUTINE TO GET NEXT CHAR FROM TTY LINE BUFFER
;VALUES T3=ASCII CHAR
COMTYI::! ;MAKE ONCE/TWICE WORK THE SAME FOR CHARACTER I/O
ONCTYI: ILDB T3,ONCTIP
MOVEM T3,TTCMCH ;SAVE CHAR FOR LATER
POPJ P,
TPOPJ1::AOS -1(P)
TPOPJ:: POP P,T1
POPJ P,
UPOPJ1::AOS -1(P) ;GIVE SKIP RETURN
LPOPJ::
UPOPJ:: POP P,U ;RESTORE U
POPJ P, ;RETURN
T2POPJ::POP P,T2 ;RESTORE T2
POPJ P, ;RETURN
JPOPJ1::AOS -1(P)
JPOPJ:: POP P,J
POPJ P,
SUBTTL TTY OUTPUT ROUTINES
;SUBROUTINE TO OUTPUT CARRIAGE RETURN LINE FEED
CRLF:: MOVEI T1,[ASCIZ /
/]
PJRST CONMES ;OUTPUT CARRIAGE RETURN LINE FEED
;SUBROUTINE TO INITIALIZE OUTPUT BUFFER AND TYPE AN ASCII LINE
;ARGS T1=ADDR OF ASCII LINE
ICONM:: PUSHJ P,OTSET ;INITIALIZE BUFFER
;SUBROUTINE TO TYPE AN ASCII LINE
;ARGS T1=ADDR OF ASCII LINE
CONMES::HRLI T1,(POINT 7,) ;MAKE T1 A BYTE POINTER
CON0: ILDB T3,T1 ;NEXT CHAR
JUMPE T3,CPOPJ ;EXIT AT NULL
PUSHJ P,ONCTYO ;TYPE CHAR
JRST CON0 ;LOOP TILL NULL
;SUBROUTINE TO INITIALIZE OUTPUT BUFFER
OTSET:: MOVEI T3,ONCTSZ ;SIZE OF BUFFER
MOVEM T3,ONCCNT ;SO CANT OVERFLOW
MOVE T3,LINEP ;BYTE POINTER
MOVEM T3,ONCTOP
POPJ P,
;SUBROUTINE TO ACTUALLY OUTPUT THE OUTPUT BUFFER
OPOUT:: SKPINL ;CLEAR CONTROL O FLAG
JFCL ;DONT CARE ABOUT INPUT
OPOUTX: MOVEI T3,0
IDPB T3,ONCTOP ;MAKE SURE NULL AT END
OUTSTR LINBUF ;OUTPUT BUFFER
POPJ P,
;SUBROUTINE TO TYPE SIXBIT STRING IN T2
;ARGS T2=SIXBIT STRING
PRNAME::SETZ T1,
LSHC T1,6 ;T1=NEXT CHAR
JUMPE T1,CPOPJ ;EXIT AT END OF STRING
MOVEI T3," "-' '(T1) ;CONVERT TO ASCII
PUSHJ P,ONCTYO ;STORE IN BUFFER
JRST PRNAME ;LOOP
;SUBROUTINE TO TYPE A DECIMAL OR OCTAL NUMBER
;ARGS T1=NUMBER TO TYPE
RADX10::SKIPA T3,[12]
PRTDI8::MOVEI T3,10
PRTRDX: IDIV T1,T3
HRLM T2,(P)
JUMPE T1,.+2
PUSHJ P,PRTRDX
HLRZ T1,(P)
MOVEI T3,"0"(T1)
PJRST ONCTYO
;SUBROUTINE TO TYPE A QUESTION MARK
PRQM:: MOVEI T3,"?"
PJRST ONCTYO ;TYPE QUESTION MARK
;SUBROUTINE TO STORE A CHAR IN TTY OUTPUT BUFFER
;ARGS T3=CHAR
COMTYO::
ONCTYO: SOSLE ONCCNT ;SKIP IF BUFFER FULL
IDPB T3,ONCTOP ;STORE CHAR IN BUFFER
POPJ P,
SUBTTL DISK I/O ROUTINES
;SUBROUTINE TO HANDLE USER MODE DISK I/O
;ARGS F=ADDR OF DDB
; S=STATUS BITS (IO=0 FOR READ, =1 FOR WRITE)
;VALUES S=STATUS FROM GETSTS
USRDIO::SKIPN FILFLG ;SKIP IF USING SCRATCH FILE
JRST USRDI1 ;NO, REGULAR WAY
SKIPG FILFLG ;SKIP IF FILE OPEN
PUSHJ P,OPNFIL ;NO, OPEN IT
PUSHJ P,FNDUNI ;FIND 1ST BLOCK FOR THIS UNIT
STOPCD .,HALT,NM1, ;NO SUCH UNIT?
IMULI T1,BLKPUN ;TIMES BLOCKS=BEGINNING OF THIS UNIT
MOVE T2,DEVBLK##(F) ;BLOCK ON UNIT
CAILE T2,BLKPUN-1 ;SKIP IF IN RANGE
MOVEI T2,BLKPUN-1 ;DONT OVERFLOW TO FOLLOWING UNITS
ADD T1,T2 ;ADD IN BLOCK ON UNIT, = BLOCK FOR IO
SETZ T2, ;CLEAR END OF IOWD LIST
TLNE S,IO ;SKIP IF READ, NOT IF WRITE
JRST USRDI0 ;DO WRITE
USETI DSK,1(T1) ;FIRST BLOCK OF FILE IS BLOCK 1, NOT 0
MOVE T1,DEVDMP##(F) ;GET IOWD
INPUT DSK,T1 ;READ BLOCK
JRST USRDFN ;FINISH UP
USRDI0: USETO DSK,1(T1) ;1ST BLOCK OF FILE IS BLOCK 1, NOT 0
MOVE T1,DEVDMP##(F) ;GET IOWD
OUTPUT DSK,T1 ;WRITE BLOCK
JRST USRDFN ;FINISH UP
USRDI1: CAME U,CURUNI ;SKIP IF UNIT OPEN
PUSHJ P,OPNUNI ;NO, OPEN UNIT
SKIPA T1,DEVDMP##(F) ;GET IOWD
POPJ P, ;CANT WRITE UNIT
TLNE S,IO ;SKIP IF READ
JRST USRDO ;NO, WRITE
MOVE T2,DEVBLK##(F) ;SET TO READ THE BLOCK
TXO T2,INSVL.(DSK,SU.SCH) ;SET CHANNEL NUMBER
SUSET. T2, ;POSITION
JRST USRDOE ;ERROR
SETZ T2, ;TERMINATE I/O LIST
INPUT DSK,T1 ;AND READ IT
JRST USRDFN ;FINISH UP
USRDO: MOVSI T2,UNPSAF##
TDZN T2,UNIDES##(U) ;SKIP IF MAY WRITE THIS UNIT
JRST USRDOE ;NO, ERROR
MOVE T2,DEVBLK##(F) ;SET TO WRITE THE BLOCK
TXO T2,INSVL.(DSK,SU.SCH) ;SET CHANNEL NUMBER
SUSET. T2, ;POSITION
JRST USRDOE ;ERROR
SETZ T2, ;TERMINATE I/O LIST
OUTPUT DSK,T1 ;OUTPUT IT
USRDFN: GETSTS DSK,T1 ;GET STATUS
HRR S,T1 ;SAVE IN S
TRZE T1,740000 ;CLEAR ERROR BITS AND SKIP IF NO ERRORS
SETSTS DSK,(T1) ;CLEAR ERRORS IN STATUS FOR FUTURE I/O
USRDX: POPJ P, ;RETURN
USRDOE: TRO S,740000
JRST USRDX
OPNUNI: PUSHJ P,SAVE3
MOVEI P1,17
MOVE P2,UNINAM##(U)
SETZ P3,
OPEN DSK,P1
JRST OPNUNN ;CANT DO I/O IF CANT OPEN
MOVEM U,CURUNI ;REMEMBER OPEN UNIT
POPJ P,
OPNUNN: SETZM CURUNI ;DONT REMEMBER UNIT NAME
JRST CPOPJ1 ;AND NOTE CANT WRITE
;SUBROUTINE TO OPEN SCRATCH FILE
OPNFIL: INIT DSK,17 ;START BY OPENING DSK
SIXBIT .DSK.
0
STOPCD .,HALT,NM2,
MOVE T1,[SIXBIT .TWICE.] ;FILE NAME
MOVEM T1,TWCFIL ;STORE FILE NAME
MOVSI T1,'BIN' ;EXT
MOVEM T1,TWCFIL+1 ;STORE EXT
SETZM TWCFIL+2 ;CLEAR ATTRIBUTES
MOVEI T1,RETRYN ;NUMBER OF TIMES TO RETRY FOR FBM
MOVEM T1,RETRYC ;SET RETRY COUNTER
OPNFL1: SETZM TWCFIL+3 ;CLEAR DIRECTORY
LOOKUP DSK,TWCFIL ;SEE IF FILE ALREADY EXISTS
JRST OPNFL2 ;NO, MUST CREATE IT
SETZM TWCFIL+3 ;CLEAR DIRECTORY AGAIN
ENTER DSK,TWCFIL ;SET FOR UPDATE
JRST OPNFL3 ;CANT UPDATE?
PUSH P,U ;SAVE U
SETZ U, ;LOOK FOR END OF LIST
PUSHJ P,FNDUNI ;TO GET NUMBER OF UNITS IN OUR "SYS"
;*** NORMALLY WOULD BE A SKIP RETURN POSSIBLE, BUT CAN NEVER FIND UNIT
;0 BECAUSE 0 IS END OF LIST
IMULI T1,BLKPUN ;TIMES BLOCKS FOR EACH UNIT
USETO DSK,1(T1) ;ALLOCATE THAT MANY BLOCKS AND CLEAR
HRRZS FILFLG ;NOTE FILE READY TO WRITE
JRST UPOPJ ;RESTORE U AND RETURN
OPNFL2: HRRZ T1,TWCFIL+1 ;GET ERROR CODE
JUMPN T1,OPNFL4 ;CANT GO ON
SETZM TWCFIL+3 ;CLEAR DIRECTORY
ENTER DSK,TWCFIL ;TRY TO CREATE FILE
JRST OPNFL3 ;CANT
CLOSE DSK, ;FILE NOW EXISTS
JRST OPNFL1 ;TRY TO UPDATE AGAIN
OPNFL3: HRRZ T1,TWCFIL+1 ;GET ERROR CODE
CAIE T1,14 ;SKIP IF NO ROOM
CAIN T1,3 ;SKIP IF NOT FILE BEING MODIFIED
SOSG T1,RETRYC ;DECREMENT RETRY COUNTER
OPNFL4: STOPCD .,HALT,NM3, ;DONT RETRY OR TOO MANY RETRIES
CAIN T1,RETRYN-^D10 ;SKIP UNLESS 10 SECONDS LATER
OUTSTR [ASCIZ .% Wait please.]
MOVEI T1,1 ;1 SECOND FOR SLEEP
SLEEP T1, ;WAIT A WHILE
JRST OPNFL1 ;TRY AGAIN
;SUBROUTINE TO FIND POSITION OF UNIT IN LIST OF UNITS
;ARGS U=ADDR OF UNIT DATA BLOCK
;VALUES T1=POSITION OF UNIT IN LIST OF UNITS (0=1ST, ETC)
;NONSKIP IF UNIT NOT FOUND, T1=NUMBER OF UNITS
;SKIP IF UNIT FOUND, T1 SET UP
FNDUNI: SETZ T1, ;CLEAR T1 IN CASE NO UNITS
HLRZ T2,SYSUNI## ;ADDR OF 1ST UNIT IN SYS
FNDUN1: JUMPE T2,CPOPJ ;JUMP IF THAT WAS LAST UNIT
CAMN T2,U ;SKIP IF NOT DESIRED UNIT
JRST CPOPJ1 ;FOUND UNIT, GOOD RETURN
HLRZ T2,UNISYS##(T2) ;MOVE TO NEXT UNIT IN SYS
AOJA T1,FNDUN1 ;COUNT UNITS
STRTAD==200000
RELABP==40000
;SUBROUTINE TO FIND N CONSECUTIVE 0'S IN A TABLE
;ENTER WITH P1 = AOBJN WORD TO THE TABLE
;P2 = PREVIOUS BEST SO FAR
;RH(P3)= HOW MANY, BIT STRTAD =1 IF START LOC SPECIFIED
;LH(P3) HAS BITS 0,1,2 USED BY FILSER
;EXIT CPOPJ1 IF FOUND, WITH P4 = WHERE THE HOLE IS, P1=UPDATED POINTER
;EXIT CPOPJ IF UNSUCCESSFUL, P2 = LARGEST HOLE FOUND
;P2,P4 CHANGED
;NOTE--SHOULD NOT CONTAIN A METER POINT SINCE IS CALLED
; BY ENDSTS ON 407 START BEFORE METINI IS CALLED
GETZ:: PUSHJ P,SETR ;ZERO R IF OLD STYLE CALL
GETZ0: TLNE P3,STRTAD ;START LOC SPECIFIED? (NOTE THAT ENTRY TO ROUTINE
; IS AT GETZR IF START LOC SPECIFIED)
POPJ P, ;YES, ERROR RETURN
HRRM P1,-2(P) ;STORE ABOJN POINTER IN INDIRECT WORD
SETCM T1,@-2(P) ;WORD TO INVESTIGATE
JRST GETZA ;SKIP CALL TO SETR
GETZX:: PUSHJ P,SETR ;SETUP INDIRECT POINTER
GETZA: MOVEI T4,^D36 ;NO. SET UP COUNT
JUMPE T1,GETZ4 ;FULL IF 0
JUMPG T1,GETZ3 ;1ST BIT UNAVAILABLE IF POSITIVE
GETZ1: SETCA T1, ;SET TO REAL CONTENTS
JFFO T1,.+2 ;COUNT THE NUMBER OF 0'S
MOVEI T2,^D36 ;36 OF THEM
JRST GETZB ;SKIP CALL TO SETR
GETZR:: PUSHJ P,SETR ;SETUP INDIRECT POINTER TO THE BIT TABLE
GETZB: MOVE T3,T2 ;SHIFT COUNT (T3 CAN BE .GT. 36 AT GETZ2)
MOVEM P1,P4 ;SAVE POSITION IN P4
HRLM T4,P4 ;LOC OF HOLE
GETZ2: CAIL T3,(P3) ;FOUND ENOUGH?
JRST CPOPJ1 ;YES. GOOD RETURN
CAILE T3,(P2) ;NO. BEST SO FAR?
HRRI P2,(T3) ;YES. SAVE IT
SUBI T4,(T2) ;DECREASE POSITION COUNTER
JUMPLE T4,GETZ5 ;0'S ON END
TLNE P3,STRTAD ;THIS HOLE NOT GOOD ENOUGH
POPJ P, ;ERROR RETURN IF START ADDRESS GIVEN
SETCA T1, ;NOW WE WANT TO COUNT 1'S
LSH T1,1(T2) ;REMOVE BITS WE ALREADY LOOKED AT
JUMPE T1,GETZ4 ;GO IF THE REST OF THE WORD IS ALL ONES
GETZ3: JFFO T1,.+1 ;NUMBER OF (REAL) 1'S
LSH T1,(T2) ;GET RID OF THEM
CAIN T4,^D36 ;1ST POSITION IN WORD?
ADDI T4,1 ;YES, SUBTRACT REAL JFFO COUNT
SUBI T4,1(T2) ;DECREASE POSITION COUNT
JUMPG T4,GETZ1 ;TRY NEXT 0 - HOLE
GETZ4: AOBJN P1,GETZ0 ;1'S ON END - START FRESH AT NEXT WORD
;HERE IF THE DESIRED SIZE NOT YET FOUND, BUT THE WORD HAD 0'S ON THE END
GETZ5: AOBJP P1,CPOPJ ;THROUGH IF END OF SAT
HRRM P1,-2(P) ;STORE UPDATED AOBJN POINTER
SKIPGE T1,@-2(P) ;NEXT WORD POSITIVE?
JRST GETZ0 ;NO. THIS HOLE NOT GOOD ENOUGH
JFFO T1,.+2 ;YES. COUNT THE 0'S
MOVEI T2,^D36 ;36 0'S
ADDI T3,(T2) ;ADD TO PREVIOUS ZERO-COUNT
MOVEI T4,^D36 ;RESET T4
JRST GETZ2 ;AND TEST THIS HOLE
;SUBROUTINE TO SET UP A BIT MASK FOR IORM OR ANDCAM INTO A TABLE
;ENTER WITH T1=POSITION (36=BIT0, 1=BIT35)
; AND T3=HOW MANY
;AFTER THE FIRST CALL USE BITMS2, T3=COUNT RETURNS T1=MASK,
;T3=REMAINING COUNT ROUTINE HAS RETURNED FINAL MASK IF
;T3 .LE. 0 ASSUMES T4=ADR IN TABLE, BITMS2 INCREMENTS T4
BITMSK::PUSH P,T1 ;SAVE POSITION
MOVN T1,T3 ;- COUNT
CAILE T3,^D36 ;MORE THAN 1 WORD?
MOVNI T1,^D36 ;YES, SETTLE FOR A WORD (OR LESS)
MOVSI T2,400000 ;SET TO PROPOGATE A MASK
ASH T2,1(T1) ;GET THE RIGHT NUMBER OF BITS
SETZ T1,
LSHC T1,@0(P) ;POSITION THE BITS IN T1 (=MASK)
SUB T3,0(P) ;REDUCE THE COUNT TO THE NEW VALUE
PJRST T2POPJ ;AND RETURN
;HERE AFTER FIRST CALL, MASK STARTS AT BIT 0
BITMS2::SETO T1, ;MASK STARTS AT BIT 0
MOVNI T2,-^D36(T3) ;SET UP SHIFT
CAIGE T3,^D36 ;DONT SHIFT IS .GE. 36
LSH T1,(T2) ;POSTION THE MASK
SUBI T3,^D36 ;REDUCE THE COUNT
AOJA T4,CPOPJ ;UPDATE THE POSITION AND RETURN
;SUBROUTINE TO MARK BITS AS TAKEN IN A TABLE
;USES ACS AS RETURNED BY GETZ - P3=HOW MANY
; LH(P4)=POSITION, RH(P4)=WHERE (POSITION=36 IF BIT0, 1 IF BIT35)
;RETURNS CPOPJ IF BIT IS ALREADY SET, CPOPJ1 NORMALLY, RESPECTS T1
SETOS:: PUSHJ P,SETR ;SETUP INDIRECT POINTER TO THE BIT TABLE
PUSH P,T1 ;SAVE T1
MOVE T4,P4 ;WHERE
HRRZ T3,P3 ;COUNT
HLRZ T1,P4 ;POSITION IN WORD
PUSHJ P,BITMSK ;SET UP A MASK
SETOS1: HRRM T4,-3(P) ;FOR INDIRECT
TDNE T1,@-3(P) ;BIT ALREADY ON?
JRST SETOS2 ;YES
IORM T1,@-3(P) ;NO, NOW IT IS
JUMPLE T3,TPOPJ1 ;DONE IF COUNT .LE. 0
PUSHJ P,BITMS2 ;NOT DONE, GET MASK FOR NEXT WORD
JRST SETOS1 ;AND GO SET THE BITS IN THAT WORD
;HERE IF BIT ALREADY ON
SETOS2: PUSH P,T3 ;SAVE CURRENT COUNT
HLRZ T1,P4 ;RESTORE ORIGINAL VALUES
HRRZ T3,P3
MOVE T4,P4
PUSHJ P,BITMSK ;AND GENERATE A MASK
SETOS3: HRRM T4,-4(P) ;SET FOR INDIRECT
CAMN T3,(P) ;IS THE COUNT FOR MASK=COUNT WHEN SET?
JRST SETOS4 ;YES, DONE
ANDCAM T1,@-4(P) ;NO, CLEAR THOSE BITS
PUSHJ P,BITMS2 ;GENERATE NEXT MASK
JRST SETOS3 ;AND CONTINUE
SETOS4: POP P,(P) ;CLEARED ALL THE RIGHT BITS - FIX PD LIST
JRST TPOPJ ;AND NON-SKIP RETURN
;SUBROUTINE TO OBTAIN FREE BITS, MARK THEM AS TAKEN IN THE TABLE
;ENTER WITH T1=HOW MANY,
;T2=XWD ADR OF 1ST WORD OF TABLE, ADR OF TABLE AOBJN WORD (OR 0, LOC OF AOBJN)
;RETURNS CPOPJ IF NOT ENOUGH AVAILABLE, T1=SIZE OF LARGEST HOLE
;RETURNS CPOPJ1 IF GOTTEN, T1= RELATIVE ADDRESS OF BLOCK OBTAINED
;T3 IS UPDATED AOBJN POINTER
GETBIT::PUSHJ P,SAVE4 ;SAVE P1-P4
TLNN T2,-1 ;STARTING AT AN OFFSET?
HRL T2,(T2) ;NO, START AT FIRST WORD
PUSH P,T2 ;SAVE ADR OF AOBJN WORD FOR TABLE
GETBI1: HRRZ P1,0(P) ;GET AOBJN WORD
MOVE P1,(P1)
SETZ P2, ;NO BEST SO FAR
MOVE P3,T1 ;NUMBER OF BITS TO GET
PUSHJ P,GETZ ;GET THE BITS
JRST GETBI2 ;NOT ENOUGH AVAILABLE
HRRZ T1,P4 ;GOT THEM - FIRST WORD WITH ZEROES
HLRZ T2,(P) ;LOC OF FIRST WORD OF TABLE
SUBI T1,(T2) ;COMPUTE RELATIVE ADDRESS OF START
IMULI T1,^D36 ;36 BITS PER WORD
HLRZ T2,P4 ;BIT POSITION OF 1ST 0 IN THE WORD
MOVNS T2
ADDI T1,^D36(T2) ;T1= RELATIVE LOC WITHIN THE TABLE
PUSHJ P,SETOS ;MARK THE BITS AS TAKEN
SKIPA T1,P3 ;SOME FINK SNUCK IN ON US!
AOSA -1(P) ;GOT THEM - WIN RETURN
JRST GETBI1 ;TRY AGAIN TO GET SOME BITS
MOVE T3,P1 ;UPDATED POINTER
JRST T2POPJ ;RETURN
;HERE IF NOT ENOUGH ARE AVAILABLE
GETBI2: MOVE T1,P2 ;T1=LARGEST HOLE FOUND
PJRST T2POPJ ;NON-SKIP RETURN
;INTERFACE ROUTINE TO GETZ/SETOS WHICH ALLOWS THEM TO BE CALLED WITH AN
; EXTENDED ADDRESS AND A AOBJN POINTER RELATIVE TO A BIT TABLE
;CALLING SEQUENCE:
; MOVE R,ADDRESS OF THE BIT TABLE
; MOVE P1,AOBJN POINTER RELATIVE TO THE TABLE
; TLO P3,RELABP ;INDICATE THIS FORM OF CALL
; PUSHJ P,SETR ;MUST BE IN A NON-ZERO SECTION IF RELABP IS ON
;ALWAYS RETURN CPOPJ, -2(P) IS AN INSTRUCTION FORMAT INDIRECT WORD TO BIT TABLE
SETR: PUSH P,R ;SAVE R, SOME CALLERS MAY WANT IT RETURNED
MOVSI R,400000+R ;LOCAL INSTRUCTION FORMAT INDIRECT WORD
EXCH R,-1(P) ;SAVE IT ON THE STACK, GET RETURN ADDRESS
MOVEM R,1(P) ;TO CALL THE CALLER
IFN FTXMON,<
TLNN P3,RELABP ;RELATIVE AOBJN POINTER SPECIFIED?
JRST SETR1 ;NO, OLD CALL
SKIPE KSFLAG ;DON'T CHECK SECTION ON KS
JRST SETR0
TLNN R,(SECMSK) ;MUST BE IN A NON-ZERO SECTION IF RELABP IS ON
STOPCD SETR2,DEBUG,NNS,;++NOT IN A NON-ZERO SECTION
>
SETR0: TLNN P3,RELABP ;NEW CALL?
SETR1: TDZA R,R ;NO, NO RELOCATION
MOVE R,(P) ;YES, GET RELOCATION
PUSHJ P,@1(P) ;CALL CALLER AS A COROUTINE
CAIA ;NON-SKIP RETURN
AOS -2(P) ;PROPAGATE SKIP
SETR2: POP P,R ;RESTORE R
POP P,(P) ;POP OFF JUNK
POPJ P, ;AND RETURN
DOHALT::HALT .
DIE:: PUSHJ P,OTSET ;INITIALIZE BUFFERS AND POINTERS
MOVEI T1,[ASCIZ .?STOPCD .]
PUSHJ P,CONMES
MOVE T1,(P) ;GET PC+1 OF CALLER
MOVE T1,-1(T1) ;GET XCT INSTRUCTION
MOVE T2,1(T1) ;GET STOPCODE NAME
PUSHJ P,PRNAME
PUSHJ P,CRLF
PUSHJ P,OPOUT
EXIT
ILLINP::STOPCD .,HALT,INP
; CO-ROUTINE TO ENTER SECTION ZERO
SSEC0:: EXCH T1,(P) ;GET PC WE WERE CALLED AT
TLZN T1,37 ;MAKE SURE IT IS AN EXTENDED PC
JRST [EXCH T1,(P) ;RESTORE T1
POPJ P,] ;AND RETURN IN SECTION 0 (ROUTINE IS A NOOP).
PUSH P,T1 ;SAVE AS A SECTION 0 PC.
HRRZI T1,SSEC0E ;NOTE SECTION 0 PC.
EXCH T1,-1(P) ;RESTORE T1, LEAVE A RETURN PATH TO US.
POPJ P, ;"RETURN" TO CALLER.
SSEC0E: SKIPA ;RETURNED NON-SKIP, LEAVE EVERYTHING ALONE
AOS (P) ;SKIP RETURN, BUMP CALLERS PC
EXCH T1,(P) ;GET RETURN PC TO HIGHER LEVEL ROUTINE.
TLZ T1,777740 ;WIPE FLAGS IN CASE SECTION 0 PC
MOVEM T1,1(P) ;SAVE AS PC PART OF XJRSTF DUO-WORD
POP P,T1 ;RESTORE T1
XJRST 2(P) ;RETURN IN PROPER SECTION
; CO-ROUTINE TO ENTER SECTION ONE
SSEC1:: PUSH P,T1 ;SAVE A TEMP
XMOVEI T1,. ;CURRENT SECTION
TLNE T1,-1 ;ARE WE ALREADY EXTENDED?
JRST TPOPJ ;YES, GO HOME
HRRZS -2(P) ;MAKE CALLER RETURN TO SECTION 0
MOVSI T1,1 ;A SECTION 1
HLLM T1,-1(P) ;FOR OUR POPJ
XJRST [MCSEC1+TPOPJ] ;ENTER SECTION 1 AND RETURN
;SUBROUTINES TO SAVE AND RESTORE PRESERVED ACS
;SAVEN IS CALLED AT THE BEGINNING OF A SUBROUTINE
;FOR CONVENIENCE NO MATCHING SUB IS NEEDED TO BE CALLED
;TO RESTORE THIS ACS.
;INSTEAD AN EXTRA RETURN IS PUT ON STACK
;5 CHAR NAME INDICATES IT VIOLATES
;SUBROUTINE CALLING CONVENTIONS
;CALL: PUSHJ P,SAVEN
; RETURN HERE IMMEDIATELY WITH EXTRA RETURN ON STACK
; RESPECTS ALL ACS
;NOTE: THIS CODE USES 1 LOC BEYOND END OF STACK BUT THEN PUSHES ON TOP OF IT
;SO GET OVERFLOW INTERUPT IF TOO FULL. OK TO DO 1(P) SINCE THIS WORD WRITTEN ON OVERFLOW
SAVE1:: EXCH P1,(P) ;SAVE P1, GET CALLER PC
MOVEM P1,1(P) ;SAVE CALLER PC ONE BEYOND END
MOVE P1,(P) ;RESTORE P1
PUSHJ P,@1(P) ;GO BACK TO CALLER, OVERWRITE CALLER PC WITH .+1
JRST RES1
AOS -1(P)
JRST RES1
SAVE2:: EXCH P1,(P) ;SAVE P1, GET CALLER PC
PUSH P,P2
MOVEM P1,1(P) ;SAVE CALLER PC ONE BEYOND END
MOVE P1,-1(P) ;RESTORE P1
PUSHJ P,@1(P) ;GO BACK TO CALLER, OVERWRITE CALLER PC WITH .+1
JRST RES2
AOS -2(P)
JRST RES2
SAVE3:: EXCH P1,(P) ;SAVE P1, GET CALLER PC
PUSH P,P2
PUSH P,P3
MOVEM P1,1(P) ;SAVE CALLER PC ONE BEYOND END
MOVE P1,-2(P) ;RESTORE P1
PUSHJ P,@1(P) ;GO BACK TO CALLER, OVERWRITE CALLER PC WITH .+1
JRST RES3
AOS -3(P)
JRST RES3
SAVE4:: EXCH P1,(P) ;SAVE P1, GET CALLER PC
PUSH P,P2
PUSH P,P3
PUSH P,P4
MOVEM P1,1(P) ;SAVE CALLER PC ONE BEYOND END
MOVE P1,-3(P) ;RESTORE P1
PUSHJ P,@1(P) ;GO BACK TO CALLER, OVERWRITE CALLER PC WITH .+1
JRST RES4
AOS -4(P)
RES4: POP P,P4
RES3: POP P,P3
RES2: POP P,P2
RES1: POP P,P1
POPJ P,
;SUBROUTINE TO SAVE AND RESTORE TEMP ACS
;CALLED BY PUSHJ P,SAVT RETURN EITHER CPOPJ OR CPOPJ1 WHEN THROUGH
SAVT:: EXCH T4,(P) ;SAVE T4, GET RETURN ADR.
PUSH P,T3 ;SAVE T3
PUSH P,T2 ;AND T2
PUSH P,T1 ;AND T1
MOVEM T4,1(P) ;STORE PC
MOVE T4,-3(P) ;RESTORE T4
PUSHJ P,@1(P) ;RETURN TO CALLER
SKIPA ;POPJ RETURN
AOS -4(P) ;CPOPJ1 - SET SKIP RETURN
POP P,T1 ;RESTORE T1
POP P,T2 ;RESTORE T3 ACS
POP P,T3
POP P,T4
POPJ P, ;AND RETURN
SUBTTL DISK OFF LINE INTERCEPTION
;WHEN A FILE STRUCTURE IS REMOVED VIA STRUUO, AND THE OPERATOR
; REMOVES THE PACK(S), THE RP10 HARDWARE DOES NOT INTERRUPT
; AS THE UNIT GOES OFF LINE, NOR IS THERE ANY WAY TO PASSIVELY CHECK
; TO SEE IF THE UNIT IS OFF LINE. THEREFORE, TWICE MUST INTERCEPT
; THE DISK OFF LINE MESSAGE.
;
;ON THE KS, AN XJRST IS AN ILLEGAL INSTRUCTION. INTERCEPT IT HERE
;AND SIMULATE IT BY DOING THE APPROPRIATE JRST.
;
DOLBLK: XWD 4,DOLINT ;INTERRUPT TO DOLINT
EXP ER.MSG!ER.OFL!ER.EIJ ;INHIBIT MESSAGE, TRAP ON DISK OFF LINE
;AND "ERROR IN JOB" (XJRST)
DOLPC: 0 ;STARTS OUT ZERO
0 ;EXTRA STUFF
DOLINT: MOVEM T1,DOLSAV ;SAVE T1
MOVSI T1,ER.EIJ ;SEE WHAT KIND OF ERROR WE GOT
TDZN T1,DOLPC+1 ;WAS IT "ERROR IN JOB"?
JRST DOLIN1 ;NO, MUST BE DISK OFFLINE
SOS T1,DOLPC ;BACK UP THE PC, AND FETCH IT
MOVE T1,(T1) ;GET FAILING INSTRUCTION
TLCE T1,(XJRST) ;IS IT AN XJRST?
TLNE T1,777740 ; IN THE INSTRUCTION PART OF THE WORD?
JRST @DOLPC ;NO, RE-DO THE INSTRUCTION TO GET REAL ERROR
EXCH T1,DOLSAV ;RESTORE OLD T1, STORE "E" PART OF INSTRUCTION
MOVEM T1,DOLSAV+1 ;SAVE T1 IN ANOTHER PLACE TOO
HRRZ T1,@DOLSAV ;USE ONLY 18-BIT ADDRESS NOW
EXCH T1,DOLSAV+1 ;RESTORE T1 AND SAVE TARGET ADDRESS
SETZM DOLPC ;ALLOW MORE INTERRUPTS
JRST @DOLSAV+1 ;FINALLY, DO THE JRST
DOLIN1: SETZ T1, ;CLEAR DOLPC SO WE CAN INTERRUPT AGAIN
EXCH T1,DOLPC ;
EXCH T1,DOLSAV ;GET PC INTO DOLSAV, RESTORE T1
OUTSTR [ASCIZ/% Unexpected disk off line condition
/]
JRST @DOLSAV ;RETURN
DOLSAV: BLOCK 2
;ROUTINES TO SAVE AND RESTORE SETKON ROUTINE SO THAT TWICE CAN CONTROL
; WHEN UNIT STATUS' ARE CLEARED.
; CALL ONCE BEFORE ENTERING ACTUAL ONCE CODE, AND BEFORE EXITING.
SAVKON: PUSHJ P,SETKON## ;CALL SAVKON NOW TO CLEAR OUT STATUS'
MOVE T1,CPOPJ ;GET A POPJ
EXCH T1,SETKON##+1 ;GET INSTRUCTION TO BE REPLACED, MAKE IT POPJ
MOVEM T1,KONSAV ;SAVE THE INSTRUCTION
POPJ P, ;RETURN
RESKON: MOVE T1,KONSAV ;GET OLD INSTRUCTION
MOVEM T1,SETKON##+1 ;RESTORE OLD INSTRUCTION
POPJ P, ;RETURN
KONSAV: BLOCK 1 ;PLACE TO SAVE INSTRUCTION
SUBTTL ROUTINES TO SATISFY KONTROLLER REQUESTS IN ONCMOD
;COMMOD.MAC WILL CONDITIONALLY DEFINE CERTAIN SYMBOLS BASED ON
;THE VALUES OF M.RC10 AND M.RP10. THESE DUMMY DEFINITIONS ARE
;DONE TO SATISFY GLOBAL REQUESTS AT LINK TIME. IF COMMOD HAS
;ALREADY DEFINED THEM, THEN TWICE SHOULD NOT, AND VISA-VERSA.
;THEREFORE, THE CONDITIONALS HERE ARE SIMPLY REVERSED FROM THOSE
;IN COMMOD.MAC
XP RD10N,M.RC10
XP RP10N,M.RP10
USRCPY::MOVE T1,UNINAM##(U) ;NAME OF UNIT
MOVEM T1,CHRBUF ;STORE FOR DSKCHR
MOVE T1,[XWD .DCMAX,CHRBUF]
DSKCHR T1, ;FIND OUT ABOUT UNIT
JRST USRCP1 ;NO SUCH UNIT
MOVE T2,CHRBUF+.DCBUM ;BLOCKS/UNIT PLUS MAINTENANCE BLOCKS
MOVE T3,CHRBUF+.DCBUC ;BLOCKS/UNIT IN COMPATIBILITY MODE
LDB T4,[POINTR T1,DC.UNT] ;GET UNIT TYPE
LDB W,[POINTR CHRBUF+.DCUCH,DC.UCT] ;BLOCKS/TRACK
HRLZS W ;IN LEFT HALF
HRR W,CHRBUF+.DCUCH ;BLOCKS/CYLINDER
TLNE T1,(DC.OFL) ;SKIP UNLESS UNIT OFF LINE
TLOA T4,KOPUHE## ;FLAG THAT ONCMOD EXPECTS
AOS (P) ;ON LINE, SKIP RETURN
MOVE T1,CHRBUF+.DCUSZ ;CAPACITY OF UNIT
POPJ P,
USRCP1: MOVSI T4,KOPUHE## ;SET FLAG FOR ONCMOD
TLO T4,KOPNSU## ;NOTE ALSO NO SUCH UNIT
POPJ P, ;RETURN
FHXUPA::
FSXUPA::
RPXUPA::
RNXUPA::
DPXUPA::MOVEI T1,1 ;RETURN WRITE HEADER LOCKOUT SWITCH OFF
JRST CPOPJ1 ;ALWAYS RETURN KONTROLLER ON LINE
UVACKS::SKIPA T2,T1
DODTI4::
IFN RP10N,< ;IF RP10 CONTROLLERS:
DPXSTS:: ;THEN DEFINE SINCE COMMOD DID NOT
>
MOVEI T2,0 ;DUMMY READ STATUS ROUTINE
POPJ P, ;ALWAYS CALLED BY ONCMOD
;RETURN 0 STATUS(NOT WRTIE LOCKED)
DEFINE CHNCB(N),<
CHN'N'CB==:0
>
CHNCB (\M.CHN)
DEFINE KONKON(TYPE),<
IRP TYPE,<
..XX==0
REPEAT 4,<
..YY==0
REPEAT ^D8,<
KONSAV(TYPE,\<..XX*10+..YY>)
..YY==..YY+1
>
..XX==..XX+1
>
TYPE'XERR::
TYPE'XWRT::
TYPE'XWTC::
TYPE'XWTF::
TYPE'XWTS::
TYPE'XINT::
TYPE'XECC::
TYPE'XUNL::
TYPE'XPOS::
TYPE'XLTM::
TYPE'XRCL::
TYPE'XRED::
TYPE'XSTP::
TYPE'XRDF::
TYPE'XRDC::
TYPE'XRDS::
TYPE'XKON::
TYPE'XCPY::
>>
DEFINE KONSAV(TYPE,CHN),<
TYPE'CHN'SAV::
TYPE'CHN'SV::
>
KONKON (<FH,FS,DP,RP,RN>)
SUBTTL ROUTINES TO SATISFY UNNEEDED GLOBAL REQUESTS
;MACRO TO SATISFY GLOBAL REQUESTS FOR ERROR RETURN LABELS
DEFINE ERCALC(A),<ECOD'A::>
;GENERATE THE LABELS
.N==0
REPEAT ECDMAX,<
ERCALC(\.N)
.N==.N+1
>
;GENERATE SKPCPU MACRO LABELS
DEFINE SKPXXX(A),<
IRP A,<$SCP'A::>
>
;GENERATE THE LABELS
SKPXXX(<A,I,L,AI,AL,IA,IL,LI,LA>)
.PDJSE::.PDJSL::COMERA::CPUJOB::CTLJBD::DAEEIM::FNDQSR::GETWRD::MEMSIZ::
QSRSPL::SETLGL::SLEEP::TTYFNU::TTYTAB::%SIQSR::
DODELE::FNDPDB::GCH4WD::JBTST2::T2POJ1::VIRTAL::
TDVKDB::TDVUDB::TKBCDB::TTMCIC::TTMCIS::TTMCOC::TTXCIS::TTXCOS::
MCUALT::MCUATP::TUYKTP::
GTWST2::PUTWDU::PUTWD1::JBTPRV::IPOPJ::IPOPJ1::PUUOAC::IADRCK::
STOTC1::DVCNSG::RTM1::RTZER::SYSINI::DSKINI::REMSEG::STOP1::WAIT1::SERIAL::JOB::
SAVDDL::DEVLG::IOIERR::ADVBFE::SETACT::CLRACT::CLOSE1::CLOCK::REGSIZ::STDIOD::
SWPINT::OUT::JBTPPN::JBTNAM::JBTLOC::JBTSPL::USRJDA::USRHCU::UUOERR::
WSYNC::DEVLST::STOTAC::STOIOS::ADVBFF::USCHED::CVTSBT::OPRLDB::MQREQ::
MQAVAL::CBAVAL::CBREQ::PJOBN::FREPTR::GET4WD::GIV4WD::GETWDS::GIVWDS::UADCK1::
LOCOCW::DAAVAL::AUAVAL::AUREQ::COMCHK::INLMES::GETJOB::HIGHJB::GETWDU::
GETWD1::PROT::PROT0::REFLOG::CDVSBT::PDVCNT::HNGSTP::TTYSTR::TTYFUW::
LGLPRC::ILLOUT::CHNNXM::
DAUSER::NU0DAC::SVEUF::CLRBTS::CHNMPE::CHNDPE::DAEERR::SVEUB::MAPIO::SETINT::RTNIOW::
AUUSER::GIVRES::WRDCNT::CBUSER::HOLD0::WSCHED::
MP3::MPDPRA::
MTXCHB::CNIMTS::CNIMTC::CNFMTA::MTXCDB::FLG256::.C0JOB::SETDVL::PUTWRD::
UADRCK::TSETBI::ILLINS::CNOCLR::RTM2::
ATTMPA::DETMPA::SAVJW::SNDMDN::
DLYCM::UADERR::ARNGE::
TTYFND::STOPCD .,HALT,NM4,
IFN RP10N,<
;SATISFY GLOBALS IN DPXCPY AND DPXUPA WHICH WILL NEVER BE CALLED BUT DO GET LOADED IF NO RP10'S
;THIS ASSEMBLES IF THE ONE IN COMMOD DOES NOT.
XP DPDONE,0
XP DPCLR,0
XP DPATTN,0
>
IFN RD10N,<
;SATISFY GLOBALS IN FHXCPY AND FHXUPA WHICH WILL NEVER BE CALLED BUT ARE LOADED IF NO RD10'S
;THIS ASSEMBLES IF THE ONE IN COMMOD DOES NOT.
XP FHALCL,0
> ;END CONDITIONAL ON RD10N
BITTBL::
SALL
ZZ==1B0
REPEAT ^D36,<
EXP ZZ
ZZ==ZZ_<-1>
>
XALL
DAFREE::AUFREE::CBFREE::MQFREE::MQWAIT::CBWAIT::DAWAIT::AUWAIT::
PRVJ::
RSPWT1::POPJ P,
T4POPJ::POP P,T4
POPJ P,
JBTSTS::BLOCK 1
FORCEF::BLOCK 1
SWPLST::BLOCK 1
SW2LST::BLOCK 1
SW3LST::BLOCK 1
BMSLST::BLOCK 1
REFLAG::BLOCK 1
DDSTAR::BLOCK 1
SYSSIZ::BLOCK 1 ;WRITABLE FOR FILMAN
SYSCHN::BLOCK 1
CNFCHN::BLOCK 1
DAREQ:: BLOCK 1
LOCORE::BLOCK 1
ONCEND::BLOCK 1
SYSINA::SYSDSP::SYSINI
THSDAT::BLOCK 1
TIME:: BLOCK 1
TICMIN::EXP ^D60*^D60
TICSEC::EXP ^D60
DEBUGF::BLOCK 1
FINISH::BLOCK 1
SKPCPI::JFCL
DATE:: BLOCK 1
.C0ASN::
.CPASN::BLOCK 1
.C0OK::
.CPOK:: BLOCK 1
.CPLOG::BLOCK 1
.CPRUN::BLOCK 1
.C0AEF::BLOCK 1
JBTADR::BLOCK 1
PAGINC::EXP 0
PAGSNC::EXP 0
FILFLG::BLOCK 1 ;SCRATCH FILE FLAG
TWCFIL::BLOCK 4 ;LOOKUP/ENTER BLOCK FOR SCRATCH FILE
RETRYC::BLOCK 1 ;RETRY COUNTER FOR CREATING SCRATCH FILE
CHRBTS: BLOCK 1 ;DSKCHR UUO BITS
PREASL::BLOCK 1
PRESSL::BLOCK 1
PRESDL::BLOCK 1
K2PLSH==:1
PAGSIZ==:1000
PG.BDY==:PAGSIZ-1
P2KLSH==:-K2PLSH
JOBMAX=:M.JOB
SKPCPA==:0
MSK22B==:0
SUBTTL DATA AND STORAGE
LINEP: POINT 7,LINBUF
CHRBUF: BLOCK .DCMAX
CURUNI: BLOCK 1
LINBUF: BLOCK LINSIZ
ONCTSZ==LINSIZ*5-1
ONCTIP: BLOCK 1
ONCTOP: BLOCK 1
ONCCNT: BLOCK 1
TTCMCH: BLOCK 1
OURPPN: BLOCK 1
KSFLAG: BLOCK 1 ;0=KL10 / 1=KS10
ONCPDL::
PDLIST: BLOCK PDLEN
PATCH:: BLOCK 100
END TWICE